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"
10 #include "base/time/time.h"
11 #include "cc/base/math_util.h"
12 #include "cc/base/util.h"
13 #include "cc/debug/debug_colors.h"
14 #include "cc/debug/micro_benchmark_impl.h"
15 #include "cc/debug/traced_value.h"
16 #include "cc/layers/append_quads_data.h"
17 #include "cc/layers/quad_sink.h"
18 #include "cc/quads/checkerboard_draw_quad.h"
19 #include "cc/quads/debug_border_draw_quad.h"
20 #include "cc/quads/picture_draw_quad.h"
21 #include "cc/quads/solid_color_draw_quad.h"
22 #include "cc/quads/tile_draw_quad.h"
23 #include "cc/resources/tile_manager.h"
24 #include "cc/trees/layer_tree_impl.h"
25 #include "ui/gfx/quad_f.h"
26 #include "ui/gfx/rect_conversions.h"
27 #include "ui/gfx/size_conversions.h"
30 const float kMaxScaleRatioDuringPinch
= 2.0f
;
32 // When creating a new tiling during pinch, snap to an existing
33 // tiling's scale if the desired scale is within this ratio.
34 const float kSnapToExistingTilingRatio
= 0.2f
;
39 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
40 : LayerImpl(tree_impl
, id
),
42 pile_(PicturePileImpl::Create()),
44 ideal_page_scale_(0.f
),
45 ideal_device_scale_(0.f
),
46 ideal_source_scale_(0.f
),
47 ideal_contents_scale_(0.f
),
48 raster_page_scale_(0.f
),
49 raster_device_scale_(0.f
),
50 raster_source_scale_(0.f
),
51 raster_contents_scale_(0.f
),
52 low_res_raster_contents_scale_(0.f
),
53 raster_source_scale_was_animating_(false),
54 is_using_lcd_text_(tree_impl
->settings().can_use_lcd_text
),
55 needs_post_commit_initialization_(true),
56 should_update_tile_priorities_(false),
57 should_use_gpu_rasterization_(tree_impl
->settings().gpu_rasterization
) {}
59 PictureLayerImpl::~PictureLayerImpl() {}
61 const char* PictureLayerImpl::LayerTypeAsString() const {
62 return "cc::PictureLayerImpl";
65 scoped_ptr
<LayerImpl
> PictureLayerImpl::CreateLayerImpl(
66 LayerTreeImpl
* tree_impl
) {
67 return PictureLayerImpl::Create(tree_impl
, id()).PassAs
<LayerImpl
>();
70 void PictureLayerImpl::PushPropertiesTo(LayerImpl
* base_layer
) {
71 // It's possible this layer was never drawn or updated (e.g. because it was
72 // a descendant of an opacity 0 layer).
73 DoPostCommitInitializationIfNeeded();
74 PictureLayerImpl
* layer_impl
= static_cast<PictureLayerImpl
*>(base_layer
);
76 // We have already synced the important bits from the the active layer, and
77 // we will soon swap out its tilings and use them for recycling. However,
78 // there are now tiles in this layer's tilings that were unref'd and replaced
79 // with new tiles (due to invalidation). This resets all active priorities on
80 // the to-be-recycled tiling to ensure replaced tiles don't linger and take
81 // memory (due to a stale 'active' priority).
82 if (layer_impl
->tilings_
)
83 layer_impl
->tilings_
->DidBecomeRecycled();
85 LayerImpl::PushPropertiesTo(base_layer
);
87 // When the pending tree pushes to the active tree, the pending twin
89 layer_impl
->twin_layer_
= NULL
;
92 layer_impl
->SetIsMask(is_mask_
);
93 layer_impl
->pile_
= pile_
;
95 // Tilings would be expensive to push, so we swap. This optimization requires
96 // an extra invalidation in SyncFromActiveLayer.
97 layer_impl
->tilings_
.swap(tilings_
);
98 layer_impl
->tilings_
->SetClient(layer_impl
);
100 tilings_
->SetClient(this);
102 layer_impl
->raster_page_scale_
= raster_page_scale_
;
103 layer_impl
->raster_device_scale_
= raster_device_scale_
;
104 layer_impl
->raster_source_scale_
= raster_source_scale_
;
105 layer_impl
->raster_contents_scale_
= raster_contents_scale_
;
106 layer_impl
->low_res_raster_contents_scale_
= low_res_raster_contents_scale_
;
108 layer_impl
->UpdateLCDTextStatus(is_using_lcd_text_
);
109 layer_impl
->needs_post_commit_initialization_
= false;
111 // The invalidation on this soon-to-be-recycled layer must be cleared to
112 // mirror clearing the invalidation in PictureLayer's version of this function
113 // in case push properties is skipped.
114 layer_impl
->invalidation_
.Swap(&invalidation_
);
115 invalidation_
.Clear();
116 needs_post_commit_initialization_
= true;
118 // We always need to push properties.
119 // See http://crbug.com/303943
120 needs_push_properties_
= true;
123 void PictureLayerImpl::AppendQuads(QuadSink
* quad_sink
,
124 AppendQuadsData
* append_quads_data
) {
125 DCHECK(!needs_post_commit_initialization_
);
126 gfx::Rect
rect(visible_content_rect());
127 gfx::Rect
content_rect(content_bounds());
129 SharedQuadState
* shared_quad_state
=
130 quad_sink
->UseSharedQuadState(CreateSharedQuadState());
132 if (current_draw_mode_
== DRAW_MODE_RESOURCELESS_SOFTWARE
) {
133 AppendDebugBorderQuad(
137 DebugColors::DirectPictureBorderColor(),
138 DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
140 gfx::Rect geometry_rect
= rect
;
141 gfx::Rect opaque_rect
= contents_opaque() ? geometry_rect
: gfx::Rect();
142 gfx::Size texture_size
= rect
.size();
143 gfx::RectF texture_rect
= gfx::RectF(texture_size
);
144 gfx::Rect quad_content_rect
= rect
;
145 float contents_scale
= contents_scale_x();
147 scoped_ptr
<PictureDrawQuad
> quad
= PictureDrawQuad::Create();
148 quad
->SetNew(shared_quad_state
,
157 if (quad_sink
->Append(quad
.PassAs
<DrawQuad
>(), append_quads_data
))
158 append_quads_data
->num_missing_tiles
++;
162 AppendDebugBorderQuad(quad_sink
, shared_quad_state
, append_quads_data
);
164 if (ShowDebugBorders()) {
165 for (PictureLayerTilingSet::CoverageIterator
iter(
166 tilings_
.get(), contents_scale_x(), rect
, ideal_contents_scale_
);
171 if (*iter
&& iter
->IsReadyToDraw()) {
172 ManagedTileState::TileVersion::Mode mode
=
173 iter
->GetTileVersionForDrawing().mode();
174 if (mode
== ManagedTileState::TileVersion::SOLID_COLOR_MODE
) {
175 color
= DebugColors::SolidColorTileBorderColor();
176 width
= DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
177 } else if (mode
== ManagedTileState::TileVersion::PICTURE_PILE_MODE
) {
178 color
= DebugColors::PictureTileBorderColor();
179 width
= DebugColors::PictureTileBorderWidth(layer_tree_impl());
180 } else if (iter
->priority(ACTIVE_TREE
).resolution
== HIGH_RESOLUTION
) {
181 color
= DebugColors::HighResTileBorderColor();
182 width
= DebugColors::HighResTileBorderWidth(layer_tree_impl());
183 } else if (iter
->priority(ACTIVE_TREE
).resolution
== LOW_RESOLUTION
) {
184 color
= DebugColors::LowResTileBorderColor();
185 width
= DebugColors::LowResTileBorderWidth(layer_tree_impl());
186 } else if (iter
->contents_scale() > contents_scale_x()) {
187 color
= DebugColors::ExtraHighResTileBorderColor();
188 width
= DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
190 color
= DebugColors::ExtraLowResTileBorderColor();
191 width
= DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
194 color
= DebugColors::MissingTileBorderColor();
195 width
= DebugColors::MissingTileBorderWidth(layer_tree_impl());
198 scoped_ptr
<DebugBorderDrawQuad
> debug_border_quad
=
199 DebugBorderDrawQuad::Create();
200 gfx::Rect geometry_rect
= iter
.geometry_rect();
201 debug_border_quad
->SetNew(shared_quad_state
, geometry_rect
, color
, width
);
202 quad_sink
->Append(debug_border_quad
.PassAs
<DrawQuad
>(),
207 // Keep track of the tilings that were used so that tilings that are
208 // unused can be considered for removal.
209 std::vector
<PictureLayerTiling
*> seen_tilings
;
211 for (PictureLayerTilingSet::CoverageIterator
iter(
212 tilings_
.get(), contents_scale_x(), rect
, ideal_contents_scale_
);
215 gfx::Rect geometry_rect
= iter
.geometry_rect();
216 if (!*iter
|| !iter
->IsReadyToDraw()) {
217 if (DrawCheckerboardForMissingTiles()) {
218 // TODO(enne): Figure out how to show debug "invalidated checker" color
219 scoped_ptr
<CheckerboardDrawQuad
> quad
= CheckerboardDrawQuad::Create();
220 SkColor color
= DebugColors::DefaultCheckerboardColor();
221 quad
->SetNew(shared_quad_state
, geometry_rect
, color
);
222 if (quad_sink
->Append(quad
.PassAs
<DrawQuad
>(), append_quads_data
))
223 append_quads_data
->num_missing_tiles
++;
225 SkColor color
= SafeOpaqueBackgroundColor();
226 scoped_ptr
<SolidColorDrawQuad
> quad
= SolidColorDrawQuad::Create();
227 quad
->SetNew(shared_quad_state
, geometry_rect
, color
, false);
228 if (quad_sink
->Append(quad
.PassAs
<DrawQuad
>(), append_quads_data
))
229 append_quads_data
->num_missing_tiles
++;
232 append_quads_data
->had_incomplete_tile
= true;
236 const ManagedTileState::TileVersion
& tile_version
=
237 iter
->GetTileVersionForDrawing();
238 scoped_ptr
<DrawQuad
> draw_quad
;
239 switch (tile_version
.mode()) {
240 case ManagedTileState::TileVersion::RESOURCE_MODE
: {
241 gfx::RectF texture_rect
= iter
.texture_rect();
242 gfx::Rect opaque_rect
= iter
->opaque_rect();
243 opaque_rect
.Intersect(geometry_rect
);
245 if (iter
->contents_scale() != ideal_contents_scale_
)
246 append_quads_data
->had_incomplete_tile
= true;
248 scoped_ptr
<TileDrawQuad
> quad
= TileDrawQuad::Create();
249 quad
->SetNew(shared_quad_state
,
252 tile_version
.get_resource_id(),
255 tile_version
.contents_swizzled());
256 draw_quad
= quad
.PassAs
<DrawQuad
>();
259 case ManagedTileState::TileVersion::PICTURE_PILE_MODE
: {
260 gfx::RectF texture_rect
= iter
.texture_rect();
261 gfx::Rect opaque_rect
= iter
->opaque_rect();
262 opaque_rect
.Intersect(geometry_rect
);
264 ResourceProvider
* resource_provider
=
265 layer_tree_impl()->resource_provider();
266 ResourceFormat format
=
267 resource_provider
->memory_efficient_texture_format();
268 scoped_ptr
<PictureDrawQuad
> quad
= PictureDrawQuad::Create();
269 quad
->SetNew(shared_quad_state
,
275 iter
->content_rect(),
276 iter
->contents_scale(),
278 draw_quad
= quad
.PassAs
<DrawQuad
>();
281 case ManagedTileState::TileVersion::SOLID_COLOR_MODE
: {
282 scoped_ptr
<SolidColorDrawQuad
> quad
= SolidColorDrawQuad::Create();
283 quad
->SetNew(shared_quad_state
,
285 tile_version
.get_solid_color(),
287 draw_quad
= quad
.PassAs
<DrawQuad
>();
293 quad_sink
->Append(draw_quad
.Pass(), append_quads_data
);
295 if (seen_tilings
.empty() || seen_tilings
.back() != iter
.CurrentTiling())
296 seen_tilings
.push_back(iter
.CurrentTiling());
299 // Aggressively remove any tilings that are not seen to save memory. Note
300 // that this is at the expense of doing cause more frequent re-painting. A
301 // better scheme would be to maintain a tighter visible_content_rect for the
303 CleanUpTilingsOnActiveLayer(seen_tilings
);
306 void PictureLayerImpl::UpdateTilePriorities() {
307 DCHECK(!needs_post_commit_initialization_
);
308 CHECK(should_update_tile_priorities_
);
310 if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) {
311 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
)
312 DCHECK(tilings_
->tiling_at(i
)->has_ever_been_updated());
316 if (!tilings_
->num_tilings())
319 double current_frame_time_in_seconds
=
320 (layer_tree_impl()->CurrentFrameTimeTicks() -
321 base::TimeTicks()).InSecondsF();
323 bool tiling_needs_update
= false;
324 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
325 if (tilings_
->tiling_at(i
)->NeedsUpdateForFrameAtTime(
326 current_frame_time_in_seconds
)) {
327 tiling_needs_update
= true;
331 if (!tiling_needs_update
)
334 UpdateLCDTextStatus(can_use_lcd_text());
336 // Use visible_content_rect, unless it's empty. If it's empty, then
337 // try to inverse project the viewport into layer space and use that.
338 gfx::Rect visible_rect_in_content_space
= visible_content_rect();
339 if (visible_rect_in_content_space
.IsEmpty()) {
340 gfx::Transform
screen_to_layer(gfx::Transform::kSkipInitialization
);
341 if (screen_space_transform().GetInverse(&screen_to_layer
)) {
342 gfx::Size viewport_size
= layer_tree_impl()->DrawViewportSize();
343 visible_rect_in_content_space
=
344 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
345 screen_to_layer
, gfx::Rect(viewport_size
)));
346 visible_rect_in_content_space
.Intersect(gfx::Rect(content_bounds()));
351 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE
: PENDING_TREE
;
353 tilings_
->UpdateTilePriorities(tree
,
354 visible_rect_in_content_space
,
356 current_frame_time_in_seconds
);
358 if (layer_tree_impl()->IsPendingTree())
359 MarkVisibleResourcesAsRequired();
361 // Tile priorities were modified.
362 layer_tree_impl()->DidModifyTilePriorities();
365 void PictureLayerImpl::DidBecomeActive() {
366 LayerImpl::DidBecomeActive();
367 tilings_
->DidBecomeActive();
368 layer_tree_impl()->DidModifyTilePriorities();
371 void PictureLayerImpl::DidBeginTracing() {
372 pile_
->DidBeginTracing();
375 void PictureLayerImpl::ReleaseResources() {
382 void PictureLayerImpl::CalculateContentsScale(
383 float ideal_contents_scale
,
384 float device_scale_factor
,
385 float page_scale_factor
,
386 bool animating_transform_to_screen
,
387 float* contents_scale_x
,
388 float* contents_scale_y
,
389 gfx::Size
* content_bounds
) {
390 DoPostCommitInitializationIfNeeded();
392 // This function sets valid raster scales and manages tilings, so tile
393 // priorities can now be updated.
394 should_update_tile_priorities_
= true;
396 if (!CanHaveTilings()) {
397 ideal_page_scale_
= page_scale_factor
;
398 ideal_device_scale_
= device_scale_factor
;
399 ideal_contents_scale_
= ideal_contents_scale
;
400 ideal_source_scale_
=
401 ideal_contents_scale_
/ ideal_page_scale_
/ ideal_device_scale_
;
402 *contents_scale_x
= ideal_contents_scale_
;
403 *contents_scale_y
= ideal_contents_scale_
;
404 *content_bounds
= gfx::ToCeiledSize(gfx::ScaleSize(bounds(),
405 ideal_contents_scale_
,
406 ideal_contents_scale_
));
410 float min_contents_scale
= MinimumContentsScale();
411 DCHECK_GT(min_contents_scale
, 0.f
);
412 float min_page_scale
= layer_tree_impl()->min_page_scale_factor();
413 DCHECK_GT(min_page_scale
, 0.f
);
414 float min_device_scale
= 1.f
;
415 float min_source_scale
=
416 min_contents_scale
/ min_page_scale
/ min_device_scale
;
418 float ideal_page_scale
= page_scale_factor
;
419 float ideal_device_scale
= device_scale_factor
;
420 float ideal_source_scale
=
421 ideal_contents_scale
/ ideal_page_scale
/ ideal_device_scale
;
423 ideal_contents_scale_
= std::max(ideal_contents_scale
, min_contents_scale
);
424 ideal_page_scale_
= ideal_page_scale
;
425 ideal_device_scale_
= ideal_device_scale
;
426 ideal_source_scale_
= std::max(ideal_source_scale
, min_source_scale
);
428 ManageTilings(animating_transform_to_screen
);
430 // The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
431 // There are (usually) several tilings at different scales. However, the
432 // content bounds is the (integer!) space in which quads are generated.
433 // In order to guarantee that we can fill this integer space with any set of
434 // tilings (and then map back to floating point texture coordinates), the
435 // contents scale must be at least as large as the largest of the tilings.
436 float max_contents_scale
= min_contents_scale
;
437 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
438 const PictureLayerTiling
* tiling
= tilings_
->tiling_at(i
);
439 max_contents_scale
= std::max(max_contents_scale
, tiling
->contents_scale());
442 *contents_scale_x
= max_contents_scale
;
443 *contents_scale_y
= max_contents_scale
;
444 *content_bounds
= gfx::ToCeiledSize(
445 gfx::ScaleSize(bounds(), max_contents_scale
, max_contents_scale
));
448 skia::RefPtr
<SkPicture
> PictureLayerImpl::GetPicture() {
449 return pile_
->GetFlattenedPicture();
452 void PictureLayerImpl::SetShouldUseGpuRasterization(
453 bool should_use_gpu_rasterization
) {
454 if (should_use_gpu_rasterization
!= should_use_gpu_rasterization_
) {
455 should_use_gpu_rasterization_
= should_use_gpu_rasterization
;
458 should_use_gpu_rasterization_
= should_use_gpu_rasterization
;
462 scoped_refptr
<Tile
> PictureLayerImpl::CreateTile(PictureLayerTiling
* tiling
,
463 const gfx::Rect
& content_rect
) {
464 if (!pile_
->CanRaster(tiling
->contents_scale(), content_rect
))
465 return scoped_refptr
<Tile
>();
468 if (is_using_lcd_text_
)
469 flags
|= Tile::USE_LCD_TEXT
;
470 if (should_use_gpu_rasterization())
471 flags
|= Tile::USE_GPU_RASTERIZATION
;
472 return layer_tree_impl()->tile_manager()->CreateTile(
476 contents_opaque() ? content_rect
: gfx::Rect(),
477 tiling
->contents_scale(),
479 layer_tree_impl()->source_frame_number(),
483 void PictureLayerImpl::UpdatePile(Tile
* tile
) {
484 tile
->set_picture_pile(pile_
);
487 const Region
* PictureLayerImpl::GetInvalidation() {
488 return &invalidation_
;
491 const PictureLayerTiling
* PictureLayerImpl::GetTwinTiling(
492 const PictureLayerTiling
* tiling
) const {
494 if (!twin_layer_
|| twin_layer_
->should_use_gpu_rasterization() !=
495 should_use_gpu_rasterization())
497 for (size_t i
= 0; i
< twin_layer_
->tilings_
->num_tilings(); ++i
)
498 if (twin_layer_
->tilings_
->tiling_at(i
)->contents_scale() ==
499 tiling
->contents_scale())
500 return twin_layer_
->tilings_
->tiling_at(i
);
504 size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
505 return layer_tree_impl()->settings().max_tiles_for_interest_area
;
508 float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
509 return layer_tree_impl()->settings().skewport_target_time_in_seconds
;
512 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
513 return layer_tree_impl()
515 .skewport_extrapolation_limit_in_content_pixels
;
518 gfx::Size
PictureLayerImpl::CalculateTileSize(
519 const gfx::Size
& content_bounds
) const {
521 int max_size
= layer_tree_impl()->MaxTextureSize();
523 std::min(max_size
, content_bounds
.width()),
524 std::min(max_size
, content_bounds
.height()));
527 int max_texture_size
=
528 layer_tree_impl()->resource_provider()->max_texture_size();
530 gfx::Size default_tile_size
= layer_tree_impl()->settings().default_tile_size
;
531 default_tile_size
.SetToMin(gfx::Size(max_texture_size
, max_texture_size
));
533 gfx::Size max_untiled_content_size
=
534 layer_tree_impl()->settings().max_untiled_layer_size
;
535 max_untiled_content_size
.SetToMin(
536 gfx::Size(max_texture_size
, max_texture_size
));
538 bool any_dimension_too_large
=
539 content_bounds
.width() > max_untiled_content_size
.width() ||
540 content_bounds
.height() > max_untiled_content_size
.height();
542 bool any_dimension_one_tile
=
543 content_bounds
.width() <= default_tile_size
.width() ||
544 content_bounds
.height() <= default_tile_size
.height();
546 // If long and skinny, tile at the max untiled content size, and clamp
547 // the smaller dimension to the content size, e.g. 1000x12 layer with
548 // 500x500 max untiled size would get 500x12 tiles. Also do this
549 // if the layer is small.
550 if (any_dimension_one_tile
|| !any_dimension_too_large
) {
552 std::min(max_untiled_content_size
.width(), content_bounds
.width());
554 std::min(max_untiled_content_size
.height(), content_bounds
.height());
555 // Round width and height up to the closest multiple of 64, or 56 if
556 // we should avoid power-of-two textures. This helps reduce the number
557 // of different textures sizes to help recycling, and also keeps all
558 // textures multiple-of-eight, which is preferred on some drivers (IMG).
560 layer_tree_impl()->GetRendererCapabilities().avoid_pow2_textures
;
561 int round_up_to
= avoid_pow2
? 56 : 64;
562 width
= RoundUp(width
, round_up_to
);
563 height
= RoundUp(height
, round_up_to
);
564 return gfx::Size(width
, height
);
567 return default_tile_size
;
570 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl
* other
) {
571 DCHECK(!other
->needs_post_commit_initialization_
);
572 DCHECK(other
->tilings_
);
574 UpdateLCDTextStatus(other
->is_using_lcd_text_
);
576 if (!DrawsContent()) {
581 raster_page_scale_
= other
->raster_page_scale_
;
582 raster_device_scale_
= other
->raster_device_scale_
;
583 raster_source_scale_
= other
->raster_source_scale_
;
584 raster_contents_scale_
= other
->raster_contents_scale_
;
585 low_res_raster_contents_scale_
= other
->low_res_raster_contents_scale_
;
587 // Add synthetic invalidations for any recordings that were dropped. As
588 // tiles are updated to point to this new pile, this will force the dropping
589 // of tiles that can no longer be rastered. This is not ideal, but is a
590 // trade-off for memory (use the same pile as much as possible, by switching
591 // during DidBecomeActive) and for time (don't bother checking every tile
592 // during activation to see if the new pile can still raster it).
593 for (int x
= 0; x
< pile_
->num_tiles_x(); ++x
) {
594 for (int y
= 0; y
< pile_
->num_tiles_y(); ++y
) {
595 bool previously_had
= other
->pile_
->HasRecordingAt(x
, y
);
596 bool now_has
= pile_
->HasRecordingAt(x
, y
);
597 if (now_has
|| !previously_had
)
599 gfx::Rect layer_rect
= pile_
->tile_bounds(x
, y
);
600 invalidation_
.Union(layer_rect
);
604 // Union in the other newly exposed regions as invalid.
605 Region difference_region
= Region(gfx::Rect(bounds()));
606 difference_region
.Subtract(gfx::Rect(other
->bounds()));
607 invalidation_
.Union(difference_region
);
609 if (CanHaveTilings()) {
610 // The recycle tree's tiling set is two frames out of date, so it needs to
611 // have both this frame's invalidation and the previous frame's invalidation
612 // (stored on the active layer).
613 Region tiling_invalidation
= other
->invalidation_
;
614 tiling_invalidation
.Union(invalidation_
);
615 tilings_
->SyncTilings(*other
->tilings_
,
618 MinimumContentsScale());
623 SanityCheckTilingState();
626 void PictureLayerImpl::SyncTiling(
627 const PictureLayerTiling
* tiling
) {
628 if (!CanHaveTilingWithScale(tiling
->contents_scale()))
630 tilings_
->AddTiling(tiling
->contents_scale());
632 // If this tree needs update draw properties, then the tiling will
633 // get updated prior to drawing or activation. If this tree does not
634 // need update draw properties, then its transforms are up to date and
635 // we can create tiles for this tiling immediately.
636 if (!layer_tree_impl()->needs_update_draw_properties() &&
637 should_update_tile_priorities_
)
638 UpdateTilePriorities();
641 void PictureLayerImpl::SetIsMask(bool is_mask
) {
642 if (is_mask_
== is_mask
)
646 tilings_
->RemoveAllTiles();
649 ResourceProvider::ResourceId
PictureLayerImpl::ContentsResourceId() const {
650 gfx::Rect
content_rect(content_bounds());
651 float scale
= contents_scale_x();
652 PictureLayerTilingSet::CoverageIterator
iter(
653 tilings_
.get(), scale
, content_rect
, ideal_contents_scale_
);
655 // Mask resource not ready yet.
659 // Masks only supported if they fit on exactly one tile.
660 if (iter
.geometry_rect() != content_rect
)
663 const ManagedTileState::TileVersion
& tile_version
=
664 iter
->GetTileVersionForDrawing();
665 if (!tile_version
.IsReadyToDraw() ||
666 tile_version
.mode() != ManagedTileState::TileVersion::RESOURCE_MODE
)
669 return tile_version
.get_resource_id();
672 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
673 DCHECK(layer_tree_impl()->IsPendingTree());
674 DCHECK(!layer_tree_impl()->needs_update_draw_properties());
675 DCHECK(ideal_contents_scale_
);
676 DCHECK_GT(tilings_
->num_tilings(), 0u);
678 // The goal of this function is to find the minimum set of tiles that need to
679 // be ready to draw in order to activate without flashing content from a
680 // higher res on the active tree to a lower res on the pending tree.
682 gfx::Rect
rect(visible_content_rect());
684 float min_acceptable_scale
=
685 std::min(raster_contents_scale_
, ideal_contents_scale_
);
687 if (PictureLayerImpl
* twin
= twin_layer_
) {
688 float twin_min_acceptable_scale
=
689 std::min(twin
->ideal_contents_scale_
, twin
->raster_contents_scale_
);
690 // Ignore 0 scale in case CalculateContentsScale() has never been
691 // called for active twin.
692 if (twin_min_acceptable_scale
!= 0.0f
) {
693 min_acceptable_scale
=
694 std::min(min_acceptable_scale
, twin_min_acceptable_scale
);
698 PictureLayerTiling
* high_res
= NULL
;
699 PictureLayerTiling
* low_res
= NULL
;
701 // First pass: ready to draw tiles in acceptable but non-ideal tilings are
702 // marked as required for activation so that their textures are not thrown
703 // away; any non-ready tiles are not marked as required.
704 Region missing_region
= rect
;
705 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
706 PictureLayerTiling
* tiling
= tilings_
->tiling_at(i
);
707 DCHECK(tiling
->has_ever_been_updated());
709 if (tiling
->resolution() == LOW_RESOLUTION
) {
710 DCHECK(!low_res
) << "There can only be one low res tiling";
713 if (tiling
->contents_scale() < min_acceptable_scale
)
715 if (tiling
->resolution() == HIGH_RESOLUTION
) {
716 DCHECK(!high_res
) << "There can only be one high res tiling";
720 for (PictureLayerTiling::CoverageIterator
iter(tiling
,
725 if (!*iter
|| !iter
->IsReadyToDraw())
728 missing_region
.Subtract(iter
.geometry_rect());
729 iter
->MarkRequiredForActivation();
732 DCHECK(high_res
) << "There must be one high res tiling";
734 // If these pointers are null (because no twin, no matching tiling, or the
735 // simpification just below), then high res tiles will be required to fill any
736 // holes left by the first pass above. If the pointers are valid, then this
737 // layer is allowed to skip any tiles that are not ready on its twin.
738 const PictureLayerTiling
* twin_high_res
= NULL
;
739 const PictureLayerTiling
* twin_low_res
= NULL
;
741 // As a simplification, only allow activating to skip twin tiles that the
742 // active layer is also missing when both this layer and its twin have 2
743 // tilings (high and low). This avoids having to iterate/track coverage of
744 // non-ideal tilings during the last draw call on the active layer.
745 if (high_res
&& low_res
&& tilings_
->num_tilings() == 2 &&
746 twin_layer_
&& twin_layer_
->tilings_
->num_tilings() == 2) {
747 twin_low_res
= GetTwinTiling(low_res
);
749 twin_high_res
= GetTwinTiling(high_res
);
751 // If this layer and its twin have different transforms, then don't compare
752 // them and only allow activating to high res tiles, since tiles on each layer
753 // will be in different places on screen.
754 if (!twin_high_res
|| !twin_low_res
||
755 twin_layer_
->layer_tree_impl()->RequiresHighResToDraw() ||
756 draw_properties().screen_space_transform
!=
757 twin_layer_
->draw_properties().screen_space_transform
) {
758 twin_high_res
= NULL
;
762 // As a second pass, mark as required any visible high res tiles not filled in
763 // by acceptable non-ideal tiles from the first pass.
764 if (MarkVisibleTilesAsRequired(
765 high_res
, twin_high_res
, contents_scale_x(), rect
, missing_region
)) {
766 // As an optional third pass, if a high res tile was skipped because its
767 // twin was also missing, then fall back to mark low res tiles as required
768 // in case the active twin is substituting those for missing high res
770 MarkVisibleTilesAsRequired(
771 low_res
, twin_low_res
, contents_scale_x(), rect
, missing_region
);
775 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
776 PictureLayerTiling
* tiling
,
777 const PictureLayerTiling
* optional_twin_tiling
,
778 float contents_scale
,
779 const gfx::Rect
& rect
,
780 const Region
& missing_region
) const {
781 bool twin_had_missing_tile
= false;
782 for (PictureLayerTiling::CoverageIterator
iter(tiling
,
788 // A null tile (i.e. missing recording) can just be skipped.
792 // If the missing region doesn't cover it, this tile is fully
793 // covered by acceptable tiles at other scales.
794 if (!missing_region
.Intersects(iter
.geometry_rect()))
797 // If the twin tile doesn't exist (i.e. missing recording or so far away
798 // that it is outside the visible tile rect) or this tile is shared between
799 // with the twin, then this tile isn't required to prevent flashing.
800 if (optional_twin_tiling
) {
801 Tile
* twin_tile
= optional_twin_tiling
->TileAt(iter
.i(), iter
.j());
802 if (!twin_tile
|| twin_tile
== tile
) {
803 twin_had_missing_tile
= true;
808 tile
->MarkRequiredForActivation();
810 return twin_had_missing_tile
;
813 void PictureLayerImpl::DoPostCommitInitialization() {
814 DCHECK(needs_post_commit_initialization_
);
815 DCHECK(layer_tree_impl()->IsPendingTree());
818 tilings_
.reset(new PictureLayerTilingSet(this, bounds()));
820 DCHECK(!twin_layer_
);
821 twin_layer_
= static_cast<PictureLayerImpl
*>(
822 layer_tree_impl()->FindActiveTreeLayerById(id()));
824 DCHECK(!twin_layer_
->twin_layer_
);
825 twin_layer_
->twin_layer_
= this;
826 // If the twin has never been pushed to, do not sync from it.
827 // This can happen if this function is called during activation.
828 if (!twin_layer_
->needs_post_commit_initialization_
)
829 SyncFromActiveLayer(twin_layer_
);
832 needs_post_commit_initialization_
= false;
835 PictureLayerTiling
* PictureLayerImpl::AddTiling(float contents_scale
) {
836 DCHECK(CanHaveTilingWithScale(contents_scale
)) <<
837 "contents_scale: " << contents_scale
;
839 PictureLayerTiling
* tiling
= tilings_
->AddTiling(contents_scale
);
841 const Region
& recorded
= pile_
->recorded_region();
842 DCHECK(!recorded
.IsEmpty());
844 if (twin_layer_
&& twin_layer_
->should_use_gpu_rasterization() ==
845 should_use_gpu_rasterization())
846 twin_layer_
->SyncTiling(tiling
);
851 void PictureLayerImpl::RemoveTiling(float contents_scale
) {
852 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
853 PictureLayerTiling
* tiling
= tilings_
->tiling_at(i
);
854 if (tiling
->contents_scale() == contents_scale
) {
855 tilings_
->Remove(tiling
);
859 if (tilings_
->num_tilings() == 0)
861 SanityCheckTilingState();
864 void PictureLayerImpl::RemoveAllTilings() {
865 tilings_
->RemoveAllTilings();
866 // If there are no tilings, then raster scales are no longer meaningful.
872 inline float PositiveRatio(float float1
, float float2
) {
873 DCHECK_GT(float1
, 0);
874 DCHECK_GT(float2
, 0);
875 return float1
> float2
? float1
/ float2
: float2
/ float1
;
880 void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen
) {
881 DCHECK(ideal_contents_scale_
);
882 DCHECK(ideal_page_scale_
);
883 DCHECK(ideal_device_scale_
);
884 DCHECK(ideal_source_scale_
);
885 DCHECK(CanHaveTilings());
886 DCHECK(!needs_post_commit_initialization_
);
888 bool change_target_tiling
=
889 raster_page_scale_
== 0.f
||
890 raster_device_scale_
== 0.f
||
891 raster_source_scale_
== 0.f
||
892 raster_contents_scale_
== 0.f
||
893 low_res_raster_contents_scale_
== 0.f
||
894 ShouldAdjustRasterScale(animating_transform_to_screen
);
896 if (tilings_
->num_tilings() == 0) {
897 DCHECK(change_target_tiling
)
898 << "A layer with no tilings shouldn't have valid raster scales";
901 // Store the value for the next time ShouldAdjustRasterScale is called.
902 raster_source_scale_was_animating_
= animating_transform_to_screen
;
904 if (!change_target_tiling
)
907 if (!layer_tree_impl()->device_viewport_valid_for_tile_management())
910 RecalculateRasterScales(animating_transform_to_screen
);
912 PictureLayerTiling
* high_res
= NULL
;
913 PictureLayerTiling
* low_res
= NULL
;
915 PictureLayerTiling
* previous_low_res
= NULL
;
916 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
917 PictureLayerTiling
* tiling
= tilings_
->tiling_at(i
);
918 if (tiling
->contents_scale() == raster_contents_scale_
)
920 if (tiling
->contents_scale() == low_res_raster_contents_scale_
)
922 if (tiling
->resolution() == LOW_RESOLUTION
)
923 previous_low_res
= tiling
;
925 // Reset all tilings to non-ideal until the end of this function.
926 tiling
->set_resolution(NON_IDEAL_RESOLUTION
);
930 high_res
= AddTiling(raster_contents_scale_
);
931 if (raster_contents_scale_
== low_res_raster_contents_scale_
)
935 // Only create new low res tilings when the transform is static. This
936 // prevents wastefully creating a paired low res tiling for every new high res
937 // tiling during a pinch or a CSS animation.
938 bool is_pinching
= layer_tree_impl()->PinchGestureActive();
939 if (ShouldHaveLowResTiling() && !is_pinching
&&
940 !animating_transform_to_screen
&&
941 !low_res
&& low_res
!= high_res
)
942 low_res
= AddTiling(low_res_raster_contents_scale_
);
944 // Set low-res if we have one.
946 low_res
= previous_low_res
;
947 if (low_res
&& low_res
!= high_res
)
948 low_res
->set_resolution(LOW_RESOLUTION
);
950 // Make sure we always have one high-res (even if high == low).
951 high_res
->set_resolution(HIGH_RESOLUTION
);
953 SanityCheckTilingState();
956 bool PictureLayerImpl::ShouldAdjustRasterScale(
957 bool animating_transform_to_screen
) const {
958 // TODO(danakj): Adjust raster source scale closer to ideal source scale at
959 // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
960 // tree. This will allow CSS scale changes to get re-rastered at an
963 if (raster_source_scale_was_animating_
&& !animating_transform_to_screen
)
966 bool is_pinching
= layer_tree_impl()->PinchGestureActive();
967 if (is_pinching
&& raster_page_scale_
) {
968 // We change our raster scale when it is:
969 // - Higher than ideal (need a lower-res tiling available)
970 // - Too far from ideal (need a higher-res tiling available)
971 float ratio
= ideal_page_scale_
/ raster_page_scale_
;
972 if (raster_page_scale_
> ideal_page_scale_
||
973 ratio
> kMaxScaleRatioDuringPinch
)
978 // When not pinching, match the ideal page scale factor.
979 if (raster_page_scale_
!= ideal_page_scale_
)
983 // Always match the ideal device scale factor.
984 if (raster_device_scale_
!= ideal_device_scale_
)
990 float PictureLayerImpl::SnappedContentsScale(float scale
) {
991 // If a tiling exists within the max snapping ratio, snap to its scale.
992 float snapped_contents_scale
= scale
;
993 float snapped_ratio
= kSnapToExistingTilingRatio
;
994 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
995 float tiling_contents_scale
= tilings_
->tiling_at(i
)->contents_scale();
996 float ratio
= PositiveRatio(tiling_contents_scale
, scale
);
997 if (ratio
< snapped_ratio
) {
998 snapped_contents_scale
= tiling_contents_scale
;
999 snapped_ratio
= ratio
;
1002 return snapped_contents_scale
;
1005 void PictureLayerImpl::RecalculateRasterScales(
1006 bool animating_transform_to_screen
) {
1007 raster_device_scale_
= ideal_device_scale_
;
1008 raster_source_scale_
= ideal_source_scale_
;
1010 bool is_pinching
= layer_tree_impl()->PinchGestureActive();
1011 if (!is_pinching
|| raster_contents_scale_
== 0.f
) {
1012 // When not pinching or when we have no previous scale, we use ideal scale:
1013 raster_page_scale_
= ideal_page_scale_
;
1014 raster_contents_scale_
= ideal_contents_scale_
;
1016 // See ShouldAdjustRasterScale:
1017 // - When zooming out, preemptively create new tiling at lower resolution.
1018 // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
1019 bool zooming_out
= raster_page_scale_
> ideal_page_scale_
;
1020 float desired_contents_scale
=
1021 zooming_out
? raster_contents_scale_
/ kMaxScaleRatioDuringPinch
1022 : raster_contents_scale_
* kMaxScaleRatioDuringPinch
;
1023 raster_contents_scale_
= SnappedContentsScale(desired_contents_scale
);
1024 raster_page_scale_
= raster_contents_scale_
/ raster_device_scale_
;
1027 raster_contents_scale_
=
1028 std::max(raster_contents_scale_
, MinimumContentsScale());
1030 // Don't allow animating CSS scales to drop below 1. This is needed because
1031 // changes in raster source scale aren't handled. See the comment in
1032 // ShouldAdjustRasterScale.
1033 if (animating_transform_to_screen
) {
1034 raster_contents_scale_
= std::max(
1035 raster_contents_scale_
, 1.f
* ideal_page_scale_
* ideal_device_scale_
);
1038 // If this layer would only create one tile at this content scale,
1039 // don't create a low res tiling.
1040 gfx::Size content_bounds
=
1041 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_
));
1042 gfx::Size tile_size
= CalculateTileSize(content_bounds
);
1043 if (tile_size
.width() >= content_bounds
.width() &&
1044 tile_size
.height() >= content_bounds
.height()) {
1045 low_res_raster_contents_scale_
= raster_contents_scale_
;
1049 float low_res_factor
=
1050 layer_tree_impl()->settings().low_res_contents_scale_factor
;
1051 low_res_raster_contents_scale_
= std::max(
1052 raster_contents_scale_
* low_res_factor
,
1053 MinimumContentsScale());
1056 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
1057 std::vector
<PictureLayerTiling
*> used_tilings
) {
1058 DCHECK(layer_tree_impl()->IsActiveTree());
1059 if (tilings_
->num_tilings() == 0)
1062 float min_acceptable_high_res_scale
= std::min(
1063 raster_contents_scale_
, ideal_contents_scale_
);
1064 float max_acceptable_high_res_scale
= std::max(
1065 raster_contents_scale_
, ideal_contents_scale_
);
1067 PictureLayerImpl
* twin
= twin_layer_
;
1069 min_acceptable_high_res_scale
= std::min(
1070 min_acceptable_high_res_scale
,
1071 std::min(twin
->raster_contents_scale_
, twin
->ideal_contents_scale_
));
1072 max_acceptable_high_res_scale
= std::max(
1073 max_acceptable_high_res_scale
,
1074 std::max(twin
->raster_contents_scale_
, twin
->ideal_contents_scale_
));
1077 std::vector
<PictureLayerTiling
*> to_remove
;
1078 for (size_t i
= 0; i
< tilings_
->num_tilings(); ++i
) {
1079 PictureLayerTiling
* tiling
= tilings_
->tiling_at(i
);
1081 // Keep multiple high resolution tilings even if not used to help
1082 // activate earlier at non-ideal resolutions.
1083 if (tiling
->contents_scale() >= min_acceptable_high_res_scale
&&
1084 tiling
->contents_scale() <= max_acceptable_high_res_scale
)
1087 // Keep low resolution tilings, if the layer should have them.
1088 if (tiling
->resolution() == LOW_RESOLUTION
&& ShouldHaveLowResTiling())
1091 // Don't remove tilings that are being used (and thus would cause a flash.)
1092 if (std::find(used_tilings
.begin(), used_tilings
.end(), tiling
) !=
1096 to_remove
.push_back(tiling
);
1099 for (size_t i
= 0; i
< to_remove
.size(); ++i
) {
1100 const PictureLayerTiling
* twin_tiling
= GetTwinTiling(to_remove
[i
]);
1101 // Only remove tilings from the twin layer if they have
1102 // NON_IDEAL_RESOLUTION.
1103 if (twin_tiling
&& twin_tiling
->resolution() == NON_IDEAL_RESOLUTION
)
1104 twin
->RemoveTiling(to_remove
[i
]->contents_scale());
1105 tilings_
->Remove(to_remove
[i
]);
1107 DCHECK_GT(tilings_
->num_tilings(), 0u);
1109 SanityCheckTilingState();
1112 float PictureLayerImpl::MinimumContentsScale() const {
1113 float setting_min
= layer_tree_impl()->settings().minimum_contents_scale
;
1115 // If the contents scale is less than 1 / width (also for height),
1116 // then it will end up having less than one pixel of content in that
1117 // dimension. Bump the minimum contents scale up in this case to prevent
1118 // this from happening.
1119 int min_dimension
= std::min(bounds().width(), bounds().height());
1123 return std::max(1.f
/ min_dimension
, setting_min
);
1126 void PictureLayerImpl::UpdateLCDTextStatus(bool new_status
) {
1127 // Once this layer is not using lcd text, don't switch back.
1128 if (!is_using_lcd_text_
)
1131 if (is_using_lcd_text_
== new_status
)
1134 is_using_lcd_text_
= new_status
;
1135 tilings_
->SetCanUseLCDText(is_using_lcd_text_
);
1138 void PictureLayerImpl::ResetRasterScale() {
1139 raster_page_scale_
= 0.f
;
1140 raster_device_scale_
= 0.f
;
1141 raster_source_scale_
= 0.f
;
1142 raster_contents_scale_
= 0.f
;
1143 low_res_raster_contents_scale_
= 0.f
;
1145 // When raster scales aren't valid, don't update tile priorities until
1146 // this layer has been updated via UpdateDrawProperties.
1147 should_update_tile_priorities_
= false;
1150 bool PictureLayerImpl::CanHaveTilings() const {
1151 if (!DrawsContent())
1153 if (pile_
->recorded_region().IsEmpty())
1158 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale
) const {
1159 if (!CanHaveTilings())
1161 if (contents_scale
< MinimumContentsScale())
1166 void PictureLayerImpl::SanityCheckTilingState() const {
1167 if (!DCHECK_IS_ON())
1170 if (!CanHaveTilings()) {
1171 DCHECK_EQ(0u, tilings_
->num_tilings());
1174 if (tilings_
->num_tilings() == 0)
1177 // MarkVisibleResourcesAsRequired depends on having exactly 1 high res
1178 // tiling to mark its tiles as being required for activation.
1179 DCHECK_EQ(1, tilings_
->NumHighResTilings());
1182 void PictureLayerImpl::GetDebugBorderProperties(
1184 float* width
) const {
1185 *color
= DebugColors::TiledContentLayerBorderColor();
1186 *width
= DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1189 void PictureLayerImpl::AsValueInto(base::DictionaryValue
* state
) const {
1190 const_cast<PictureLayerImpl
*>(this)->DoPostCommitInitializationIfNeeded();
1191 LayerImpl::AsValueInto(state
);
1192 state
->SetDouble("ideal_contents_scale", ideal_contents_scale_
);
1193 state
->SetDouble("geometry_contents_scale", contents_scale_x());
1194 state
->Set("tilings", tilings_
->AsValue().release());
1195 state
->Set("pictures", pile_
->AsValue().release());
1196 state
->Set("invalidation", invalidation_
.AsValue().release());
1198 Region
unrecorded_region(gfx::Rect(pile_
->size()));
1199 unrecorded_region
.Subtract(pile_
->recorded_region());
1200 if (!unrecorded_region
.IsEmpty())
1201 state
->Set("unrecorded_region", unrecorded_region
.AsValue().release());
1203 scoped_ptr
<base::ListValue
> coverage_tiles(new base::ListValue
);
1204 for (PictureLayerTilingSet::CoverageIterator
iter(tilings_
.get(),
1206 gfx::Rect(content_bounds()),
1207 ideal_contents_scale_
);
1210 scoped_ptr
<base::DictionaryValue
> tile_data(new base::DictionaryValue
);
1211 tile_data
->Set("geometry_rect",
1212 MathUtil::AsValue(iter
.geometry_rect()).release());
1214 tile_data
->Set("tile", TracedValue::CreateIDRef(*iter
).release());
1216 coverage_tiles
->Append(tile_data
.release());
1218 state
->Set("coverage_tiles", coverage_tiles
.release());
1219 state
->SetBoolean("is_using_lcd_text", is_using_lcd_text_
);
1222 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1223 const_cast<PictureLayerImpl
*>(this)->DoPostCommitInitializationIfNeeded();
1224 return tilings_
->GPUMemoryUsageInBytes();
1227 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl
* benchmark
) {
1228 benchmark
->RunOnLayer(this);