blob: 56885c3ffe6b69bbd2ee784c0866e92d2ba1474b [file] [log] [blame]
[email protected]d98c0242012-11-08 06:22:351// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cc3cfaa2013-03-18 09:05:525#include "cc/layers/picture_layer.h"
[email protected]f117a4c2012-12-16 04:53:106
[email protected]4ea293f72014-08-13 03:03:177#include "base/auto_reset.h"
danakj7a3089f2016-01-16 01:20:138#include "base/trace_event/trace_event.h"
[email protected]f7837a92013-08-21 03:00:059#include "cc/layers/content_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5210#include "cc/layers/picture_layer_impl.h"
danakj920156852015-05-18 20:22:2911#include "cc/playback/display_list_recording_source.h"
dtrainor8e9da482016-01-04 09:53:0512#include "cc/proto/cc_conversions.h"
13#include "cc/proto/gfx_conversions.h"
14#include "cc/proto/layer.pb.h"
jamesr9b8fda32015-03-16 19:11:0515#include "cc/trees/layer_tree_host.h"
[email protected]556fd292013-03-18 08:03:0416#include "cc/trees/layer_tree_impl.h"
[email protected]de14c2c2014-04-24 01:02:2517#include "third_party/skia/include/core/SkPictureRecorder.h"
heejin.r.chungd28506ba2014-10-23 16:36:2018#include "ui/gfx/geometry/rect_conversions.h"
[email protected]d98c0242012-11-08 06:22:3519
20namespace cc {
21
loyso0940d412016-03-14 01:30:3122scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) {
23 return make_scoped_refptr(new PictureLayer(client));
[email protected]d98c0242012-11-08 06:22:3524}
25
loyso0940d412016-03-14 01:30:3126PictureLayer::PictureLayer(ContentLayerClient* client)
27 : client_(client),
[email protected]f6d55aa2014-03-11 20:42:5328 instrumentation_object_tracker_(id()),
[email protected]36df0632014-06-12 20:26:1529 update_source_frame_number_(-1),
jackhou24229612014-12-13 23:41:0030 is_mask_(false),
loyso0940d412016-03-14 01:30:3131 nearest_neighbor_(false) {}
[email protected]d98c0242012-11-08 06:22:3532
loyso0940d412016-03-14 01:30:3133PictureLayer::PictureLayer(ContentLayerClient* client,
hendrikwddb87659a2015-10-06 20:23:3734 scoped_ptr<DisplayListRecordingSource> source)
loyso0940d412016-03-14 01:30:3135 : PictureLayer(client) {
danakja04855a2015-11-18 20:39:1036 recording_source_ = std::move(source);
danakja819c2552014-11-14 02:05:0437}
38
[email protected]d98c0242012-11-08 06:22:3539PictureLayer::~PictureLayer() {
40}
41
[email protected]8c406cda32013-03-14 16:20:3242scoped_ptr<LayerImpl> PictureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
sunxdc36713a2016-03-03 22:31:1043 return PictureLayerImpl::Create(tree_impl, id(), is_mask_);
[email protected]d98c0242012-11-08 06:22:3544}
45
[email protected]7aba6662013-03-12 10:17:3446void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
47 Layer::PushPropertiesTo(base_layer);
danakj7a3089f2016-01-16 01:20:1348 TRACE_EVENT0("cc", "PictureLayer::PushPropertiesTo");
[email protected]3621e182012-11-09 22:37:0949 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
danakja4ed6a22014-12-11 01:09:3850 // TODO(danakj): Make is_mask_ a constructor parameter for PictureLayer.
danakjd193f6b2014-12-16 00:06:2351 DCHECK_EQ(layer_impl->is_mask(), is_mask_);
dtrainor8e9da482016-01-04 09:53:0552 DropRecordingSourceContentIfInvalid();
[email protected]eda36f02013-10-23 08:15:3153
jackhou24229612014-12-13 23:41:0054 layer_impl->SetNearestNeighbor(nearest_neighbor_);
55
enneaf5bda32015-02-19 01:27:3656 // Preserve lcd text settings from the current raster source.
57 bool can_use_lcd_text = layer_impl->RasterSourceUsesLCDText();
vmpstr41d68f882016-03-30 01:20:2358 scoped_refptr<RasterSource> raster_source =
enneaf5bda32015-02-19 01:27:3659 recording_source_->CreateRasterSource(can_use_lcd_text);
hendrikw757ba9e2015-03-23 21:13:0960 layer_impl->set_gpu_raster_max_texture_size(
61 layer_tree_host()->device_viewport_size());
chrishtrc41aca7b2016-03-18 15:44:2962 layer_impl->UpdateRasterSource(raster_source, &last_updated_invalidation_,
danakja4ed6a22014-12-11 01:09:3863 nullptr);
chrishtrc41aca7b2016-03-18 15:44:2964 DCHECK(last_updated_invalidation_.IsEmpty());
[email protected]3621e182012-11-09 22:37:0965}
66
[email protected]7aba6662013-03-12 10:17:3467void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
68 Layer::SetLayerTreeHost(host);
ennebdb6fd202015-03-10 06:01:5769 if (!host)
70 return;
71
vmpstr5c4b6812015-09-29 19:57:1372 if (!recording_source_)
73 recording_source_.reset(new DisplayListRecordingSource);
ennebdb6fd202015-03-10 06:01:5774 recording_source_->SetSlowdownRasterScaleFactor(
75 host->debug_state().slow_down_raster_scale_factor);
vmpstrdfd22862015-09-25 17:42:4176 // If we need to enable image decode tasks, then we have to generate the
77 // discardable images metadata.
vmpstr5c4b6812015-09-29 19:57:1378 const LayerTreeSettings& settings = layer_tree_host()->settings();
vmpstrdfd22862015-09-25 17:42:4179 recording_source_->SetGenerateDiscardableImagesMetadata(
80 settings.image_decode_tasks_enabled);
[email protected]ce37a152013-01-08 17:12:3381}
82
danakj19f0c9e2014-10-11 03:24:4283void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
chrishtrbb9af002015-12-09 02:00:1184 DCHECK(!layer_tree_host() || !layer_tree_host()->in_paint_layer_contents());
chrishtrc41aca7b2016-03-18 15:44:2985 if (recording_source_)
86 recording_source_->SetNeedsDisplayRect(layer_rect);
[email protected]7aba6662013-03-12 10:17:3487 Layer::SetNeedsDisplayRect(layer_rect);
[email protected]3621e182012-11-09 22:37:0988}
89
danakj5f46636a2015-06-19 00:01:4090bool PictureLayer::Update() {
[email protected]abe51342013-10-28 22:04:3891 update_source_frame_number_ = layer_tree_host()->source_frame_number();
danakj5f46636a2015-06-19 00:01:4092 bool updated = Layer::Update();
[email protected]c50b997292013-08-03 18:44:3093
danakj64767d902015-06-19 00:10:4394 gfx::Rect update_rect = visible_layer_rect();
[email protected]a108f5db2014-07-16 06:10:2795 gfx::Size layer_size = paint_properties().bounds;
[email protected]4c1598952014-04-16 02:54:4896
enneffe57812015-02-14 02:37:2097 recording_source_->SetBackgroundColor(SafeOpaqueBackgroundColor());
98 recording_source_->SetRequiresClear(!contents_opaque() &&
99 !client_->FillsBoundsCompletely());
100
[email protected]08ac6f9e2013-12-04 05:44:09101 TRACE_EVENT1("cc", "PictureLayer::Update",
102 "source_frame_number",
103 layer_tree_host()->source_frame_number());
[email protected]8af1ce12014-06-15 12:18:36104 devtools_instrumentation::ScopedLayerTreeTask update_layer(
105 devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->id());
[email protected]08ac6f9e2013-12-04 05:44:09106
[email protected]8f322ba2014-06-18 23:48:18107 // UpdateAndExpandInvalidation will give us an invalidation that covers
108 // anything not explicitly recorded in this frame. We give this region
109 // to the impl side so that it drops tiles that may not have a recording
110 // for them.
[email protected]1d96e032014-03-25 05:59:08111 DCHECK(client_);
hendrikw9d909aa72014-11-11 20:19:52112 updated |= recording_source_->UpdateAndExpandInvalidation(
chrishtrc41aca7b2016-03-18 15:44:29113 client_, &last_updated_invalidation_, layer_size, update_rect,
hendrikwddb87659a2015-10-06 20:23:37114 update_source_frame_number_, DisplayListRecordingSource::RECORD_NORMALLY);
danakj64767d902015-06-19 00:10:43115 last_updated_visible_layer_rect_ = visible_layer_rect();
[email protected]048ff152013-11-25 21:02:11116
[email protected]214c86972013-08-20 23:43:06117 if (updated) {
118 SetNeedsPushProperties();
119 } else {
hendrikw312ee8ac2014-11-12 23:24:34120 // If this invalidation did not affect the recording source, then it can be
121 // cleared as an optimization.
chrishtrc41aca7b2016-03-18 15:44:29122 last_updated_invalidation_.Clear();
[email protected]49304bde2013-07-08 21:31:22123 }
[email protected]214c86972013-08-20 23:43:06124
[email protected]49304bde2013-07-08 21:31:22125 return updated;
[email protected]d98c0242012-11-08 06:22:35126}
127
[email protected]7aba6662013-03-12 10:17:34128void PictureLayer::SetIsMask(bool is_mask) {
hendrikw4e8c6322014-11-18 05:46:32129 is_mask_ = is_mask;
[email protected]f6776532012-12-21 20:24:33130}
131
fmalita2d743282016-03-22 13:32:10132sk_sp<SkPicture> PictureLayer::GetPicture() const {
hendrikwddb87659a2015-10-06 20:23:37133 // We could either flatten the DisplayListRecordingSource into a single
134 // SkPicture, or paint a fresh one depending on what we intend to do with the
[email protected]f7837a92013-08-21 03:00:05135 // picture. For now we just paint a fresh one to get consistent results.
136 if (!DrawsContent())
fmalita2d743282016-03-22 13:32:10137 return nullptr;
[email protected]f7837a92013-08-21 03:00:05138
pan.deng0bd2a732015-04-01 03:22:05139 gfx::Size layer_size = bounds();
hendrikwddb87659a2015-10-06 20:23:37140 scoped_ptr<DisplayListRecordingSource> recording_source(
141 new DisplayListRecordingSource);
pdrb42dfda32015-09-16 18:34:19142 Region recording_invalidation;
143 recording_source->UpdateAndExpandInvalidation(
144 client_, &recording_invalidation, layer_size, gfx::Rect(layer_size),
hendrikwddb87659a2015-10-06 20:23:37145 update_source_frame_number_, DisplayListRecordingSource::RECORD_NORMALLY);
pan.deng0bd2a732015-04-01 03:22:05146
vmpstr41d68f882016-03-30 01:20:23147 scoped_refptr<RasterSource> raster_source =
pdrb42dfda32015-09-16 18:34:19148 recording_source->CreateRasterSource(false);
pan.deng0bd2a732015-04-01 03:22:05149
pdrb42dfda32015-09-16 18:34:19150 return raster_source->GetFlattenedPicture();
[email protected]f7837a92013-08-21 03:00:05151}
152
[email protected]a6c1b232014-05-05 23:53:08153bool PictureLayer::IsSuitableForGpuRasterization() const {
hendrikw9d909aa72014-11-11 20:19:52154 return recording_source_->IsSuitableForGpuRasterization();
[email protected]a6c1b232014-05-05 23:53:08155}
156
[email protected]ad63b2f2014-08-11 17:39:54157void PictureLayer::ClearClient() {
kulkarni.a4015690f12014-10-10 13:50:06158 client_ = nullptr;
[email protected]ad63b2f2014-08-11 17:39:54159 UpdateDrawsContent(HasDrawableContent());
160}
161
jackhou24229612014-12-13 23:41:00162void PictureLayer::SetNearestNeighbor(bool nearest_neighbor) {
163 if (nearest_neighbor_ == nearest_neighbor)
164 return;
165
166 nearest_neighbor_ = nearest_neighbor;
167 SetNeedsCommit();
168}
169
[email protected]ad63b2f2014-08-11 17:39:54170bool PictureLayer::HasDrawableContent() const {
171 return client_ && Layer::HasDrawableContent();
172}
173
dtrainor8e9da482016-01-04 09:53:05174void PictureLayer::SetTypeForProtoSerialization(proto::LayerNode* proto) const {
nyquist607e072e92016-02-19 00:30:41175 proto->set_type(proto::LayerNode::PICTURE_LAYER);
dtrainor8e9da482016-01-04 09:53:05176}
177
178void PictureLayer::LayerSpecificPropertiesToProto(
179 proto::LayerProperties* proto) {
180 Layer::LayerSpecificPropertiesToProto(proto);
181 DropRecordingSourceContentIfInvalid();
182
183 proto::PictureLayerProperties* picture = proto->mutable_picture();
nyquist16febb42016-02-12 00:15:04184 recording_source_->ToProtobuf(
185 picture->mutable_recording_source(),
186 layer_tree_host()->image_serialization_processor());
chrishtrc41aca7b2016-03-18 15:44:29187 RegionToProto(last_updated_invalidation_, picture->mutable_invalidation());
dtrainor8e9da482016-01-04 09:53:05188 RectToProto(last_updated_visible_layer_rect_,
189 picture->mutable_last_updated_visible_layer_rect());
190 picture->set_is_mask(is_mask_);
191 picture->set_nearest_neighbor(nearest_neighbor_);
192
193 picture->set_update_source_frame_number(update_source_frame_number_);
194
chrishtrc41aca7b2016-03-18 15:44:29195 last_updated_invalidation_.Clear();
dtrainor8e9da482016-01-04 09:53:05196}
197
198void PictureLayer::FromLayerSpecificPropertiesProto(
199 const proto::LayerProperties& proto) {
200 Layer::FromLayerSpecificPropertiesProto(proto);
201 const proto::PictureLayerProperties& picture = proto.picture();
nyquist34a0f412016-02-19 00:19:15202 // If this is a new layer, ensure it has a recording source. During layer
203 // hierarchy deserialization, ::SetLayerTreeHost(...) is not called, but
204 // instead the member is set directly, so it needs to be set here explicitly.
205 if (!recording_source_)
206 recording_source_.reset(new DisplayListRecordingSource);
207
nyquist16febb42016-02-12 00:15:04208 recording_source_->FromProtobuf(
209 picture.recording_source(),
210 layer_tree_host()->image_serialization_processor());
dtrainor8e9da482016-01-04 09:53:05211
212 Region new_invalidation = RegionFromProto(picture.invalidation());
chrishtrc41aca7b2016-03-18 15:44:29213 last_updated_invalidation_.Swap(&new_invalidation);
dtrainor8e9da482016-01-04 09:53:05214 last_updated_visible_layer_rect_ =
215 ProtoToRect(picture.last_updated_visible_layer_rect());
216 is_mask_ = picture.is_mask();
217 nearest_neighbor_ = picture.nearest_neighbor();
218
219 update_source_frame_number_ = picture.update_source_frame_number();
220}
221
[email protected]1a55d7dc2013-10-12 07:52:20222void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
223 benchmark->RunOnLayer(this);
224}
225
dtrainor8e9da482016-01-04 09:53:05226void PictureLayer::DropRecordingSourceContentIfInvalid() {
227 int source_frame_number = layer_tree_host()->source_frame_number();
228 gfx::Size recording_source_bounds = recording_source_->GetSize();
229
230 gfx::Size layer_bounds = bounds();
231 if (paint_properties().source_frame_number == source_frame_number)
232 layer_bounds = paint_properties().bounds;
233
234 // If update called, then recording source size must match bounds pushed to
235 // impl layer.
236 DCHECK(update_source_frame_number_ != source_frame_number ||
237 layer_bounds == recording_source_bounds)
238 << " bounds " << layer_bounds.ToString() << " recording source "
239 << recording_source_bounds.ToString();
240
241 if (update_source_frame_number_ != source_frame_number &&
242 recording_source_bounds != layer_bounds) {
243 // Update may not get called for the layer (if it's not in the viewport
244 // for example), even though it has resized making the recording source no
245 // longer valid. In this case just destroy the recording source.
246 recording_source_->SetEmptyBounds();
247 }
248}
249
[email protected]d98c0242012-11-08 06:22:35250} // namespace cc