Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(417)

Unified Diff: cc/layers/picture_layer.cc

Issue 2141233002: cc: Clean up RecordingSource API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove recoding_source_ from PictureLayer, and move all its internal state to PictureLayer Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/layers/picture_layer.cc
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index 081e3158841943ab15a3d8bfaeff318afe457f5e..fa2b006763c109910431b943e655376a92dbcd4f 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -31,9 +31,11 @@ PictureLayer::PictureLayer(ContentLayerClient* client)
}
PictureLayer::PictureLayer(ContentLayerClient* client,
- std::unique_ptr<RecordingSource> source)
+ const PictureLayerData& pl_data,
+ const ContentLayerClientData& clc_data)
: PictureLayer(client) {
- recording_source_ = std::move(source);
+ pl_data_ = pl_data;
vmpstr 2016/07/19 23:43:22 set these in the initialization list just above
Menglin 2016/07/20 00:28:42 Done.
Menglin 2016/07/20 21:25:22 Actually, if i move the initialization in the list
+ clc_data_ = clc_data;
}
PictureLayer::~PictureLayer() {
@@ -56,8 +58,10 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
// Preserve lcd text settings from the current raster source.
bool can_use_lcd_text = layer_impl->RasterSourceUsesLCDText();
+ std::unique_ptr<RecordingSource> recording_source(
vmpstr 2016/07/19 23:43:22 Just create this on the stack if you need it. Do y
Menglin 2016/07/20 00:18:13 Currently the raster source is constructed based o
vmpstr 2016/07/20 00:27:06 I think we can just have RasterSource(display_list
Menglin 2016/07/20 21:25:22 I change it to RasterSource(const PictureLayerData
+ new RecordingSource(pl_data_, clc_data_));
scoped_refptr<RasterSource> raster_source =
- recording_source_->CreateRasterSource(can_use_lcd_text);
+ recording_source->CreateRasterSource(can_use_lcd_text);
layer_impl->set_gpu_raster_max_texture_size(
layer_tree_host()->device_viewport_size());
layer_impl->UpdateRasterSource(raster_source, &last_updated_invalidation_,
@@ -70,21 +74,19 @@ void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
if (!host)
return;
- if (!recording_source_)
- recording_source_.reset(new RecordingSource);
- recording_source_->SetSlowdownRasterScaleFactor(
+ pl_data_.reset();
vmpstr 2016/07/19 23:43:22 Where is PictureLayerData defined? I can't find it
Menglin 2016/07/20 00:18:13 Now it's in recording_source.h. I had it there bec
+ clc_data_.reset();
+ SetSlowdownRasterScaleFactor(
host->debug_state().slow_down_raster_scale_factor);
// If we need to enable image decode tasks, then we have to generate the
// discardable images metadata.
const LayerTreeSettings& settings = layer_tree_host()->settings();
- recording_source_->SetGenerateDiscardableImagesMetadata(
- settings.image_decode_tasks_enabled);
+ SetGenerateDiscardableImagesMetadata(settings.image_decode_tasks_enabled);
}
void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
DCHECK(!layer_tree_host() || !layer_tree_host()->in_paint_layer_contents());
- if (recording_source_)
- recording_source_->SetNeedsDisplayRect(layer_rect);
+ SetNeedsDisplayRectSimple(layer_rect);
Layer::SetNeedsDisplayRect(layer_rect);
}
@@ -94,9 +96,9 @@ bool PictureLayer::Update() {
gfx::Size layer_size = paint_properties().bounds;
- recording_source_->SetBackgroundColor(SafeOpaqueBackgroundColor());
- recording_source_->SetRequiresClear(!contents_opaque() &&
- !inputs_.client->FillsBoundsCompletely());
+ SetBackgroundColorSimple(SafeOpaqueBackgroundColor());
+ SetRequiresClear(!contents_opaque() &&
+ !inputs_.client->FillsBoundsCompletely());
TRACE_EVENT1("cc", "PictureLayer::Update",
"source_frame_number",
@@ -109,9 +111,9 @@ bool PictureLayer::Update() {
// to the impl side so that it drops tiles that may not have a recording
// for them.
DCHECK(inputs_.client);
- updated |= recording_source_->UpdateAndExpandInvalidation(
- inputs_.client, &last_updated_invalidation_, layer_size,
- update_source_frame_number_, RecordingSource::RECORD_NORMALLY);
+ updated |= UpdateAndExpandInvalidation(
+ &last_updated_invalidation_, layer_size, RecordingSource::RECORD_NORMALLY,
+ &pl_data_, &clc_data_, &invalidation_);
if (updated) {
SetNeedsPushProperties();
@@ -136,12 +138,15 @@ sk_sp<SkPicture> PictureLayer::GetPicture() const {
return nullptr;
gfx::Size layer_size = bounds();
- std::unique_ptr<RecordingSource> recording_source(new RecordingSource);
Region recording_invalidation;
- recording_source->UpdateAndExpandInvalidation(
- inputs_.client, &recording_invalidation, layer_size,
- update_source_frame_number_, RecordingSource::RECORD_NORMALLY);
-
+ InvalidationRegion invalidation_local;
vmpstr 2016/07/19 23:43:22 I don't think you need the word "local".. lack of
Menglin 2016/07/20 21:25:22 Done.
+ PictureLayerData pl_data_local = PictureLayerData();
+ ContentLayerClientData clc_data_local = ContentLayerClientData();
+ UpdateAndExpandInvalidation(&recording_invalidation, layer_size,
+ RecordingSource::RECORD_NORMALLY, &pl_data_local,
+ &clc_data_local, &invalidation_local);
+ std::unique_ptr<RecordingSource> recording_source(
vmpstr 2016/07/19 23:43:22 Same comment as above: Either create it on the sta
Menglin 2016/07/20 21:25:22 Done.
+ new RecordingSource(pl_data_local, clc_data_local));
scoped_refptr<RasterSource> raster_source =
recording_source->CreateRasterSource(false);
@@ -149,7 +154,12 @@ sk_sp<SkPicture> PictureLayer::GetPicture() const {
}
bool PictureLayer::IsSuitableForGpuRasterization() const {
- return recording_source_->IsSuitableForGpuRasterization();
+ // The display list needs to be created (see: UpdateAndExpandInvalidation)
+ // before checking for suitability. There are cases where an update will not
+ // create a display list (e.g., if the size is empty). We return true in these
+ // cases because the gpu suitability bit sticks false.
+ return !clc_data_.display_list ||
+ clc_data_.display_list->IsSuitableForGpuRasterization();
}
void PictureLayer::ClearClient() {
@@ -179,10 +189,26 @@ void PictureLayer::LayerSpecificPropertiesToProto(
DropRecordingSourceContentIfInvalid();
proto::PictureLayerProperties* picture = proto->mutable_picture();
- recording_source_->ToProtobuf(picture->mutable_recording_source());
+
+ RectToProto(clc_data_.recorded_viewport,
+ picture->mutable_recorded_viewport());
+ SizeToProto(pl_data_.size, picture->mutable_size());
+ picture->set_slow_down_raster_scale_factor_for_debug(
+ pl_data_.slow_down_raster_scale_factor_for_debug);
+ picture->set_generate_discardable_images_metadata(
+ pl_data_.generate_discardable_images_metadata);
+ picture->set_requires_clear(pl_data_.requires_clear);
+ picture->set_is_solid_color(pl_data_.is_solid_color);
+ picture->set_clear_canvas_with_debug_color(
+ pl_data_.clear_canvas_with_debug_color);
+ picture->set_solid_color(static_cast<uint64_t>(pl_data_.solid_color));
+ picture->set_background_color(
+ static_cast<uint64_t>(pl_data_.background_color));
+ if (clc_data_.display_list)
+ clc_data_.display_list->ToProtobuf(picture->mutable_display_list());
// Add all SkPicture items to the picture cache.
- const DisplayItemList* display_list = recording_source_->GetDisplayItemList();
+ const DisplayItemList* display_list = GetDisplayItemList();
if (display_list) {
for (auto it = display_list->begin(); it != display_list->end(); ++it) {
sk_sp<const SkPicture> picture = it->GetPicture();
@@ -210,13 +236,35 @@ void PictureLayer::FromLayerSpecificPropertiesProto(
// If this is a new layer, ensure it has a recording source. During layer
// hierarchy deserialization, ::SetLayerTreeHost(...) is not called, but
// instead the member is set directly, so it needs to be set here explicitly.
- if (!recording_source_)
- recording_source_.reset(new RecordingSource);
-
+ pl_data_.reset();
+ clc_data_.reset();
std::vector<uint32_t> used_engine_picture_ids;
- recording_source_->FromProtobuf(picture.recording_source(),
- layer_tree_host()->client_picture_cache(),
- &used_engine_picture_ids);
+
+ DCHECK(layer_tree_host()->client_picture_cache());
+ clc_data_.recorded_viewport = ProtoToRect(picture.recorded_viewport());
+ pl_data_.size = ProtoToSize(picture.size());
+ pl_data_.slow_down_raster_scale_factor_for_debug =
+ picture.slow_down_raster_scale_factor_for_debug();
+ pl_data_.generate_discardable_images_metadata =
+ picture.generate_discardable_images_metadata();
+ pl_data_.requires_clear = picture.requires_clear();
+ pl_data_.is_solid_color = picture.is_solid_color();
+ pl_data_.clear_canvas_with_debug_color =
+ picture.clear_canvas_with_debug_color();
+ pl_data_.solid_color = static_cast<SkColor>(picture.solid_color());
+ pl_data_.background_color = static_cast<SkColor>(picture.background_color());
+
+ // This might not exist if the |clc_data_.display_list| of the serialized
+ // RecordingSource was null, which can happen if |Clear()| is
+ // called.
+ if (picture.has_display_list()) {
+ clc_data_.display_list = DisplayItemList::CreateFromProto(
+ picture.display_list(), layer_tree_host()->client_picture_cache(),
+ &used_engine_picture_ids);
+ FinishDisplayItemListUpdate(&pl_data_, &clc_data_);
+ } else {
+ clc_data_.display_list = nullptr;
+ }
// Inform picture cache about which SkPictures are now in use.
for (uint32_t engine_picture_id : used_engine_picture_ids)
@@ -234,9 +282,119 @@ void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
benchmark->RunOnLayer(this);
}
+bool PictureLayer::UpdateAndExpandInvalidation(
+ Region* invalidation,
+ const gfx::Size& layer_size,
+ RecordingSource::RecordingMode recording_mode,
+ PictureLayerData* pl_data,
+ ContentLayerClientData* clc_data,
+ InvalidationRegion* invalidation_state) const {
+ bool updated = false;
+
+ if (pl_data->size != layer_size)
+ pl_data->size = layer_size;
+
+ invalidation_state->Swap(invalidation);
+ invalidation_state->Clear();
+
+ gfx::Rect new_recorded_viewport = inputs_.client->PaintableRegion();
+ if (new_recorded_viewport != clc_data->recorded_viewport) {
+ UpdateInvalidationForNewViewport(clc_data->recorded_viewport,
+ new_recorded_viewport, invalidation);
+ clc_data->recorded_viewport = new_recorded_viewport;
+ updated = true;
+ }
+
+ if (!updated && !invalidation->Intersects(clc_data->recorded_viewport))
+ return false;
+
+ if (invalidation->IsEmpty())
+ return false;
+
+ ContentLayerClient::PaintingControlSetting painting_control =
+ ContentLayerClient::PAINTING_BEHAVIOR_NORMAL;
+
+ switch (recording_mode) {
+ case RecordingSource::RECORD_NORMALLY:
+ // Already setup for normal recording.
+ break;
+ case RecordingSource::RECORD_WITH_PAINTING_DISABLED:
+ painting_control = ContentLayerClient::DISPLAY_LIST_PAINTING_DISABLED;
+ break;
+ case RecordingSource::RECORD_WITH_CACHING_DISABLED:
+ painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED;
+ break;
+ case RecordingSource::RECORD_WITH_CONSTRUCTION_DISABLED:
+ painting_control = ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED;
+ break;
+ case RecordingSource::RECORD_WITH_SUBSEQUENCE_CACHING_DISABLED:
+ painting_control = ContentLayerClient::SUBSEQUENCE_CACHING_DISABLED;
+ break;
+ case RecordingSource::RECORD_WITH_SK_NULL_CANVAS:
+ case RecordingSource::RECORDING_MODE_COUNT:
+ NOTREACHED();
+ }
+
+ // TODO(vmpstr): Add a slow_down_recording_scale_factor_for_debug_ to be able
+ // to slow down recording.
+ clc_data->display_list =
+ inputs_.client->PaintContentsToDisplayList(painting_control);
+ clc_data->painter_reported_memory_usage =
+ inputs_.client->GetApproximateUnsharedMemoryUsage();
+
+ FinishDisplayItemListUpdate(pl_data, clc_data);
+
+ return true;
+}
+
+void PictureLayer::SetEmptyBounds() {
+ pl_data_.size = gfx::Size();
+ Clear();
+}
+
+void PictureLayer::SetSlowdownRasterScaleFactor(int factor) {
vmpstr 2016/07/19 23:43:22 As far as I can tell there's not a lot of places t
Menglin 2016/07/20 00:18:13 OK. I will check each one of them, and do the clea
Menglin 2016/07/20 21:25:22 For now I only removed SetSlowdownRasterScaleFacto
+ pl_data_.slow_down_raster_scale_factor_for_debug = factor;
+}
+
+void PictureLayer::SetGenerateDiscardableImagesMetadata(
+ bool generate_metadata) {
+ pl_data_.generate_discardable_images_metadata = generate_metadata;
+}
+
+void PictureLayer::SetBackgroundColorSimple(SkColor background_color) {
+ pl_data_.background_color = background_color;
+}
+
+void PictureLayer::SetRequiresClear(bool requires_clear) {
+ pl_data_.requires_clear = requires_clear;
+}
+
+void PictureLayer::SetNeedsDisplayRectSimple(const gfx::Rect& layer_rect) {
+ if (!layer_rect.IsEmpty()) {
+ // Clamp invalidation to the layer bounds.
+ invalidation_.Union(
+ gfx::IntersectRects(layer_rect, gfx::Rect(pl_data_.size)));
+ }
+}
+
+gfx::Size PictureLayer::GetSize() const {
+ return pl_data_.size;
+}
+
+const DisplayItemList* PictureLayer::GetDisplayItemList() {
+ return clc_data_.display_list.get();
+}
+
+void PictureLayer::Clear() {
+ clc_data_.recorded_viewport = gfx::Rect();
+ clc_data_.display_list = nullptr;
+ clc_data_.painter_reported_memory_usage = 0;
+ pl_data_.is_solid_color = false;
+}
+
void PictureLayer::DropRecordingSourceContentIfInvalid() {
int source_frame_number = layer_tree_host()->source_frame_number();
- gfx::Size recording_source_bounds = recording_source_->GetSize();
+ gfx::Size recording_source_bounds = GetSize();
gfx::Size layer_bounds = bounds();
if (paint_properties().source_frame_number == source_frame_number)
@@ -254,8 +412,50 @@ void PictureLayer::DropRecordingSourceContentIfInvalid() {
// Update may not get called for the layer (if it's not in the viewport
// for example), even though it has resized making the recording source no
// longer valid. In this case just destroy the recording source.
- recording_source_->SetEmptyBounds();
+ SetEmptyBounds();
}
}
+void PictureLayer::FinishDisplayItemListUpdate(
+ PictureLayerData* pl_data,
+ ContentLayerClientData* clc_data) const {
+ TRACE_EVENT0("cc", "PictureLayer::FinishDisplayItemListUpdate");
+ DetermineIfSolidColor(pl_data, clc_data);
+ clc_data->display_list->EmitTraceSnapshot();
+ if (pl_data->generate_discardable_images_metadata)
+ clc_data->display_list->GenerateDiscardableImagesMetadata();
+}
+
+void PictureLayer::DetermineIfSolidColor(
+ PictureLayerData* pl_data,
+ ContentLayerClientData* clc_data) const {
+ DCHECK(clc_data->display_list);
+ pl_data->is_solid_color = false;
+ pl_data->solid_color = SK_ColorTRANSPARENT;
+
+ if (!clc_data->display_list->ShouldBeAnalyzedForSolidColor())
+ return;
+
+ TRACE_EVENT1("cc", "PictureLayer::DetermineIfSolidColor", "opcount",
+ clc_data->display_list->ApproximateOpCount());
+ gfx::Size layer_size = pl_data->size;
+ skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height());
+ clc_data->display_list->Raster(&canvas, nullptr, gfx::Rect(), 1.f);
+ pl_data->is_solid_color = canvas.GetColorIfSolid(&pl_data->solid_color);
+}
+
+void PictureLayer::UpdateInvalidationForNewViewport(
+ const gfx::Rect& old_recorded_viewport,
+ const gfx::Rect& new_recorded_viewport,
+ Region* invalidation) const {
+ // Invalidate newly-exposed and no-longer-exposed areas.
+ Region newly_exposed_region(new_recorded_viewport);
+ newly_exposed_region.Subtract(old_recorded_viewport);
+ invalidation->Union(newly_exposed_region);
+
+ Region no_longer_exposed_region(old_recorded_viewport);
+ no_longer_exposed_region.Subtract(new_recorded_viewport);
+ invalidation->Union(no_longer_exposed_region);
+}
+
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698