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"
11 #include "base/debug/trace_event_argument.h"
12 #include "base/time/time.h"
13 #include "cc/base/math_util.h"
14 #include "cc/base/util.h"
15 #include "cc/debug/debug_colors.h"
16 #include "cc/debug/micro_benchmark_impl.h"
17 #include "cc/debug/traced_value.h"
18 #include "cc/layers/append_quads_data.h"
19 #include "cc/layers/solid_color_layer_impl.h"
20 #include "cc/output/begin_frame_args.h"
21 #include "cc/quads/checkerboard_draw_quad.h"
22 #include "cc/quads/debug_border_draw_quad.h"
23 #include "cc/quads/picture_draw_quad.h"
24 #include "cc/quads/solid_color_draw_quad.h"
25 #include "cc/quads/tile_draw_quad.h"
26 #include "cc/resources/tile_manager.h"
27 #include "cc/trees/layer_tree_impl.h"
28 #include "cc/trees/occlusion.h"
29 #include "ui/gfx/geometry/quad_f.h"
30 #include "ui/gfx/geometry/rect_conversions.h"
31 #include "ui/gfx/geometry/size_conversions.h"
34 const float kMaxScaleRatioDuringPinch = 2.0f;
36 // When creating a new tiling during pinch, snap to an existing
37 // tiling's scale if the desired scale is within this ratio.
38 const float kSnapToExistingTilingRatio = 1.2f;
40 // Estimate skewport 60 frames ahead for pre-rasterization on the CPU.
41 const float kCpuSkewportTargetTimeInFrames = 60.0f;
43 // Don't pre-rasterize on the GPU (except for kBackflingGuardDistancePixels in
44 // TileManager::BinFromTilePriority).
45 const float kGpuSkewportTargetTimeInFrames = 0.0f;
47 // Even for really wide viewports, at some point GPU raster should use
48 // less than 4 tiles to fill the viewport. This is set to 256 as a
49 // sane minimum for now, but we might want to tune this for low-end.
50 const int kMinHeightForGpuRasteredTile = 256;
52 // When making odd-sized tiles, round them up to increase the chances
53 // of using the same tile size.
54 const int kTileRoundUp = 64;
60 PictureLayerImpl::Pair::Pair() : active(nullptr), pending(nullptr) {
63 PictureLayerImpl::Pair::Pair(PictureLayerImpl* active_layer,
64 PictureLayerImpl* pending_layer)
65 : active(active_layer), pending(pending_layer) {
68 PictureLayerImpl::Pair::~Pair() {
71 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
72 : LayerImpl(tree_impl, id),
74 pile_(PicturePileImpl::Create()),
75 ideal_page_scale_(0.f),
76 ideal_device_scale_(0.f),
77 ideal_source_scale_(0.f),
78 ideal_contents_scale_(0.f),
79 raster_page_scale_(0.f),
80 raster_device_scale_(0.f),
81 raster_source_scale_(0.f),
82 raster_contents_scale_(0.f),
83 low_res_raster_contents_scale_(0.f),
84 raster_source_scale_is_fixed_(false),
85 was_screen_space_transform_animating_(false),
86 needs_post_commit_initialization_(true),
87 should_update_tile_priorities_(false),
88 only_used_low_res_last_append_quads_(false) {
89 layer_tree_impl()->RegisterPictureLayerImpl(this);
92 PictureLayerImpl::~PictureLayerImpl() {
94 twin_layer_->twin_layer_ = nullptr;
95 layer_tree_impl()->UnregisterPictureLayerImpl(this);
98 const char* PictureLayerImpl::LayerTypeAsString() const {
99 return "cc::PictureLayerImpl";
102 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
103 LayerTreeImpl* tree_impl) {
104 return PictureLayerImpl::Create(tree_impl, id());
107 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
108 // It's possible this layer was never drawn or updated (e.g. because it was
109 // a descendant of an opacity 0 layer).
110 DoPostCommitInitializationIfNeeded();
111 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
113 LayerImpl::PushPropertiesTo(base_layer);
115 // Twin relationships should never change once established.
116 DCHECK_IMPLIES(twin_layer_, twin_layer_ == layer_impl);
117 DCHECK_IMPLIES(twin_layer_, layer_impl->twin_layer_ == this);
118 // The twin relationship does not need to exist before the first
119 // PushPropertiesTo from pending to active layer since before that the active
120 // layer can not have a pile or tilings, it has only been created and inserted
121 // into the tree at that point.
122 twin_layer_ = layer_impl;
123 layer_impl->twin_layer_ = this;
125 layer_impl->UpdatePile(pile_);
127 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
128 // Tilings would be expensive to push, so we swap.
129 layer_impl->tilings_.swap(tilings_);
130 layer_impl->tilings_->SetClient(layer_impl);
132 tilings_->SetClient(this);
134 // Ensure that the recycle tree doesn't have any unshared tiles.
135 if (tilings_ && pile_->is_solid_color())
136 tilings_->RemoveAllTilings();
138 // Remove invalidated tiles from what will become a recycle tree.
140 tilings_->RemoveTilesInRegion(invalidation_);
142 layer_impl->raster_page_scale_ = raster_page_scale_;
143 layer_impl->raster_device_scale_ = raster_device_scale_;
144 layer_impl->raster_source_scale_ = raster_source_scale_;
145 layer_impl->raster_contents_scale_ = raster_contents_scale_;
146 layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
147 layer_impl->needs_post_commit_initialization_ = false;
149 // The invalidation on this soon-to-be-recycled layer must be cleared to
150 // mirror clearing the invalidation in PictureLayer's version of this function
151 // in case push properties is skipped.
152 layer_impl->invalidation_.Swap(&invalidation_);
153 invalidation_.Clear();
154 needs_post_commit_initialization_ = true;
156 // We always need to push properties.
157 // See http://crbug.com/303943
158 needs_push_properties_ = true;
161 void PictureLayerImpl::UpdatePile(scoped_refptr<PicturePileImpl> pile) {
162 bool could_have_tilings = CanHaveTilings();
165 // Need to call UpdateTiles again if CanHaveTilings changed.
166 if (could_have_tilings != CanHaveTilings()) {
167 layer_tree_impl()->set_needs_update_draw_properties();
171 void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
172 const Occlusion& occlusion_in_content_space,
173 AppendQuadsData* append_quads_data) {
174 DCHECK(!needs_post_commit_initialization_);
175 // The bounds and the pile size may differ if the pile wasn't updated (ie.
176 // PictureLayer::Update didn't happen). In that case the pile will be empty.
177 DCHECK_IMPLIES(!pile_->tiling_size().IsEmpty(),
178 bounds() == pile_->tiling_size())
179 << " bounds " << bounds().ToString() << " pile "
180 << pile_->tiling_size().ToString();
182 SharedQuadState* shared_quad_state =
183 render_pass->CreateAndAppendSharedQuadState();
185 if (pile_->is_solid_color()) {
186 PopulateSharedQuadState(shared_quad_state);
188 AppendDebugBorderQuad(
189 render_pass, bounds(), shared_quad_state, append_quads_data);
191 SolidColorLayerImpl::AppendSolidQuads(render_pass,
192 occlusion_in_content_space,
194 visible_content_rect(),
195 pile_->solid_color(),
200 float max_contents_scale = MaximumTilingContentsScale();
201 gfx::Transform scaled_draw_transform = draw_transform();
202 scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale,
203 SK_MScalar1 / max_contents_scale);
204 gfx::Size scaled_content_bounds =
205 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), max_contents_scale));
206 gfx::Rect scaled_visible_content_rect =
207 gfx::ScaleToEnclosingRect(visible_content_rect(), max_contents_scale);
208 scaled_visible_content_rect.Intersect(gfx::Rect(scaled_content_bounds));
209 Occlusion scaled_occlusion =
210 occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
211 scaled_draw_transform);
213 shared_quad_state->SetAll(scaled_draw_transform,
214 scaled_content_bounds,
215 scaled_visible_content_rect,
216 draw_properties().clip_rect,
217 draw_properties().is_clipped,
218 draw_properties().opacity,
220 sorting_context_id_);
222 if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
223 AppendDebugBorderQuad(
225 scaled_content_bounds,
228 DebugColors::DirectPictureBorderColor(),
229 DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
231 gfx::Rect geometry_rect = scaled_visible_content_rect;
232 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
233 gfx::Rect visible_geometry_rect =
234 scaled_occlusion.GetUnoccludedContentRect(geometry_rect);
235 if (visible_geometry_rect.IsEmpty())
238 gfx::Size texture_size = scaled_visible_content_rect.size();
239 gfx::RectF texture_rect = gfx::RectF(texture_size);
240 gfx::Rect quad_content_rect = scaled_visible_content_rect;
242 PictureDrawQuad* quad =
243 render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
244 quad->SetNew(shared_quad_state,
247 visible_geometry_rect,
257 AppendDebugBorderQuad(
258 render_pass, scaled_content_bounds, shared_quad_state, append_quads_data);
260 if (ShowDebugBorders()) {
261 for (PictureLayerTilingSet::CoverageIterator iter(
264 scaled_visible_content_rect,
265 ideal_contents_scale_);
270 if (*iter && iter->IsReadyToDraw()) {
271 ManagedTileState::DrawInfo::Mode mode = iter->draw_info().mode();
272 if (mode == ManagedTileState::DrawInfo::SOLID_COLOR_MODE) {
273 color = DebugColors::SolidColorTileBorderColor();
274 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
275 } else if (mode == ManagedTileState::DrawInfo::PICTURE_PILE_MODE) {
276 color = DebugColors::PictureTileBorderColor();
277 width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
278 } else if (iter.resolution() == HIGH_RESOLUTION) {
279 color = DebugColors::HighResTileBorderColor();
280 width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
281 } else if (iter.resolution() == LOW_RESOLUTION) {
282 color = DebugColors::LowResTileBorderColor();
283 width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
284 } else if (iter->contents_scale() > max_contents_scale) {
285 color = DebugColors::ExtraHighResTileBorderColor();
286 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
288 color = DebugColors::ExtraLowResTileBorderColor();
289 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
292 color = DebugColors::MissingTileBorderColor();
293 width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
296 DebugBorderDrawQuad* debug_border_quad =
297 render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
298 gfx::Rect geometry_rect = iter.geometry_rect();
299 gfx::Rect visible_geometry_rect = geometry_rect;
300 debug_border_quad->SetNew(shared_quad_state,
302 visible_geometry_rect,
308 // Keep track of the tilings that were used so that tilings that are
309 // unused can be considered for removal.
310 std::vector<PictureLayerTiling*> seen_tilings;
312 // Ignore missing tiles outside of viewport for tile priority. This is
313 // normally the same as draw viewport but can be independently overridden by
314 // embedders like Android WebView with SetExternalDrawConstraints.
315 gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
316 GetViewportForTilePriorityInContentSpace(), max_contents_scale);
318 size_t missing_tile_count = 0u;
319 size_t on_demand_missing_tile_count = 0u;
320 only_used_low_res_last_append_quads_ = true;
321 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
323 scaled_visible_content_rect,
324 ideal_contents_scale_);
327 gfx::Rect geometry_rect = iter.geometry_rect();
328 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
329 gfx::Rect visible_geometry_rect =
330 scaled_occlusion.GetUnoccludedContentRect(geometry_rect);
331 if (visible_geometry_rect.IsEmpty())
334 append_quads_data->visible_content_area +=
335 visible_geometry_rect.width() * visible_geometry_rect.height();
337 bool has_draw_quad = false;
338 if (*iter && iter->IsReadyToDraw()) {
339 const ManagedTileState::DrawInfo& draw_info = iter->draw_info();
340 switch (draw_info.mode()) {
341 case ManagedTileState::DrawInfo::RESOURCE_MODE: {
342 gfx::RectF texture_rect = iter.texture_rect();
344 // The raster_contents_scale_ is the best scale that the layer is
345 // trying to produce, even though it may not be ideal. Since that's
346 // the best the layer can promise in the future, consider those as
347 // complete. But if a tile is ideal scale, we don't want to consider
348 // it incomplete and trying to replace it with a tile at a worse
350 if (iter->contents_scale() != raster_contents_scale_ &&
351 iter->contents_scale() != ideal_contents_scale_ &&
352 geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
353 append_quads_data->num_incomplete_tiles++;
357 render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
358 quad->SetNew(shared_quad_state,
361 visible_geometry_rect,
362 draw_info.get_resource_id(),
365 draw_info.contents_swizzled());
366 has_draw_quad = true;
369 case ManagedTileState::DrawInfo::PICTURE_PILE_MODE: {
370 if (!layer_tree_impl()
371 ->GetRendererCapabilities()
372 .allow_rasterize_on_demand) {
373 ++on_demand_missing_tile_count;
377 gfx::RectF texture_rect = iter.texture_rect();
379 ResourceProvider* resource_provider =
380 layer_tree_impl()->resource_provider();
381 ResourceFormat format =
382 resource_provider->memory_efficient_texture_format();
383 PictureDrawQuad* quad =
384 render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
385 quad->SetNew(shared_quad_state,
388 visible_geometry_rect,
392 iter->content_rect(),
393 iter->contents_scale(),
395 has_draw_quad = true;
398 case ManagedTileState::DrawInfo::SOLID_COLOR_MODE: {
399 SolidColorDrawQuad* quad =
400 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
401 quad->SetNew(shared_quad_state,
403 visible_geometry_rect,
404 draw_info.get_solid_color(),
406 has_draw_quad = true;
412 if (!has_draw_quad) {
413 if (draw_checkerboard_for_missing_tiles()) {
414 CheckerboardDrawQuad* quad =
415 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
416 SkColor color = DebugColors::DefaultCheckerboardColor();
418 shared_quad_state, geometry_rect, visible_geometry_rect, color);
420 SkColor color = SafeOpaqueBackgroundColor();
421 SolidColorDrawQuad* quad =
422 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
423 quad->SetNew(shared_quad_state,
425 visible_geometry_rect,
430 if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
431 append_quads_data->num_missing_tiles++;
432 ++missing_tile_count;
434 append_quads_data->approximated_visible_content_area +=
435 visible_geometry_rect.width() * visible_geometry_rect.height();
439 if (iter.resolution() != HIGH_RESOLUTION) {
440 append_quads_data->approximated_visible_content_area +=
441 visible_geometry_rect.width() * visible_geometry_rect.height();
444 // If we have a draw quad, but it's not low resolution, then
445 // mark that we've used something other than low res to draw.
446 if (iter.resolution() != LOW_RESOLUTION)
447 only_used_low_res_last_append_quads_ = false;
449 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
450 seen_tilings.push_back(iter.CurrentTiling());
453 if (missing_tile_count) {
454 TRACE_EVENT_INSTANT2("cc",
455 "PictureLayerImpl::AppendQuads checkerboard",
456 TRACE_EVENT_SCOPE_THREAD,
457 "missing_tile_count",
459 "on_demand_missing_tile_count",
460 on_demand_missing_tile_count);
463 // Aggressively remove any tilings that are not seen to save memory. Note
464 // that this is at the expense of doing cause more frequent re-painting. A
465 // better scheme would be to maintain a tighter visible_content_rect for the
467 CleanUpTilingsOnActiveLayer(seen_tilings);
470 void PictureLayerImpl::UpdateTiles(const Occlusion& occlusion_in_content_space,
471 bool resourceless_software_draw) {
472 DCHECK_EQ(1.f, contents_scale_x());
473 DCHECK_EQ(1.f, contents_scale_y());
475 DoPostCommitInitializationIfNeeded();
477 if (!resourceless_software_draw) {
478 visible_rect_for_tile_priority_ = visible_content_rect();
481 if (!CanHaveTilings()) {
482 ideal_page_scale_ = 0.f;
483 ideal_device_scale_ = 0.f;
484 ideal_contents_scale_ = 0.f;
485 ideal_source_scale_ = 0.f;
486 SanityCheckTilingState();
492 DCHECK(tilings_->num_tilings() > 0 || raster_contents_scale_ == 0.f)
493 << "A layer with no tilings shouldn't have valid raster scales";
494 if (!raster_contents_scale_ || ShouldAdjustRasterScale()) {
495 RecalculateRasterScales();
496 AddTilingsForRasterScale();
499 DCHECK(raster_page_scale_);
500 DCHECK(raster_device_scale_);
501 DCHECK(raster_source_scale_);
502 DCHECK(raster_contents_scale_);
503 DCHECK(low_res_raster_contents_scale_);
505 was_screen_space_transform_animating_ =
506 draw_properties().screen_space_transform_is_animating;
508 if (draw_transform_is_animating())
509 pile_->set_likely_to_be_used_for_transform_animation();
511 should_update_tile_priorities_ = true;
513 UpdateTilePriorities(occlusion_in_content_space);
516 void PictureLayerImpl::UpdateTilePriorities(
517 const Occlusion& occlusion_in_content_space) {
518 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
519 double current_frame_time_in_seconds =
520 (layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
521 base::TimeTicks()).InSecondsF();
523 gfx::Rect viewport_rect_in_layer_space =
524 GetViewportForTilePriorityInContentSpace();
525 bool tiling_needs_update = false;
526 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
527 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTimeAndViewport(
528 current_frame_time_in_seconds, viewport_rect_in_layer_space)) {
529 tiling_needs_update = true;
533 if (!tiling_needs_update)
537 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
538 bool can_require_tiles_for_activation =
539 !only_used_low_res_last_append_quads_ || RequiresHighResToDraw() ||
540 !layer_tree_impl()->SmoothnessTakesPriority();
541 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
542 PictureLayerTiling* tiling = tilings_->tiling_at(i);
544 tiling->set_can_require_tiles_for_activation(
545 can_require_tiles_for_activation);
547 // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since
548 // they are the same space in picture layer, as contents scale is always 1.
549 tiling->ComputeTilePriorityRects(tree,
550 viewport_rect_in_layer_space,
551 ideal_contents_scale_,
552 current_frame_time_in_seconds,
553 occlusion_in_content_space);
556 // Tile priorities were modified.
557 // TODO(vmpstr): See if this can be removed in favour of calling it from LTHI
558 layer_tree_impl()->DidModifyTilePriorities();
561 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
562 // If visible_rect_for_tile_priority_ is empty or
563 // viewport_rect_for_tile_priority is set to be different from the device
564 // viewport, try to inverse project the viewport into layer space and use
565 // that. Otherwise just use visible_rect_for_tile_priority_
566 gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_;
567 gfx::Rect viewport_rect_for_tile_priority =
568 layer_tree_impl()->ViewportRectForTilePriority();
570 if (visible_rect_in_content_space.IsEmpty() ||
571 layer_tree_impl()->DeviceViewport() != viewport_rect_for_tile_priority) {
572 gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization);
573 if (screen_space_transform().GetInverse(&view_to_layer)) {
574 // Transform from view space to content space.
575 visible_rect_in_content_space =
576 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
577 view_to_layer, viewport_rect_for_tile_priority));
580 return visible_rect_in_content_space;
583 PictureLayerImpl* PictureLayerImpl::GetPendingOrActiveTwinLayer() const {
584 if (!twin_layer_ || !twin_layer_->IsOnActiveOrPendingTree())
589 PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() const {
590 if (!twin_layer_ || twin_layer_->IsOnActiveOrPendingTree())
595 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
596 if (layer_tree_impl()->IsActiveTree()) {
597 gfx::RectF layer_damage_rect =
598 gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
599 AddDamageRect(layer_damage_rect);
603 void PictureLayerImpl::DidBecomeActive() {
604 LayerImpl::DidBecomeActive();
605 // TODO(vmpstr): See if this can be removed in favour of calling it from LTHI
606 layer_tree_impl()->DidModifyTilePriorities();
609 void PictureLayerImpl::DidBeginTracing() {
610 pile_->DidBeginTracing();
613 void PictureLayerImpl::ReleaseResources() {
619 // To avoid an edge case after lost context where the tree is up to date but
620 // the tilings have not been managed, request an update draw properties
621 // to force tilings to get managed.
622 layer_tree_impl()->set_needs_update_draw_properties();
625 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
626 return pile_->GetFlattenedPicture();
629 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
630 const gfx::Rect& content_rect) {
631 DCHECK(!pile_->is_solid_color());
632 if (!pile_->CoversRect(content_rect, tiling->contents_scale()))
633 return scoped_refptr<Tile>();
637 // TODO(vmpstr): Revisit this. For now, enabling analysis means that we get as
638 // much savings on memory as we can. However, for some cases like ganesh or
639 // small layers, the amount of time we spend analyzing might not justify
640 // memory savings that we can get. Note that we don't handle solid color
641 // masks, so we shouldn't bother analyzing those.
642 // Bugs: crbug.com/397198, crbug.com/396908
643 if (!pile_->is_mask())
644 flags = Tile::USE_PICTURE_ANALYSIS;
646 return layer_tree_impl()->tile_manager()->CreateTile(
650 tiling->contents_scale(),
652 layer_tree_impl()->source_frame_number(),
656 RasterSource* PictureLayerImpl::GetRasterSource() {
660 const Region* PictureLayerImpl::GetPendingInvalidation() {
661 if (layer_tree_impl()->IsPendingTree())
662 return &invalidation_;
663 DCHECK(layer_tree_impl()->IsActiveTree());
664 if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
665 return &twin_layer->invalidation_;
669 const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling(
670 const PictureLayerTiling* tiling) const {
671 PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
674 // TODO(danakj): Remove this when no longer swapping tilings.
675 if (!twin_layer->tilings_)
677 return twin_layer->tilings_->TilingAtScale(tiling->contents_scale());
680 PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling(
681 const PictureLayerTiling* tiling) {
682 PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
683 if (!recycled_twin || !recycled_twin->tilings_)
685 return recycled_twin->tilings_->TilingAtScale(tiling->contents_scale());
688 size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
689 return layer_tree_impl()->settings().max_tiles_for_interest_area;
692 float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
693 float skewport_target_time_in_frames =
694 layer_tree_impl()->use_gpu_rasterization()
695 ? kGpuSkewportTargetTimeInFrames
696 : kCpuSkewportTargetTimeInFrames;
697 return skewport_target_time_in_frames *
698 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() *
699 layer_tree_impl()->settings().skewport_target_time_multiplier;
702 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
703 return layer_tree_impl()
705 .skewport_extrapolation_limit_in_content_pixels;
708 bool PictureLayerImpl::RequiresHighResToDraw() const {
709 return layer_tree_impl()->RequiresHighResToDraw();
712 gfx::Size PictureLayerImpl::CalculateTileSize(
713 const gfx::Size& content_bounds) const {
714 int max_texture_size =
715 layer_tree_impl()->resource_provider()->max_texture_size();
717 if (pile_->is_mask()) {
718 // Masks are not tiled, so if we can't cover the whole mask with one tile,
719 // don't make any tiles at all. Returning an empty size signals this.
720 if (content_bounds.width() > max_texture_size ||
721 content_bounds.height() > max_texture_size)
723 return content_bounds;
726 int default_tile_width = 0;
727 int default_tile_height = 0;
728 if (layer_tree_impl()->use_gpu_rasterization()) {
729 // For GPU rasterization, we pick an ideal tile size using the viewport
730 // so we don't need any settings. The current approach uses 4 tiles
731 // to cover the viewport vertically.
732 int viewport_width = layer_tree_impl()->device_viewport_size().width();
733 int viewport_height = layer_tree_impl()->device_viewport_size().height();
734 default_tile_width = viewport_width;
735 // Also, increase the height proportionally as the width decreases, and
736 // pad by our border texels to make the tiles exactly match the viewport.
738 if (content_bounds.width() <= viewport_width / 2)
740 if (content_bounds.width() <= viewport_width / 4)
742 default_tile_height = RoundUp(viewport_height, divisor) / divisor;
743 default_tile_height += 2 * PictureLayerTiling::kBorderTexels;
744 default_tile_height =
745 std::max(default_tile_height, kMinHeightForGpuRasteredTile);
747 // For CPU rasterization we use tile-size settings.
748 const LayerTreeSettings& settings = layer_tree_impl()->settings();
749 int max_untiled_content_width = settings.max_untiled_layer_size.width();
750 int max_untiled_content_height = settings.max_untiled_layer_size.height();
751 default_tile_width = settings.default_tile_size.width();
752 default_tile_height = settings.default_tile_size.height();
754 // If the content width is small, increase tile size vertically.
755 // If the content height is small, increase tile size horizontally.
756 // If both are less than the untiled-size, use a single tile.
757 if (content_bounds.width() < default_tile_width)
758 default_tile_height = max_untiled_content_height;
759 if (content_bounds.height() < default_tile_height)
760 default_tile_width = max_untiled_content_width;
761 if (content_bounds.width() < max_untiled_content_width &&
762 content_bounds.height() < max_untiled_content_height) {
763 default_tile_height = max_untiled_content_height;
764 default_tile_width = max_untiled_content_width;
768 int tile_width = default_tile_width;
769 int tile_height = default_tile_height;
771 // Clamp the tile width/height to the content width/height to save space.
772 if (content_bounds.width() < default_tile_width) {
773 tile_width = std::min(tile_width, content_bounds.width());
774 tile_width = RoundUp(tile_width, kTileRoundUp);
775 tile_width = std::min(tile_width, default_tile_width);
777 if (content_bounds.height() < default_tile_height) {
778 tile_height = std::min(tile_height, content_bounds.height());
779 tile_height = RoundUp(tile_height, kTileRoundUp);
780 tile_height = std::min(tile_height, default_tile_height);
783 // Under no circumstance should we be larger than the max texture size.
784 tile_width = std::min(tile_width, max_texture_size);
785 tile_height = std::min(tile_height, max_texture_size);
786 return gfx::Size(tile_width, tile_height);
789 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
790 DCHECK(!other->needs_post_commit_initialization_);
791 DCHECK(other->tilings_);
793 if (!DrawsContent()) {
798 raster_page_scale_ = other->raster_page_scale_;
799 raster_device_scale_ = other->raster_device_scale_;
800 raster_source_scale_ = other->raster_source_scale_;
801 raster_contents_scale_ = other->raster_contents_scale_;
802 low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
804 bool synced_high_res_tiling = false;
805 if (CanHaveTilings()) {
806 synced_high_res_tiling = tilings_->SyncTilings(*other->tilings_,
807 pile_->tiling_size(),
809 MinimumContentsScale());
814 // If our MinimumContentsScale has changed to prevent the twin's high res
815 // tiling from being synced, we should reset the raster scale and let it be
816 // recalculated (1) again. This can happen if our bounds shrink to the point
817 // where min contents scale grows.
818 // (1) - TODO(vmpstr) Instead of hoping that this will be recalculated, we
819 // should refactor this code a little bit and actually recalculate this.
820 // However, this is a larger undertaking, so this will work for now.
821 if (!synced_high_res_tiling)
824 SanityCheckTilingState();
827 void PictureLayerImpl::SyncTiling(
828 const PictureLayerTiling* tiling) {
831 if (!CanHaveTilingWithScale(tiling->contents_scale()))
833 tilings_->AddTiling(tiling->contents_scale(), pile_->tiling_size());
835 // If this tree needs update draw properties, then the tiling will
836 // get updated prior to drawing or activation. If this tree does not
837 // need update draw properties, then its transforms are up to date and
838 // we can create tiles for this tiling immediately.
839 if (!layer_tree_impl()->needs_update_draw_properties() &&
840 should_update_tile_priorities_) {
841 // TODO(danakj): Add a DCHECK() that we are not using occlusion tracking
842 // when we stop using the pending tree in the browser compositor. If we want
843 // to support occlusion tracking here, we need to dirty the draw properties
844 // or save occlusion as a draw property.
845 UpdateTilePriorities(Occlusion());
849 void PictureLayerImpl::GetContentsResourceId(
850 ResourceProvider::ResourceId* resource_id,
851 gfx::Size* resource_size) const {
852 DCHECK_EQ(bounds().ToString(), pile_->tiling_size().ToString());
853 gfx::Rect content_rect(bounds());
854 PictureLayerTilingSet::CoverageIterator iter(
855 tilings_.get(), 1.f, content_rect, ideal_contents_scale_);
857 // Mask resource not ready yet.
858 if (!iter || !*iter) {
863 // Masks only supported if they fit on exactly one tile.
864 DCHECK(iter.geometry_rect() == content_rect)
865 << "iter rect " << iter.geometry_rect().ToString() << " content rect "
866 << content_rect.ToString();
868 const ManagedTileState::DrawInfo& draw_info = iter->draw_info();
869 if (!draw_info.IsReadyToDraw() ||
870 draw_info.mode() != ManagedTileState::DrawInfo::RESOURCE_MODE) {
875 *resource_id = draw_info.get_resource_id();
876 *resource_size = iter.texture_size();
879 void PictureLayerImpl::DoPostCommitInitialization() {
880 DCHECK(needs_post_commit_initialization_);
881 DCHECK(layer_tree_impl()->IsPendingTree());
884 tilings_ = make_scoped_ptr(new PictureLayerTilingSet(this));
886 PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
888 // If the twin has never been pushed to, do not sync from it.
889 // This can happen if this function is called during activation.
890 if (!twin_layer->needs_post_commit_initialization_)
891 SyncFromActiveLayer(twin_layer);
894 needs_post_commit_initialization_ = false;
897 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
898 DCHECK(CanHaveTilingWithScale(contents_scale)) <<
899 "contents_scale: " << contents_scale;
901 PictureLayerTiling* tiling =
902 tilings_->AddTiling(contents_scale, pile_->tiling_size());
904 DCHECK(pile_->HasRecordings());
906 if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
907 twin_layer->SyncTiling(tiling);
912 void PictureLayerImpl::RemoveTiling(float contents_scale) {
913 if (!tilings_ || tilings_->num_tilings() == 0)
916 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
917 PictureLayerTiling* tiling = tilings_->tiling_at(i);
918 if (tiling->contents_scale() == contents_scale) {
919 tilings_->Remove(tiling);
923 if (tilings_->num_tilings() == 0)
925 SanityCheckTilingState();
928 void PictureLayerImpl::RemoveAllTilings() {
930 tilings_->RemoveAllTilings();
931 // If there are no tilings, then raster scales are no longer meaningful.
937 inline float PositiveRatio(float float1, float float2) {
938 DCHECK_GT(float1, 0);
939 DCHECK_GT(float2, 0);
940 return float1 > float2 ? float1 / float2 : float2 / float1;
945 void PictureLayerImpl::AddTilingsForRasterScale() {
946 PictureLayerTiling* high_res = nullptr;
947 PictureLayerTiling* low_res = nullptr;
949 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
950 PictureLayerTiling* tiling = tilings_->tiling_at(i);
951 if (tiling->contents_scale() == raster_contents_scale_)
953 if (tiling->contents_scale() == low_res_raster_contents_scale_)
956 // Reset all tilings to non-ideal until the end of this function.
957 tiling->set_resolution(NON_IDEAL_RESOLUTION);
961 high_res = AddTiling(raster_contents_scale_);
962 if (raster_contents_scale_ == low_res_raster_contents_scale_)
966 // Only create new low res tilings when the transform is static. This
967 // prevents wastefully creating a paired low res tiling for every new high res
968 // tiling during a pinch or a CSS animation.
969 bool is_pinching = layer_tree_impl()->PinchGestureActive();
970 if (layer_tree_impl()->create_low_res_tiling() && !is_pinching &&
971 !draw_properties().screen_space_transform_is_animating && !low_res &&
973 low_res = AddTiling(low_res_raster_contents_scale_);
975 // Set low-res if we have one.
976 if (low_res && low_res != high_res)
977 low_res->set_resolution(LOW_RESOLUTION);
979 // Make sure we always have one high-res (even if high == low).
980 high_res->set_resolution(HIGH_RESOLUTION);
982 SanityCheckTilingState();
985 bool PictureLayerImpl::ShouldAdjustRasterScale() const {
986 if (was_screen_space_transform_animating_ !=
987 draw_properties().screen_space_transform_is_animating)
990 if (draw_properties().screen_space_transform_is_animating &&
991 raster_contents_scale_ != ideal_contents_scale_ &&
992 ShouldAdjustRasterScaleDuringScaleAnimations())
995 bool is_pinching = layer_tree_impl()->PinchGestureActive();
996 if (is_pinching && raster_page_scale_) {
997 // We change our raster scale when it is:
998 // - Higher than ideal (need a lower-res tiling available)
999 // - Too far from ideal (need a higher-res tiling available)
1000 float ratio = ideal_page_scale_ / raster_page_scale_;
1001 if (raster_page_scale_ > ideal_page_scale_ ||
1002 ratio > kMaxScaleRatioDuringPinch)
1007 // When not pinching, match the ideal page scale factor.
1008 if (raster_page_scale_ != ideal_page_scale_)
1012 // Always match the ideal device scale factor.
1013 if (raster_device_scale_ != ideal_device_scale_)
1016 // When the source scale changes we want to match it, but not when animating
1017 // or when we've fixed the scale in place.
1018 if (!draw_properties().screen_space_transform_is_animating &&
1019 !raster_source_scale_is_fixed_ &&
1020 raster_source_scale_ != ideal_source_scale_)
1026 float PictureLayerImpl::SnappedContentsScale(float scale) {
1027 // If a tiling exists within the max snapping ratio, snap to its scale.
1028 float snapped_contents_scale = scale;
1029 float snapped_ratio = kSnapToExistingTilingRatio;
1030 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1031 float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale();
1032 float ratio = PositiveRatio(tiling_contents_scale, scale);
1033 if (ratio < snapped_ratio) {
1034 snapped_contents_scale = tiling_contents_scale;
1035 snapped_ratio = ratio;
1038 return snapped_contents_scale;
1041 void PictureLayerImpl::RecalculateRasterScales() {
1042 float old_raster_contents_scale = raster_contents_scale_;
1043 float old_raster_page_scale = raster_page_scale_;
1044 float old_raster_source_scale = raster_source_scale_;
1046 raster_device_scale_ = ideal_device_scale_;
1047 raster_page_scale_ = ideal_page_scale_;
1048 raster_source_scale_ = ideal_source_scale_;
1049 raster_contents_scale_ = ideal_contents_scale_;
1051 // If we're not animating, or leaving an animation, and the
1052 // ideal_source_scale_ changes, then things are unpredictable, and we fix
1053 // the raster_source_scale_ in place.
1054 if (old_raster_source_scale &&
1055 !draw_properties().screen_space_transform_is_animating &&
1056 !was_screen_space_transform_animating_ &&
1057 old_raster_source_scale != ideal_source_scale_)
1058 raster_source_scale_is_fixed_ = true;
1060 // TODO(danakj): Adjust raster source scale closer to ideal source scale at
1061 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
1062 // tree. This will allow CSS scale changes to get re-rastered at an
1063 // appropriate rate. (crbug.com/413636)
1064 if (raster_source_scale_is_fixed_) {
1065 raster_contents_scale_ /= raster_source_scale_;
1066 raster_source_scale_ = 1.f;
1069 // During pinch we completely ignore the current ideal scale, and just use
1070 // a multiple of the previous scale.
1071 // TODO(danakj): This seems crazy, we should use the current ideal, no?
1072 bool is_pinching = layer_tree_impl()->PinchGestureActive();
1073 if (is_pinching && old_raster_contents_scale) {
1074 // See ShouldAdjustRasterScale:
1075 // - When zooming out, preemptively create new tiling at lower resolution.
1076 // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
1077 bool zooming_out = old_raster_page_scale > ideal_page_scale_;
1078 float desired_contents_scale =
1079 zooming_out ? old_raster_contents_scale / kMaxScaleRatioDuringPinch
1080 : old_raster_contents_scale * kMaxScaleRatioDuringPinch;
1081 raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
1082 raster_page_scale_ =
1083 raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
1086 // If we're not re-rasterizing during animation, rasterize at the maximum
1087 // scale that will occur during the animation, if the maximum scale is
1088 // known. However we want to avoid excessive memory use. If the scale is
1089 // smaller than what we would choose otherwise, then it's always better off
1090 // for us memory-wise. But otherwise, we don't choose a scale at which this
1091 // layer's rastered content would become larger than the viewport.
1092 if (draw_properties().screen_space_transform_is_animating &&
1093 !ShouldAdjustRasterScaleDuringScaleAnimations()) {
1094 bool can_raster_at_maximum_scale = false;
1095 // TODO(ajuma): If we need to deal with scale-down animations starting right
1096 // as a layer gets promoted, then we'd want to have the
1097 // |starting_animation_contents_scale| passed in here as a separate draw
1098 // property so we could try use that when the max is too large.
1099 // See crbug.com/422341.
1100 float maximum_scale = draw_properties().maximum_animation_contents_scale;
1101 if (maximum_scale) {
1102 gfx::Size bounds_at_maximum_scale = gfx::ToCeiledSize(
1103 gfx::ScaleSize(pile_->tiling_size(), maximum_scale));
1104 if (bounds_at_maximum_scale.GetArea() <=
1105 layer_tree_impl()->device_viewport_size().GetArea())
1106 can_raster_at_maximum_scale = true;
1108 // Use the computed scales for the raster scale directly, do not try to use
1109 // the ideal scale here. The current ideal scale may be way too large in the
1110 // case of an animation with scale, and will be constantly changing.
1111 if (can_raster_at_maximum_scale)
1112 raster_contents_scale_ = maximum_scale;
1114 raster_contents_scale_ = 1.f * ideal_page_scale_ * ideal_device_scale_;
1117 raster_contents_scale_ =
1118 std::max(raster_contents_scale_, MinimumContentsScale());
1120 // If this layer would create zero or one tiles at this content scale,
1121 // don't create a low res tiling.
1122 gfx::Size raster_bounds = gfx::ToCeiledSize(
1123 gfx::ScaleSize(pile_->tiling_size(), raster_contents_scale_));
1124 gfx::Size tile_size = CalculateTileSize(raster_bounds);
1125 bool tile_covers_bounds = tile_size.width() >= raster_bounds.width() &&
1126 tile_size.height() >= raster_bounds.height();
1127 if (tile_size.IsEmpty() || tile_covers_bounds) {
1128 low_res_raster_contents_scale_ = raster_contents_scale_;
1132 float low_res_factor =
1133 layer_tree_impl()->settings().low_res_contents_scale_factor;
1134 low_res_raster_contents_scale_ = std::max(
1135 raster_contents_scale_ * low_res_factor,
1136 MinimumContentsScale());
1137 DCHECK_LE(low_res_raster_contents_scale_, raster_contents_scale_);
1138 DCHECK_GE(low_res_raster_contents_scale_, MinimumContentsScale());
1141 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
1142 std::vector<PictureLayerTiling*> used_tilings) {
1143 DCHECK(layer_tree_impl()->IsActiveTree());
1144 if (tilings_->num_tilings() == 0)
1147 float min_acceptable_high_res_scale = std::min(
1148 raster_contents_scale_, ideal_contents_scale_);
1149 float max_acceptable_high_res_scale = std::max(
1150 raster_contents_scale_, ideal_contents_scale_);
1151 float twin_low_res_scale = 0.f;
1153 PictureLayerImpl* twin = GetPendingOrActiveTwinLayer();
1154 if (twin && twin->CanHaveTilings()) {
1155 min_acceptable_high_res_scale = std::min(
1156 min_acceptable_high_res_scale,
1157 std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1158 max_acceptable_high_res_scale = std::max(
1159 max_acceptable_high_res_scale,
1160 std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1162 // TODO(danakj): Remove the tilings_ check when we create them in the
1164 if (twin->tilings_) {
1165 for (size_t i = 0; i < twin->tilings_->num_tilings(); ++i) {
1166 PictureLayerTiling* tiling = twin->tilings_->tiling_at(i);
1167 if (tiling->resolution() == LOW_RESOLUTION)
1168 twin_low_res_scale = tiling->contents_scale();
1173 std::vector<PictureLayerTiling*> to_remove;
1174 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1175 PictureLayerTiling* tiling = tilings_->tiling_at(i);
1177 // Keep multiple high resolution tilings even if not used to help
1178 // activate earlier at non-ideal resolutions.
1179 if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
1180 tiling->contents_scale() <= max_acceptable_high_res_scale)
1183 // Keep low resolution tilings, if the layer should have them.
1184 if (layer_tree_impl()->create_low_res_tiling()) {
1185 if (tiling->resolution() == LOW_RESOLUTION ||
1186 tiling->contents_scale() == twin_low_res_scale)
1190 // Don't remove tilings that are being used (and thus would cause a flash.)
1191 if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
1195 to_remove.push_back(tiling);
1198 if (to_remove.empty())
1201 PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
1202 // Remove tilings on this tree and the twin tree.
1203 for (size_t i = 0; i < to_remove.size(); ++i) {
1204 const PictureLayerTiling* twin_tiling =
1205 GetPendingOrActiveTwinTiling(to_remove[i]);
1206 // Only remove tilings from the twin layer if they have
1207 // NON_IDEAL_RESOLUTION.
1208 if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
1209 twin->RemoveTiling(to_remove[i]->contents_scale());
1210 // Remove the tiling from the recycle tree. Note that we ignore resolution,
1211 // since we don't need to maintain high/low res on the recycle tree.
1213 recycled_twin->RemoveTiling(to_remove[i]->contents_scale());
1214 // TODO(enne): temporary sanity CHECK for http://crbug.com/358350
1215 CHECK_NE(HIGH_RESOLUTION, to_remove[i]->resolution());
1216 tilings_->Remove(to_remove[i]);
1219 DCHECK_GT(tilings_->num_tilings(), 0u);
1220 SanityCheckTilingState();
1223 float PictureLayerImpl::MinimumContentsScale() const {
1224 float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
1226 // If the contents scale is less than 1 / width (also for height),
1227 // then it will end up having less than one pixel of content in that
1228 // dimension. Bump the minimum contents scale up in this case to prevent
1229 // this from happening.
1231 std::min(pile_->tiling_size().width(), pile_->tiling_size().height());
1235 return std::max(1.f / min_dimension, setting_min);
1238 void PictureLayerImpl::ResetRasterScale() {
1239 raster_page_scale_ = 0.f;
1240 raster_device_scale_ = 0.f;
1241 raster_source_scale_ = 0.f;
1242 raster_contents_scale_ = 0.f;
1243 low_res_raster_contents_scale_ = 0.f;
1244 raster_source_scale_is_fixed_ = false;
1246 // When raster scales aren't valid, don't update tile priorities until
1247 // this layer has been updated via UpdateDrawProperties.
1248 should_update_tile_priorities_ = false;
1251 bool PictureLayerImpl::CanHaveTilings() const {
1252 if (pile_->is_solid_color())
1254 if (!DrawsContent())
1256 if (!pile_->HasRecordings())
1261 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
1262 if (!CanHaveTilings())
1264 if (contents_scale < MinimumContentsScale())
1269 void PictureLayerImpl::SanityCheckTilingState() const {
1271 // Recycle tree doesn't have any restrictions.
1272 if (layer_tree_impl()->IsRecycleTree())
1275 if (!CanHaveTilings()) {
1276 DCHECK_EQ(0u, tilings_->num_tilings());
1279 if (tilings_->num_tilings() == 0)
1282 // We should only have one high res tiling.
1283 DCHECK_EQ(1, tilings_->NumHighResTilings());
1287 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const {
1288 return layer_tree_impl()->use_gpu_rasterization();
1291 float PictureLayerImpl::MaximumTilingContentsScale() const {
1292 float max_contents_scale = MinimumContentsScale();
1293 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1294 const PictureLayerTiling* tiling = tilings_->tiling_at(i);
1295 max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
1297 return max_contents_scale;
1300 void PictureLayerImpl::UpdateIdealScales() {
1301 DCHECK(CanHaveTilings());
1303 float min_contents_scale = MinimumContentsScale();
1304 DCHECK_GT(min_contents_scale, 0.f);
1305 float min_page_scale = layer_tree_impl()->min_page_scale_factor();
1306 DCHECK_GT(min_page_scale, 0.f);
1307 float min_device_scale = 1.f;
1308 float min_source_scale =
1309 min_contents_scale / min_page_scale / min_device_scale;
1311 float ideal_page_scale = draw_properties().page_scale_factor;
1312 float ideal_device_scale = draw_properties().device_scale_factor;
1313 float ideal_source_scale = draw_properties().ideal_contents_scale /
1314 ideal_page_scale / ideal_device_scale;
1315 ideal_contents_scale_ =
1316 std::max(draw_properties().ideal_contents_scale, min_contents_scale);
1317 ideal_page_scale_ = draw_properties().page_scale_factor;
1318 ideal_device_scale_ = draw_properties().device_scale_factor;
1319 ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
1322 void PictureLayerImpl::GetDebugBorderProperties(
1324 float* width) const {
1325 *color = DebugColors::TiledContentLayerBorderColor();
1326 *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1329 void PictureLayerImpl::GetAllTilesForTracing(
1330 std::set<const Tile*>* tiles) const {
1334 for (size_t i = 0; i < tilings_->num_tilings(); ++i)
1335 tilings_->tiling_at(i)->GetAllTilesForTracing(tiles);
1338 void PictureLayerImpl::AsValueInto(base::debug::TracedValue* state) const {
1339 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1340 LayerImpl::AsValueInto(state);
1341 state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1342 state->SetDouble("geometry_contents_scale", MaximumTilingContentsScale());
1343 state->BeginArray("tilings");
1344 tilings_->AsValueInto(state);
1347 state->BeginArray("tile_priority_rect");
1348 MathUtil::AddToTracedValue(GetViewportForTilePriorityInContentSpace(), state);
1351 state->BeginArray("visible_rect");
1352 MathUtil::AddToTracedValue(visible_content_rect(), state);
1355 state->BeginArray("pictures");
1356 pile_->AsValueInto(state);
1359 state->BeginArray("invalidation");
1360 invalidation_.AsValueInto(state);
1363 state->BeginArray("coverage_tiles");
1364 for (PictureLayerTilingSet::CoverageIterator iter(
1367 gfx::Rect(pile_->tiling_size()),
1368 ideal_contents_scale_);
1371 state->BeginDictionary();
1373 state->BeginArray("geometry_rect");
1374 MathUtil::AddToTracedValue(iter.geometry_rect(), state);
1378 TracedValue::SetIDRef(*iter, state, "tile");
1380 state->EndDictionary();
1385 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1386 const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1387 return tilings_->GPUMemoryUsageInBytes();
1390 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
1391 benchmark->RunOnLayer(this);
1394 WhichTree PictureLayerImpl::GetTree() const {
1395 return layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
1398 bool PictureLayerImpl::IsOnActiveOrPendingTree() const {
1399 return !layer_tree_impl()->IsRecycleTree();
1402 bool PictureLayerImpl::HasValidTilePriorities() const {
1403 return IsOnActiveOrPendingTree() && IsDrawnRenderSurfaceLayerListMember();
1406 bool PictureLayerImpl::AllTilesRequiredForActivationAreReadyToDraw() const {
1407 if (!layer_tree_impl()->IsPendingTree())
1410 if (!HasValidTilePriorities())
1416 if (visible_rect_for_tile_priority_.IsEmpty())
1419 gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
1420 rect.Intersect(visible_rect_for_tile_priority_);
1422 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1423 PictureLayerTiling* tiling = tilings_->tiling_at(i);
1424 if (tiling->resolution() != HIGH_RESOLUTION &&
1425 tiling->resolution() != LOW_RESOLUTION)
1428 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
1430 const Tile* tile = *iter;
1431 // A null tile (i.e. missing recording) can just be skipped.
1432 // TODO(vmpstr): Verify this is true if we create tiles in raster
1437 // We can't check tile->required_for_activation, because that value might
1438 // be out of date. It is updated in the raster/eviction iterators.
1439 // TODO(vmpstr): Remove the comment once you can't access this information
1441 if (tiling->IsTileRequiredForActivation(tile) && !tile->IsReadyToDraw()) {
1442 TRACE_EVENT_INSTANT0("cc",
1443 "PictureLayerImpl::"
1444 "AllTilesRequiredForActivationAreReadyToDraw not "
1445 "ready to activate",
1446 TRACE_EVENT_SCOPE_THREAD);
1455 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator()
1456 : layer_(nullptr), current_stage_(arraysize(stages_)) {
1459 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator(
1460 PictureLayerImpl* layer,
1461 bool prioritize_low_res)
1462 : layer_(layer), current_stage_(0) {
1465 // Early out if the layer has no tilings.
1466 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) {
1467 current_stage_ = arraysize(stages_);
1471 // Tiles without valid priority are treated as having lowest priority and
1472 // never considered for raster.
1473 if (!layer_->HasValidTilePriorities()) {
1474 current_stage_ = arraysize(stages_);
1478 // Find high and low res tilings and initialize the iterators.
1479 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) {
1480 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i);
1481 if (tiling->resolution() == HIGH_RESOLUTION) {
1482 iterators_[HIGH_RES] =
1483 PictureLayerTiling::TilingRasterTileIterator(tiling);
1486 if (prioritize_low_res && tiling->resolution() == LOW_RESOLUTION) {
1487 iterators_[LOW_RES] =
1488 PictureLayerTiling::TilingRasterTileIterator(tiling);
1492 if (prioritize_low_res) {
1493 stages_[0].iterator_type = LOW_RES;
1494 stages_[0].tile_type = TilePriority::NOW;
1496 stages_[1].iterator_type = HIGH_RES;
1497 stages_[1].tile_type = TilePriority::NOW;
1499 stages_[0].iterator_type = HIGH_RES;
1500 stages_[0].tile_type = TilePriority::NOW;
1502 stages_[1].iterator_type = LOW_RES;
1503 stages_[1].tile_type = TilePriority::NOW;
1506 stages_[2].iterator_type = HIGH_RES;
1507 stages_[2].tile_type = TilePriority::SOON;
1509 stages_[3].iterator_type = HIGH_RES;
1510 stages_[3].tile_type = TilePriority::EVENTUALLY;
1512 IteratorType index = stages_[current_stage_].iterator_type;
1513 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
1514 if (!iterators_[index] || iterators_[index].get_type() != tile_type)
1515 AdvanceToNextStage();
1518 PictureLayerImpl::LayerRasterTileIterator::~LayerRasterTileIterator() {}
1520 PictureLayerImpl::LayerRasterTileIterator::operator bool() const {
1521 return current_stage_ < arraysize(stages_);
1524 PictureLayerImpl::LayerRasterTileIterator&
1525 PictureLayerImpl::LayerRasterTileIterator::
1527 IteratorType index = stages_[current_stage_].iterator_type;
1528 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
1530 // First advance the iterator.
1531 DCHECK(iterators_[index]);
1532 DCHECK(iterators_[index].get_type() == tile_type);
1533 ++iterators_[index];
1535 if (!iterators_[index] || iterators_[index].get_type() != tile_type)
1536 AdvanceToNextStage();
1541 Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() {
1544 IteratorType index = stages_[current_stage_].iterator_type;
1545 DCHECK(iterators_[index]);
1546 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
1548 return *iterators_[index];
1551 const Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() const {
1554 IteratorType index = stages_[current_stage_].iterator_type;
1555 DCHECK(iterators_[index]);
1556 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
1558 return *iterators_[index];
1561 void PictureLayerImpl::LayerRasterTileIterator::AdvanceToNextStage() {
1562 DCHECK_LT(current_stage_, arraysize(stages_));
1564 while (current_stage_ < arraysize(stages_)) {
1565 IteratorType index = stages_[current_stage_].iterator_type;
1566 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
1568 if (iterators_[index] && iterators_[index].get_type() == tile_type)
1574 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator()
1576 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
1577 current_category_(PictureLayerTiling::EVENTUALLY),
1578 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
1579 current_tiling_(0u) {
1582 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator(
1583 PictureLayerImpl* layer,
1584 TreePriority tree_priority)
1586 tree_priority_(tree_priority),
1587 current_category_(PictureLayerTiling::EVENTUALLY),
1588 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
1589 current_tiling_(CurrentTilingRange().start - 1u) {
1590 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure
1591 // that layers that don't have valid tile priorities have lowest priorities so
1592 // they evict their tiles first (crbug.com/381704)
1593 DCHECK(layer_->tilings_);
1595 if (!AdvanceToNextTiling())
1598 current_iterator_ = PictureLayerTiling::TilingEvictionTileIterator(
1599 layer_->tilings_->tiling_at(CurrentTilingIndex()),
1602 } while (!current_iterator_);
1605 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {
1608 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() {
1610 return *current_iterator_;
1613 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const {
1615 return *current_iterator_;
1618 PictureLayerImpl::LayerEvictionTileIterator&
1619 PictureLayerImpl::LayerEvictionTileIterator::
1622 ++current_iterator_;
1623 while (!current_iterator_) {
1624 if (!AdvanceToNextTiling())
1627 current_iterator_ = PictureLayerTiling::TilingEvictionTileIterator(
1628 layer_->tilings_->tiling_at(CurrentTilingIndex()),
1635 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const {
1636 return !!current_iterator_;
1639 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextCategory() {
1640 switch (current_category_) {
1641 case PictureLayerTiling::EVENTUALLY:
1643 PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION;
1645 case PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1646 current_category_ = PictureLayerTiling::SOON;
1648 case PictureLayerTiling::SOON:
1649 current_category_ = PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION;
1651 case PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION:
1652 current_category_ = PictureLayerTiling::NOW;
1654 case PictureLayerTiling::NOW:
1655 current_category_ = PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION;
1657 case PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION:
1665 PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextTilingRangeType() {
1666 switch (current_tiling_range_type_) {
1667 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
1668 current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES;
1670 case PictureLayerTilingSet::LOWER_THAN_LOW_RES:
1671 current_tiling_range_type_ =
1672 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES;
1674 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
1675 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES;
1677 case PictureLayerTilingSet::LOW_RES:
1678 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
1680 case PictureLayerTilingSet::HIGH_RES:
1681 if (!AdvanceToNextCategory())
1684 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
1691 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextTiling() {
1692 DCHECK_NE(current_tiling_, CurrentTilingRange().end);
1694 while (current_tiling_ == CurrentTilingRange().end) {
1695 if (!AdvanceToNextTilingRangeType())
1698 current_tiling_ = CurrentTilingRange().start;
1703 PictureLayerTilingSet::TilingRange
1704 PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingRange() const {
1705 return layer_->tilings_->GetTilingRange(current_tiling_range_type_);
1708 size_t PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingIndex() const {
1709 DCHECK_NE(current_tiling_, CurrentTilingRange().end);
1710 switch (current_tiling_range_type_) {
1711 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
1712 case PictureLayerTilingSet::LOW_RES:
1713 case PictureLayerTilingSet::HIGH_RES:
1714 return current_tiling_;
1715 // Tilings in the following ranges are accessed in reverse order.
1716 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
1717 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: {
1718 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange();
1719 size_t current_tiling_range_offset = current_tiling_ - tiling_range.start;
1720 return tiling_range.end - 1 - current_tiling_range_offset;