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

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: Address comments 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..6c842baa7ae739438818d40d08ae291a2f67c5b5 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -8,7 +8,6 @@
#include "base/trace_event/trace_event.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/picture_layer_impl.h"
-#include "cc/playback/recording_source.h"
#include "cc/proto/cc_conversions.h"
#include "cc/proto/gfx_conversions.h"
#include "cc/proto/layer.pb.h"
@@ -19,6 +18,17 @@
namespace cc {
+PictureLayerData::PictureLayerData() = default;
+
+PictureLayerData::~PictureLayerData() = default;
+
+ContentLayerClientData::ContentLayerClientData() = default;
+
+ContentLayerClientData::ContentLayerClientData(const ContentLayerClientData&) =
+ default;
+
+ContentLayerClientData::~ContentLayerClientData() = default;
+
scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) {
return make_scoped_refptr(new PictureLayer(client));
}
@@ -31,9 +41,11 @@ PictureLayer::PictureLayer(ContentLayerClient* client)
}
PictureLayer::PictureLayer(ContentLayerClient* client,
- std::unique_ptr<RecordingSource> source)
+ const PictureLayerData& layer_data,
+ const ContentLayerClientData& client_data)
: PictureLayer(client) {
- recording_source_ = std::move(source);
+ layer_data_ = layer_data;
+ client_data_ = client_data;
}
PictureLayer::~PictureLayer() {
@@ -57,7 +69,7 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
// Preserve lcd text settings from the current raster source.
bool can_use_lcd_text = layer_impl->RasterSourceUsesLCDText();
scoped_refptr<RasterSource> raster_source =
- recording_source_->CreateRasterSource(can_use_lcd_text);
+ CreateRasterSource(layer_data_, client_data_, 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 +82,19 @@ void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
if (!host)
return;
- if (!recording_source_)
- recording_source_.reset(new RecordingSource);
- recording_source_->SetSlowdownRasterScaleFactor(
- host->debug_state().slow_down_raster_scale_factor);
+ layer_data_ = PictureLayerData();
vmpstr 2016/07/20 22:18:10 What's the difference between this and ResetLayerA
Menglin 2016/07/20 22:39:31 ResetLayerAndClientData() is essentially layer_
vmpstr 2016/07/20 23:55:54 Hmm... It certainly isn't reset if it's only reset
+ client_data_ = ContentLayerClientData();
+ layer_data_.slow_down_raster_scale_factor_for_debug =
+ 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);
vmpstr 2016/07/20 22:18:10 Can this function go away as well and just be repl
Menglin 2016/07/20 22:39:31 we probably want to keep it since the test code us
vmpstr 2016/07/20 23:55:54 Thanks! FWIW, we sometimes have FooInternal when t
Layer::SetNeedsDisplayRect(layer_rect);
}
@@ -94,9 +104,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 +119,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, PictureLayer::RECORD_NORMALLY,
vmpstr 2016/07/20 22:18:10 Do we ever pass something other than "RECORD_NORMA
Menglin 2016/07/20 22:39:31 I checked, it always pass RECORD_NORMALLY
+ &layer_data_, &client_data_, &invalidation_);
vmpstr 2016/07/20 22:18:10 In general, if we can eliminate some of these para
Menglin 2016/07/20 22:39:31 but that doesn't work in GetPicture, where it rece
vmpstr 2016/07/20 23:55:54 Oh yeah, good point.
if (updated) {
SetNeedsPushProperties();
@@ -136,20 +146,26 @@ 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_regision;
vmpstr 2016/07/20 22:18:10 s/regision/region/
Menglin 2016/07/20 22:39:31 ok
+ PictureLayerData layer_data = PictureLayerData();
+ ContentLayerClientData client_data = ContentLayerClientData();
+ UpdateAndExpandInvalidation(&recording_invalidation, layer_size,
+ PictureLayer::RECORD_NORMALLY, &layer_data,
+ &client_data, &invalidation_regision);
Menglin 2016/07/20 22:39:31 Here it needs the local variables
vmpstr 2016/07/20 23:55:54 Acknowledged.
scoped_refptr<RasterSource> raster_source =
- recording_source->CreateRasterSource(false);
+ CreateRasterSource(layer_data, client_data, false);
return raster_source->GetFlattenedPicture();
}
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 !client_data_.display_list ||
+ client_data_.display_list->IsSuitableForGpuRasterization();
}
void PictureLayer::ClearClient() {
@@ -179,10 +195,26 @@ void PictureLayer::LayerSpecificPropertiesToProto(
DropRecordingSourceContentIfInvalid();
proto::PictureLayerProperties* picture = proto->mutable_picture();
- recording_source_->ToProtobuf(picture->mutable_recording_source());
+
+ RectToProto(client_data_.recorded_viewport,
+ picture->mutable_recorded_viewport());
+ SizeToProto(layer_data_.size, picture->mutable_size());
+ picture->set_slow_down_raster_scale_factor_for_debug(
+ layer_data_.slow_down_raster_scale_factor_for_debug);
+ picture->set_generate_discardable_images_metadata(
+ layer_data_.generate_discardable_images_metadata);
+ picture->set_requires_clear(layer_data_.requires_clear);
+ picture->set_is_solid_color(layer_data_.is_solid_color);
+ picture->set_clear_canvas_with_debug_color(
+ layer_data_.clear_canvas_with_debug_color);
+ picture->set_solid_color(static_cast<uint64_t>(layer_data_.solid_color));
+ picture->set_background_color(
+ static_cast<uint64_t>(layer_data_.background_color));
+ if (client_data_.display_list)
+ client_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 +242,36 @@ 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);
-
+ layer_data_ = PictureLayerData();
+ client_data_ = ContentLayerClientData();
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());
+ client_data_.recorded_viewport = ProtoToRect(picture.recorded_viewport());
+ layer_data_.size = ProtoToSize(picture.size());
+ layer_data_.slow_down_raster_scale_factor_for_debug =
+ picture.slow_down_raster_scale_factor_for_debug();
+ layer_data_.generate_discardable_images_metadata =
+ picture.generate_discardable_images_metadata();
+ layer_data_.requires_clear = picture.requires_clear();
+ layer_data_.is_solid_color = picture.is_solid_color();
+ layer_data_.clear_canvas_with_debug_color =
+ picture.clear_canvas_with_debug_color();
+ layer_data_.solid_color = static_cast<SkColor>(picture.solid_color());
+ layer_data_.background_color =
+ static_cast<SkColor>(picture.background_color());
+
+ // This might not exist if the |client_data_.display_list| of the serialized
+ // RecordingSource was null, which can happen if |Clear()| is
+ // called.
+ if (picture.has_display_list()) {
+ client_data_.display_list = DisplayItemList::CreateFromProto(
+ picture.display_list(), layer_tree_host()->client_picture_cache(),
+ &used_engine_picture_ids);
+ FinishDisplayItemListUpdate(&layer_data_, &client_data_);
+ } else {
+ client_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 +289,119 @@ void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
benchmark->RunOnLayer(this);
}
+bool PictureLayer::UpdateAndExpandInvalidation(
+ Region* invalidation,
+ const gfx::Size& layer_size,
+ PictureLayer::RecordingMode recording_mode,
+ PictureLayerData* layer_data,
+ ContentLayerClientData* client_data,
+ InvalidationRegion* invalidation_state) const {
+ bool updated = false;
+
+ if (layer_data->size != layer_size)
+ layer_data->size = layer_size;
+
+ invalidation_state->Swap(invalidation);
+ invalidation_state->Clear();
+
+ gfx::Rect new_recorded_viewport = inputs_.client->PaintableRegion();
+ if (new_recorded_viewport != client_data->recorded_viewport) {
+ UpdateInvalidationForNewViewport(client_data->recorded_viewport,
+ new_recorded_viewport, invalidation);
+ client_data->recorded_viewport = new_recorded_viewport;
+ updated = true;
+ }
+
+ if (!updated && !invalidation->Intersects(client_data->recorded_viewport))
+ return false;
+
+ if (invalidation->IsEmpty())
+ return false;
+
+ ContentLayerClient::PaintingControlSetting painting_control =
+ ContentLayerClient::PAINTING_BEHAVIOR_NORMAL;
+
+ switch (recording_mode) {
+ case PictureLayer::RECORD_NORMALLY:
+ // Already setup for normal recording.
+ break;
+ case PictureLayer::RECORD_WITH_PAINTING_DISABLED:
+ painting_control = ContentLayerClient::DISPLAY_LIST_PAINTING_DISABLED;
+ break;
+ case PictureLayer::RECORD_WITH_CACHING_DISABLED:
+ painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED;
+ break;
+ case PictureLayer::RECORD_WITH_CONSTRUCTION_DISABLED:
+ painting_control = ContentLayerClient::DISPLAY_LIST_CONSTRUCTION_DISABLED;
+ break;
+ case PictureLayer::RECORD_WITH_SUBSEQUENCE_CACHING_DISABLED:
+ painting_control = ContentLayerClient::SUBSEQUENCE_CACHING_DISABLED;
+ break;
+ case PictureLayer::RECORD_WITH_SK_NULL_CANVAS:
+ case PictureLayer::RECORDING_MODE_COUNT:
+ NOTREACHED();
+ }
+
+ // TODO(vmpstr): Add a slow_down_recording_scale_factor_for_debug_ to be able
+ // to slow down recording.
+ client_data->display_list =
+ inputs_.client->PaintContentsToDisplayList(painting_control);
+ client_data->painter_reported_memory_usage =
+ inputs_.client->GetApproximateUnsharedMemoryUsage();
+
+ FinishDisplayItemListUpdate(layer_data, client_data);
+
+ return true;
+}
+
+void PictureLayer::ResetLayerAndClientData() {
+ layer_data_.size = gfx::Size();
+ client_data_.recorded_viewport = gfx::Rect();
+ client_data_.display_list = nullptr;
+ client_data_.painter_reported_memory_usage = 0;
+ layer_data_.is_solid_color = false;
+}
+
+void PictureLayer::SetGenerateDiscardableImagesMetadata(
+ bool generate_metadata) {
+ layer_data_.generate_discardable_images_metadata = generate_metadata;
+}
+
+void PictureLayer::SetBackgroundColorSimple(SkColor background_color) {
+ layer_data_.background_color = background_color;
+}
+
+void PictureLayer::SetRequiresClear(bool requires_clear) {
+ layer_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(layer_data_.size)));
+ }
+}
+
+gfx::Size PictureLayer::GetSizeInLayerData() const {
+ return layer_data_.size;
+}
+
+const DisplayItemList* PictureLayer::GetDisplayItemList() {
+ return client_data_.display_list.get();
+}
+
+scoped_refptr<RasterSource> PictureLayer::CreateRasterSource(
+ const PictureLayerData& layer_data,
+ const ContentLayerClientData& client_data,
+ bool can_use_lcd_text) const {
+ return scoped_refptr<RasterSource>(RasterSource::CreateFromDataStruct(
vmpstr 2016/07/20 22:18:10 You don't need to wrap this in scoped_refptr, sinc
+ layer_data, client_data, can_use_lcd_text));
+}
+
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 = GetSizeInLayerData();
gfx::Size layer_bounds = bounds();
if (paint_properties().source_frame_number == source_frame_number)
@@ -254,8 +419,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();
+ ResetLayerAndClientData();
}
}
+void PictureLayer::FinishDisplayItemListUpdate(
+ PictureLayerData* layer_data,
+ ContentLayerClientData* client_data) const {
+ TRACE_EVENT0("cc", "PictureLayer::FinishDisplayItemListUpdate");
+ DetermineIfSolidColor(layer_data, client_data);
+ client_data->display_list->EmitTraceSnapshot();
+ if (layer_data->generate_discardable_images_metadata)
+ client_data->display_list->GenerateDiscardableImagesMetadata();
+}
+
+void PictureLayer::DetermineIfSolidColor(
+ PictureLayerData* layer_data,
+ ContentLayerClientData* client_data) const {
+ DCHECK(client_data->display_list);
+ layer_data->is_solid_color = false;
+ layer_data->solid_color = SK_ColorTRANSPARENT;
+
+ if (!client_data->display_list->ShouldBeAnalyzedForSolidColor())
+ return;
+
+ TRACE_EVENT1("cc", "PictureLayer::DetermineIfSolidColor", "opcount",
+ client_data->display_list->ApproximateOpCount());
+ gfx::Size layer_size = layer_data->size;
+ skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height());
+ client_data->display_list->Raster(&canvas, nullptr, gfx::Rect(), 1.f);
+ layer_data->is_solid_color = canvas.GetColorIfSolid(&layer_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