diff options
author | dtrainor <dtrainor@chromium.org> | 2015-10-28 09:02:52 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-28 16:03:33 +0000 |
commit | 2191e4d3cb6b574fd532547a8f93e02f9168a706 (patch) | |
tree | 557ba88e2f263f76111a1f717543e75e71914d09 | |
parent | c754d858cdae6ae15a554ecbc003d67b41168605 (diff) | |
download | chromium_src-2191e4d3cb6b574fd532547a8f93e02f9168a706.zip chromium_src-2191e4d3cb6b574fd532547a8f93e02f9168a706.tar.gz chromium_src-2191e4d3cb6b574fd532547a8f93e02f9168a706.tar.bz2 |
Add protobuf serialization to DisplayItemList
Serialize the following classes:
- DisplayItemListSettings
- DisplayItemList
- DisplayItem and all subclasses
- Did not fully serialize FilterDisplayItem. Serializing
FilterOperations will require more work. Will do in a follow up CL.
Added unit tests for all DisplayItems serialized.
BUG=541321
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1407793002
Cr-Commit-Position: refs/heads/master@{#356563}
28 files changed, 787 insertions, 13 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 778f637..2ff2593 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn @@ -292,6 +292,8 @@ component("cc") { "playback/display_item_list.h", "playback/display_item_list_settings.cc", "playback/display_item_list_settings.h", + "playback/display_item_proto_factory.cc", + "playback/display_item_proto_factory.h", "playback/display_list_raster_source.cc", "playback/display_list_raster_source.h", "playback/display_list_recording_source.cc", @@ -354,6 +354,8 @@ 'playback/display_item_list.h', 'playback/display_item_list_settings.cc', 'playback/display_item_list_settings.h', + 'playback/display_item_proto_factory.cc', + 'playback/display_item_proto_factory.h', 'playback/display_list_raster_source.cc', 'playback/display_list_raster_source.h', 'playback/display_list_recording_source.cc', @@ -581,6 +583,7 @@ 'target_name': 'cc_proto', 'type': '<(component)', 'sources': [ + 'proto/display_item.proto', 'proto/point.proto', 'proto/pointf.proto', 'proto/rect.proto', diff --git a/cc/playback/clip_display_item.cc b/cc/playback/clip_display_item.cc index 5941502..ac2bc93 100644 --- a/cc/playback/clip_display_item.cc +++ b/cc/playback/clip_display_item.cc @@ -6,8 +6,12 @@ #include <string> +#include "base/logging.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/gfx_conversions.h" +#include "cc/proto/skia_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/skia_util.h" @@ -31,6 +35,30 @@ void ClipDisplayItem::SetNew(gfx::Rect clip_rect, external_memory_usage); } +void ClipDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_Clip); + + proto::ClipDisplayItem* details = proto->mutable_clip_item(); + RectToProto(clip_rect_, details->mutable_clip_rect()); + DCHECK_EQ(0, details->rounded_rects_size()); + for (const auto& rrect : rounded_clip_rects_) { + SkRRectToProto(rrect, details->add_rounded_rects()); + } +} + +void ClipDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_Clip, proto.type()); + + const proto::ClipDisplayItem& details = proto.clip_item(); + gfx::Rect clip_rect = ProtoToRect(details.clip_rect()); + std::vector<SkRRect> rounded_clip_rects; + rounded_clip_rects.reserve(details.rounded_rects_size()); + for (int i = 0; i < details.rounded_rects_size(); i++) { + rounded_clip_rects.push_back(ProtoToSkRRect(details.rounded_rects(i))); + } + SetNew(clip_rect, rounded_clip_rects); +} + void ClipDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { @@ -82,6 +110,14 @@ EndClipDisplayItem::EndClipDisplayItem() { EndClipDisplayItem::~EndClipDisplayItem() { } +void EndClipDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_EndClip); +} + +void EndClipDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_EndClip, proto.type()); +} + void EndClipDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { diff --git a/cc/playback/clip_display_item.h b/cc/playback/clip_display_item.h index 83e0b6b..320ea31 100644 --- a/cc/playback/clip_display_item.h +++ b/cc/playback/clip_display_item.h @@ -25,6 +25,8 @@ class CC_EXPORT ClipDisplayItem : public DisplayItem { void SetNew(gfx::Rect clip_rect, const std::vector<SkRRect>& rounded_clip_rects); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; @@ -40,6 +42,8 @@ class CC_EXPORT EndClipDisplayItem : public DisplayItem { EndClipDisplayItem(); ~EndClipDisplayItem() override; + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/playback/clip_path_display_item.cc b/cc/playback/clip_path_display_item.cc index f7fd606..3b46621 100644 --- a/cc/playback/clip_path_display_item.cc +++ b/cc/playback/clip_path_display_item.cc @@ -6,6 +6,8 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/skia_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" namespace cc { @@ -29,6 +31,39 @@ void ClipPathDisplayItem::SetNew(const SkPath& clip_path, 0 /* external_memory_usage */); } +void ClipPathDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_ClipPath); + + proto::ClipPathDisplayItem* details = proto->mutable_clip_path_item(); + details->set_clip_op(SkRegionOpToProto(clip_op_)); + details->set_antialias(antialias_); + + // Just use skia's serialization method for the SkPath for now. + size_t path_size = clip_path_.writeToMemory(nullptr); + if (path_size > 0) { + scoped_ptr<char[]> buffer(new char[path_size]); + clip_path_.writeToMemory(buffer.get()); + details->set_clip_path(std::string(buffer.get(), path_size)); + } +} + +void ClipPathDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_ClipPath, proto.type()); + + const proto::ClipPathDisplayItem& details = proto.clip_path_item(); + SkRegion::Op clip_op = SkRegionOpFromProto(details.clip_op()); + bool antialias = details.antialias(); + + SkPath clip_path; + if (details.has_clip_path()) { + size_t bytes_read = clip_path.readFromMemory(details.clip_path().c_str(), + details.clip_path().size()); + DCHECK_EQ(details.clip_path().size(), bytes_read); + } + + SetNew(clip_path, clip_op, antialias); +} + void ClipPathDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { @@ -50,6 +85,14 @@ EndClipPathDisplayItem::EndClipPathDisplayItem() { EndClipPathDisplayItem::~EndClipPathDisplayItem() { } +void EndClipPathDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_EndClipPath); +} + +void EndClipPathDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_EndClipPath, proto.type()); +} + void EndClipPathDisplayItem::Raster( SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, diff --git a/cc/playback/clip_path_display_item.h b/cc/playback/clip_path_display_item.h index 732087b..6e42539 100644 --- a/cc/playback/clip_path_display_item.h +++ b/cc/playback/clip_path_display_item.h @@ -22,6 +22,8 @@ class CC_EXPORT ClipPathDisplayItem : public DisplayItem { void SetNew(const SkPath& path, SkRegion::Op clip_op, bool antialias); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; @@ -42,6 +44,8 @@ class CC_EXPORT EndClipPathDisplayItem : public DisplayItem { return make_scoped_ptr(new EndClipPathDisplayItem()); } + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/playback/compositing_display_item.cc b/cc/playback/compositing_display_item.cc index 31365b5..2489d3c 100644 --- a/cc/playback/compositing_display_item.cc +++ b/cc/playback/compositing_display_item.cc @@ -6,7 +6,13 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/gfx_conversions.h" +#include "cc/proto/skia_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkData.h" +#include "third_party/skia/include/core/SkFlattenable.h" +#include "third_party/skia/include/core/SkFlattenableSerialization.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/skia_util.h" @@ -36,6 +42,46 @@ void CompositingDisplayItem::SetNew(uint8_t alpha, external_memory_usage); } +void CompositingDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_Compositing); + + proto::CompositingDisplayItem* details = proto->mutable_compositing_item(); + details->set_alpha(static_cast<uint32_t>(alpha_)); + details->set_mode(SkXfermodeModeToProto(xfermode_)); + if (has_bounds_) + RectFToProto(gfx::SkRectToRectF(bounds_), details->mutable_bounds()); + + if (color_filter_) { + skia::RefPtr<SkData> data = + skia::AdoptRef(SkValidatingSerializeFlattenable(color_filter_.get())); + if (data->size() > 0) + details->set_color_filter(data->data(), data->size()); + } +} + +void CompositingDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_Compositing, proto.type()); + + const proto::CompositingDisplayItem& details = proto.compositing_item(); + uint8_t alpha = static_cast<uint8_t>(details.alpha()); + SkXfermode::Mode xfermode = SkXfermodeModeFromProto(details.mode()); + scoped_ptr<SkRect> bounds; + if (details.has_bounds()) { + bounds.reset( + new SkRect(gfx::RectFToSkRect(ProtoToRectF(details.bounds())))); + } + + skia::RefPtr<SkColorFilter> filter; + if (details.has_color_filter()) { + SkFlattenable* flattenable = SkValidatingDeserializeFlattenable( + details.color_filter().c_str(), details.color_filter().size(), + SkColorFilter::GetFlattenableType()); + filter = skia::AdoptRef(static_cast<SkColorFilter*>(flattenable)); + } + + SetNew(alpha, xfermode, bounds.get(), filter.Pass()); +} + void CompositingDisplayItem::Raster( SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, @@ -66,6 +112,14 @@ EndCompositingDisplayItem::EndCompositingDisplayItem() { EndCompositingDisplayItem::~EndCompositingDisplayItem() { } +void EndCompositingDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_EndCompositing); +} + +void EndCompositingDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_EndCompositing, proto.type()); +} + void EndCompositingDisplayItem::Raster( SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, diff --git a/cc/playback/compositing_display_item.h b/cc/playback/compositing_display_item.h index 91cd3e7..8042de6 100644 --- a/cc/playback/compositing_display_item.h +++ b/cc/playback/compositing_display_item.h @@ -28,6 +28,8 @@ class CC_EXPORT CompositingDisplayItem : public DisplayItem { SkRect* bounds, skia::RefPtr<SkColorFilter> color_filter); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; @@ -50,6 +52,8 @@ class CC_EXPORT EndCompositingDisplayItem : public DisplayItem { return make_scoped_ptr(new EndCompositingDisplayItem()); } + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/playback/display_item.h b/cc/playback/display_item.h index d89807d..3991cb2 100644 --- a/cc/playback/display_item.h +++ b/cc/playback/display_item.h @@ -15,6 +15,10 @@ class SkCanvas; namespace cc { +namespace proto { +class DisplayItem; +} + class CC_EXPORT DisplayItem { public: virtual ~DisplayItem() {} @@ -27,6 +31,8 @@ class CC_EXPORT DisplayItem { external_memory_usage_ = external_memory_usage; } + virtual void ToProtobuf(proto::DisplayItem* proto) const = 0; + virtual void FromProtobuf(const proto::DisplayItem& proto) = 0; virtual void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const = 0; diff --git a/cc/playback/display_item_list.cc b/cc/playback/display_item_list.cc index 7614bfd..fbf184a 100644 --- a/cc/playback/display_item_list.cc +++ b/cc/playback/display_item_list.cc @@ -14,7 +14,10 @@ #include "cc/debug/traced_display_item_list.h" #include "cc/debug/traced_value.h" #include "cc/playback/display_item_list_settings.h" +#include "cc/playback/display_item_proto_factory.h" #include "cc/playback/largest_display_item.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/gfx_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/utils/SkPictureUtils.h" @@ -47,11 +50,29 @@ scoped_refptr<DisplayItemList> DisplayItemList::Create( !settings.use_cached_picture || DisplayItemsTracingEnabled())); } +scoped_refptr<DisplayItemList> DisplayItemList::CreateFromProto( + const proto::DisplayItemList& proto) { + gfx::Rect layer_rect = ProtoToRect(proto.layer_rect()); + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(ProtoToRect(proto.layer_rect()), + DisplayItemListSettings(proto.settings())); + + for (int i = 0; i < proto.items_size(); i++) { + const proto::DisplayItem& item_proto = proto.items(i); + DisplayItem* item = + DisplayItemProtoFactory::AllocateAndConstruct(list, item_proto); + if (item) + item->FromProtobuf(item_proto); + } + + return list; +} + DisplayItemList::DisplayItemList(gfx::Rect layer_rect, const DisplayItemListSettings& settings, bool retain_individual_display_items) : items_(LargestDisplayItemSize(), kDefaultNumDisplayItemsToReserve), - use_cached_picture_(settings.use_cached_picture), + settings_(settings), retain_individual_display_items_(retain_individual_display_items), layer_rect_(layer_rect), is_suitable_for_gpu_rasterization_(true), @@ -61,7 +82,7 @@ DisplayItemList::DisplayItemList(gfx::Rect layer_rect, #if DCHECK_IS_ON() needs_process_ = false; #endif - if (use_cached_picture_) { + if (settings_.use_cached_picture) { SkRTreeFactory factory; recorder_.reset(new SkPictureRecorder()); canvas_ = skia::SharePtr(recorder_->beginRecording( @@ -74,12 +95,21 @@ DisplayItemList::DisplayItemList(gfx::Rect layer_rect, DisplayItemList::~DisplayItemList() { } +void DisplayItemList::ToProtobuf(proto::DisplayItemList* proto) { + RectToProto(layer_rect_, proto->mutable_layer_rect()); + settings_.ToProtobuf(proto->mutable_settings()); + + DCHECK_EQ(0, proto->items_size()); + for (auto* item : items_) + item->ToProtobuf(proto->add_items()); +} + void DisplayItemList::Raster(SkCanvas* canvas, SkPicture::AbortCallback* callback, const gfx::Rect& canvas_target_playback_rect, float contents_scale) const { DCHECK(ProcessAppendedItemsCalled()); - if (!use_cached_picture_) { + if (!settings_.use_cached_picture) { canvas->save(); canvas->scale(contents_scale, contents_scale); for (auto* item : items_) @@ -122,7 +152,7 @@ void DisplayItemList::ProcessAppendedItems() { needs_process_ = false; #endif for (const DisplayItem* item : items_) { - if (use_cached_picture_) { + if (settings_.use_cached_picture) { // When using a cached picture we will calculate gpu suitability on the // entire cached picture instead of the items. This is more permissive // since none of the items might individually trigger a veto even though @@ -165,16 +195,16 @@ void DisplayItemList::RemoveLast() { // The last item should not have been handled by ProcessAppendedItems, so we // don't need to remove it from approximate_op_count_, etc. DCHECK(retain_individual_display_items_); - DCHECK(!use_cached_picture_); + DCHECK(!settings_.use_cached_picture); items_.RemoveLast(); } void DisplayItemList::Finalize() { ProcessAppendedItems(); - if (use_cached_picture_) { + if (settings_.use_cached_picture) { // Convert to an SkPicture for faster rasterization. - DCHECK(use_cached_picture_); + DCHECK(settings_.use_cached_picture); DCHECK(!picture_); picture_ = skia::AdoptRef(recorder_->endRecordingAsPicture()); DCHECK(picture_); @@ -200,10 +230,10 @@ int DisplayItemList::ApproximateOpCount() const { size_t DisplayItemList::ApproximateMemoryUsage() const { DCHECK(ProcessAppendedItemsCalled()); // We double-count in this case. Produce zero to avoid being misleading. - if (use_cached_picture_ && retain_individual_display_items_) + if (settings_.use_cached_picture && retain_individual_display_items_) return 0; - DCHECK_IMPLIES(use_cached_picture_, picture_); + DCHECK_IMPLIES(settings_.use_cached_picture, picture_); size_t memory_usage = sizeof(*this); @@ -273,8 +303,8 @@ void DisplayItemList::GenerateDiscardableImagesMetadata() { DCHECK(ProcessAppendedItemsCalled()); // This should be only called once, and only after CreateAndCacheSkPicture. DCHECK(image_map_.empty()); - DCHECK_IMPLIES(use_cached_picture_, picture_); - if (use_cached_picture_ && !picture_->willPlayBackBitmaps()) + DCHECK_IMPLIES(settings_.use_cached_picture, picture_); + if (settings_.use_cached_picture && !picture_->willPlayBackBitmaps()) return; // The cached picture is translated by -layer_rect_.origin during record, diff --git a/cc/playback/display_item_list.h b/cc/playback/display_item_list.h index 95342ed..2142260 100644 --- a/cc/playback/display_item_list.h +++ b/cc/playback/display_item_list.h @@ -13,6 +13,7 @@ #include "cc/base/list_container.h" #include "cc/playback/discardable_image_map.h" #include "cc/playback/display_item.h" +#include "cc/playback/display_item_list_settings.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/geometry/rect.h" @@ -22,7 +23,9 @@ class SkPictureRecorder; namespace cc { -class DisplayItemListSettings; +namespace proto { +class DisplayItemList; +} class CC_EXPORT DisplayItemList : public base::RefCountedThreadSafe<DisplayItemList> { @@ -36,6 +39,17 @@ class CC_EXPORT DisplayItemList const gfx::Rect& layer_rect, const DisplayItemListSettings& settings); + // Creates a DisplayItemList from a Protobuf. + // TODO(dtrainor): Pass in a list of possible DisplayItems to reuse + // (crbug.com/548434). + static scoped_refptr<DisplayItemList> CreateFromProto( + const proto::DisplayItemList& proto); + + // Creates a Protobuf representing the state of this DisplayItemList. + // TODO(dtrainor): Don't resend DisplayItems that were already serialized + // (crbug.com/548434). + void ToProtobuf(proto::DisplayItemList* proto); + void Raster(SkCanvas* canvas, SkPicture::AbortCallback* callback, const gfx::Rect& canvas_target_playback_rect, @@ -103,7 +117,7 @@ class CC_EXPORT DisplayItemList scoped_ptr<SkPictureRecorder> recorder_; skia::RefPtr<SkCanvas> canvas_; - const bool use_cached_picture_; + const DisplayItemListSettings settings_; bool retain_individual_display_items_; gfx::Rect layer_rect_; diff --git a/cc/playback/display_item_list_settings.cc b/cc/playback/display_item_list_settings.cc index c71d9ee..616fc61 100644 --- a/cc/playback/display_item_list_settings.cc +++ b/cc/playback/display_item_list_settings.cc @@ -3,13 +3,23 @@ // found in the LICENSE file. #include "cc/playback/display_item_list_settings.h" +#include "cc/proto/display_item.pb.h" namespace cc { DisplayItemListSettings::DisplayItemListSettings() : use_cached_picture(false) {} +DisplayItemListSettings::DisplayItemListSettings( + const proto::DisplayItemListSettings& proto) + : use_cached_picture(proto.use_cached_picture()) {} + DisplayItemListSettings::~DisplayItemListSettings() { } +void DisplayItemListSettings::ToProtobuf( + proto::DisplayItemListSettings* proto) const { + proto->set_use_cached_picture(use_cached_picture); +} + } // namespace cc diff --git a/cc/playback/display_item_list_settings.h b/cc/playback/display_item_list_settings.h index 85fe8db..9c08162 100644 --- a/cc/playback/display_item_list_settings.h +++ b/cc/playback/display_item_list_settings.h @@ -11,11 +11,18 @@ namespace cc { +namespace proto { +class DisplayItemListSettings; +} + class CC_EXPORT DisplayItemListSettings { public: DisplayItemListSettings(); + explicit DisplayItemListSettings(const proto::DisplayItemListSettings& proto); ~DisplayItemListSettings(); + void ToProtobuf(proto::DisplayItemListSettings* proto) const; + // If set, a picture will be cached inside the DisplayItemList. bool use_cached_picture; }; diff --git a/cc/playback/display_item_list_unittest.cc b/cc/playback/display_item_list_unittest.cc index c490bbf..cb19e39 100644 --- a/cc/playback/display_item_list_unittest.cc +++ b/cc/playback/display_item_list_unittest.cc @@ -9,10 +9,14 @@ #include "cc/output/filter_operation.h" #include "cc/output/filter_operations.h" #include "cc/playback/clip_display_item.h" +#include "cc/playback/clip_path_display_item.h" +#include "cc/playback/compositing_display_item.h" #include "cc/playback/display_item_list_settings.h" #include "cc/playback/drawing_display_item.h" #include "cc/playback/filter_display_item.h" +#include "cc/playback/float_clip_display_item.h" #include "cc/playback/transform_display_item.h" +#include "cc/proto/display_item.pb.h" #include "cc/test/skia_common.h" #include "skia/ext/refptr.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,6 +25,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/core/SkXfermode.h" #include "third_party/skia/include/effects/SkImageSource.h" #include "third_party/skia/include/utils/SkPictureUtils.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -28,6 +33,238 @@ namespace cc { +namespace { + +void AppendFirstSerializationTestPicture(scoped_refptr<DisplayItemList> list, + const gfx::Size& layer_size) { + gfx::PointF offset(2.f, 3.f); + SkPictureRecorder recorder; + skia::RefPtr<SkCanvas> canvas; + skia::RefPtr<SkPicture> picture; + + SkPaint red_paint; + red_paint.setColor(SK_ColorRED); + + canvas = skia::SharePtr(recorder.beginRecording(SkRect::MakeXYWH( + offset.x(), offset.y(), layer_size.width(), layer_size.height()))); + canvas->translate(offset.x(), offset.y()); + canvas->drawRectCoords(0.f, 0.f, 4.f, 4.f, red_paint); + picture = skia::AdoptRef(recorder.endRecordingAsPicture()); + list->CreateAndAppendItem<DrawingDisplayItem>()->SetNew(picture); +} + +void AppendSecondSerializationTestPicture(scoped_refptr<DisplayItemList> list, + const gfx::Size& layer_size) { + gfx::PointF offset(2.f, 2.f); + SkPictureRecorder recorder; + skia::RefPtr<SkCanvas> canvas; + skia::RefPtr<SkPicture> picture; + + SkPaint blue_paint; + blue_paint.setColor(SK_ColorBLUE); + + canvas = skia::SharePtr(recorder.beginRecording(SkRect::MakeXYWH( + offset.x(), offset.y(), layer_size.width(), layer_size.height()))); + canvas->translate(offset.x(), offset.y()); + canvas->drawRectCoords(3.f, 3.f, 7.f, 7.f, blue_paint); + picture = skia::AdoptRef(recorder.endRecordingAsPicture()); + list->CreateAndAppendItem<DrawingDisplayItem>()->SetNew(picture); +} + +void ValidateDisplayItemListSerialization(const gfx::Size& layer_size, + scoped_refptr<DisplayItemList> list) { + // Serialize and deserialize the DisplayItemList. + proto::DisplayItemList proto; + list->ToProtobuf(&proto); + scoped_refptr<DisplayItemList> new_list = + DisplayItemList::CreateFromProto(proto); + + // Finalize the DisplayItemLists to perform raster. + list->Finalize(); + new_list->Finalize(); + + const int pixel_size = 4 * layer_size.GetArea(); + + // Get the rendered contents of the old DisplayItemList. + scoped_ptr<unsigned char[]> pixels(new unsigned char[pixel_size]); + memset(pixels.get(), 0, pixel_size); + DrawDisplayList(pixels.get(), gfx::Rect(layer_size), list); + + // Get the rendered contents of the new DisplayItemList. + scoped_ptr<unsigned char[]> new_pixels(new unsigned char[pixel_size]); + memset(new_pixels.get(), 0, pixel_size); + DrawDisplayList(new_pixels.get(), gfx::Rect(layer_size), new_list); + + EXPECT_EQ(0, memcmp(pixels.get(), new_pixels.get(), pixel_size)); +} + +} // namespace + +TEST(DisplayItemListTest, SerializeDisplayItemListSettings) { + DisplayItemListSettings settings; + settings.use_cached_picture = false; + + { + proto::DisplayItemListSettings proto; + settings.ToProtobuf(&proto); + DisplayItemListSettings deserialized(proto); + EXPECT_EQ(settings.use_cached_picture, deserialized.use_cached_picture); + } + + settings.use_cached_picture = true; + { + proto::DisplayItemListSettings proto; + settings.ToProtobuf(&proto); + DisplayItemListSettings deserialized(proto); + EXPECT_EQ(settings.use_cached_picture, deserialized.use_cached_picture); + } +} + +TEST(DisplayItemListTest, SerializeSingleDrawingItem) { + gfx::Size layer_size(10, 10); + + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(gfx::Rect(layer_size), settings); + + // Build the DrawingDisplayItem. + AppendFirstSerializationTestPicture(list, layer_size); + + ValidateDisplayItemListSerialization(layer_size, list); +} + +TEST(DisplayItemListTest, SerializeClipItem) { + gfx::Size layer_size(10, 10); + + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(gfx::Rect(layer_size), settings); + + // Build the DrawingDisplayItem. + AppendFirstSerializationTestPicture(list, layer_size); + + // Build the ClipDisplayItem. + gfx::Rect clip_rect(6, 6, 1, 1); + std::vector<SkRRect> rrects; + rrects.push_back(SkRRect::MakeOval(SkRect::MakeXYWH(5.f, 5.f, 4.f, 4.f))); + auto* item = list->CreateAndAppendItem<ClipDisplayItem>(); + item->SetNew(clip_rect, rrects); + + // Build the second DrawingDisplayItem. + AppendSecondSerializationTestPicture(list, layer_size); + + // Build the EndClipDisplayItem. + list->CreateAndAppendItem<EndClipDisplayItem>(); + + ValidateDisplayItemListSerialization(layer_size, list); +} + +TEST(DisplayItemListTest, SerializeClipPathItem) { + gfx::Size layer_size(10, 10); + + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(gfx::Rect(layer_size), settings); + + // Build the DrawingDisplayItem. + AppendFirstSerializationTestPicture(list, layer_size); + + // Build the ClipPathDisplayItem. + SkPath path; + path.addCircle(5.f, 5.f, 2.f, SkPath::Direction::kCW_Direction); + auto* item = list->CreateAndAppendItem<ClipPathDisplayItem>(); + item->SetNew(path, SkRegion::Op::kReplace_Op, false); + + // Build the second DrawingDisplayItem. + AppendSecondSerializationTestPicture(list, layer_size); + + // Build the EndClipPathDisplayItem. + list->CreateAndAppendItem<EndClipPathDisplayItem>(); + + ValidateDisplayItemListSerialization(layer_size, list); +} + +TEST(DisplayItemListTest, SerializeCompositingItem) { + gfx::Size layer_size(10, 10); + + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(gfx::Rect(layer_size), settings); + + // Build the DrawingDisplayItem. + AppendFirstSerializationTestPicture(list, layer_size); + + // Build the CompositingDisplayItem. + skia::RefPtr<SkColorFilter> filter = skia::AdoptRef( + SkColorFilter::CreateLightingFilter(SK_ColorRED, SK_ColorGREEN)); + auto* item = list->CreateAndAppendItem<CompositingDisplayItem>(); + item->SetNew(150, SkXfermode::Mode::kDst_Mode, nullptr, filter); + + // Build the second DrawingDisplayItem. + AppendSecondSerializationTestPicture(list, layer_size); + + // Build the EndCompositingDisplayItem. + list->CreateAndAppendItem<EndCompositingDisplayItem>(); + + ValidateDisplayItemListSerialization(layer_size, list); +} + +TEST(DisplayItemListTest, SerializeFloatClipItem) { + gfx::Size layer_size(10, 10); + + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(gfx::Rect(layer_size), settings); + + // Build the DrawingDisplayItem. + AppendFirstSerializationTestPicture(list, layer_size); + + // Build the FloatClipDisplayItem. + gfx::RectF clip_rect(6.f, 6.f, 1.f, 1.f); + auto* item2 = list->CreateAndAppendItem<FloatClipDisplayItem>(); + item2->SetNew(clip_rect); + + // Build the second DrawingDisplayItem. + AppendSecondSerializationTestPicture(list, layer_size); + + // Build the EndFloatClipDisplayItem. + list->CreateAndAppendItem<EndFloatClipDisplayItem>(); + + ValidateDisplayItemListSerialization(layer_size, list); +} + +TEST(DisplayItemListTest, SerializeTransformItem) { + gfx::Size layer_size(10, 10); + + DisplayItemListSettings settings; + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = + DisplayItemList::Create(gfx::Rect(layer_size), settings); + + // Build the DrawingDisplayItem. + AppendFirstSerializationTestPicture(list, layer_size); + + // Build the TransformDisplayItem. + gfx::Transform transform; + transform.Scale(1.25f, 1.25f); + transform.Translate(-1.f, -1.f); + auto* item2 = list->CreateAndAppendItem<TransformDisplayItem>(); + item2->SetNew(transform); + + // Build the second DrawingDisplayItem. + AppendSecondSerializationTestPicture(list, layer_size); + + // Build the EndTransformDisplayItem. + list->CreateAndAppendItem<EndTransformDisplayItem>(); + + ValidateDisplayItemListSerialization(layer_size, list); +} + TEST(DisplayItemListTest, SingleDrawingItem) { gfx::Rect layer_rect(100, 100); SkPictureRecorder recorder; diff --git a/cc/playback/display_item_proto_factory.cc b/cc/playback/display_item_proto_factory.cc new file mode 100644 index 0000000..b71fc9a --- /dev/null +++ b/cc/playback/display_item_proto_factory.cc @@ -0,0 +1,55 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/playback/display_item_proto_factory.h" + +#include "cc/playback/clip_display_item.h" +#include "cc/playback/clip_path_display_item.h" +#include "cc/playback/compositing_display_item.h" +#include "cc/playback/drawing_display_item.h" +#include "cc/playback/filter_display_item.h" +#include "cc/playback/float_clip_display_item.h" +#include "cc/playback/transform_display_item.h" +#include "cc/proto/display_item.pb.h" + +namespace cc { + +// static +DisplayItem* DisplayItemProtoFactory::AllocateAndConstruct( + scoped_refptr<DisplayItemList> list, + const proto::DisplayItem& proto) { + switch (proto.type()) { + case proto::DisplayItem::Type_Clip: + return list->CreateAndAppendItem<ClipDisplayItem>(); + case proto::DisplayItem::Type_EndClip: + return list->CreateAndAppendItem<EndClipDisplayItem>(); + case proto::DisplayItem::Type_ClipPath: + return list->CreateAndAppendItem<ClipPathDisplayItem>(); + case proto::DisplayItem::Type_EndClipPath: + return list->CreateAndAppendItem<EndClipPathDisplayItem>(); + case proto::DisplayItem::Type_Compositing: + return list->CreateAndAppendItem<CompositingDisplayItem>(); + case proto::DisplayItem::Type_EndCompositing: + return list->CreateAndAppendItem<EndCompositingDisplayItem>(); + case proto::DisplayItem::Type_Drawing: + return list->CreateAndAppendItem<DrawingDisplayItem>(); + case proto::DisplayItem::Type_Filter: + return list->CreateAndAppendItem<FilterDisplayItem>(); + case proto::DisplayItem::Type_EndFilter: + return list->CreateAndAppendItem<EndFilterDisplayItem>(); + case proto::DisplayItem::Type_FloatClip: + return list->CreateAndAppendItem<FloatClipDisplayItem>(); + case proto::DisplayItem::Type_EndFloatClip: + return list->CreateAndAppendItem<EndFloatClipDisplayItem>(); + case proto::DisplayItem::Type_Transform: + return list->CreateAndAppendItem<TransformDisplayItem>(); + case proto::DisplayItem::Type_EndTransform: + return list->CreateAndAppendItem<EndTransformDisplayItem>(); + } + + NOTREACHED(); + return nullptr; +} + +} // namespace cc diff --git a/cc/playback/display_item_proto_factory.h b/cc/playback/display_item_proto_factory.h new file mode 100644 index 0000000..43325df --- /dev/null +++ b/cc/playback/display_item_proto_factory.h @@ -0,0 +1,33 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_PLAYBACK_DISPLAY_ITEM_PROTO_FACTORY_H_ +#define CC_PLAYBACK_DISPLAY_ITEM_PROTO_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "cc/playback/display_item.h" +#include "cc/playback/display_item_list.h" + +namespace cc { + +namespace proto { +class DisplayItem; +} + +class DisplayItemProtoFactory { + public: + static DisplayItem* AllocateAndConstruct(scoped_refptr<DisplayItemList> list, + const proto::DisplayItem& proto); + + private: + DisplayItemProtoFactory() {} + virtual ~DisplayItemProtoFactory() {} + + DISALLOW_COPY_AND_ASSIGN(DisplayItemProtoFactory); +}; + +} // namespace cc + +#endif // CC_PLAYBACK_DISPLAY_ITEM_PROTO_FACTORY_H_ diff --git a/cc/playback/drawing_display_item.cc b/cc/playback/drawing_display_item.cc index 6cebed2..a2740f9 100644 --- a/cc/playback/drawing_display_item.cc +++ b/cc/playback/drawing_display_item.cc @@ -9,9 +9,12 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" #include "cc/debug/picture_debug_util.h" +#include "cc/proto/display_item.pb.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkPicture.h" +#include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/utils/SkPictureUtils.h" #include "ui/gfx/skia_util.h" @@ -30,6 +33,40 @@ void DrawingDisplayItem::SetNew(skia::RefPtr<SkPicture> picture) { SkPictureUtils::ApproximateBytesUsed(picture_.get())); } +void DrawingDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_Drawing); + + proto::DrawingDisplayItem* details = proto->mutable_drawing_item(); + + // Just use skia's serialize() method for now. + if (picture_) { + SkDynamicMemoryWStream stream; + + // TODO(dtrainor, nyquist): Add an SkPixelSerializer to not serialize images + // more than once (crbug.com/548434). + picture_->serialize(&stream, nullptr); + if (stream.bytesWritten() > 0) { + SkAutoDataUnref data(stream.copyToData()); + details->set_picture(data->data(), data->size()); + } + } +} + +void DrawingDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_Drawing, proto.type()); + + skia::RefPtr<SkPicture> picture; + const proto::DrawingDisplayItem& details = proto.drawing_item(); + if (details.has_picture()) { + SkMemoryStream stream(details.picture().data(), details.picture().size()); + + // TODO(dtrainor, nyquist): Add an image decoder. + picture = skia::AdoptRef(SkPicture::CreateFromStream(&stream, nullptr)); + } + + SetNew(picture.Pass()); +} + void DrawingDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { diff --git a/cc/playback/drawing_display_item.h b/cc/playback/drawing_display_item.h index f94e7c9..9ca8530 100644 --- a/cc/playback/drawing_display_item.h +++ b/cc/playback/drawing_display_item.h @@ -23,6 +23,8 @@ class CC_EXPORT DrawingDisplayItem : public DisplayItem { void SetNew(skia::RefPtr<SkPicture> picture); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/playback/filter_display_item.cc b/cc/playback/filter_display_item.cc index c155b68..bcd676c7 100644 --- a/cc/playback/filter_display_item.cc +++ b/cc/playback/filter_display_item.cc @@ -7,6 +7,8 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" #include "cc/output/render_surface_filters.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/gfx_conversions.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkImageFilter.h" @@ -34,6 +36,27 @@ void FilterDisplayItem::SetNew(const FilterOperations& filters, external_memory_usage); } +void FilterDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_Filter); + + proto::FilterDisplayItem* details = proto->mutable_filter_item(); + RectFToProto(bounds_, details->mutable_bounds()); + + // TODO(dtrainor): Support serializing FilterOperations (crbug.com/541321). +} + +void FilterDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_Filter, proto.type()); + + const proto::FilterDisplayItem& details = proto.filter_item(); + gfx::RectF bounds = ProtoToRectF(details.bounds()); + + // TODO(dtrainor): Support deserializing FilterOperations (crbug.com/541321). + FilterOperations filters; + + SetNew(filters, bounds); +} + void FilterDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { @@ -74,6 +97,14 @@ EndFilterDisplayItem::EndFilterDisplayItem() { EndFilterDisplayItem::~EndFilterDisplayItem() { } +void EndFilterDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_EndFilter); +} + +void EndFilterDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_EndFilter, proto.type()); +} + void EndFilterDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { diff --git a/cc/playback/filter_display_item.h b/cc/playback/filter_display_item.h index 9672878..edffb9e 100644 --- a/cc/playback/filter_display_item.h +++ b/cc/playback/filter_display_item.h @@ -22,6 +22,8 @@ class CC_EXPORT FilterDisplayItem : public DisplayItem { void SetNew(const FilterOperations& filters, const gfx::RectF& bounds); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; @@ -41,6 +43,8 @@ class CC_EXPORT EndFilterDisplayItem : public DisplayItem { return make_scoped_ptr(new EndFilterDisplayItem()); } + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/playback/float_clip_display_item.cc b/cc/playback/float_clip_display_item.cc index 8b29fc2..f1ff6cb 100644 --- a/cc/playback/float_clip_display_item.cc +++ b/cc/playback/float_clip_display_item.cc @@ -6,6 +6,8 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/gfx_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/skia_util.h" @@ -24,6 +26,22 @@ void FloatClipDisplayItem::SetNew(const gfx::RectF& clip_rect) { 0 /* external_memory_usage */); } +void FloatClipDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_FloatClip); + + proto::FloatClipDisplayItem* details = proto->mutable_float_clip_item(); + RectFToProto(clip_rect_, details->mutable_clip_rect()); +} + +void FloatClipDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_FloatClip, proto.type()); + + const proto::FloatClipDisplayItem& details = proto.float_clip_item(); + gfx::RectF clip_rect = ProtoToRectF(details.clip_rect()); + + SetNew(clip_rect); +} + void FloatClipDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { @@ -45,6 +63,14 @@ EndFloatClipDisplayItem::EndFloatClipDisplayItem() { EndFloatClipDisplayItem::~EndFloatClipDisplayItem() { } +void EndFloatClipDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_EndFloatClip); +} + +void EndFloatClipDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_EndFloatClip, proto.type()); +} + void EndFloatClipDisplayItem::Raster( SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, diff --git a/cc/playback/float_clip_display_item.h b/cc/playback/float_clip_display_item.h index 13d637f..2399935 100644 --- a/cc/playback/float_clip_display_item.h +++ b/cc/playback/float_clip_display_item.h @@ -23,6 +23,8 @@ class CC_EXPORT FloatClipDisplayItem : public DisplayItem { void SetNew(const gfx::RectF& clip_rect); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; @@ -41,6 +43,8 @@ class CC_EXPORT EndFloatClipDisplayItem : public DisplayItem { return make_scoped_ptr(new EndFloatClipDisplayItem()); } + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/playback/transform_display_item.cc b/cc/playback/transform_display_item.cc index df7ca1b..d0e7de7 100644 --- a/cc/playback/transform_display_item.cc +++ b/cc/playback/transform_display_item.cc @@ -6,6 +6,8 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/proto/display_item.pb.h" +#include "cc/proto/gfx_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" namespace cc { @@ -24,6 +26,22 @@ void TransformDisplayItem::SetNew(const gfx::Transform& transform) { 0 /* external_memory_usage */); } +void TransformDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_Transform); + + proto::TransformDisplayItem* details = proto->mutable_transform_item(); + TransformToProto(transform_, details->mutable_transform()); +} + +void TransformDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_Transform, proto.type()); + + const proto::TransformDisplayItem& details = proto.transform_item(); + gfx::Transform transform = ProtoToTransform(details.transform()); + + SetNew(transform); +} + void TransformDisplayItem::Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const { @@ -46,6 +64,14 @@ EndTransformDisplayItem::EndTransformDisplayItem() { EndTransformDisplayItem::~EndTransformDisplayItem() { } +void EndTransformDisplayItem::ToProtobuf(proto::DisplayItem* proto) const { + proto->set_type(proto::DisplayItem::Type_EndTransform); +} + +void EndTransformDisplayItem::FromProtobuf(const proto::DisplayItem& proto) { + DCHECK_EQ(proto::DisplayItem::Type_EndTransform, proto.type()); +} + void EndTransformDisplayItem::Raster( SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, diff --git a/cc/playback/transform_display_item.h b/cc/playback/transform_display_item.h index 9d3f9c6..304ee8c 100644 --- a/cc/playback/transform_display_item.h +++ b/cc/playback/transform_display_item.h @@ -21,6 +21,8 @@ class CC_EXPORT TransformDisplayItem : public DisplayItem { void SetNew(const gfx::Transform& transform); + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; @@ -39,6 +41,8 @@ class CC_EXPORT EndTransformDisplayItem : public DisplayItem { return make_scoped_ptr(new EndTransformDisplayItem()); } + void ToProtobuf(proto::DisplayItem* proto) const override; + void FromProtobuf(const proto::DisplayItem& proto) override; void Raster(SkCanvas* canvas, const gfx::Rect& canvas_target_playback_rect, SkPicture::AbortCallback* callback) const override; diff --git a/cc/proto/BUILD.gn b/cc/proto/BUILD.gn index acf5e9b..dcd4214 100644 --- a/cc/proto/BUILD.gn +++ b/cc/proto/BUILD.gn @@ -29,6 +29,7 @@ proto_library("proto_internal") { sources = [ # TODO(dtrainor): Move protos to their correct packages once it's possible # to include protos from other directories/targets (crbug.com/542423). + "display_item.proto", "point.proto", "pointf.proto", "rect.proto", diff --git a/cc/proto/display_item.proto b/cc/proto/display_item.proto new file mode 100644 index 0000000..6a01dff --- /dev/null +++ b/cc/proto/display_item.proto @@ -0,0 +1,93 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; + +import "skregion.proto"; +import "skrrect.proto"; +import "skxfermode.proto"; +import "rect.proto"; +import "rectf.proto"; +import "transform.proto"; + +option optimize_for = LITE_RUNTIME; + +package cc.proto; + +message DisplayItemListSettings { + optional bool use_cached_picture = 1; +} + +message DisplayItemList { + repeated DisplayItem items = 1; + optional cc.proto.Rect layer_rect = 2; + optional DisplayItemListSettings settings = 3; +} + +message DisplayItem { + enum Type { + Type_Clip = 1; + Type_EndClip = 2; + Type_ClipPath = 3; + Type_EndClipPath = 4; + Type_Compositing = 5; + Type_EndCompositing = 6; + Type_Drawing = 7; + Type_Filter = 8; + Type_EndFilter = 9; + Type_FloatClip = 10; + Type_EndFloatClip = 11; + Type_Transform = 12; + Type_EndTransform = 13; + } + + optional Type type = 1; + + // Unique DisplayItem types. |type| determines which one (if any) is valid. + optional ClipDisplayItem clip_item = 1000; + optional ClipPathDisplayItem clip_path_item = 1001; + optional CompositingDisplayItem compositing_item = 1002; + optional DrawingDisplayItem drawing_item = 1003; + optional FilterDisplayItem filter_item = 1004; + optional FloatClipDisplayItem float_clip_item = 1005; + optional TransformDisplayItem transform_item = 1006; +} + +message ClipDisplayItem { + optional cc.proto.Rect clip_rect = 1; + + repeated cc.proto.SkRRect rounded_rects = 2; +} + +message ClipPathDisplayItem { + optional cc.proto.SkRegion.Op clip_op = 1; + optional bool antialias = 2; + optional bytes clip_path = 3; /* SkPath */ +} + +message CompositingDisplayItem { + optional uint32 alpha = 1; + + optional cc.proto.SkXfermode.Mode mode = 2; + optional cc.proto.RectF bounds = 3; + optional bytes color_filter = 4; /* SkColorFilter */ +} + +message DrawingDisplayItem { + optional bytes picture = 1; /* SkPicture */ +} + +message FilterDisplayItem { + optional cc.proto.RectF bounds = 1; + + // TODO(dtrainor): Support FilterOperations. +} + +message FloatClipDisplayItem { + optional cc.proto.RectF clip_rect = 1; +} + +message TransformDisplayItem { + optional cc.proto.Transform transform = 1; +} diff --git a/cc/proto/gfx_conversions.h b/cc/proto/gfx_conversions.h index e982e58..5b5c315 100644 --- a/cc/proto/gfx_conversions.h +++ b/cc/proto/gfx_conversions.h @@ -29,6 +29,8 @@ class SizeF; class Transform; } +// TODO(dtrainor): Move these to a class and make them static +// (crbug.com/548432). CC_EXPORT void PointToProto(const gfx::Point& point, proto::Point* proto); CC_EXPORT gfx::Point ProtoToPoint(const proto::Point& proto); diff --git a/cc/proto/skia_conversions.h b/cc/proto/skia_conversions.h index 302e313c..6735cf1 100644 --- a/cc/proto/skia_conversions.h +++ b/cc/proto/skia_conversions.h @@ -21,6 +21,8 @@ namespace proto { class SkRRect; } +// TODO(dtrainor): Move these to a class and make them static +// (crbug.com/548432). CC_EXPORT SkRegion::Op SkRegionOpFromProto(proto::SkRegion::Op op); CC_EXPORT proto::SkRegion::Op SkRegionOpToProto(SkRegion::Op op); |