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"
9 #include "base/time/time.h"
10 #include "cc/base/math_util.h"
11 #include "cc/base/util.h"
12 #include "cc/debug/debug_colors.h"
13 #include "cc/debug/traced_value.h"
14 #include "cc/layers/append_quads_data.h"
15 #include "cc/layers/quad_sink.h"
16 #include "cc/quads/checkerboard_draw_quad.h"
17 #include "cc/quads/debug_border_draw_quad.h"
18 #include "cc/quads/picture_draw_quad.h"
19 #include "cc/quads/solid_color_draw_quad.h"
20 #include "cc/quads/tile_draw_quad.h"
21 #include "cc/resources/tile_manager.h"
22 #include "cc/trees/layer_tree_impl.h"
23 #include "ui/gfx/quad_f.h"
24 #include "ui/gfx/rect_conversions.h"
25 #include "ui/gfx/size_conversions.h"
28 const float kMaxScaleRatioDuringPinch = 2.0f;
33 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
34 : LayerImpl(tree_impl, id),
36 pile_(PicturePileImpl::Create()),
37 last_content_scale_(0),
39 ideal_page_scale_(0.f),
40 ideal_device_scale_(0.f),
41 ideal_source_scale_(0.f),
42 ideal_contents_scale_(0.f),
43 raster_page_scale_(0.f),
44 raster_device_scale_(0.f),
45 raster_source_scale_(0.f),
46 raster_contents_scale_(0.f),
47 low_res_raster_contents_scale_(0.f),
48 raster_source_scale_was_animating_(false),
49 is_using_lcd_text_(tree_impl->settings().can_use_lcd_text),
50 needs_post_commit_initialization_(true),
51 should_update_tile_priorities_(false) {}
53 PictureLayerImpl::~PictureLayerImpl() {}
55 const char* PictureLayerImpl::LayerTypeAsString() const {
56 return "cc::PictureLayerImpl";
59 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
60 LayerTreeImpl* tree_impl) {
61 return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
64 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
65 // It's possible this layer was never drawn or updated (e.g. because it was
66 // a descendant of an opacity 0 layer).
67 DoPostCommitInitializationIfNeeded();
68 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
70 // We have already synced the important bits from the the active layer, and
71 // we will soon swap out its tilings and use them for recycling. However,
72 // there are now tiles in this layer's tilings that were unref'd and replaced
73 // with new tiles (due to invalidation). This resets all active priorities on
74 // the to-be-recycled tiling to ensure replaced tiles don't linger and take
75 // memory (due to a stale 'active' priority).
76 if (layer_impl->tilings_)
77 layer_impl->tilings_->DidBecomeRecycled();
79 LayerImpl::PushPropertiesTo(base_layer);
81 // When the pending tree pushes to the active tree, the pending twin
83 layer_impl->twin_layer_ = NULL;
86 layer_impl->SetIsMask(is_mask_);
87 layer_impl->pile_ = pile_;
89 // Tilings would be expensive to push, so we swap. This optimization requires
90 // an extra invalidation in SyncFromActiveLayer.
91 layer_impl->tilings_.swap(tilings_);
92 layer_impl->tilings_->SetClient(layer_impl);
94 tilings_->SetClient(this);
96 layer_impl->raster_page_scale_ = raster_page_scale_;
97 layer_impl->raster_device_scale_ = raster_device_scale_;
98 layer_impl->raster_source_scale_ = raster_source_scale_;
99 layer_impl->raster_contents_scale_ = raster_contents_scale_;
100 layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
102 layer_impl->UpdateLCDTextStatus(is_using_lcd_text_);
103 layer_impl->needs_post_commit_initialization_ = false;
105 // The invalidation on this soon-to-be-recycled layer must be cleared to
106 // mirror clearing the invalidation in PictureLayer's version of this function
107 // in case push properties is skipped.
108 layer_impl->invalidation_.Swap(&invalidation_);
109 invalidation_.Clear();
110 needs_post_commit_initialization_ = true;
113 void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
114 AppendQuadsData* append_quads_data) {
115 DCHECK(!needs_post_commit_initialization_);
116 gfx::Rect rect(visible_content_rect());
117 gfx::Rect content_rect(content_bounds());
119 SharedQuadState* shared_quad_state =
120 quad_sink->UseSharedQuadState(CreateSharedQuadState());
122 bool draw_direct_to_backbuffer =
123 draw_properties().can_draw_directly_to_backbuffer &&
124 layer_tree_impl()->settings().force_direct_layer_drawing;
126 if (draw_direct_to_backbuffer ||
127 current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
128 AppendDebugBorderQuad(
132 DebugColors::DirectPictureBorderColor(),
133 DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
135 gfx::Rect geometry_rect = rect;
136 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
137 gfx::Size texture_size = rect.size();
138 gfx::RectF texture_rect = gfx::RectF(texture_size);
139 gfx::Rect quad_content_rect = rect;
140 float contents_scale = contents_scale_x();
142 scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
143 quad->SetNew(shared_quad_state,
151 draw_direct_to_backbuffer,
153 if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
154 append_quads_data->num_missing_tiles++;
158 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
160 if (ShowDebugBorders()) {
161 for (PictureLayerTilingSet::CoverageIterator iter(
162 tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
167 if (*iter && iter->IsReadyToDraw()) {
168 ManagedTileState::TileVersion::Mode mode =
169 iter->GetTileVersionForDrawing().mode();
170 if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
171 color = DebugColors::SolidColorTileBorderColor();
172 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
173 } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
174 color = DebugColors::PictureTileBorderColor();
175 width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
176 } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
177 color = DebugColors::HighResTileBorderColor();
178 width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
179 } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
180 color = DebugColors::LowResTileBorderColor();
181 width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
182 } else if (iter->contents_scale() > contents_scale_x()) {
183 color = DebugColors::ExtraHighResTileBorderColor();
184 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
186 color = DebugColors::ExtraLowResTileBorderColor();
187 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
190 color = DebugColors::MissingTileBorderColor();
191 width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
194 scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
195 DebugBorderDrawQuad::Create();
196 gfx::Rect geometry_rect = iter.geometry_rect();
197 debug_border_quad->SetNew(shared_quad_state, geometry_rect, color, width);
198 quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(),
203 // Keep track of the tilings that were used so that tilings that are
204 // unused can be considered for removal.
205 std::vector<PictureLayerTiling*> seen_tilings;
207 for (PictureLayerTilingSet::CoverageIterator iter(
208 tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
211 gfx::Rect geometry_rect = iter.geometry_rect();
212 if (!*iter || !iter->IsReadyToDraw()) {
213 if (DrawCheckerboardForMissingTiles()) {
214 // TODO(enne): Figure out how to show debug "invalidated checker" color
215 scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
216 SkColor color = DebugColors::DefaultCheckerboardColor();
217 quad->SetNew(shared_quad_state, geometry_rect, color);
218 if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
219 append_quads_data->num_missing_tiles++;
221 SkColor color = SafeOpaqueBackgroundColor();
222 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
223 quad->SetNew(shared_quad_state, geometry_rect, color, false);
224 if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
225 append_quads_data->num_missing_tiles++;
228 append_quads_data->had_incomplete_tile = true;
232 const ManagedTileState::TileVersion& tile_version =
233 iter->GetTileVersionForDrawing();
234 scoped_ptr<DrawQuad> draw_quad;
235 switch (tile_version.mode()) {
236 case ManagedTileState::TileVersion::RESOURCE_MODE: {
237 gfx::RectF texture_rect = iter.texture_rect();
238 gfx::Rect opaque_rect = iter->opaque_rect();
239 opaque_rect.Intersect(geometry_rect);
241 if (iter->contents_scale() != ideal_contents_scale_)
242 append_quads_data->had_incomplete_tile = true;
244 scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
245 quad->SetNew(shared_quad_state,
248 tile_version.get_resource_id(),
251 tile_version.contents_swizzled());
252 draw_quad = quad.PassAs<DrawQuad>();
255 case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
256 gfx::RectF texture_rect = iter.texture_rect();
257 gfx::Rect opaque_rect = iter->opaque_rect();
258 opaque_rect.Intersect(geometry_rect);
260 ResourceProvider* resource_provider =
261 layer_tree_impl()->resource_provider();
262 ResourceFormat format =
263 resource_provider->memory_efficient_texture_format();
264 scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
265 quad->SetNew(shared_quad_state,
271 iter->content_rect(),
272 iter->contents_scale(),
273 draw_direct_to_backbuffer,
275 draw_quad = quad.PassAs<DrawQuad>();
278 case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
279 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
280 quad->SetNew(shared_quad_state,
282 tile_version.get_solid_color(),
284 draw_quad = quad.PassAs<DrawQuad>();
290 quad_sink->Append(draw_quad.Pass(), append_quads_data);
292 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
293 seen_tilings.push_back(iter.CurrentTiling());
296 // Aggressively remove any tilings that are not seen to save memory. Note
297 // that this is at the expense of doing cause more frequent re-painting. A
298 // better scheme would be to maintain a tighter visible_content_rect for the
300 CleanUpTilingsOnActiveLayer(seen_tilings);
303 void PictureLayerImpl::UpdateTilePriorities() {
304 DCHECK(!needs_post_commit_initialization_);
305 CHECK(should_update_tile_priorities_);
307 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) {
308 for (size_t i = 0; i < tilings_->num_tilings(); ++i)
309 DCHECK(tilings_->tiling_at(i)->has_ever_been_updated());
313 if (!tilings_->num_tilings())
316 double current_frame_time_in_seconds =
317 (layer_tree_impl()->CurrentFrameTimeTicks() -
318 base::TimeTicks()).InSecondsF();
320 bool tiling_needs_update = false;
321 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
322 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
323 current_frame_time_in_seconds)) {
324 tiling_needs_update = true;
328 if (!tiling_needs_update)
331 UpdateLCDTextStatus(can_use_lcd_text());
333 gfx::Transform current_screen_space_transform = screen_space_transform();
335 gfx::Size viewport_size = layer_tree_impl()->DrawViewportSize();
336 gfx::Rect viewport_in_content_space;
337 gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization);
338 if (screen_space_transform().GetInverse(&screen_to_layer)) {
339 viewport_in_content_space =
340 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
341 screen_to_layer, gfx::Rect(viewport_size)));
345 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
346 size_t max_tiles_for_interest_area =
347 layer_tree_impl()->settings().max_tiles_for_interest_area;
348 tilings_->UpdateTilePriorities(
351 viewport_in_content_space,
352 visible_content_rect(),
357 last_screen_space_transform_,
358 current_screen_space_transform,
359 current_frame_time_in_seconds,
360 max_tiles_for_interest_area);
362 if (layer_tree_impl()->IsPendingTree())
363 MarkVisibleResourcesAsRequired();
365 last_screen_space_transform_ = current_screen_space_transform;
366 last_bounds_ = bounds();
367 last_content_scale_ = contents_scale_x();
369 // Tile priorities were modified.
370 layer_tree_impl()->DidModifyTilePriorities();
373 void PictureLayerImpl::DidBecomeActive() {
374 LayerImpl::DidBecomeActive();
375 tilings_->DidBecomeActive();
376 layer_tree_impl()->DidModifyTilePriorities();
379 void PictureLayerImpl::DidBeginTracing() {
380 pile_->DidBeginTracing();
383 void PictureLayerImpl::DidLoseOutputSurface() {
385 tilings_->RemoveAllTilings();
390 void PictureLayerImpl::CalculateContentsScale(
391 float ideal_contents_scale,
392 float device_scale_factor,
393 float page_scale_factor,
394 bool animating_transform_to_screen,
395 float* contents_scale_x,
396 float* contents_scale_y,
397 gfx::Size* content_bounds) {
398 DoPostCommitInitializationIfNeeded();
400 // This function sets valid raster scales and manages tilings, so tile
401 // priorities can now be updated.
402 should_update_tile_priorities_ = true;
404 if (!CanHaveTilings()) {
405 ideal_page_scale_ = page_scale_factor;
406 ideal_device_scale_ = device_scale_factor;
407 ideal_contents_scale_ = ideal_contents_scale;
408 ideal_source_scale_ =
409 ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
410 *contents_scale_x = ideal_contents_scale_;
411 *contents_scale_y = ideal_contents_scale_;
412 *content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(),
413 ideal_contents_scale_,
414 ideal_contents_scale_));
418 float min_contents_scale = MinimumContentsScale();
419 DCHECK_GT(min_contents_scale, 0.f);
420 float min_page_scale = layer_tree_impl()->min_page_scale_factor();
421 DCHECK_GT(min_page_scale, 0.f);
422 float min_device_scale = 1.f;
423 float min_source_scale =
424 min_contents_scale / min_page_scale / min_device_scale;
426 float ideal_page_scale = page_scale_factor;
427 float ideal_device_scale = device_scale_factor;
428 float ideal_source_scale =
429 ideal_contents_scale / ideal_page_scale / ideal_device_scale;
431 ideal_contents_scale_ = std::max(ideal_contents_scale, min_contents_scale);
432 ideal_page_scale_ = ideal_page_scale;
433 ideal_device_scale_ = ideal_device_scale;
434 ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
436 ManageTilings(animating_transform_to_screen);
438 // The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
439 // There are (usually) several tilings at different scales. However, the
440 // content bounds is the (integer!) space in which quads are generated.
441 // In order to guarantee that we can fill this integer space with any set of
442 // tilings (and then map back to floating point texture coordinates), the
443 // contents scale must be at least as large as the largest of the tilings.
444 float max_contents_scale = min_contents_scale;
445 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
446 const PictureLayerTiling* tiling = tilings_->tiling_at(i);
447 max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
450 *contents_scale_x = max_contents_scale;
451 *contents_scale_y = max_contents_scale;
452 *content_bounds = gfx::ToCeiledSize(
453 gfx::ScaleSize(bounds(), max_contents_scale, max_contents_scale));
456 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
457 return pile_->GetFlattenedPicture();
460 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
461 gfx::Rect content_rect) {
462 if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
463 return scoped_refptr<Tile>();
465 return layer_tree_impl()->tile_manager()->CreateTile(
469 contents_opaque() ? content_rect : gfx::Rect(),
470 tiling->contents_scale(),
472 layer_tree_impl()->source_frame_number(),
476 void PictureLayerImpl::UpdatePile(Tile* tile) {
477 tile->set_picture_pile(pile_);
480 const Region* PictureLayerImpl::GetInvalidation() {
481 return &invalidation_;
484 const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
485 const PictureLayerTiling* tiling) {
489 for (size_t i = 0; i < twin_layer_->tilings_->num_tilings(); ++i)
490 if (twin_layer_->tilings_->tiling_at(i)->contents_scale() ==
491 tiling->contents_scale())
492 return twin_layer_->tilings_->tiling_at(i);
496 gfx::Size PictureLayerImpl::CalculateTileSize(
497 gfx::Size content_bounds) const {
499 int max_size = layer_tree_impl()->MaxTextureSize();
501 std::min(max_size, content_bounds.width()),
502 std::min(max_size, content_bounds.height()));
505 int max_texture_size =
506 layer_tree_impl()->resource_provider()->max_texture_size();
508 gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
509 default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
511 gfx::Size max_untiled_content_size =
512 layer_tree_impl()->settings().max_untiled_layer_size;
513 max_untiled_content_size.SetToMin(
514 gfx::Size(max_texture_size, max_texture_size));
516 bool any_dimension_too_large =
517 content_bounds.width() > max_untiled_content_size.width() ||
518 content_bounds.height() > max_untiled_content_size.height();
520 bool any_dimension_one_tile =
521 content_bounds.width() <= default_tile_size.width() ||
522 content_bounds.height() <= default_tile_size.height();
524 // If long and skinny, tile at the max untiled content size, and clamp
525 // the smaller dimension to the content size, e.g. 1000x12 layer with
526 // 500x500 max untiled size would get 500x12 tiles. Also do this
527 // if the layer is small.
528 if (any_dimension_one_tile || !any_dimension_too_large) {
530 std::min(max_untiled_content_size.width(), content_bounds.width());
532 std::min(max_untiled_content_size.height(), content_bounds.height());
533 // Round width and height up to the closest multiple of 64, or 56 if
534 // we should avoid power-of-two textures. This helps reduce the number
535 // of different textures sizes to help recycling, and also keeps all
536 // textures multiple-of-eight, which is preferred on some drivers (IMG).
538 layer_tree_impl()->GetRendererCapabilities().avoid_pow2_textures;
539 int round_up_to = avoid_pow2 ? 56 : 64;
540 width = RoundUp(width, round_up_to);
541 height = RoundUp(height, round_up_to);
542 return gfx::Size(width, height);
545 return default_tile_size;
548 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
549 DCHECK(!other->needs_post_commit_initialization_);
550 DCHECK(other->tilings_);
552 UpdateLCDTextStatus(other->is_using_lcd_text_);
554 if (!DrawsContent()) {
556 tilings_->RemoveAllTilings();
560 raster_page_scale_ = other->raster_page_scale_;
561 raster_device_scale_ = other->raster_device_scale_;
562 raster_source_scale_ = other->raster_source_scale_;
563 raster_contents_scale_ = other->raster_contents_scale_;
564 low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
566 // Add synthetic invalidations for any recordings that were dropped. As
567 // tiles are updated to point to this new pile, this will force the dropping
568 // of tiles that can no longer be rastered. This is not ideal, but is a
569 // trade-off for memory (use the same pile as much as possible, by switching
570 // during DidBecomeActive) and for time (don't bother checking every tile
571 // during activation to see if the new pile can still raster it).
572 for (int x = 0; x < pile_->num_tiles_x(); ++x) {
573 for (int y = 0; y < pile_->num_tiles_y(); ++y) {
574 bool previously_had = other->pile_->HasRecordingAt(x, y);
575 bool now_has = pile_->HasRecordingAt(x, y);
576 if (now_has || !previously_had)
578 gfx::Rect layer_rect = pile_->tile_bounds(x, y);
579 invalidation_.Union(layer_rect);
583 // Union in the other newly exposed regions as invalid.
584 Region difference_region = Region(gfx::Rect(bounds()));
585 difference_region.Subtract(gfx::Rect(other->bounds()));
586 invalidation_.Union(difference_region);
588 if (CanHaveTilings()) {
589 // The recycle tree's tiling set is two frames out of date, so it needs to
590 // have both this frame's invalidation and the previous frame's invalidation
591 // (stored on the active layer).
592 Region tiling_invalidation = other->invalidation_;
593 tiling_invalidation.Union(invalidation_);
594 tilings_->SyncTilings(*other->tilings_,
597 MinimumContentsScale());
599 tilings_->RemoveAllTilings();
602 SanityCheckTilingState();
605 void PictureLayerImpl::SyncTiling(
606 const PictureLayerTiling* tiling) {
607 if (!CanHaveTilingWithScale(tiling->contents_scale()))
609 tilings_->AddTiling(tiling->contents_scale());
611 // If this tree needs update draw properties, then the tiling will
612 // get updated prior to drawing or activation. If this tree does not
613 // need update draw properties, then its transforms are up to date and
614 // we can create tiles for this tiling immediately.
615 if (!layer_tree_impl()->needs_update_draw_properties() &&
616 should_update_tile_priorities_)
617 UpdateTilePriorities();
620 void PictureLayerImpl::SetIsMask(bool is_mask) {
621 if (is_mask_ == is_mask)
625 tilings_->RemoveAllTiles();
628 ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
629 gfx::Rect content_rect(content_bounds());
630 float scale = contents_scale_x();
631 PictureLayerTilingSet::CoverageIterator iter(
632 tilings_.get(), scale, content_rect, ideal_contents_scale_);
634 // Mask resource not ready yet.
638 // Masks only supported if they fit on exactly one tile.
639 if (iter.geometry_rect() != content_rect)
642 const ManagedTileState::TileVersion& tile_version =
643 iter->GetTileVersionForDrawing();
644 if (!tile_version.IsReadyToDraw() ||
645 tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
648 return tile_version.get_resource_id();
651 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
652 DCHECK(layer_tree_impl()->IsPendingTree());
653 DCHECK(!layer_tree_impl()->needs_update_draw_properties());
654 DCHECK(ideal_contents_scale_);
655 DCHECK_GT(tilings_->num_tilings(), 0u);
657 gfx::Rect rect(visible_content_rect());
659 float min_acceptable_scale =
660 std::min(raster_contents_scale_, ideal_contents_scale_);
662 if (PictureLayerImpl* twin = twin_layer_) {
663 float twin_min_acceptable_scale =
664 std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
665 // Ignore 0 scale in case CalculateContentsScale() has never been
666 // called for active twin.
667 if (twin_min_acceptable_scale != 0.0f) {
668 min_acceptable_scale =
669 std::min(min_acceptable_scale, twin_min_acceptable_scale);
673 // Mark tiles for activation in two passes. Ready to draw tiles in acceptable
674 // but non-ideal tilings are marked as required for activation, but any
675 // non-ready tiles are not marked as required. From there, any missing holes
676 // will need to be filled in from the high res tiling.
678 PictureLayerTiling* high_res = NULL;
679 Region missing_region = rect;
680 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
681 PictureLayerTiling* tiling = tilings_->tiling_at(i);
682 DCHECK(tiling->has_ever_been_updated());
684 if (tiling->contents_scale() < min_acceptable_scale)
686 if (tiling->resolution() == HIGH_RESOLUTION) {
687 DCHECK(!high_res) << "There can only be one high res tiling";
691 for (PictureLayerTiling::CoverageIterator iter(tiling,
696 if (!*iter || !iter->IsReadyToDraw())
699 // This iteration is over the visible content rect which is potentially
700 // less conservative than projecting the viewport into the layer.
701 // Ignore tiles that are know to be outside the viewport.
702 if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
705 missing_region.Subtract(iter.geometry_rect());
706 iter->MarkRequiredForActivation();
710 DCHECK(high_res) << "There must be one high res tiling";
711 for (PictureLayerTiling::CoverageIterator iter(high_res,
716 // A null tile (i.e. missing recording) can just be skipped.
720 // This iteration is over the visible content rect which is potentially
721 // less conservative than projecting the viewport into the layer.
722 // Ignore tiles that are know to be outside the viewport.
723 if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
726 // If the missing region doesn't cover it, this tile is fully
727 // covered by acceptable tiles at other scales.
728 if (!missing_region.Intersects(iter.geometry_rect()))
731 iter->MarkRequiredForActivation();
735 void PictureLayerImpl::DoPostCommitInitialization() {
736 DCHECK(needs_post_commit_initialization_);
737 DCHECK(layer_tree_impl()->IsPendingTree());
740 tilings_.reset(new PictureLayerTilingSet(this, bounds()));
742 DCHECK(!twin_layer_);
743 twin_layer_ = static_cast<PictureLayerImpl*>(
744 layer_tree_impl()->FindActiveTreeLayerById(id()));
746 DCHECK(!twin_layer_->twin_layer_);
747 twin_layer_->twin_layer_ = this;
748 // If the twin has never been pushed to, do not sync from it.
749 // This can happen if this function is called during activation.
750 if (!twin_layer_->needs_post_commit_initialization_)
751 SyncFromActiveLayer(twin_layer_);
754 needs_post_commit_initialization_ = false;
757 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
758 DCHECK(CanHaveTilingWithScale(contents_scale)) <<
759 "contents_scale: " << contents_scale;
761 PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
763 const Region& recorded = pile_->recorded_region();
764 DCHECK(!recorded.IsEmpty());
767 twin_layer_->SyncTiling(tiling);
772 void PictureLayerImpl::RemoveTiling(float contents_scale) {
773 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
774 PictureLayerTiling* tiling = tilings_->tiling_at(i);
775 if (tiling->contents_scale() == contents_scale) {
776 tilings_->Remove(tiling);
780 SanityCheckTilingState();
785 inline float PositiveRatio(float float1, float float2) {
786 DCHECK_GT(float1, 0);
787 DCHECK_GT(float2, 0);
788 return float1 > float2 ? float1 / float2 : float2 / float1;
791 inline bool IsCloserToThan(
792 PictureLayerTiling* layer1,
793 PictureLayerTiling* layer2,
794 float contents_scale) {
795 // Absolute value for ratios.
796 float ratio1 = PositiveRatio(layer1->contents_scale(), contents_scale);
797 float ratio2 = PositiveRatio(layer2->contents_scale(), contents_scale);
798 return ratio1 < ratio2;
803 void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) {
804 DCHECK(ideal_contents_scale_);
805 DCHECK(ideal_page_scale_);
806 DCHECK(ideal_device_scale_);
807 DCHECK(ideal_source_scale_);
808 DCHECK(CanHaveTilings());
809 DCHECK(!needs_post_commit_initialization_);
811 bool change_target_tiling =
812 raster_page_scale_ == 0.f ||
813 raster_device_scale_ == 0.f ||
814 raster_source_scale_ == 0.f ||
815 raster_contents_scale_ == 0.f ||
816 low_res_raster_contents_scale_ == 0.f ||
817 ShouldAdjustRasterScale(animating_transform_to_screen);
819 // Store the value for the next time ShouldAdjustRasterScale is called.
820 raster_source_scale_was_animating_ = animating_transform_to_screen;
822 if (!change_target_tiling)
825 if (!layer_tree_impl()->device_viewport_valid_for_tile_management())
828 raster_page_scale_ = ideal_page_scale_;
829 raster_device_scale_ = ideal_device_scale_;
830 raster_source_scale_ = ideal_source_scale_;
832 CalculateRasterContentsScale(animating_transform_to_screen,
833 &raster_contents_scale_,
834 &low_res_raster_contents_scale_);
836 PictureLayerTiling* high_res = NULL;
837 PictureLayerTiling* low_res = NULL;
839 PictureLayerTiling* previous_low_res = NULL;
840 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
841 PictureLayerTiling* tiling = tilings_->tiling_at(i);
842 if (tiling->contents_scale() == raster_contents_scale_)
844 if (tiling->contents_scale() == low_res_raster_contents_scale_)
846 if (tiling->resolution() == LOW_RESOLUTION)
847 previous_low_res = tiling;
849 // Reset all tilings to non-ideal until the end of this function.
850 tiling->set_resolution(NON_IDEAL_RESOLUTION);
854 high_res = AddTiling(raster_contents_scale_);
855 if (raster_contents_scale_ == low_res_raster_contents_scale_)
859 // Only create new low res tilings when the transform is static. This
860 // prevents wastefully creating a paired low res tiling for every new high res
861 // tiling during a pinch or a CSS animation.
862 bool is_pinching = layer_tree_impl()->PinchGestureActive();
863 if (!is_pinching && !animating_transform_to_screen && !low_res &&
865 low_res = AddTiling(low_res_raster_contents_scale_);
867 high_res->set_resolution(HIGH_RESOLUTION);
868 if (low_res && low_res != high_res)
869 low_res->set_resolution(LOW_RESOLUTION);
870 else if (!low_res && previous_low_res)
871 previous_low_res->set_resolution(LOW_RESOLUTION);
873 SanityCheckTilingState();
876 bool PictureLayerImpl::ShouldAdjustRasterScale(
877 bool animating_transform_to_screen) const {
878 // TODO(danakj): Adjust raster source scale closer to ideal source scale at
879 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
880 // tree. This will allow CSS scale changes to get re-rastered at an
883 if (raster_source_scale_was_animating_ && !animating_transform_to_screen)
886 bool is_pinching = layer_tree_impl()->PinchGestureActive();
887 if (is_pinching && raster_page_scale_) {
888 // If the page scale diverges too far during pinch, change raster target to
889 // the current page scale.
890 float ratio = PositiveRatio(ideal_page_scale_, raster_page_scale_);
891 if (ratio >= kMaxScaleRatioDuringPinch)
896 // When not pinching, match the ideal page scale factor.
897 if (raster_page_scale_ != ideal_page_scale_)
901 // Always match the ideal device scale factor.
902 if (raster_device_scale_ != ideal_device_scale_)
908 void PictureLayerImpl::CalculateRasterContentsScale(
909 bool animating_transform_to_screen,
910 float* raster_contents_scale,
911 float* low_res_raster_contents_scale) const {
912 *raster_contents_scale = ideal_contents_scale_;
914 // Don't allow animating CSS scales to drop below 1. This is needed because
915 // changes in raster source scale aren't handled. See the comment in
916 // ShouldAdjustRasterScale.
917 if (animating_transform_to_screen) {
918 *raster_contents_scale = std::max(
919 *raster_contents_scale, 1.f * ideal_page_scale_ * ideal_device_scale_);
922 // If this layer would only create one tile at this content scale,
923 // don't create a low res tiling.
924 gfx::Size content_bounds =
925 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), *raster_contents_scale));
926 gfx::Size tile_size = CalculateTileSize(content_bounds);
927 if (tile_size.width() >= content_bounds.width() &&
928 tile_size.height() >= content_bounds.height()) {
929 *low_res_raster_contents_scale = *raster_contents_scale;
933 float low_res_factor =
934 layer_tree_impl()->settings().low_res_contents_scale_factor;
935 *low_res_raster_contents_scale = std::max(
936 *raster_contents_scale * low_res_factor,
937 MinimumContentsScale());
940 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
941 std::vector<PictureLayerTiling*> used_tilings) {
942 DCHECK(layer_tree_impl()->IsActiveTree());
944 float min_acceptable_high_res_scale = std::min(
945 raster_contents_scale_, ideal_contents_scale_);
946 float max_acceptable_high_res_scale = std::max(
947 raster_contents_scale_, ideal_contents_scale_);
949 PictureLayerImpl* twin = twin_layer_;
951 min_acceptable_high_res_scale = std::min(
952 min_acceptable_high_res_scale,
953 std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
954 max_acceptable_high_res_scale = std::max(
955 max_acceptable_high_res_scale,
956 std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
959 std::vector<PictureLayerTiling*> to_remove;
960 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
961 PictureLayerTiling* tiling = tilings_->tiling_at(i);
963 // Keep multiple high resolution tilings even if not used to help
964 // activate earlier at non-ideal resolutions.
965 if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
966 tiling->contents_scale() <= max_acceptable_high_res_scale)
969 // Low resolution can't activate, so only keep one around.
970 if (tiling->resolution() == LOW_RESOLUTION)
973 // Don't remove tilings that are being used (and thus would cause a flash.)
974 if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
978 to_remove.push_back(tiling);
981 for (size_t i = 0; i < to_remove.size(); ++i) {
983 twin->RemoveTiling(to_remove[i]->contents_scale());
984 tilings_->Remove(to_remove[i]);
987 SanityCheckTilingState();
990 float PictureLayerImpl::MinimumContentsScale() const {
991 float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
993 // If the contents scale is less than 1 / width (also for height),
994 // then it will end up having less than one pixel of content in that
995 // dimension. Bump the minimum contents scale up in this case to prevent
996 // this from happening.
997 int min_dimension = std::min(bounds().width(), bounds().height());
1001 return std::max(1.f / min_dimension, setting_min);
1004 void PictureLayerImpl::UpdateLCDTextStatus(bool new_status) {
1005 // Once this layer is not using lcd text, don't switch back.
1006 if (!is_using_lcd_text_)
1009 if (is_using_lcd_text_ == new_status)
1012 is_using_lcd_text_ = new_status;
1013 tilings_->SetCanUseLCDText(is_using_lcd_text_);
1016 void PictureLayerImpl::ResetRasterScale() {
1017 raster_page_scale_ = 0.f;
1018 raster_device_scale_ = 0.f;
1019 raster_source_scale_ = 0.f;
1020 raster_contents_scale_ = 0.f;
1021 low_res_raster_contents_scale_ = 0.f;
1023 // When raster scales aren't valid, don't update tile priorities until
1024 // this layer has been updated via UpdateDrawProperties.
1025 should_update_tile_priorities_ = false;
1028 bool PictureLayerImpl::CanHaveTilings() const {
1029 if (!DrawsContent())
1031 if (pile_->recorded_region().IsEmpty())
1033 if (draw_properties().can_draw_directly_to_backbuffer &&
1034 layer_tree_impl()->settings().force_direct_layer_drawing)
1039 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
1040 if (!CanHaveTilings())
1042 if (contents_scale < MinimumContentsScale())
1047 void PictureLayerImpl::SanityCheckTilingState() const {
1048 if (!DCHECK_IS_ON())
1051 if (!CanHaveTilings()) {
1052 DCHECK_EQ(0u, tilings_->num_tilings());
1055 if (tilings_->num_tilings() == 0)
1058 // MarkVisibleResourcesAsRequired depends on having exactly 1 high res
1059 // tiling to mark its tiles as being required for activation.
1060 DCHECK_EQ(1, tilings_->NumHighResTilings());
1063 void PictureLayerImpl::GetDebugBorderProperties(
1065 float* width) const {
1066 *color = DebugColors::TiledContentLayerBorderColor();
1067 *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1070 void PictureLayerImpl::AsValueInto(base::DictionaryValue* state) const {
1071 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1072 LayerImpl::AsValueInto(state);
1073 state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1074 state->SetDouble("geometry_contents_scale", contents_scale_x());
1075 state->Set("tilings", tilings_->AsValue().release());
1076 state->Set("pictures", pile_->AsValue().release());
1077 state->Set("invalidation", invalidation_.AsValue().release());
1079 scoped_ptr<base::ListValue> coverage_tiles(new base::ListValue);
1080 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
1082 gfx::Rect(content_bounds()),
1083 ideal_contents_scale_);
1086 scoped_ptr<base::DictionaryValue> tile_data(new base::DictionaryValue);
1087 tile_data->Set("geometry_rect",
1088 MathUtil::AsValue(iter.geometry_rect()).release());
1090 tile_data->Set("tile", TracedValue::CreateIDRef(*iter).release());
1092 coverage_tiles->Append(tile_data.release());
1094 state->Set("coverage_tiles", coverage_tiles.release());
1095 state->SetBoolean("is_using_lcd_text", is_using_lcd_text_);
1098 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1099 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1100 return tilings_->GPUMemoryUsageInBytes();