Remove "keyboard" from keyboard strings.
[chromium-blink-merge.git] / cc / layers / picture_layer_impl.cc
blob9ec6fac5c412c7dff2a8c98c38dfecaa0625ad26
1 // 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.
5 #include "cc/layers/picture_layer_impl.h"
7 #include <algorithm>
8 #include <limits>
10 #include "base/time/time.h"
11 #include "cc/base/math_util.h"
12 #include "cc/base/util.h"
13 #include "cc/debug/debug_colors.h"
14 #include "cc/debug/micro_benchmark_impl.h"
15 #include "cc/debug/traced_value.h"
16 #include "cc/layers/append_quads_data.h"
17 #include "cc/layers/quad_sink.h"
18 #include "cc/quads/checkerboard_draw_quad.h"
19 #include "cc/quads/debug_border_draw_quad.h"
20 #include "cc/quads/picture_draw_quad.h"
21 #include "cc/quads/solid_color_draw_quad.h"
22 #include "cc/quads/tile_draw_quad.h"
23 #include "cc/resources/tile_manager.h"
24 #include "cc/trees/layer_tree_impl.h"
25 #include "ui/gfx/quad_f.h"
26 #include "ui/gfx/rect_conversions.h"
27 #include "ui/gfx/size_conversions.h"
29 namespace {
30 const float kMaxScaleRatioDuringPinch = 2.0f;
32 // When creating a new tiling during pinch, snap to an existing
33 // tiling's scale if the desired scale is within this ratio.
34 const float kSnapToExistingTilingRatio = 0.2f;
37 namespace cc {
39 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
40 : LayerImpl(tree_impl, id),
41 twin_layer_(NULL),
42 pile_(PicturePileImpl::Create()),
43 is_mask_(false),
44 ideal_page_scale_(0.f),
45 ideal_device_scale_(0.f),
46 ideal_source_scale_(0.f),
47 ideal_contents_scale_(0.f),
48 raster_page_scale_(0.f),
49 raster_device_scale_(0.f),
50 raster_source_scale_(0.f),
51 raster_contents_scale_(0.f),
52 low_res_raster_contents_scale_(0.f),
53 raster_source_scale_was_animating_(false),
54 is_using_lcd_text_(tree_impl->settings().can_use_lcd_text),
55 needs_post_commit_initialization_(true),
56 should_update_tile_priorities_(false),
57 has_gpu_rasterization_hint_(false) {}
59 PictureLayerImpl::~PictureLayerImpl() {}
61 const char* PictureLayerImpl::LayerTypeAsString() const {
62 return "cc::PictureLayerImpl";
65 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
66 LayerTreeImpl* tree_impl) {
67 return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
70 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
71 // It's possible this layer was never drawn or updated (e.g. because it was
72 // a descendant of an opacity 0 layer).
73 DoPostCommitInitializationIfNeeded();
74 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
76 // We have already synced the important bits from the the active layer, and
77 // we will soon swap out its tilings and use them for recycling. However,
78 // there are now tiles in this layer's tilings that were unref'd and replaced
79 // with new tiles (due to invalidation). This resets all active priorities on
80 // the to-be-recycled tiling to ensure replaced tiles don't linger and take
81 // memory (due to a stale 'active' priority).
82 if (layer_impl->tilings_)
83 layer_impl->tilings_->DidBecomeRecycled();
85 LayerImpl::PushPropertiesTo(base_layer);
87 // When the pending tree pushes to the active tree, the pending twin
88 // disappears.
89 layer_impl->twin_layer_ = NULL;
90 twin_layer_ = NULL;
92 layer_impl->SetIsMask(is_mask_);
93 layer_impl->pile_ = pile_;
94 layer_impl->SetHasGpuRasterizationHint(has_gpu_rasterization_hint_);
96 // Tilings would be expensive to push, so we swap. This optimization requires
97 // an extra invalidation in SyncFromActiveLayer.
98 layer_impl->tilings_.swap(tilings_);
99 layer_impl->tilings_->SetClient(layer_impl);
100 if (tilings_)
101 tilings_->SetClient(this);
103 layer_impl->raster_page_scale_ = raster_page_scale_;
104 layer_impl->raster_device_scale_ = raster_device_scale_;
105 layer_impl->raster_source_scale_ = raster_source_scale_;
106 layer_impl->raster_contents_scale_ = raster_contents_scale_;
107 layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
109 layer_impl->UpdateLCDTextStatus(is_using_lcd_text_);
110 layer_impl->needs_post_commit_initialization_ = false;
112 // The invalidation on this soon-to-be-recycled layer must be cleared to
113 // mirror clearing the invalidation in PictureLayer's version of this function
114 // in case push properties is skipped.
115 layer_impl->invalidation_.Swap(&invalidation_);
116 invalidation_.Clear();
117 needs_post_commit_initialization_ = true;
119 // We always need to push properties.
120 // See http://crbug.com/303943
121 needs_push_properties_ = true;
124 void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
125 AppendQuadsData* append_quads_data) {
126 DCHECK(!needs_post_commit_initialization_);
127 gfx::Rect rect(visible_content_rect());
128 gfx::Rect content_rect(content_bounds());
130 SharedQuadState* shared_quad_state =
131 quad_sink->UseSharedQuadState(CreateSharedQuadState());
133 if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
134 AppendDebugBorderQuad(
135 quad_sink,
136 shared_quad_state,
137 append_quads_data,
138 DebugColors::DirectPictureBorderColor(),
139 DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
141 gfx::Rect geometry_rect = rect;
142 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
143 gfx::Rect visible_geometry_rect = geometry_rect;
144 gfx::Size texture_size = rect.size();
145 gfx::RectF texture_rect = gfx::RectF(texture_size);
146 gfx::Rect quad_content_rect = rect;
147 float contents_scale = contents_scale_x();
149 scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
150 quad->SetNew(shared_quad_state,
151 geometry_rect,
152 opaque_rect,
153 visible_geometry_rect,
154 texture_rect,
155 texture_size,
156 RGBA_8888,
157 quad_content_rect,
158 contents_scale,
159 pile_);
160 if (quad_sink->MaybeAppend(quad.PassAs<DrawQuad>()))
161 append_quads_data->num_missing_tiles++;
162 return;
165 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
167 if (ShowDebugBorders()) {
168 for (PictureLayerTilingSet::CoverageIterator iter(
169 tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
170 iter;
171 ++iter) {
172 SkColor color;
173 float width;
174 if (*iter && iter->IsReadyToDraw()) {
175 ManagedTileState::TileVersion::Mode mode =
176 iter->GetTileVersionForDrawing().mode();
177 if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
178 color = DebugColors::SolidColorTileBorderColor();
179 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
180 } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
181 color = DebugColors::PictureTileBorderColor();
182 width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
183 } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
184 color = DebugColors::HighResTileBorderColor();
185 width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
186 } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
187 color = DebugColors::LowResTileBorderColor();
188 width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
189 } else if (iter->contents_scale() > contents_scale_x()) {
190 color = DebugColors::ExtraHighResTileBorderColor();
191 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
192 } else {
193 color = DebugColors::ExtraLowResTileBorderColor();
194 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
196 } else {
197 color = DebugColors::MissingTileBorderColor();
198 width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
201 scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
202 DebugBorderDrawQuad::Create();
203 gfx::Rect geometry_rect = iter.geometry_rect();
204 gfx::Rect visible_geometry_rect = geometry_rect;
205 debug_border_quad->SetNew(shared_quad_state,
206 geometry_rect,
207 visible_geometry_rect,
208 color,
209 width);
210 quad_sink->MaybeAppend(debug_border_quad.PassAs<DrawQuad>());
214 // Keep track of the tilings that were used so that tilings that are
215 // unused can be considered for removal.
216 std::vector<PictureLayerTiling*> seen_tilings;
218 for (PictureLayerTilingSet::CoverageIterator iter(
219 tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
220 iter;
221 ++iter) {
222 gfx::Rect geometry_rect = iter.geometry_rect();
223 gfx::Rect visible_geometry_rect = geometry_rect;
224 if (!*iter || !iter->IsReadyToDraw()) {
225 if (draw_checkerboard_for_missing_tiles()) {
226 // TODO(enne): Figure out how to show debug "invalidated checker" color
227 scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
228 SkColor color = DebugColors::DefaultCheckerboardColor();
229 quad->SetNew(
230 shared_quad_state, geometry_rect, visible_geometry_rect, color);
231 if (quad_sink->MaybeAppend(quad.PassAs<DrawQuad>()))
232 append_quads_data->num_missing_tiles++;
233 } else {
234 SkColor color = SafeOpaqueBackgroundColor();
235 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
236 quad->SetNew(shared_quad_state,
237 geometry_rect,
238 visible_geometry_rect,
239 color,
240 false);
241 if (quad_sink->MaybeAppend(quad.PassAs<DrawQuad>()))
242 append_quads_data->num_missing_tiles++;
245 append_quads_data->had_incomplete_tile = true;
246 continue;
249 const ManagedTileState::TileVersion& tile_version =
250 iter->GetTileVersionForDrawing();
251 scoped_ptr<DrawQuad> draw_quad;
252 switch (tile_version.mode()) {
253 case ManagedTileState::TileVersion::RESOURCE_MODE: {
254 gfx::RectF texture_rect = iter.texture_rect();
255 gfx::Rect opaque_rect = iter->opaque_rect();
256 opaque_rect.Intersect(geometry_rect);
258 if (iter->contents_scale() != ideal_contents_scale_)
259 append_quads_data->had_incomplete_tile = true;
261 scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
262 quad->SetNew(shared_quad_state,
263 geometry_rect,
264 opaque_rect,
265 visible_geometry_rect,
266 tile_version.get_resource_id(),
267 texture_rect,
268 iter.texture_size(),
269 tile_version.contents_swizzled());
270 draw_quad = quad.PassAs<DrawQuad>();
271 break;
273 case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
274 gfx::RectF texture_rect = iter.texture_rect();
275 gfx::Rect opaque_rect = iter->opaque_rect();
276 opaque_rect.Intersect(geometry_rect);
278 ResourceProvider* resource_provider =
279 layer_tree_impl()->resource_provider();
280 ResourceFormat format =
281 resource_provider->memory_efficient_texture_format();
282 scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
283 quad->SetNew(shared_quad_state,
284 geometry_rect,
285 opaque_rect,
286 visible_geometry_rect,
287 texture_rect,
288 iter.texture_size(),
289 format,
290 iter->content_rect(),
291 iter->contents_scale(),
292 pile_);
293 draw_quad = quad.PassAs<DrawQuad>();
294 break;
296 case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
297 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
298 quad->SetNew(shared_quad_state,
299 geometry_rect,
300 visible_geometry_rect,
301 tile_version.get_solid_color(),
302 false);
303 draw_quad = quad.PassAs<DrawQuad>();
304 break;
308 DCHECK(draw_quad);
309 quad_sink->MaybeAppend(draw_quad.Pass());
311 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
312 seen_tilings.push_back(iter.CurrentTiling());
315 // Aggressively remove any tilings that are not seen to save memory. Note
316 // that this is at the expense of doing cause more frequent re-painting. A
317 // better scheme would be to maintain a tighter visible_content_rect for the
318 // finer tilings.
319 CleanUpTilingsOnActiveLayer(seen_tilings);
322 void PictureLayerImpl::UpdateTilePriorities() {
323 DCHECK(!needs_post_commit_initialization_);
324 CHECK(should_update_tile_priorities_);
326 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) {
327 for (size_t i = 0; i < tilings_->num_tilings(); ++i)
328 DCHECK(tilings_->tiling_at(i)->has_ever_been_updated());
329 return;
332 if (!tilings_->num_tilings())
333 return;
335 double current_frame_time_in_seconds =
336 (layer_tree_impl()->CurrentFrameTimeTicks() -
337 base::TimeTicks()).InSecondsF();
339 bool tiling_needs_update = false;
340 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
341 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
342 current_frame_time_in_seconds)) {
343 tiling_needs_update = true;
344 break;
347 if (!tiling_needs_update)
348 return;
350 UpdateLCDTextStatus(can_use_lcd_text());
352 // Use visible_content_rect, unless it's empty. If it's empty, then
353 // try to inverse project the viewport into layer space and use that.
354 gfx::Rect visible_rect_in_content_space = visible_content_rect();
355 if (visible_rect_in_content_space.IsEmpty()) {
356 gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization);
357 if (screen_space_transform().GetInverse(&screen_to_layer)) {
358 gfx::Size viewport_size = layer_tree_impl()->DrawViewportSize();
359 visible_rect_in_content_space =
360 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
361 screen_to_layer, gfx::Rect(viewport_size)));
362 visible_rect_in_content_space.Intersect(gfx::Rect(content_bounds()));
366 WhichTree tree =
367 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
369 tilings_->UpdateTilePriorities(tree,
370 visible_rect_in_content_space,
371 contents_scale_x(),
372 current_frame_time_in_seconds);
374 if (layer_tree_impl()->IsPendingTree())
375 MarkVisibleResourcesAsRequired();
377 // Tile priorities were modified.
378 layer_tree_impl()->DidModifyTilePriorities();
381 void PictureLayerImpl::DidBecomeActive() {
382 LayerImpl::DidBecomeActive();
383 tilings_->DidBecomeActive();
384 layer_tree_impl()->DidModifyTilePriorities();
387 void PictureLayerImpl::DidBeginTracing() {
388 pile_->DidBeginTracing();
391 void PictureLayerImpl::ReleaseResources() {
392 if (tilings_)
393 RemoveAllTilings();
395 ResetRasterScale();
398 void PictureLayerImpl::CalculateContentsScale(
399 float ideal_contents_scale,
400 float device_scale_factor,
401 float page_scale_factor,
402 bool animating_transform_to_screen,
403 float* contents_scale_x,
404 float* contents_scale_y,
405 gfx::Size* content_bounds) {
406 DoPostCommitInitializationIfNeeded();
408 // This function sets valid raster scales and manages tilings, so tile
409 // priorities can now be updated.
410 should_update_tile_priorities_ = true;
412 if (!CanHaveTilings()) {
413 ideal_page_scale_ = page_scale_factor;
414 ideal_device_scale_ = device_scale_factor;
415 ideal_contents_scale_ = ideal_contents_scale;
416 ideal_source_scale_ =
417 ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
418 *contents_scale_x = ideal_contents_scale_;
419 *contents_scale_y = ideal_contents_scale_;
420 *content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(),
421 ideal_contents_scale_,
422 ideal_contents_scale_));
423 return;
426 float min_contents_scale = MinimumContentsScale();
427 DCHECK_GT(min_contents_scale, 0.f);
428 float min_page_scale = layer_tree_impl()->min_page_scale_factor();
429 DCHECK_GT(min_page_scale, 0.f);
430 float min_device_scale = 1.f;
431 float min_source_scale =
432 min_contents_scale / min_page_scale / min_device_scale;
434 float ideal_page_scale = page_scale_factor;
435 float ideal_device_scale = device_scale_factor;
436 float ideal_source_scale =
437 ideal_contents_scale / ideal_page_scale / ideal_device_scale;
439 ideal_contents_scale_ = std::max(ideal_contents_scale, min_contents_scale);
440 ideal_page_scale_ = ideal_page_scale;
441 ideal_device_scale_ = ideal_device_scale;
442 ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
444 ManageTilings(animating_transform_to_screen);
446 // The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
447 // There are (usually) several tilings at different scales. However, the
448 // content bounds is the (integer!) space in which quads are generated.
449 // In order to guarantee that we can fill this integer space with any set of
450 // tilings (and then map back to floating point texture coordinates), the
451 // contents scale must be at least as large as the largest of the tilings.
452 float max_contents_scale = min_contents_scale;
453 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
454 const PictureLayerTiling* tiling = tilings_->tiling_at(i);
455 max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
458 *contents_scale_x = max_contents_scale;
459 *contents_scale_y = max_contents_scale;
460 *content_bounds = gfx::ToCeiledSize(
461 gfx::ScaleSize(bounds(), max_contents_scale, max_contents_scale));
464 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
465 return pile_->GetFlattenedPicture();
468 void PictureLayerImpl::SetHasGpuRasterizationHint(bool has_hint) {
469 bool old_should_use_gpu_rasterization = ShouldUseGpuRasterization();
470 has_gpu_rasterization_hint_ = has_hint;
471 if (ShouldUseGpuRasterization() != old_should_use_gpu_rasterization)
472 RemoveAllTilings();
475 bool PictureLayerImpl::ShouldUseGpuRasterization() const {
476 switch (layer_tree_impl()->settings().rasterization_site) {
477 case LayerTreeSettings::CpuRasterization:
478 return false;
479 case LayerTreeSettings::HybridRasterization:
480 return has_gpu_rasterization_hint_;
481 case LayerTreeSettings::GpuRasterization:
482 return true;
484 NOTREACHED();
485 return false;
488 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
489 const gfx::Rect& content_rect) {
490 if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
491 return scoped_refptr<Tile>();
493 int flags = 0;
494 if (is_using_lcd_text_)
495 flags |= Tile::USE_LCD_TEXT;
496 if (ShouldUseGpuRasterization())
497 flags |= Tile::USE_GPU_RASTERIZATION;
498 return layer_tree_impl()->tile_manager()->CreateTile(
499 pile_.get(),
500 content_rect.size(),
501 content_rect,
502 contents_opaque() ? content_rect : gfx::Rect(),
503 tiling->contents_scale(),
504 id(),
505 layer_tree_impl()->source_frame_number(),
506 flags);
509 void PictureLayerImpl::UpdatePile(Tile* tile) {
510 tile->set_picture_pile(pile_);
513 const Region* PictureLayerImpl::GetInvalidation() {
514 return &invalidation_;
517 const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
518 const PictureLayerTiling* tiling) const {
520 if (!twin_layer_ ||
521 twin_layer_->ShouldUseGpuRasterization() != ShouldUseGpuRasterization())
522 return NULL;
523 for (size_t i = 0; i < twin_layer_->tilings_->num_tilings(); ++i)
524 if (twin_layer_->tilings_->tiling_at(i)->contents_scale() ==
525 tiling->contents_scale())
526 return twin_layer_->tilings_->tiling_at(i);
527 return NULL;
530 size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
531 return layer_tree_impl()->settings().max_tiles_for_interest_area;
534 float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
535 return layer_tree_impl()->settings().skewport_target_time_in_seconds;
538 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
539 return layer_tree_impl()
540 ->settings()
541 .skewport_extrapolation_limit_in_content_pixels;
544 gfx::Size PictureLayerImpl::CalculateTileSize(
545 const gfx::Size& content_bounds) const {
546 if (is_mask_) {
547 int max_size = layer_tree_impl()->MaxTextureSize();
548 return gfx::Size(
549 std::min(max_size, content_bounds.width()),
550 std::min(max_size, content_bounds.height()));
553 int max_texture_size =
554 layer_tree_impl()->resource_provider()->max_texture_size();
556 gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
557 default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
559 gfx::Size max_untiled_content_size =
560 layer_tree_impl()->settings().max_untiled_layer_size;
561 max_untiled_content_size.SetToMin(
562 gfx::Size(max_texture_size, max_texture_size));
564 bool any_dimension_too_large =
565 content_bounds.width() > max_untiled_content_size.width() ||
566 content_bounds.height() > max_untiled_content_size.height();
568 bool any_dimension_one_tile =
569 content_bounds.width() <= default_tile_size.width() ||
570 content_bounds.height() <= default_tile_size.height();
572 // If long and skinny, tile at the max untiled content size, and clamp
573 // the smaller dimension to the content size, e.g. 1000x12 layer with
574 // 500x500 max untiled size would get 500x12 tiles. Also do this
575 // if the layer is small.
576 if (any_dimension_one_tile || !any_dimension_too_large) {
577 int width =
578 std::min(max_untiled_content_size.width(), content_bounds.width());
579 int height =
580 std::min(max_untiled_content_size.height(), content_bounds.height());
581 // Round width and height up to the closest multiple of 64, or 56 if
582 // we should avoid power-of-two textures. This helps reduce the number
583 // of different textures sizes to help recycling, and also keeps all
584 // textures multiple-of-eight, which is preferred on some drivers (IMG).
585 bool avoid_pow2 =
586 layer_tree_impl()->GetRendererCapabilities().avoid_pow2_textures;
587 int round_up_to = avoid_pow2 ? 56 : 64;
588 width = RoundUp(width, round_up_to);
589 height = RoundUp(height, round_up_to);
590 return gfx::Size(width, height);
593 return default_tile_size;
596 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
597 DCHECK(!other->needs_post_commit_initialization_);
598 DCHECK(other->tilings_);
600 UpdateLCDTextStatus(other->is_using_lcd_text_);
602 if (!DrawsContent()) {
603 RemoveAllTilings();
604 return;
607 raster_page_scale_ = other->raster_page_scale_;
608 raster_device_scale_ = other->raster_device_scale_;
609 raster_source_scale_ = other->raster_source_scale_;
610 raster_contents_scale_ = other->raster_contents_scale_;
611 low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
613 // Add synthetic invalidations for any recordings that were dropped. As
614 // tiles are updated to point to this new pile, this will force the dropping
615 // of tiles that can no longer be rastered. This is not ideal, but is a
616 // trade-off for memory (use the same pile as much as possible, by switching
617 // during DidBecomeActive) and for time (don't bother checking every tile
618 // during activation to see if the new pile can still raster it).
619 for (int x = 0; x < pile_->num_tiles_x(); ++x) {
620 for (int y = 0; y < pile_->num_tiles_y(); ++y) {
621 bool previously_had = other->pile_->HasRecordingAt(x, y);
622 bool now_has = pile_->HasRecordingAt(x, y);
623 if (now_has || !previously_had)
624 continue;
625 gfx::Rect layer_rect = pile_->tile_bounds(x, y);
626 invalidation_.Union(layer_rect);
630 // Union in the other newly exposed regions as invalid.
631 Region difference_region = Region(gfx::Rect(bounds()));
632 difference_region.Subtract(gfx::Rect(other->bounds()));
633 invalidation_.Union(difference_region);
635 if (CanHaveTilings()) {
636 // The recycle tree's tiling set is two frames out of date, so it needs to
637 // have both this frame's invalidation and the previous frame's invalidation
638 // (stored on the active layer).
639 Region tiling_invalidation = other->invalidation_;
640 tiling_invalidation.Union(invalidation_);
641 tilings_->SyncTilings(*other->tilings_,
642 bounds(),
643 tiling_invalidation,
644 MinimumContentsScale());
645 } else {
646 RemoveAllTilings();
649 SanityCheckTilingState();
652 void PictureLayerImpl::SyncTiling(
653 const PictureLayerTiling* tiling) {
654 if (!CanHaveTilingWithScale(tiling->contents_scale()))
655 return;
656 tilings_->AddTiling(tiling->contents_scale());
658 // If this tree needs update draw properties, then the tiling will
659 // get updated prior to drawing or activation. If this tree does not
660 // need update draw properties, then its transforms are up to date and
661 // we can create tiles for this tiling immediately.
662 if (!layer_tree_impl()->needs_update_draw_properties() &&
663 should_update_tile_priorities_)
664 UpdateTilePriorities();
667 void PictureLayerImpl::SetIsMask(bool is_mask) {
668 if (is_mask_ == is_mask)
669 return;
670 is_mask_ = is_mask;
671 if (tilings_)
672 tilings_->RemoveAllTiles();
675 ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
676 gfx::Rect content_rect(content_bounds());
677 float scale = contents_scale_x();
678 PictureLayerTilingSet::CoverageIterator iter(
679 tilings_.get(), scale, content_rect, ideal_contents_scale_);
681 // Mask resource not ready yet.
682 if (!iter || !*iter)
683 return 0;
685 // Masks only supported if they fit on exactly one tile.
686 if (iter.geometry_rect() != content_rect)
687 return 0;
689 const ManagedTileState::TileVersion& tile_version =
690 iter->GetTileVersionForDrawing();
691 if (!tile_version.IsReadyToDraw() ||
692 tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
693 return 0;
695 return tile_version.get_resource_id();
698 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
699 DCHECK(layer_tree_impl()->IsPendingTree());
700 DCHECK(!layer_tree_impl()->needs_update_draw_properties());
701 DCHECK(ideal_contents_scale_);
702 DCHECK_GT(tilings_->num_tilings(), 0u);
704 // The goal of this function is to find the minimum set of tiles that need to
705 // be ready to draw in order to activate without flashing content from a
706 // higher res on the active tree to a lower res on the pending tree.
708 gfx::Rect rect(visible_content_rect());
710 float min_acceptable_scale =
711 std::min(raster_contents_scale_, ideal_contents_scale_);
713 if (PictureLayerImpl* twin = twin_layer_) {
714 float twin_min_acceptable_scale =
715 std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
716 // Ignore 0 scale in case CalculateContentsScale() has never been
717 // called for active twin.
718 if (twin_min_acceptable_scale != 0.0f) {
719 min_acceptable_scale =
720 std::min(min_acceptable_scale, twin_min_acceptable_scale);
724 PictureLayerTiling* high_res = NULL;
725 PictureLayerTiling* low_res = NULL;
727 // First pass: ready to draw tiles in acceptable but non-ideal tilings are
728 // marked as required for activation so that their textures are not thrown
729 // away; any non-ready tiles are not marked as required.
730 Region missing_region = rect;
731 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
732 PictureLayerTiling* tiling = tilings_->tiling_at(i);
733 DCHECK(tiling->has_ever_been_updated());
735 if (tiling->resolution() == LOW_RESOLUTION) {
736 DCHECK(!low_res) << "There can only be one low res tiling";
737 low_res = tiling;
739 if (tiling->contents_scale() < min_acceptable_scale)
740 continue;
741 if (tiling->resolution() == HIGH_RESOLUTION) {
742 DCHECK(!high_res) << "There can only be one high res tiling";
743 high_res = tiling;
744 continue;
746 for (PictureLayerTiling::CoverageIterator iter(tiling,
747 contents_scale_x(),
748 rect);
749 iter;
750 ++iter) {
751 if (!*iter || !iter->IsReadyToDraw())
752 continue;
754 missing_region.Subtract(iter.geometry_rect());
755 iter->MarkRequiredForActivation();
758 DCHECK(high_res) << "There must be one high res tiling";
760 // If these pointers are null (because no twin, no matching tiling, or the
761 // simpification just below), then high res tiles will be required to fill any
762 // holes left by the first pass above. If the pointers are valid, then this
763 // layer is allowed to skip any tiles that are not ready on its twin.
764 const PictureLayerTiling* twin_high_res = NULL;
765 const PictureLayerTiling* twin_low_res = NULL;
767 // As a simplification, only allow activating to skip twin tiles that the
768 // active layer is also missing when both this layer and its twin have 2
769 // tilings (high and low). This avoids having to iterate/track coverage of
770 // non-ideal tilings during the last draw call on the active layer.
771 if (high_res && low_res && tilings_->num_tilings() == 2 &&
772 twin_layer_ && twin_layer_->tilings_->num_tilings() == 2) {
773 twin_low_res = GetTwinTiling(low_res);
774 if (twin_low_res)
775 twin_high_res = GetTwinTiling(high_res);
777 // If this layer and its twin have different transforms, then don't compare
778 // them and only allow activating to high res tiles, since tiles on each layer
779 // will be in different places on screen.
780 if (!twin_high_res || !twin_low_res ||
781 twin_layer_->layer_tree_impl()->RequiresHighResToDraw() ||
782 draw_properties().screen_space_transform !=
783 twin_layer_->draw_properties().screen_space_transform) {
784 twin_high_res = NULL;
785 twin_low_res = NULL;
788 // As a second pass, mark as required any visible high res tiles not filled in
789 // by acceptable non-ideal tiles from the first pass.
790 if (MarkVisibleTilesAsRequired(
791 high_res, twin_high_res, contents_scale_x(), rect, missing_region)) {
792 // As an optional third pass, if a high res tile was skipped because its
793 // twin was also missing, then fall back to mark low res tiles as required
794 // in case the active twin is substituting those for missing high res
795 // content.
796 MarkVisibleTilesAsRequired(
797 low_res, twin_low_res, contents_scale_x(), rect, missing_region);
801 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
802 PictureLayerTiling* tiling,
803 const PictureLayerTiling* optional_twin_tiling,
804 float contents_scale,
805 const gfx::Rect& rect,
806 const Region& missing_region) const {
807 bool twin_had_missing_tile = false;
808 for (PictureLayerTiling::CoverageIterator iter(tiling,
809 contents_scale,
810 rect);
811 iter;
812 ++iter) {
813 Tile* tile = *iter;
814 // A null tile (i.e. missing recording) can just be skipped.
815 if (!tile)
816 continue;
818 // If the missing region doesn't cover it, this tile is fully
819 // covered by acceptable tiles at other scales.
820 if (!missing_region.Intersects(iter.geometry_rect()))
821 continue;
823 // If the twin tile doesn't exist (i.e. missing recording or so far away
824 // that it is outside the visible tile rect) or this tile is shared between
825 // with the twin, then this tile isn't required to prevent flashing.
826 if (optional_twin_tiling) {
827 Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
828 if (!twin_tile || twin_tile == tile) {
829 twin_had_missing_tile = true;
830 continue;
834 tile->MarkRequiredForActivation();
836 return twin_had_missing_tile;
839 void PictureLayerImpl::DoPostCommitInitialization() {
840 DCHECK(needs_post_commit_initialization_);
841 DCHECK(layer_tree_impl()->IsPendingTree());
843 if (!tilings_)
844 tilings_.reset(new PictureLayerTilingSet(this, bounds()));
846 DCHECK(!twin_layer_);
847 twin_layer_ = static_cast<PictureLayerImpl*>(
848 layer_tree_impl()->FindActiveTreeLayerById(id()));
849 if (twin_layer_) {
850 DCHECK(!twin_layer_->twin_layer_);
851 twin_layer_->twin_layer_ = this;
852 // If the twin has never been pushed to, do not sync from it.
853 // This can happen if this function is called during activation.
854 if (!twin_layer_->needs_post_commit_initialization_)
855 SyncFromActiveLayer(twin_layer_);
858 needs_post_commit_initialization_ = false;
861 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
862 DCHECK(CanHaveTilingWithScale(contents_scale)) <<
863 "contents_scale: " << contents_scale;
865 PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
867 const Region& recorded = pile_->recorded_region();
868 DCHECK(!recorded.IsEmpty());
870 if (twin_layer_ &&
871 twin_layer_->ShouldUseGpuRasterization() == ShouldUseGpuRasterization())
872 twin_layer_->SyncTiling(tiling);
874 return tiling;
877 void PictureLayerImpl::RemoveTiling(float contents_scale) {
878 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
879 PictureLayerTiling* tiling = tilings_->tiling_at(i);
880 if (tiling->contents_scale() == contents_scale) {
881 tilings_->Remove(tiling);
882 break;
885 if (tilings_->num_tilings() == 0)
886 ResetRasterScale();
887 SanityCheckTilingState();
890 void PictureLayerImpl::RemoveAllTilings() {
891 if (tilings_)
892 tilings_->RemoveAllTilings();
893 // If there are no tilings, then raster scales are no longer meaningful.
894 ResetRasterScale();
897 namespace {
899 inline float PositiveRatio(float float1, float float2) {
900 DCHECK_GT(float1, 0);
901 DCHECK_GT(float2, 0);
902 return float1 > float2 ? float1 / float2 : float2 / float1;
905 } // namespace
907 void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) {
908 DCHECK(ideal_contents_scale_);
909 DCHECK(ideal_page_scale_);
910 DCHECK(ideal_device_scale_);
911 DCHECK(ideal_source_scale_);
912 DCHECK(CanHaveTilings());
913 DCHECK(!needs_post_commit_initialization_);
915 bool change_target_tiling =
916 raster_page_scale_ == 0.f ||
917 raster_device_scale_ == 0.f ||
918 raster_source_scale_ == 0.f ||
919 raster_contents_scale_ == 0.f ||
920 low_res_raster_contents_scale_ == 0.f ||
921 ShouldAdjustRasterScale(animating_transform_to_screen);
923 if (tilings_->num_tilings() == 0) {
924 DCHECK(change_target_tiling)
925 << "A layer with no tilings shouldn't have valid raster scales";
928 // Store the value for the next time ShouldAdjustRasterScale is called.
929 raster_source_scale_was_animating_ = animating_transform_to_screen;
931 if (!change_target_tiling)
932 return;
934 if (!layer_tree_impl()->device_viewport_valid_for_tile_management())
935 return;
937 RecalculateRasterScales(animating_transform_to_screen);
939 PictureLayerTiling* high_res = NULL;
940 PictureLayerTiling* low_res = NULL;
942 PictureLayerTiling* previous_low_res = NULL;
943 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
944 PictureLayerTiling* tiling = tilings_->tiling_at(i);
945 if (tiling->contents_scale() == raster_contents_scale_)
946 high_res = tiling;
947 if (tiling->contents_scale() == low_res_raster_contents_scale_)
948 low_res = tiling;
949 if (tiling->resolution() == LOW_RESOLUTION)
950 previous_low_res = tiling;
952 // Reset all tilings to non-ideal until the end of this function.
953 tiling->set_resolution(NON_IDEAL_RESOLUTION);
956 if (!high_res) {
957 high_res = AddTiling(raster_contents_scale_);
958 if (raster_contents_scale_ == low_res_raster_contents_scale_)
959 low_res = high_res;
962 // Only create new low res tilings when the transform is static. This
963 // prevents wastefully creating a paired low res tiling for every new high res
964 // tiling during a pinch or a CSS animation.
965 bool is_pinching = layer_tree_impl()->PinchGestureActive();
966 if (ShouldHaveLowResTiling() && !is_pinching &&
967 !animating_transform_to_screen &&
968 !low_res && low_res != high_res)
969 low_res = AddTiling(low_res_raster_contents_scale_);
971 // Set low-res if we have one.
972 if (!low_res)
973 low_res = previous_low_res;
974 if (low_res && low_res != high_res)
975 low_res->set_resolution(LOW_RESOLUTION);
977 // Make sure we always have one high-res (even if high == low).
978 high_res->set_resolution(HIGH_RESOLUTION);
980 SanityCheckTilingState();
983 bool PictureLayerImpl::ShouldAdjustRasterScale(
984 bool animating_transform_to_screen) const {
985 // TODO(danakj): Adjust raster source scale closer to ideal source scale at
986 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
987 // tree. This will allow CSS scale changes to get re-rastered at an
988 // appropriate rate.
990 if (raster_source_scale_was_animating_ && !animating_transform_to_screen)
991 return true;
993 bool is_pinching = layer_tree_impl()->PinchGestureActive();
994 if (is_pinching && raster_page_scale_) {
995 // We change our raster scale when it is:
996 // - Higher than ideal (need a lower-res tiling available)
997 // - Too far from ideal (need a higher-res tiling available)
998 float ratio = ideal_page_scale_ / raster_page_scale_;
999 if (raster_page_scale_ > ideal_page_scale_ ||
1000 ratio > kMaxScaleRatioDuringPinch)
1001 return true;
1004 if (!is_pinching) {
1005 // When not pinching, match the ideal page scale factor.
1006 if (raster_page_scale_ != ideal_page_scale_)
1007 return true;
1010 // Always match the ideal device scale factor.
1011 if (raster_device_scale_ != ideal_device_scale_)
1012 return true;
1014 return false;
1017 float PictureLayerImpl::SnappedContentsScale(float scale) {
1018 // If a tiling exists within the max snapping ratio, snap to its scale.
1019 float snapped_contents_scale = scale;
1020 float snapped_ratio = kSnapToExistingTilingRatio;
1021 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1022 float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale();
1023 float ratio = PositiveRatio(tiling_contents_scale, scale);
1024 if (ratio < snapped_ratio) {
1025 snapped_contents_scale = tiling_contents_scale;
1026 snapped_ratio = ratio;
1029 return snapped_contents_scale;
1032 void PictureLayerImpl::RecalculateRasterScales(
1033 bool animating_transform_to_screen) {
1034 raster_device_scale_ = ideal_device_scale_;
1035 raster_source_scale_ = ideal_source_scale_;
1037 bool is_pinching = layer_tree_impl()->PinchGestureActive();
1038 if (!is_pinching || raster_contents_scale_ == 0.f) {
1039 // When not pinching or when we have no previous scale, we use ideal scale:
1040 raster_page_scale_ = ideal_page_scale_;
1041 raster_contents_scale_ = ideal_contents_scale_;
1042 } else {
1043 // See ShouldAdjustRasterScale:
1044 // - When zooming out, preemptively create new tiling at lower resolution.
1045 // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
1046 bool zooming_out = raster_page_scale_ > ideal_page_scale_;
1047 float desired_contents_scale =
1048 zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch
1049 : raster_contents_scale_ * kMaxScaleRatioDuringPinch;
1050 raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
1051 raster_page_scale_ = raster_contents_scale_ / raster_device_scale_;
1054 raster_contents_scale_ =
1055 std::max(raster_contents_scale_, MinimumContentsScale());
1057 // Don't allow animating CSS scales to drop below 1. This is needed because
1058 // changes in raster source scale aren't handled. See the comment in
1059 // ShouldAdjustRasterScale.
1060 if (animating_transform_to_screen) {
1061 raster_contents_scale_ = std::max(
1062 raster_contents_scale_, 1.f * ideal_page_scale_ * ideal_device_scale_);
1065 // If this layer would only create one tile at this content scale,
1066 // don't create a low res tiling.
1067 gfx::Size content_bounds =
1068 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_));
1069 gfx::Size tile_size = CalculateTileSize(content_bounds);
1070 if (tile_size.width() >= content_bounds.width() &&
1071 tile_size.height() >= content_bounds.height()) {
1072 low_res_raster_contents_scale_ = raster_contents_scale_;
1073 return;
1076 float low_res_factor =
1077 layer_tree_impl()->settings().low_res_contents_scale_factor;
1078 low_res_raster_contents_scale_ = std::max(
1079 raster_contents_scale_ * low_res_factor,
1080 MinimumContentsScale());
1083 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
1084 std::vector<PictureLayerTiling*> used_tilings) {
1085 DCHECK(layer_tree_impl()->IsActiveTree());
1086 if (tilings_->num_tilings() == 0)
1087 return;
1089 float min_acceptable_high_res_scale = std::min(
1090 raster_contents_scale_, ideal_contents_scale_);
1091 float max_acceptable_high_res_scale = std::max(
1092 raster_contents_scale_, ideal_contents_scale_);
1094 PictureLayerImpl* twin = twin_layer_;
1095 if (twin) {
1096 min_acceptable_high_res_scale = std::min(
1097 min_acceptable_high_res_scale,
1098 std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1099 max_acceptable_high_res_scale = std::max(
1100 max_acceptable_high_res_scale,
1101 std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1104 std::vector<PictureLayerTiling*> to_remove;
1105 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1106 PictureLayerTiling* tiling = tilings_->tiling_at(i);
1108 // Keep multiple high resolution tilings even if not used to help
1109 // activate earlier at non-ideal resolutions.
1110 if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
1111 tiling->contents_scale() <= max_acceptable_high_res_scale)
1112 continue;
1114 // Keep low resolution tilings, if the layer should have them.
1115 if (tiling->resolution() == LOW_RESOLUTION && ShouldHaveLowResTiling())
1116 continue;
1118 // Don't remove tilings that are being used (and thus would cause a flash.)
1119 if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
1120 used_tilings.end())
1121 continue;
1123 to_remove.push_back(tiling);
1126 for (size_t i = 0; i < to_remove.size(); ++i) {
1127 const PictureLayerTiling* twin_tiling = GetTwinTiling(to_remove[i]);
1128 // Only remove tilings from the twin layer if they have
1129 // NON_IDEAL_RESOLUTION.
1130 if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
1131 twin->RemoveTiling(to_remove[i]->contents_scale());
1132 tilings_->Remove(to_remove[i]);
1134 DCHECK_GT(tilings_->num_tilings(), 0u);
1136 SanityCheckTilingState();
1139 float PictureLayerImpl::MinimumContentsScale() const {
1140 float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
1142 // If the contents scale is less than 1 / width (also for height),
1143 // then it will end up having less than one pixel of content in that
1144 // dimension. Bump the minimum contents scale up in this case to prevent
1145 // this from happening.
1146 int min_dimension = std::min(bounds().width(), bounds().height());
1147 if (!min_dimension)
1148 return setting_min;
1150 return std::max(1.f / min_dimension, setting_min);
1153 void PictureLayerImpl::UpdateLCDTextStatus(bool new_status) {
1154 // Once this layer is not using lcd text, don't switch back.
1155 if (!is_using_lcd_text_)
1156 return;
1158 if (is_using_lcd_text_ == new_status)
1159 return;
1161 is_using_lcd_text_ = new_status;
1162 tilings_->SetCanUseLCDText(is_using_lcd_text_);
1165 void PictureLayerImpl::ResetRasterScale() {
1166 raster_page_scale_ = 0.f;
1167 raster_device_scale_ = 0.f;
1168 raster_source_scale_ = 0.f;
1169 raster_contents_scale_ = 0.f;
1170 low_res_raster_contents_scale_ = 0.f;
1172 // When raster scales aren't valid, don't update tile priorities until
1173 // this layer has been updated via UpdateDrawProperties.
1174 should_update_tile_priorities_ = false;
1177 bool PictureLayerImpl::CanHaveTilings() const {
1178 if (!DrawsContent())
1179 return false;
1180 if (pile_->recorded_region().IsEmpty())
1181 return false;
1182 return true;
1185 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
1186 if (!CanHaveTilings())
1187 return false;
1188 if (contents_scale < MinimumContentsScale())
1189 return false;
1190 return true;
1193 void PictureLayerImpl::SanityCheckTilingState() const {
1194 #if DCHECK_IS_ON
1195 if (!CanHaveTilings()) {
1196 DCHECK_EQ(0u, tilings_->num_tilings());
1197 return;
1199 if (tilings_->num_tilings() == 0)
1200 return;
1202 // MarkVisibleResourcesAsRequired depends on having exactly 1 high res
1203 // tiling to mark its tiles as being required for activation.
1204 DCHECK_EQ(1, tilings_->NumHighResTilings());
1205 #endif
1208 void PictureLayerImpl::GetDebugBorderProperties(
1209 SkColor* color,
1210 float* width) const {
1211 *color = DebugColors::TiledContentLayerBorderColor();
1212 *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1215 void PictureLayerImpl::AsValueInto(base::DictionaryValue* state) const {
1216 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1217 LayerImpl::AsValueInto(state);
1218 state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1219 state->SetDouble("geometry_contents_scale", contents_scale_x());
1220 state->Set("tilings", tilings_->AsValue().release());
1221 state->Set("pictures", pile_->AsValue().release());
1222 state->Set("invalidation", invalidation_.AsValue().release());
1224 Region unrecorded_region(gfx::Rect(pile_->size()));
1225 unrecorded_region.Subtract(pile_->recorded_region());
1226 if (!unrecorded_region.IsEmpty())
1227 state->Set("unrecorded_region", unrecorded_region.AsValue().release());
1229 scoped_ptr<base::ListValue> coverage_tiles(new base::ListValue);
1230 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
1231 contents_scale_x(),
1232 gfx::Rect(content_bounds()),
1233 ideal_contents_scale_);
1234 iter;
1235 ++iter) {
1236 scoped_ptr<base::DictionaryValue> tile_data(new base::DictionaryValue);
1237 tile_data->Set("geometry_rect",
1238 MathUtil::AsValue(iter.geometry_rect()).release());
1239 if (*iter)
1240 tile_data->Set("tile", TracedValue::CreateIDRef(*iter).release());
1242 coverage_tiles->Append(tile_data.release());
1244 state->Set("coverage_tiles", coverage_tiles.release());
1245 state->SetBoolean("is_using_lcd_text", is_using_lcd_text_);
1246 state->SetBoolean("using_gpu_rasterization", ShouldUseGpuRasterization());
1249 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1250 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1251 return tilings_->GPUMemoryUsageInBytes();
1254 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
1255 benchmark->RunOnLayer(this);
1258 } // namespace cc