blob: 811e8068634f7db9b036886c133c1e5ebc9a6c7c [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"
[email protected]f7837a92013-08-21 03:00:058#include "cc/layers/content_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:529#include "cc/layers/picture_layer_impl.h"
danakj920156852015-05-18 20:22:2910#include "cc/playback/display_list_recording_source.h"
jamesr9b8fda32015-03-16 19:11:0511#include "cc/trees/layer_tree_host.h"
[email protected]556fd292013-03-18 08:03:0412#include "cc/trees/layer_tree_impl.h"
[email protected]de14c2c2014-04-24 01:02:2513#include "third_party/skia/include/core/SkPictureRecorder.h"
heejin.r.chungd28506ba2014-10-23 16:36:2014#include "ui/gfx/geometry/rect_conversions.h"
[email protected]d98c0242012-11-08 06:22:3515
16namespace cc {
17
loysoa6edaaff2015-05-25 03:26:4418scoped_refptr<PictureLayer> PictureLayer::Create(const LayerSettings& settings,
19 ContentLayerClient* client) {
20 return make_scoped_refptr(new PictureLayer(settings, client));
[email protected]d98c0242012-11-08 06:22:3521}
22
loysoa6edaaff2015-05-25 03:26:4423PictureLayer::PictureLayer(const LayerSettings& settings,
24 ContentLayerClient* client)
25 : Layer(settings),
26 client_(client),
[email protected]f6d55aa2014-03-11 20:42:5327 instrumentation_object_tracker_(id()),
[email protected]36df0632014-06-12 20:26:1528 update_source_frame_number_(-1),
jackhou24229612014-12-13 23:41:0029 is_mask_(false),
30 nearest_neighbor_(false) {
[email protected]36df0632014-06-12 20:26:1531}
[email protected]d98c0242012-11-08 06:22:3532
loysoa6edaaff2015-05-25 03:26:4433PictureLayer::PictureLayer(const LayerSettings& settings,
34 ContentLayerClient* client,
hendrikwddb87659a2015-10-06 20:23:3735 scoped_ptr<DisplayListRecordingSource> source)
loysoa6edaaff2015-05-25 03:26:4436 : PictureLayer(settings, client) {
danakja04855a2015-11-18 20:39:1037 recording_source_ = std::move(source);
danakja819c2552014-11-14 02:05:0438}
39
[email protected]d98c0242012-11-08 06:22:3540PictureLayer::~PictureLayer() {
41}
42
[email protected]8c406cda32013-03-14 16:20:3243scoped_ptr<LayerImpl> PictureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
aeliasd0070ba2015-01-31 13:44:4944 return PictureLayerImpl::Create(tree_impl, id(), is_mask_,
45 new LayerImpl::SyncedScrollOffset);
[email protected]d98c0242012-11-08 06:22:3546}
47
[email protected]7aba6662013-03-12 10:17:3448void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
49 Layer::PushPropertiesTo(base_layer);
[email protected]3621e182012-11-09 22:37:0950 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
danakja4ed6a22014-12-11 01:09:3851 // TODO(danakj): Make is_mask_ a constructor parameter for PictureLayer.
danakjd193f6b2014-12-16 00:06:2352 DCHECK_EQ(layer_impl->is_mask(), is_mask_);
[email protected]23257682013-05-17 22:53:0353
danakj45377972014-11-06 22:05:4954 int source_frame_number = layer_tree_host()->source_frame_number();
55 gfx::Size impl_bounds = layer_impl->bounds();
hendrikw9d909aa72014-11-11 20:19:5256 gfx::Size recording_source_bounds = recording_source_->GetSize();
danakj45377972014-11-06 22:05:4957
hendrikw312ee8ac2014-11-12 23:24:3458 // If update called, then recording source size must match bounds pushed to
59 // impl layer.
vmpstracfa9222015-10-28 22:42:2360 DCHECK(update_source_frame_number_ != source_frame_number ||
61 impl_bounds == recording_source_bounds)
hendrikw312ee8ac2014-11-12 23:24:3462 << " bounds " << impl_bounds.ToString() << " recording source "
hendrikw9d909aa72014-11-11 20:19:5263 << recording_source_bounds.ToString();
danakj45377972014-11-06 22:05:4964
65 if (update_source_frame_number_ != source_frame_number &&
hendrikw9d909aa72014-11-11 20:19:5266 recording_source_bounds != impl_bounds) {
danakj45377972014-11-06 22:05:4967 // Update may not get called for the layer (if it's not in the viewport
hendrikw312ee8ac2014-11-12 23:24:3468 // for example, even though it has resized making the recording source no
69 // longer valid. In this case just destroy the recording source.
hendrikw9d909aa72014-11-11 20:19:5270 recording_source_->SetEmptyBounds();
[email protected]eda36f02013-10-23 08:15:3171 }
72
jackhou24229612014-12-13 23:41:0073 layer_impl->SetNearestNeighbor(nearest_neighbor_);
74
enneaf5bda32015-02-19 01:27:3675 // Preserve lcd text settings from the current raster source.
76 bool can_use_lcd_text = layer_impl->RasterSourceUsesLCDText();
hendrikwc7014b22015-10-19 23:45:0977 scoped_refptr<DisplayListRasterSource> raster_source =
enneaf5bda32015-02-19 01:27:3678 recording_source_->CreateRasterSource(can_use_lcd_text);
hendrikw757ba9e2015-03-23 21:13:0979 layer_impl->set_gpu_raster_max_texture_size(
80 layer_tree_host()->device_viewport_size());
chrishtrbb9af002015-12-09 02:00:1181 layer_impl->UpdateRasterSource(raster_source, invalidation_.region(),
danakja4ed6a22014-12-11 01:09:3882 nullptr);
chrishtrbb9af002015-12-09 02:00:1183 DCHECK(invalidation_.IsEmpty());
[email protected]3621e182012-11-09 22:37:0984}
85
[email protected]7aba6662013-03-12 10:17:3486void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
87 Layer::SetLayerTreeHost(host);
ennebdb6fd202015-03-10 06:01:5788 if (!host)
89 return;
90
vmpstr5c4b6812015-09-29 19:57:1391 if (!recording_source_)
92 recording_source_.reset(new DisplayListRecordingSource);
ennebdb6fd202015-03-10 06:01:5793 recording_source_->SetSlowdownRasterScaleFactor(
94 host->debug_state().slow_down_raster_scale_factor);
vmpstrdfd22862015-09-25 17:42:4195 // If we need to enable image decode tasks, then we have to generate the
96 // discardable images metadata.
vmpstr5c4b6812015-09-29 19:57:1397 const LayerTreeSettings& settings = layer_tree_host()->settings();
vmpstrdfd22862015-09-25 17:42:4198 recording_source_->SetGenerateDiscardableImagesMetadata(
99 settings.image_decode_tasks_enabled);
[email protected]ce37a152013-01-08 17:12:33100}
101
danakj19f0c9e2014-10-11 03:24:42102void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
chrishtrbb9af002015-12-09 02:00:11103 DCHECK(!layer_tree_host() || !layer_tree_host()->in_paint_layer_contents());
danakj19f0c9e2014-10-11 03:24:42104 if (!layer_rect.IsEmpty()) {
[email protected]7a9fc132013-01-10 00:54:58105 // Clamp invalidation to the layer bounds.
chrishtrbb9af002015-12-09 02:00:11106 invalidation_.Union(gfx::IntersectRects(layer_rect, gfx::Rect(bounds())));
[email protected]7a9fc132013-01-10 00:54:58107 }
[email protected]7aba6662013-03-12 10:17:34108 Layer::SetNeedsDisplayRect(layer_rect);
[email protected]3621e182012-11-09 22:37:09109}
110
danakj5f46636a2015-06-19 00:01:40111bool PictureLayer::Update() {
[email protected]abe51342013-10-28 22:04:38112 update_source_frame_number_ = layer_tree_host()->source_frame_number();
danakj5f46636a2015-06-19 00:01:40113 bool updated = Layer::Update();
[email protected]c50b997292013-08-03 18:44:30114
danakj64767d902015-06-19 00:10:43115 gfx::Rect update_rect = visible_layer_rect();
[email protected]a108f5db2014-07-16 06:10:27116 gfx::Size layer_size = paint_properties().bounds;
[email protected]4c1598952014-04-16 02:54:48117
danakj64767d902015-06-19 00:10:43118 if (last_updated_visible_layer_rect_ == update_rect &&
chrishtrbb9af002015-12-09 02:00:11119 recording_source_->GetSize() == layer_size && invalidation_.IsEmpty()) {
[email protected]048ff152013-11-25 21:02:11120 // Only early out if the visible content rect of this layer hasn't changed.
121 return updated;
122 }
123
enneffe57812015-02-14 02:37:20124 recording_source_->SetBackgroundColor(SafeOpaqueBackgroundColor());
125 recording_source_->SetRequiresClear(!contents_opaque() &&
126 !client_->FillsBoundsCompletely());
127
[email protected]08ac6f9e2013-12-04 05:44:09128 TRACE_EVENT1("cc", "PictureLayer::Update",
129 "source_frame_number",
130 layer_tree_host()->source_frame_number());
[email protected]8af1ce12014-06-15 12:18:36131 devtools_instrumentation::ScopedLayerTreeTask update_layer(
132 devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->id());
[email protected]08ac6f9e2013-12-04 05:44:09133
[email protected]8f322ba2014-06-18 23:48:18134 // UpdateAndExpandInvalidation will give us an invalidation that covers
135 // anything not explicitly recorded in this frame. We give this region
136 // to the impl side so that it drops tiles that may not have a recording
137 // for them.
[email protected]1d96e032014-03-25 05:59:08138 DCHECK(client_);
hendrikw9d909aa72014-11-11 20:19:52139 updated |= recording_source_->UpdateAndExpandInvalidation(
chrishtrbb9af002015-12-09 02:00:11140 client_, invalidation_.region(), layer_size, update_rect,
hendrikwddb87659a2015-10-06 20:23:37141 update_source_frame_number_, DisplayListRecordingSource::RECORD_NORMALLY);
danakj64767d902015-06-19 00:10:43142 last_updated_visible_layer_rect_ = visible_layer_rect();
[email protected]048ff152013-11-25 21:02:11143
[email protected]214c86972013-08-20 23:43:06144 if (updated) {
145 SetNeedsPushProperties();
146 } else {
hendrikw312ee8ac2014-11-12 23:24:34147 // If this invalidation did not affect the recording source, then it can be
148 // cleared as an optimization.
chrishtrbb9af002015-12-09 02:00:11149 invalidation_.Clear();
[email protected]49304bde2013-07-08 21:31:22150 }
[email protected]214c86972013-08-20 23:43:06151
[email protected]49304bde2013-07-08 21:31:22152 return updated;
[email protected]d98c0242012-11-08 06:22:35153}
154
[email protected]7aba6662013-03-12 10:17:34155void PictureLayer::SetIsMask(bool is_mask) {
hendrikw4e8c6322014-11-18 05:46:32156 is_mask_ = is_mask;
[email protected]f6776532012-12-21 20:24:33157}
158
[email protected]f7837a92013-08-21 03:00:05159skia::RefPtr<SkPicture> PictureLayer::GetPicture() const {
hendrikwddb87659a2015-10-06 20:23:37160 // We could either flatten the DisplayListRecordingSource into a single
161 // SkPicture, or paint a fresh one depending on what we intend to do with the
[email protected]f7837a92013-08-21 03:00:05162 // picture. For now we just paint a fresh one to get consistent results.
163 if (!DrawsContent())
164 return skia::RefPtr<SkPicture>();
165
pan.deng0bd2a732015-04-01 03:22:05166 gfx::Size layer_size = bounds();
hendrikwddb87659a2015-10-06 20:23:37167 scoped_ptr<DisplayListRecordingSource> recording_source(
168 new DisplayListRecordingSource);
pdrb42dfda32015-09-16 18:34:19169 Region recording_invalidation;
170 recording_source->UpdateAndExpandInvalidation(
171 client_, &recording_invalidation, layer_size, gfx::Rect(layer_size),
hendrikwddb87659a2015-10-06 20:23:37172 update_source_frame_number_, DisplayListRecordingSource::RECORD_NORMALLY);
pan.deng0bd2a732015-04-01 03:22:05173
hendrikwc7014b22015-10-19 23:45:09174 scoped_refptr<DisplayListRasterSource> raster_source =
pdrb42dfda32015-09-16 18:34:19175 recording_source->CreateRasterSource(false);
pan.deng0bd2a732015-04-01 03:22:05176
pdrb42dfda32015-09-16 18:34:19177 return raster_source->GetFlattenedPicture();
[email protected]f7837a92013-08-21 03:00:05178}
179
[email protected]a6c1b232014-05-05 23:53:08180bool PictureLayer::IsSuitableForGpuRasterization() const {
hendrikw9d909aa72014-11-11 20:19:52181 return recording_source_->IsSuitableForGpuRasterization();
[email protected]a6c1b232014-05-05 23:53:08182}
183
[email protected]ad63b2f2014-08-11 17:39:54184void PictureLayer::ClearClient() {
kulkarni.a4015690f12014-10-10 13:50:06185 client_ = nullptr;
[email protected]ad63b2f2014-08-11 17:39:54186 UpdateDrawsContent(HasDrawableContent());
187}
188
jackhou24229612014-12-13 23:41:00189void PictureLayer::SetNearestNeighbor(bool nearest_neighbor) {
190 if (nearest_neighbor_ == nearest_neighbor)
191 return;
192
193 nearest_neighbor_ = nearest_neighbor;
194 SetNeedsCommit();
195}
196
[email protected]ad63b2f2014-08-11 17:39:54197bool PictureLayer::HasDrawableContent() const {
198 return client_ && Layer::HasDrawableContent();
199}
200
[email protected]1a55d7dc2013-10-12 07:52:20201void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
202 benchmark->RunOnLayer(this);
203}
204
[email protected]d98c0242012-11-08 06:22:35205} // namespace cc