Undo scroll snap on to_parent at the start of new frame.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_common.cc
bloba09e57724f1f2a38d2a759724426f9f79d76d596
1 // Copyright 2011 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/trees/layer_tree_host_common.h"
7 #include <algorithm>
9 #include "base/trace_event/trace_event.h"
10 #include "cc/base/math_util.h"
11 #include "cc/layers/heads_up_display_layer_impl.h"
12 #include "cc/layers/layer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/layers/layer_iterator.h"
15 #include "cc/layers/render_surface_draw_properties.h"
16 #include "cc/layers/render_surface_impl.h"
17 #include "cc/trees/draw_property_utils.h"
18 #include "cc/trees/layer_tree_host.h"
19 #include "cc/trees/layer_tree_impl.h"
20 #include "ui/gfx/geometry/rect_conversions.h"
21 #include "ui/gfx/geometry/vector2d_conversions.h"
22 #include "ui/gfx/transform.h"
23 #include "ui/gfx/transform_util.h"
25 namespace cc {
27 LayerTreeHostCommon::CalcDrawPropsMainInputs::CalcDrawPropsMainInputs(
28 Layer* root_layer,
29 const gfx::Size& device_viewport_size,
30 const gfx::Transform& device_transform,
31 float device_scale_factor,
32 float page_scale_factor,
33 const Layer* page_scale_layer,
34 const Layer* inner_viewport_scroll_layer,
35 const Layer* outer_viewport_scroll_layer)
36 : root_layer(root_layer),
37 device_viewport_size(device_viewport_size),
38 device_transform(device_transform),
39 device_scale_factor(device_scale_factor),
40 page_scale_factor(page_scale_factor),
41 page_scale_layer(page_scale_layer),
42 inner_viewport_scroll_layer(inner_viewport_scroll_layer),
43 outer_viewport_scroll_layer(outer_viewport_scroll_layer) {}
45 LayerTreeHostCommon::CalcDrawPropsMainInputs::CalcDrawPropsMainInputs(
46 Layer* root_layer,
47 const gfx::Size& device_viewport_size,
48 const gfx::Transform& device_transform)
49 : CalcDrawPropsMainInputs(root_layer,
50 device_viewport_size,
51 device_transform,
52 1.f,
53 1.f,
54 NULL,
55 NULL,
56 NULL) {}
58 LayerTreeHostCommon::CalcDrawPropsMainInputs::CalcDrawPropsMainInputs(
59 Layer* root_layer,
60 const gfx::Size& device_viewport_size)
61 : CalcDrawPropsMainInputs(root_layer,
62 device_viewport_size,
63 gfx::Transform()) {}
65 LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
66 LayerImpl* root_layer,
67 const gfx::Size& device_viewport_size,
68 const gfx::Transform& device_transform,
69 float device_scale_factor,
70 float page_scale_factor,
71 const LayerImpl* page_scale_layer,
72 const LayerImpl* inner_viewport_scroll_layer,
73 const LayerImpl* outer_viewport_scroll_layer,
74 const gfx::Vector2dF& elastic_overscroll,
75 const LayerImpl* elastic_overscroll_application_layer,
76 int max_texture_size,
77 bool can_use_lcd_text,
78 bool layers_always_allowed_lcd_text,
79 bool can_render_to_separate_surface,
80 bool can_adjust_raster_scales,
81 bool verify_property_trees,
82 LayerImplList* render_surface_layer_list,
83 int current_render_surface_layer_list_id,
84 PropertyTrees* property_trees)
85 : root_layer(root_layer),
86 device_viewport_size(device_viewport_size),
87 device_transform(device_transform),
88 device_scale_factor(device_scale_factor),
89 page_scale_factor(page_scale_factor),
90 page_scale_layer(page_scale_layer),
91 inner_viewport_scroll_layer(inner_viewport_scroll_layer),
92 outer_viewport_scroll_layer(outer_viewport_scroll_layer),
93 elastic_overscroll(elastic_overscroll),
94 elastic_overscroll_application_layer(
95 elastic_overscroll_application_layer),
96 max_texture_size(max_texture_size),
97 can_use_lcd_text(can_use_lcd_text),
98 layers_always_allowed_lcd_text(layers_always_allowed_lcd_text),
99 can_render_to_separate_surface(can_render_to_separate_surface),
100 can_adjust_raster_scales(can_adjust_raster_scales),
101 verify_property_trees(verify_property_trees),
102 render_surface_layer_list(render_surface_layer_list),
103 current_render_surface_layer_list_id(
104 current_render_surface_layer_list_id),
105 property_trees(property_trees) {}
107 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
108 CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer,
109 const gfx::Size& device_viewport_size,
110 const gfx::Transform& device_transform,
111 LayerImplList* render_surface_layer_list)
112 : CalcDrawPropsImplInputs(root_layer,
113 device_viewport_size,
114 device_transform,
115 1.f,
116 1.f,
117 NULL,
118 NULL,
119 NULL,
120 gfx::Vector2dF(),
121 NULL,
122 std::numeric_limits<int>::max() / 2,
123 false,
124 false,
125 true,
126 false,
127 true,
128 render_surface_layer_list,
130 GetPropertyTrees(root_layer)) {
131 DCHECK(root_layer);
132 DCHECK(render_surface_layer_list);
135 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
136 CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer,
137 const gfx::Size& device_viewport_size,
138 LayerImplList* render_surface_layer_list)
139 : CalcDrawPropsImplInputsForTesting(root_layer,
140 device_viewport_size,
141 gfx::Transform(),
142 render_surface_layer_list) {}
144 ScrollAndScaleSet::ScrollAndScaleSet()
145 : page_scale_delta(1.f), top_controls_delta(0.f) {
148 ScrollAndScaleSet::~ScrollAndScaleSet() {}
150 static gfx::Vector2dF GetEffectiveScrollDelta(LayerImpl* layer) {
151 // Layer's scroll offset can have an integer part and fractional part.
152 // Due to Blink's limitation, it only counter-scrolls the position-fixed
153 // layer using the integer part of Layer's scroll offset.
154 // CC scrolls the layer using the full scroll offset, so we have to
155 // add the ScrollCompensationAdjustment (fractional part of the scroll
156 // offset) to the effective scroll delta which is used to counter-scroll
157 // the position-fixed layer.
158 gfx::Vector2dF scroll_delta =
159 layer->ScrollDelta() + layer->ScrollCompensationAdjustment();
160 // The scroll parent's scroll delta is the amount we've scrolled on the
161 // compositor thread since the commit for this layer tree's source frame.
162 // we last reported to the main thread. I.e., it's the discrepancy between
163 // a scroll parent's scroll delta and offset, so we must add it here.
164 if (layer->scroll_parent())
165 scroll_delta += layer->scroll_parent()->ScrollDelta() +
166 layer->ScrollCompensationAdjustment();
167 return scroll_delta;
170 static gfx::ScrollOffset GetEffectiveCurrentScrollOffset(LayerImpl* layer) {
171 gfx::ScrollOffset offset = layer->CurrentScrollOffset();
172 // The scroll parent's total scroll offset (scroll offset + scroll delta)
173 // can't be used because its scroll offset has already been applied to the
174 // scroll children's positions by the main thread layer positioning code.
175 if (layer->scroll_parent())
176 offset += gfx::ScrollOffset(layer->scroll_parent()->ScrollDelta());
177 return offset;
180 inline gfx::Rect CalculateVisibleRectWithCachedLayerRect(
181 const gfx::Rect& target_surface_rect,
182 const gfx::Rect& layer_bound_rect,
183 const gfx::Rect& layer_rect_in_target_space,
184 const gfx::Transform& transform) {
185 if (layer_rect_in_target_space.IsEmpty())
186 return gfx::Rect();
188 // Is this layer fully contained within the target surface?
189 if (target_surface_rect.Contains(layer_rect_in_target_space))
190 return layer_bound_rect;
192 // If the layer doesn't fill up the entire surface, then find the part of
193 // the surface rect where the layer could be visible. This avoids trying to
194 // project surface rect points that are behind the projection point.
195 gfx::Rect minimal_surface_rect = target_surface_rect;
196 minimal_surface_rect.Intersect(layer_rect_in_target_space);
198 if (minimal_surface_rect.IsEmpty())
199 return gfx::Rect();
201 // Project the corners of the target surface rect into the layer space.
202 // This bounding rectangle may be larger than it needs to be (being
203 // axis-aligned), but is a reasonable filter on the space to consider.
204 // Non-invertible transforms will create an empty rect here.
206 gfx::Transform surface_to_layer(gfx::Transform::kSkipInitialization);
207 if (!transform.GetInverse(&surface_to_layer)) {
208 // Because we cannot use the surface bounds to determine what portion of
209 // the layer is visible, we must conservatively assume the full layer is
210 // visible.
211 return layer_bound_rect;
214 gfx::Rect layer_rect = MathUtil::ProjectEnclosingClippedRect(
215 surface_to_layer, minimal_surface_rect);
216 layer_rect.Intersect(layer_bound_rect);
217 return layer_rect;
220 gfx::Rect LayerTreeHostCommon::CalculateVisibleRect(
221 const gfx::Rect& target_surface_rect,
222 const gfx::Rect& layer_bound_rect,
223 const gfx::Transform& transform) {
224 gfx::Rect layer_in_surface_space =
225 MathUtil::MapEnclosingClippedRect(transform, layer_bound_rect);
226 return CalculateVisibleRectWithCachedLayerRect(
227 target_surface_rect, layer_bound_rect, layer_in_surface_space, transform);
230 static const LayerImpl* NextTargetSurface(const LayerImpl* layer) {
231 return layer->parent() ? layer->parent()->render_target() : 0;
234 // Given two layers, this function finds their respective render targets and,
235 // computes a change of basis translation. It does this by accumulating the
236 // translation components of the draw transforms of each target between the
237 // ancestor and descendant. These transforms must be 2D translations, and this
238 // requirement is enforced at every step.
239 static gfx::Vector2dF ComputeChangeOfBasisTranslation(
240 const LayerImpl& ancestor_layer,
241 const LayerImpl& descendant_layer) {
242 DCHECK(descendant_layer.HasAncestor(&ancestor_layer));
243 const LayerImpl* descendant_target = descendant_layer.render_target();
244 DCHECK(descendant_target);
245 const LayerImpl* ancestor_target = ancestor_layer.render_target();
246 DCHECK(ancestor_target);
248 gfx::Vector2dF translation;
249 for (const LayerImpl* target = descendant_target; target != ancestor_target;
250 target = NextTargetSurface(target)) {
251 const gfx::Transform& trans = target->render_surface()->draw_transform();
252 // Ensure that this translation is truly 2d.
253 DCHECK(trans.IsIdentityOrTranslation());
254 DCHECK_EQ(0.f, trans.matrix().get(2, 3));
255 translation += trans.To2dTranslation();
258 return translation;
261 enum TranslateRectDirection {
262 TRANSLATE_RECT_DIRECTION_TO_ANCESTOR,
263 TRANSLATE_RECT_DIRECTION_TO_DESCENDANT
266 static gfx::Rect TranslateRectToTargetSpace(const LayerImpl& ancestor_layer,
267 const LayerImpl& descendant_layer,
268 const gfx::Rect& rect,
269 TranslateRectDirection direction) {
270 gfx::Vector2dF translation =
271 ComputeChangeOfBasisTranslation(ancestor_layer, descendant_layer);
272 if (direction == TRANSLATE_RECT_DIRECTION_TO_DESCENDANT)
273 translation.Scale(-1.f);
274 return gfx::ToEnclosingRect(
275 gfx::RectF(rect.origin() + translation, rect.size()));
278 // Attempts to update the clip rects for the given layer. If the layer has a
279 // clip_parent, it may not inherit its immediate ancestor's clip.
280 static void UpdateClipRectsForClipChild(
281 const LayerImpl* layer,
282 gfx::Rect* clip_rect_in_parent_target_space,
283 bool* subtree_should_be_clipped) {
284 // If the layer has no clip_parent, or the ancestor is the same as its actual
285 // parent, then we don't need special clip rects. Bail now and leave the out
286 // parameters untouched.
287 const LayerImpl* clip_parent = layer->scroll_parent();
289 if (!clip_parent)
290 clip_parent = layer->clip_parent();
292 if (!clip_parent || clip_parent == layer->parent())
293 return;
295 // The root layer is never a clip child.
296 DCHECK(layer->parent());
298 // Grab the cached values.
299 *clip_rect_in_parent_target_space = clip_parent->clip_rect();
300 *subtree_should_be_clipped = clip_parent->is_clipped();
302 // We may have to project the clip rect into our parent's target space. Note,
303 // it must be our parent's target space, not ours. For one, we haven't
304 // computed our transforms, so we couldn't put it in our space yet even if we
305 // wanted to. But more importantly, this matches the expectations of
306 // CalculateDrawPropertiesInternal. If we, say, create a render surface, these
307 // clip rects will want to be in its target space, not ours.
308 if (clip_parent == layer->clip_parent()) {
309 *clip_rect_in_parent_target_space = TranslateRectToTargetSpace(
310 *clip_parent, *layer->parent(), *clip_rect_in_parent_target_space,
311 TRANSLATE_RECT_DIRECTION_TO_DESCENDANT);
312 } else {
313 // If we're being clipped by our scroll parent, we must translate through
314 // our common ancestor. This happens to be our parent, so it is sufficent to
315 // translate from our clip parent's space to the space of its ancestor (our
316 // parent).
317 *clip_rect_in_parent_target_space = TranslateRectToTargetSpace(
318 *layer->parent(), *clip_parent, *clip_rect_in_parent_target_space,
319 TRANSLATE_RECT_DIRECTION_TO_ANCESTOR);
323 // We collect an accumulated drawable content rect per render surface.
324 // Typically, a layer will contribute to only one surface, the surface
325 // associated with its render target. Clip children, however, may affect
326 // several surfaces since there may be several surfaces between the clip child
327 // and its parent.
329 // NB: we accumulate the layer's *clipped* drawable content rect.
330 struct AccumulatedSurfaceState {
331 explicit AccumulatedSurfaceState(LayerImpl* render_target)
332 : render_target(render_target) {}
334 // The accumulated drawable content rect for the surface associated with the
335 // given |render_target|.
336 gfx::Rect drawable_content_rect;
338 // The target owning the surface. (We hang onto the target rather than the
339 // surface so that we can DCHECK that the surface's draw transform is simply
340 // a translation when |render_target| reports that it has no unclipped
341 // descendants).
342 LayerImpl* render_target;
345 template <typename LayerType>
346 static inline bool IsRootLayer(LayerType* layer) {
347 return !layer->parent();
350 void UpdateAccumulatedSurfaceState(
351 LayerImpl* layer,
352 const gfx::Rect& drawable_content_rect,
353 std::vector<AccumulatedSurfaceState>* accumulated_surface_state) {
354 if (IsRootLayer(layer))
355 return;
357 // We will apply our drawable content rect to the accumulated rects for all
358 // surfaces between us and |render_target| (inclusive). This is either our
359 // clip parent's target if we are a clip child, or else simply our parent's
360 // target. We use our parent's target because we're either the owner of a
361 // render surface and we'll want to add our rect to our *surface's* target, or
362 // we're not and our target is the same as our parent's. In both cases, the
363 // parent's target gives us what we want.
364 LayerImpl* render_target = layer->clip_parent()
365 ? layer->clip_parent()->render_target()
366 : layer->parent()->render_target();
368 // If the layer owns a surface, then the content rect is in the wrong space.
369 // Instead, we will use the surface's DrawableContentRect which is in target
370 // space as required.
371 gfx::Rect target_rect = drawable_content_rect;
372 if (layer->render_surface()) {
373 target_rect =
374 gfx::ToEnclosedRect(layer->render_surface()->DrawableContentRect());
377 if (render_target->is_clipped()) {
378 gfx::Rect clip_rect = render_target->clip_rect();
379 // If the layer has a clip parent, the clip rect may be in the wrong space,
380 // so we'll need to transform it before it is applied.
381 if (layer->clip_parent()) {
382 clip_rect =
383 TranslateRectToTargetSpace(*layer->clip_parent(), *layer, clip_rect,
384 TRANSLATE_RECT_DIRECTION_TO_DESCENDANT);
386 target_rect.Intersect(clip_rect);
389 // We must have at least one entry in the vector for the root.
390 DCHECK_LT(0ul, accumulated_surface_state->size());
392 typedef std::vector<AccumulatedSurfaceState> AccumulatedSurfaceStateVector;
393 typedef AccumulatedSurfaceStateVector::reverse_iterator
394 AccumulatedSurfaceStateIterator;
395 AccumulatedSurfaceStateIterator current_state =
396 accumulated_surface_state->rbegin();
398 // Add this rect to the accumulated content rect for all surfaces until we
399 // reach the target surface.
400 bool found_render_target = false;
401 for (; current_state != accumulated_surface_state->rend(); ++current_state) {
402 current_state->drawable_content_rect.Union(target_rect);
404 // If we've reached |render_target| our work is done and we can bail.
405 if (current_state->render_target == render_target) {
406 found_render_target = true;
407 break;
410 // Transform rect from the current target's space to the next.
411 LayerImpl* current_target = current_state->render_target;
412 DCHECK(current_target->render_surface());
413 const gfx::Transform& current_draw_transform =
414 current_target->render_surface()->draw_transform();
416 // If we have unclipped descendants, the draw transform is a translation.
417 DCHECK_IMPLIES(current_target->num_unclipped_descendants(),
418 current_draw_transform.IsIdentityOrTranslation());
420 target_rect =
421 MathUtil::MapEnclosingClippedRect(current_draw_transform, target_rect);
424 // It is an error to not reach |render_target|. If this happens, it means that
425 // either the clip parent is not an ancestor of the clip child or the surface
426 // state vector is empty, both of which should be impossible.
427 DCHECK(found_render_target);
430 template <typename LayerType>
431 static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) {
432 return layer->Is3dSorted() && layer->parent() &&
433 layer->parent()->Is3dSorted() &&
434 (layer->parent()->sorting_context_id() == layer->sorting_context_id());
437 static bool IsRootLayerOfNewRenderingContext(LayerImpl* layer) {
438 if (layer->parent())
439 return !layer->parent()->Is3dSorted() && layer->Is3dSorted();
441 return layer->Is3dSorted();
444 static bool IsLayerBackFaceVisible(LayerImpl* layer) {
445 // The current W3C spec on CSS transforms says that backface visibility should
446 // be determined differently depending on whether the layer is in a "3d
447 // rendering context" or not. For Chromium code, we can determine whether we
448 // are in a 3d rendering context by checking if the parent preserves 3d.
450 if (LayerIsInExisting3DRenderingContext(layer))
451 return layer->draw_transform().IsBackFaceVisible();
453 // In this case, either the layer establishes a new 3d rendering context, or
454 // is not in a 3d rendering context at all.
455 return layer->transform().IsBackFaceVisible();
458 static bool IsSurfaceBackFaceVisible(LayerImpl* layer,
459 const gfx::Transform& draw_transform) {
460 if (LayerIsInExisting3DRenderingContext(layer))
461 return draw_transform.IsBackFaceVisible();
463 if (IsRootLayerOfNewRenderingContext(layer))
464 return layer->transform().IsBackFaceVisible();
466 // If the render_surface is not part of a new or existing rendering context,
467 // then the layers that contribute to this surface will decide back-face
468 // visibility for themselves.
469 return false;
472 template <typename LayerType>
473 static inline bool LayerClipsSubtree(LayerType* layer) {
474 return layer->masks_to_bounds() || layer->mask_layer();
477 static gfx::Rect CalculateVisibleLayerRect(
478 LayerImpl* layer,
479 const gfx::Rect& clip_rect_of_target_surface_in_target_space,
480 const gfx::Rect& layer_rect_in_target_space) {
481 DCHECK(layer->render_target());
483 // Nothing is visible if the layer bounds are empty.
484 if (!layer->DrawsContent() || layer->bounds().IsEmpty() ||
485 layer->drawable_content_rect().IsEmpty())
486 return gfx::Rect();
488 // Compute visible bounds in target surface space.
489 gfx::Rect visible_rect_in_target_surface_space =
490 layer->drawable_content_rect();
492 if (layer->render_target()->render_surface()->is_clipped()) {
493 // The |layer| L has a target T which owns a surface Ts. The surface Ts
494 // has a target TsT.
496 // In this case the target surface Ts does clip the layer L that contributes
497 // to it. So, we have to convert the clip rect of Ts from the target space
498 // of Ts (that is the space of TsT), to the current render target's space
499 // (that is the space of T). This conversion is done outside this function
500 // so that it can be cached instead of computing it redundantly for every
501 // layer.
502 visible_rect_in_target_surface_space.Intersect(
503 clip_rect_of_target_surface_in_target_space);
506 if (visible_rect_in_target_surface_space.IsEmpty())
507 return gfx::Rect();
509 return CalculateVisibleRectWithCachedLayerRect(
510 visible_rect_in_target_surface_space, gfx::Rect(layer->bounds()),
511 layer_rect_in_target_space, layer->draw_transform());
514 static bool LayerShouldBeSkipped(LayerImpl* layer, bool layer_is_drawn) {
515 // Layers can be skipped if any of these conditions are met.
516 // - is not drawn due to it or one of its ancestors being hidden (or having
517 // no copy requests).
518 // - does not draw content.
519 // - is transparent.
520 // - has empty bounds
521 // - the layer is not double-sided, but its back face is visible.
523 // Some additional conditions need to be computed at a later point after the
524 // recursion is finished.
525 // - the intersection of render_surface content and layer clip_rect is empty
526 // - the visible_layer_rect is empty
528 // Note, if the layer should not have been drawn due to being fully
529 // transparent, we would have skipped the entire subtree and never made it
530 // into this function, so it is safe to omit this check here.
532 if (!layer_is_drawn)
533 return true;
535 if (!layer->DrawsContent() || layer->bounds().IsEmpty())
536 return true;
538 LayerImpl* backface_test_layer = layer;
539 if (layer->use_parent_backface_visibility()) {
540 DCHECK(layer->parent());
541 DCHECK(!layer->parent()->use_parent_backface_visibility());
542 backface_test_layer = layer->parent();
545 // The layer should not be drawn if (1) it is not double-sided and (2) the
546 // back of the layer is known to be facing the screen.
547 if (!backface_test_layer->double_sided() &&
548 IsLayerBackFaceVisible(backface_test_layer))
549 return true;
551 return false;
554 template <typename LayerType>
555 static bool HasInvertibleOrAnimatedTransform(LayerType* layer) {
556 return layer->transform_is_invertible() ||
557 layer->HasPotentiallyRunningTransformAnimation();
560 static inline bool SubtreeShouldBeSkipped(LayerImpl* layer,
561 bool layer_is_drawn) {
562 // If the layer transform is not invertible, it should not be drawn.
563 // TODO(ajuma): Correctly process subtrees with singular transform for the
564 // case where we may animate to a non-singular transform and wish to
565 // pre-raster.
566 if (!HasInvertibleOrAnimatedTransform(layer))
567 return true;
569 // When we need to do a readback/copy of a layer's output, we can not skip
570 // it or any of its ancestors.
571 if (layer->draw_properties().layer_or_descendant_has_copy_request)
572 return false;
574 // We cannot skip the the subtree if a descendant has a wheel or touch handler
575 // or the hit testing code will break (it requires fresh transforms, etc).
576 if (layer->draw_properties().layer_or_descendant_has_input_handler)
577 return false;
579 // If the layer is not drawn, then skip it and its subtree.
580 if (!layer_is_drawn)
581 return true;
583 // If layer is on the pending tree and opacity is being animated then
584 // this subtree can't be skipped as we need to create, prioritize and
585 // include tiles for this layer when deciding if tree can be activated.
586 if (layer->layer_tree_impl()->IsPendingTree() &&
587 layer->HasPotentiallyRunningOpacityAnimation())
588 return false;
590 // If layer has a background filter, don't skip the layer, even it the
591 // opacity is 0.
592 if (!layer->background_filters().IsEmpty())
593 return false;
595 // The opacity of a layer always applies to its children (either implicitly
596 // via a render surface or explicitly if the parent preserves 3D), so the
597 // entire subtree can be skipped if this layer is fully transparent.
598 return !layer->opacity();
601 static inline void SavePaintPropertiesLayer(LayerImpl* layer) {}
603 static bool SubtreeShouldRenderToSeparateSurface(
604 Layer* layer,
605 bool axis_aligned_with_respect_to_parent) {
607 // A layer and its descendants should render onto a new RenderSurfaceImpl if
608 // any of these rules hold:
611 // The root layer owns a render surface, but it never acts as a contributing
612 // surface to another render target. Compositor features that are applied via
613 // a contributing surface can not be applied to the root layer. In order to
614 // use these effects, another child of the root would need to be introduced
615 // in order to act as a contributing surface to the root layer's surface.
616 bool is_root = IsRootLayer(layer);
618 // If the layer uses a mask.
619 if (layer->mask_layer()) {
620 DCHECK(!is_root);
621 return true;
624 // If the layer has a reflection.
625 if (layer->replica_layer()) {
626 DCHECK(!is_root);
627 return true;
630 // If the layer uses a CSS filter.
631 if (!layer->filters().IsEmpty() || !layer->background_filters().IsEmpty()) {
632 DCHECK(!is_root);
633 return true;
636 // If the layer will use a CSS filter. In this case, the animation
637 // will start and add a filter to this layer, so it needs a surface.
638 if (layer->HasPotentiallyRunningFilterAnimation()) {
639 DCHECK(!is_root);
640 return true;
643 int num_descendants_that_draw_content =
644 layer->NumDescendantsThatDrawContent();
646 // If the layer flattens its subtree, but it is treated as a 3D object by its
647 // parent (i.e. parent participates in a 3D rendering context).
648 if (LayerIsInExisting3DRenderingContext(layer) &&
649 layer->should_flatten_transform() &&
650 num_descendants_that_draw_content > 0) {
651 TRACE_EVENT_INSTANT0(
652 "cc",
653 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface flattening",
654 TRACE_EVENT_SCOPE_THREAD);
655 DCHECK(!is_root);
656 return true;
659 // If the layer has blending.
660 // TODO(rosca): this is temporary, until blending is implemented for other
661 // types of quads than RenderPassDrawQuad. Layers having descendants that draw
662 // content will still create a separate rendering surface.
663 if (!layer->uses_default_blend_mode()) {
664 TRACE_EVENT_INSTANT0(
665 "cc",
666 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface blending",
667 TRACE_EVENT_SCOPE_THREAD);
668 DCHECK(!is_root);
669 return true;
672 // If the layer clips its descendants but it is not axis-aligned with respect
673 // to its parent.
674 bool layer_clips_external_content =
675 LayerClipsSubtree(layer) || layer->HasDelegatedContent();
676 if (layer_clips_external_content && !axis_aligned_with_respect_to_parent &&
677 num_descendants_that_draw_content > 0) {
678 TRACE_EVENT_INSTANT0(
679 "cc",
680 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface clipping",
681 TRACE_EVENT_SCOPE_THREAD);
682 DCHECK(!is_root);
683 return true;
686 // If the layer has some translucency and does not have a preserves-3d
687 // transform style. This condition only needs a render surface if two or more
688 // layers in the subtree overlap. But checking layer overlaps is unnecessarily
689 // costly so instead we conservatively create a surface whenever at least two
690 // layers draw content for this subtree.
691 bool at_least_two_layers_in_subtree_draw_content =
692 num_descendants_that_draw_content > 0 &&
693 (layer->DrawsContent() || num_descendants_that_draw_content > 1);
695 if (layer->opacity() != 1.f && layer->should_flatten_transform() &&
696 at_least_two_layers_in_subtree_draw_content) {
697 TRACE_EVENT_INSTANT0(
698 "cc",
699 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface opacity",
700 TRACE_EVENT_SCOPE_THREAD);
701 DCHECK(!is_root);
702 return true;
705 // The root layer should always have a render_surface.
706 if (is_root)
707 return true;
710 // These are allowed on the root surface, as they don't require the surface to
711 // be used as a contributing surface in order to apply correctly.
714 // If the layer has isolation.
715 // TODO(rosca): to be optimized - create separate rendering surface only when
716 // the blending descendants might have access to the content behind this layer
717 // (layer has transparent background or descendants overflow).
718 // https://code.google.com/p/chromium/issues/detail?id=301738
719 if (layer->is_root_for_isolated_group()) {
720 TRACE_EVENT_INSTANT0(
721 "cc",
722 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface isolation",
723 TRACE_EVENT_SCOPE_THREAD);
724 return true;
727 // If we force it.
728 if (layer->force_render_surface())
729 return true;
731 // If we'll make a copy of the layer's contents.
732 if (layer->HasCopyRequest())
733 return true;
735 return false;
738 // This function returns a translation matrix that can be applied on a vector
739 // that's in the layer's target surface coordinate, while the position offset is
740 // specified in some ancestor layer's coordinate.
741 gfx::Transform ComputeSizeDeltaCompensation(
742 LayerImpl* layer,
743 LayerImpl* container,
744 const gfx::Vector2dF& position_offset) {
745 gfx::Transform result_transform;
747 // To apply a translate in the container's layer space,
748 // the following steps need to be done:
749 // Step 1a. transform from target surface space to the container's target
750 // surface space
751 // Step 1b. transform from container's target surface space to the
752 // container's layer space
753 // Step 2. apply the compensation
754 // Step 3. transform back to target surface space
756 gfx::Transform target_surface_space_to_container_layer_space;
757 // Calculate step 1a
758 LayerImpl* container_target_surface = container->render_target();
759 for (const LayerImpl* current_target_surface = NextTargetSurface(layer);
760 current_target_surface &&
761 current_target_surface != container_target_surface;
762 current_target_surface = NextTargetSurface(current_target_surface)) {
763 // Note: Concat is used here to convert the result coordinate space from
764 // current render surface to the next render surface.
765 target_surface_space_to_container_layer_space.ConcatTransform(
766 current_target_surface->render_surface()->draw_transform());
768 // Calculate step 1b
769 gfx::Transform container_layer_space_to_container_target_surface_space =
770 container->draw_transform();
771 gfx::Transform container_target_surface_space_to_container_layer_space;
772 if (container_layer_space_to_container_target_surface_space.GetInverse(
773 &container_target_surface_space_to_container_layer_space)) {
774 // Note: Again, Concat is used to conver the result coordinate space from
775 // the container render surface to the container layer.
776 target_surface_space_to_container_layer_space.ConcatTransform(
777 container_target_surface_space_to_container_layer_space);
780 // Apply step 3
781 gfx::Transform container_layer_space_to_target_surface_space;
782 if (target_surface_space_to_container_layer_space.GetInverse(
783 &container_layer_space_to_target_surface_space)) {
784 result_transform.PreconcatTransform(
785 container_layer_space_to_target_surface_space);
786 } else {
787 // TODO(shawnsingh): A non-invertible matrix could still make meaningful
788 // projection. For example ScaleZ(0) is non-invertible but the layer is
789 // still visible.
790 return gfx::Transform();
793 // Apply step 2
794 result_transform.Translate(position_offset.x(), position_offset.y());
796 // Apply step 1
797 result_transform.PreconcatTransform(
798 target_surface_space_to_container_layer_space);
800 return result_transform;
803 void ApplyPositionAdjustment(LayerImpl* layer,
804 LayerImpl* container,
805 const gfx::Transform& scroll_compensation,
806 gfx::Transform* combined_transform) {
807 if (!layer->position_constraint().is_fixed_position())
808 return;
810 // Special case: this layer is a composited fixed-position layer; we need to
811 // explicitly compensate for all ancestors' nonzero scroll_deltas to keep
812 // this layer fixed correctly.
813 // Note carefully: this is Concat, not Preconcat
814 // (current_scroll_compensation * combined_transform).
815 combined_transform->ConcatTransform(scroll_compensation);
817 // For right-edge or bottom-edge anchored fixed position layers,
818 // the layer should relocate itself if the container changes its size.
819 bool fixed_to_right_edge =
820 layer->position_constraint().is_fixed_to_right_edge();
821 bool fixed_to_bottom_edge =
822 layer->position_constraint().is_fixed_to_bottom_edge();
823 gfx::Vector2dF position_offset = container->FixedContainerSizeDelta();
824 position_offset.set_x(fixed_to_right_edge ? position_offset.x() : 0);
825 position_offset.set_y(fixed_to_bottom_edge ? position_offset.y() : 0);
826 if (position_offset.IsZero())
827 return;
829 // Note: Again, this is Concat. The compensation matrix will be applied on
830 // the vector in target surface space.
831 combined_transform->ConcatTransform(
832 ComputeSizeDeltaCompensation(layer, container, position_offset));
835 gfx::Transform ComputeScrollCompensationForThisLayer(
836 LayerImpl* scrolling_layer,
837 const gfx::Transform& parent_matrix,
838 const gfx::Vector2dF& scroll_delta) {
839 // For every layer that has non-zero scroll_delta, we have to compute a
840 // transform that can undo the scroll_delta translation. In particular, we
841 // want this matrix to premultiply a fixed-position layer's parent_matrix, so
842 // we design this transform in three steps as follows. The steps described
843 // here apply from right-to-left, so Step 1 would be the right-most matrix:
845 // Step 1. transform from target surface space to the exact space where
846 // scroll_delta is actually applied.
847 // -- this is inverse of parent_matrix
848 // Step 2. undo the scroll_delta
849 // -- this is just a translation by scroll_delta.
850 // Step 3. transform back to target surface space.
851 // -- this transform is the parent_matrix
853 // These steps create a matrix that both start and end in target surface
854 // space. So this matrix can pre-multiply any fixed-position layer's
855 // draw_transform to undo the scroll_deltas -- as long as that fixed position
856 // layer is fixed onto the same render_target as this scrolling_layer.
859 gfx::Transform scroll_compensation_for_this_layer = parent_matrix; // Step 3
860 scroll_compensation_for_this_layer.Translate(
861 scroll_delta.x(),
862 scroll_delta.y()); // Step 2
864 gfx::Transform inverse_parent_matrix(gfx::Transform::kSkipInitialization);
865 if (!parent_matrix.GetInverse(&inverse_parent_matrix)) {
866 // TODO(shawnsingh): Either we need to handle uninvertible transforms
867 // here, or DCHECK that the transform is invertible.
869 scroll_compensation_for_this_layer.PreconcatTransform(
870 inverse_parent_matrix); // Step 1
871 return scroll_compensation_for_this_layer;
874 gfx::Transform ComputeScrollCompensationMatrixForChildren(
875 LayerImpl* layer,
876 const gfx::Transform& parent_matrix,
877 const gfx::Transform& current_scroll_compensation_matrix,
878 const gfx::Vector2dF& scroll_delta) {
879 // "Total scroll compensation" is the transform needed to cancel out all
880 // scroll_delta translations that occurred since the nearest container layer,
881 // even if there are render_surfaces in-between.
883 // There are some edge cases to be aware of, that are not explicit in the
884 // code:
885 // - A layer that is both a fixed-position and container should not be its
886 // own container, instead, that means it is fixed to an ancestor, and is a
887 // container for any fixed-position descendants.
888 // - A layer that is a fixed-position container and has a render_surface
889 // should behave the same as a container without a render_surface, the
890 // render_surface is irrelevant in that case.
891 // - A layer that does not have an explicit container is simply fixed to the
892 // viewport. (i.e. the root render_surface.)
893 // - If the fixed-position layer has its own render_surface, then the
894 // render_surface is the one who gets fixed.
896 // This function needs to be called AFTER layers create their own
897 // render_surfaces.
900 // Scroll compensation restarts from identity under two possible conditions:
901 // - the current layer is a container for fixed-position descendants
902 // - the current layer is fixed-position itself, so any fixed-position
903 // descendants are positioned with respect to this layer. Thus, any
904 // fixed position descendants only need to compensate for scrollDeltas
905 // that occur below this layer.
906 bool current_layer_resets_scroll_compensation_for_descendants =
907 layer->IsContainerForFixedPositionLayers() ||
908 layer->position_constraint().is_fixed_position();
910 // Avoid the overheads (including stack allocation and matrix
911 // initialization/copy) if we know that the scroll compensation doesn't need
912 // to be reset or adjusted.
913 if (!current_layer_resets_scroll_compensation_for_descendants &&
914 scroll_delta.IsZero() && !layer->render_surface())
915 return current_scroll_compensation_matrix;
917 // Start as identity matrix.
918 gfx::Transform next_scroll_compensation_matrix;
920 // If this layer does not reset scroll compensation, then it inherits the
921 // existing scroll compensations.
922 if (!current_layer_resets_scroll_compensation_for_descendants)
923 next_scroll_compensation_matrix = current_scroll_compensation_matrix;
925 // If the current layer has a non-zero scroll_delta, then we should compute
926 // its local scroll compensation and accumulate it to the
927 // next_scroll_compensation_matrix.
928 if (!scroll_delta.IsZero()) {
929 gfx::Transform scroll_compensation_for_this_layer =
930 ComputeScrollCompensationForThisLayer(
931 layer, parent_matrix, scroll_delta);
932 next_scroll_compensation_matrix.PreconcatTransform(
933 scroll_compensation_for_this_layer);
936 // If the layer created its own render_surface, we have to adjust
937 // next_scroll_compensation_matrix. The adjustment allows us to continue
938 // using the scroll compensation on the next surface.
939 // Step 1 (right-most in the math): transform from the new surface to the
940 // original ancestor surface
941 // Step 2: apply the scroll compensation
942 // Step 3: transform back to the new surface.
943 if (layer->render_surface() &&
944 !next_scroll_compensation_matrix.IsIdentity()) {
945 gfx::Transform inverse_surface_draw_transform(
946 gfx::Transform::kSkipInitialization);
947 if (!layer->render_surface()->draw_transform().GetInverse(
948 &inverse_surface_draw_transform)) {
949 // TODO(shawnsingh): Either we need to handle uninvertible transforms
950 // here, or DCHECK that the transform is invertible.
952 next_scroll_compensation_matrix =
953 inverse_surface_draw_transform * next_scroll_compensation_matrix *
954 layer->render_surface()->draw_transform();
957 return next_scroll_compensation_matrix;
960 static inline void UpdateLayerScaleDrawProperties(
961 LayerImpl* layer,
962 float maximum_animation_contents_scale,
963 float starting_animation_contents_scale) {
964 layer->draw_properties().maximum_animation_contents_scale =
965 maximum_animation_contents_scale;
966 layer->draw_properties().starting_animation_contents_scale =
967 starting_animation_contents_scale;
970 static inline void CalculateAnimationContentsScale(
971 LayerImpl* layer,
972 bool ancestor_is_animating_scale,
973 float ancestor_maximum_animation_contents_scale,
974 float ancestor_starting_animation_contents_scale,
975 const gfx::Transform& ancestor_transform,
976 const gfx::Transform& combined_transform,
977 bool* combined_is_animating_scale,
978 float* combined_maximum_animation_contents_scale,
979 float* combined_starting_animation_contents_scale) {
980 if (ancestor_is_animating_scale &&
981 ancestor_maximum_animation_contents_scale == 0.f) {
982 // We've already failed to compute a maximum animated scale at an
983 // ancestor, so we'll continue to fail.
984 *combined_maximum_animation_contents_scale = 0.f;
985 *combined_starting_animation_contents_scale = 0.f;
986 *combined_is_animating_scale = true;
987 return;
990 if (!combined_transform.IsScaleOrTranslation()) {
991 // Computing maximum animated scale in the presence of
992 // non-scale/translation transforms isn't supported.
993 *combined_maximum_animation_contents_scale = 0.f;
994 *combined_starting_animation_contents_scale = 0.f;
995 *combined_is_animating_scale = true;
996 return;
999 // We currently only support computing maximum scale for combinations of
1000 // scales and translations. We treat all non-translations as potentially
1001 // affecting scale. Animations that include non-translation/scale components
1002 // will cause the computation of MaximumScale below to fail.
1003 bool layer_is_animating_scale = !layer->HasOnlyTranslationTransforms();
1005 if (!layer_is_animating_scale && !ancestor_is_animating_scale) {
1006 *combined_maximum_animation_contents_scale = 0.f;
1007 *combined_starting_animation_contents_scale = 0.f;
1008 *combined_is_animating_scale = false;
1009 return;
1012 // We don't attempt to accumulate animation scale from multiple nodes,
1013 // because of the risk of significant overestimation. For example, one node
1014 // may be increasing scale from 1 to 10 at the same time as a descendant is
1015 // decreasing scale from 10 to 1. Naively combining these scales would produce
1016 // a scale of 100.
1017 if (layer_is_animating_scale && ancestor_is_animating_scale) {
1018 *combined_maximum_animation_contents_scale = 0.f;
1019 *combined_starting_animation_contents_scale = 0.f;
1020 *combined_is_animating_scale = true;
1021 return;
1024 // At this point, we know either the layer or an ancestor, but not both,
1025 // is animating scale.
1026 *combined_is_animating_scale = true;
1027 if (!layer_is_animating_scale) {
1028 gfx::Vector2dF layer_transform_scales =
1029 MathUtil::ComputeTransform2dScaleComponents(layer->transform(), 0.f);
1030 float max_layer_scale =
1031 std::max(layer_transform_scales.x(), layer_transform_scales.y());
1032 *combined_maximum_animation_contents_scale =
1033 ancestor_maximum_animation_contents_scale * max_layer_scale;
1034 *combined_starting_animation_contents_scale =
1035 ancestor_starting_animation_contents_scale * max_layer_scale;
1036 return;
1039 float layer_maximum_animated_scale = 0.f;
1040 float layer_start_animated_scale = 0.f;
1041 if (!layer->MaximumTargetScale(&layer_maximum_animated_scale)) {
1042 *combined_maximum_animation_contents_scale = 0.f;
1043 return;
1045 if (!layer->AnimationStartScale(&layer_start_animated_scale)) {
1046 *combined_starting_animation_contents_scale = 0.f;
1047 return;
1050 gfx::Vector2dF ancestor_transform_scales =
1051 MathUtil::ComputeTransform2dScaleComponents(ancestor_transform, 0.f);
1052 float max_scale_xy =
1053 std::max(ancestor_transform_scales.x(), ancestor_transform_scales.y());
1054 *combined_maximum_animation_contents_scale =
1055 layer_maximum_animated_scale * max_scale_xy;
1056 *combined_starting_animation_contents_scale =
1057 layer_start_animated_scale * max_scale_xy;
1060 static inline void MarkLayerWithRenderSurfaceLayerListId(
1061 LayerImpl* layer,
1062 int current_render_surface_layer_list_id) {
1063 layer->draw_properties().last_drawn_render_surface_layer_list_id =
1064 current_render_surface_layer_list_id;
1065 layer->set_layer_or_descendant_is_drawn(
1066 !!current_render_surface_layer_list_id);
1069 static inline void MarkMasksWithRenderSurfaceLayerListId(
1070 LayerImpl* layer,
1071 int current_render_surface_layer_list_id) {
1072 if (layer->mask_layer()) {
1073 MarkLayerWithRenderSurfaceLayerListId(layer->mask_layer(),
1074 current_render_surface_layer_list_id);
1076 if (layer->replica_layer() && layer->replica_layer()->mask_layer()) {
1077 MarkLayerWithRenderSurfaceLayerListId(layer->replica_layer()->mask_layer(),
1078 current_render_surface_layer_list_id);
1082 static inline void MarkLayerListWithRenderSurfaceLayerListId(
1083 LayerImplList* layer_list,
1084 int current_render_surface_layer_list_id) {
1085 for (LayerImplList::iterator it = layer_list->begin();
1086 it != layer_list->end(); ++it) {
1087 MarkLayerWithRenderSurfaceLayerListId(*it,
1088 current_render_surface_layer_list_id);
1089 MarkMasksWithRenderSurfaceLayerListId(*it,
1090 current_render_surface_layer_list_id);
1094 static inline void RemoveSurfaceForEarlyExit(
1095 LayerImpl* layer_to_remove,
1096 LayerImplList* render_surface_layer_list) {
1097 DCHECK(layer_to_remove->render_surface());
1098 // Technically, we know that the layer we want to remove should be
1099 // at the back of the render_surface_layer_list. However, we have had
1100 // bugs before that added unnecessary layers here
1101 // (https://bugs.webkit.org/show_bug.cgi?id=74147), but that causes
1102 // things to crash. So here we proactively remove any additional
1103 // layers from the end of the list.
1104 while (render_surface_layer_list->back() != layer_to_remove) {
1105 MarkLayerListWithRenderSurfaceLayerListId(
1106 &render_surface_layer_list->back()->render_surface()->layer_list(), 0);
1107 MarkLayerWithRenderSurfaceLayerListId(render_surface_layer_list->back(), 0);
1109 render_surface_layer_list->back()->ClearRenderSurfaceLayerList();
1110 render_surface_layer_list->pop_back();
1112 DCHECK_EQ(render_surface_layer_list->back(), layer_to_remove);
1113 MarkLayerListWithRenderSurfaceLayerListId(
1114 &layer_to_remove->render_surface()->layer_list(), 0);
1115 MarkLayerWithRenderSurfaceLayerListId(layer_to_remove, 0);
1116 render_surface_layer_list->pop_back();
1117 layer_to_remove->ClearRenderSurfaceLayerList();
1120 struct PreCalculateMetaInformationRecursiveData {
1121 size_t num_unclipped_descendants;
1122 int num_layer_or_descendants_with_copy_request;
1123 int num_layer_or_descendants_with_input_handler;
1125 PreCalculateMetaInformationRecursiveData()
1126 : num_unclipped_descendants(0),
1127 num_layer_or_descendants_with_copy_request(0),
1128 num_layer_or_descendants_with_input_handler(0) {}
1130 void Merge(const PreCalculateMetaInformationRecursiveData& data) {
1131 num_layer_or_descendants_with_copy_request +=
1132 data.num_layer_or_descendants_with_copy_request;
1133 num_layer_or_descendants_with_input_handler +=
1134 data.num_layer_or_descendants_with_input_handler;
1135 num_unclipped_descendants += data.num_unclipped_descendants;
1139 static void ValidateRenderSurface(LayerImpl* layer) {
1140 // This test verifies that there are no cases where a LayerImpl needs
1141 // a render surface, but doesn't have one.
1142 if (layer->render_surface())
1143 return;
1145 DCHECK(layer->filters().IsEmpty()) << "layer: " << layer->id();
1146 DCHECK(layer->background_filters().IsEmpty()) << "layer: " << layer->id();
1147 DCHECK(!layer->mask_layer()) << "layer: " << layer->id();
1148 DCHECK(!layer->replica_layer()) << "layer: " << layer->id();
1149 DCHECK(!IsRootLayer(layer)) << "layer: " << layer->id();
1150 DCHECK(!layer->is_root_for_isolated_group()) << "layer: " << layer->id();
1151 DCHECK(!layer->HasCopyRequest()) << "layer: " << layer->id();
1154 static void ValidateRenderSurface(Layer* layer) {
1157 static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
1158 return layer->layer_tree_host()->needs_meta_info_recomputation();
1161 static void UpdateMetaInformationSequenceNumber(Layer* root_layer) {
1162 root_layer->layer_tree_host()->IncrementMetaInformationSequenceNumber();
1165 static void UpdateMetaInformationSequenceNumber(LayerImpl* root_layer) {
1168 // Recursively walks the layer tree(if needed) to compute any information
1169 // that is needed before doing the main recursion.
1170 static void PreCalculateMetaInformationInternal(
1171 Layer* layer,
1172 PreCalculateMetaInformationRecursiveData* recursive_data) {
1173 ValidateRenderSurface(layer);
1175 if (!IsMetaInformationRecomputationNeeded(layer)) {
1176 DCHECK(IsRootLayer(layer));
1177 return;
1180 layer->set_sorted_for_recursion(false);
1181 layer->set_layer_or_descendant_is_drawn(false);
1182 layer->set_visited(false);
1184 if (!HasInvertibleOrAnimatedTransform(layer)) {
1185 // Layers with singular transforms should not be drawn, the whole subtree
1186 // can be skipped.
1187 return;
1190 if (layer->clip_parent())
1191 recursive_data->num_unclipped_descendants++;
1193 layer->set_num_children_with_scroll_parent(0);
1194 for (size_t i = 0; i < layer->children().size(); ++i) {
1195 Layer* child_layer = layer->child_at(i);
1197 PreCalculateMetaInformationRecursiveData data_for_child;
1198 PreCalculateMetaInformationInternal(child_layer, &data_for_child);
1200 if (child_layer->scroll_parent()) {
1201 layer->set_num_children_with_scroll_parent(
1202 layer->num_children_with_scroll_parent() + 1);
1204 recursive_data->Merge(data_for_child);
1207 if (layer->clip_children()) {
1208 size_t num_clip_children = layer->clip_children()->size();
1209 DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
1210 recursive_data->num_unclipped_descendants -= num_clip_children;
1213 if (layer->HasCopyRequest())
1214 recursive_data->num_layer_or_descendants_with_copy_request++;
1216 if (!layer->touch_event_handler_region().IsEmpty() ||
1217 layer->have_wheel_event_handlers())
1218 recursive_data->num_layer_or_descendants_with_input_handler++;
1220 layer->set_num_unclipped_descendants(
1221 recursive_data->num_unclipped_descendants);
1222 layer->set_num_layer_or_descendant_with_copy_request(
1223 recursive_data->num_layer_or_descendants_with_copy_request);
1225 if (IsRootLayer(layer))
1226 layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false);
1229 static void PreCalculateMetaInformationInternal(
1230 LayerImpl* layer,
1231 PreCalculateMetaInformationRecursiveData* recursive_data) {
1232 ValidateRenderSurface(layer);
1234 layer->set_sorted_for_recursion(false);
1235 layer->draw_properties().has_child_with_a_scroll_parent = false;
1236 layer->set_layer_or_descendant_is_drawn(false);
1237 layer->set_visited(false);
1239 if (!HasInvertibleOrAnimatedTransform(layer)) {
1240 // Layers with singular transforms should not be drawn, the whole subtree
1241 // can be skipped.
1242 return;
1245 if (layer->clip_parent())
1246 recursive_data->num_unclipped_descendants++;
1248 for (size_t i = 0; i < layer->children().size(); ++i) {
1249 LayerImpl* child_layer = layer->child_at(i);
1251 PreCalculateMetaInformationRecursiveData data_for_child;
1252 PreCalculateMetaInformationInternal(child_layer, &data_for_child);
1254 if (child_layer->scroll_parent())
1255 layer->draw_properties().has_child_with_a_scroll_parent = true;
1256 recursive_data->Merge(data_for_child);
1259 if (layer->clip_children()) {
1260 size_t num_clip_children = layer->clip_children()->size();
1261 DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
1262 recursive_data->num_unclipped_descendants -= num_clip_children;
1265 if (layer->HasCopyRequest())
1266 recursive_data->num_layer_or_descendants_with_copy_request++;
1268 if (!layer->touch_event_handler_region().IsEmpty() ||
1269 layer->have_wheel_event_handlers())
1270 recursive_data->num_layer_or_descendants_with_input_handler++;
1272 layer->draw_properties().num_unclipped_descendants =
1273 recursive_data->num_unclipped_descendants;
1274 layer->draw_properties().layer_or_descendant_has_copy_request =
1275 (recursive_data->num_layer_or_descendants_with_copy_request != 0);
1276 layer->draw_properties().layer_or_descendant_has_input_handler =
1277 (recursive_data->num_layer_or_descendants_with_input_handler != 0);
1280 void LayerTreeHostCommon::PreCalculateMetaInformation(Layer* root_layer) {
1281 PreCalculateMetaInformationRecursiveData recursive_data;
1282 PreCalculateMetaInformationInternal(root_layer, &recursive_data);
1285 void LayerTreeHostCommon::PreCalculateMetaInformationForTesting(
1286 LayerImpl* root_layer) {
1287 PreCalculateMetaInformationRecursiveData recursive_data;
1288 PreCalculateMetaInformationInternal(root_layer, &recursive_data);
1291 void LayerTreeHostCommon::PreCalculateMetaInformationForTesting(
1292 Layer* root_layer) {
1293 UpdateMetaInformationSequenceNumber(root_layer);
1294 PreCalculateMetaInformationRecursiveData recursive_data;
1295 PreCalculateMetaInformationInternal(root_layer, &recursive_data);
1298 struct SubtreeGlobals {
1299 int max_texture_size;
1300 float device_scale_factor;
1301 float page_scale_factor;
1302 const LayerImpl* page_scale_layer;
1303 gfx::Vector2dF elastic_overscroll;
1304 const LayerImpl* elastic_overscroll_application_layer;
1305 bool can_adjust_raster_scales;
1306 bool can_render_to_separate_surface;
1307 bool layers_always_allowed_lcd_text;
1310 struct DataForRecursion {
1311 // The accumulated sequence of transforms a layer will use to determine its
1312 // own draw transform.
1313 gfx::Transform parent_matrix;
1315 // The accumulated sequence of transforms a layer will use to determine its
1316 // own screen-space transform.
1317 gfx::Transform full_hierarchy_matrix;
1319 // The transform that removes all scrolling that may have occurred between a
1320 // fixed-position layer and its container, so that the layer actually does
1321 // remain fixed.
1322 gfx::Transform scroll_compensation_matrix;
1324 // The ancestor that would be the container for any fixed-position / sticky
1325 // layers.
1326 LayerImpl* fixed_container;
1328 // This is the normal clip rect that is propagated from parent to child.
1329 gfx::Rect clip_rect_in_target_space;
1331 // When the layer's children want to compute their visible content rect, they
1332 // want to know what their target surface's clip rect will be. BUT - they
1333 // want to know this clip rect represented in their own target space. This
1334 // requires inverse-projecting the surface's clip rect from the surface's
1335 // render target space down to the surface's own space. Instead of computing
1336 // this value redundantly for each child layer, it is computed only once
1337 // while dealing with the parent layer, and then this precomputed value is
1338 // passed down the recursion to the children that actually use it.
1339 gfx::Rect clip_rect_of_target_surface_in_target_space;
1341 // The maximum amount by which this layer will be scaled during the lifetime
1342 // of currently running animations, considering only scales at keyframes not
1343 // including the starting keyframe of each animation.
1344 float maximum_animation_contents_scale;
1346 // The maximum amout by which this layer will be scaled during the lifetime of
1347 // currently running animations, consdering only the starting scale of each
1348 // animation.
1349 float starting_animation_contents_scale;
1351 bool ancestor_is_animating_scale;
1352 bool ancestor_clips_subtree;
1353 bool in_subtree_of_page_scale_layer;
1354 bool subtree_can_use_lcd_text;
1355 bool subtree_is_visible_from_ancestor;
1358 static LayerImpl* GetChildContainingLayer(const LayerImpl& parent,
1359 LayerImpl* layer) {
1360 for (LayerImpl* ancestor = layer; ancestor; ancestor = ancestor->parent()) {
1361 if (ancestor->parent() == &parent)
1362 return ancestor;
1364 NOTREACHED();
1365 return 0;
1368 static void AddScrollParentChain(std::vector<LayerImpl*>* out,
1369 const LayerImpl& parent,
1370 LayerImpl* layer) {
1371 // At a high level, this function walks up the chain of scroll parents
1372 // recursively, and once we reach the end of the chain, we add the child
1373 // of |parent| containing each scroll ancestor as we unwind. The result is
1374 // an ordering of parent's children that ensures that scroll parents are
1375 // visited before their descendants.
1376 // Take for example this layer tree:
1378 // + stacking_context
1379 // + scroll_child (1)
1380 // + scroll_parent_graphics_layer (*)
1381 // | + scroll_parent_scrolling_layer
1382 // | + scroll_parent_scrolling_content_layer (2)
1383 // + scroll_grandparent_graphics_layer (**)
1384 // + scroll_grandparent_scrolling_layer
1385 // + scroll_grandparent_scrolling_content_layer (3)
1387 // The scroll child is (1), its scroll parent is (2) and its scroll
1388 // grandparent is (3). Note, this doesn't mean that (2)'s scroll parent is
1389 // (3), it means that (*)'s scroll parent is (3). We don't want our list to
1390 // look like [ (3), (2), (1) ], even though that does have the ancestor chain
1391 // in the right order. Instead, we want [ (**), (*), (1) ]. That is, only want
1392 // (1)'s siblings in the list, but we want them to appear in such an order
1393 // that the scroll ancestors get visited in the correct order.
1395 // So our first task at this step of the recursion is to determine the layer
1396 // that we will potentionally add to the list. That is, the child of parent
1397 // containing |layer|.
1398 LayerImpl* child = GetChildContainingLayer(parent, layer);
1399 if (child->sorted_for_recursion())
1400 return;
1402 if (LayerImpl* scroll_parent = child->scroll_parent())
1403 AddScrollParentChain(out, parent, scroll_parent);
1405 out->push_back(child);
1406 bool sorted_for_recursion = true;
1407 child->set_sorted_for_recursion(sorted_for_recursion);
1410 static bool SortChildrenForRecursion(std::vector<LayerImpl*>* out,
1411 const LayerImpl& parent) {
1412 out->reserve(parent.children().size());
1413 bool order_changed = false;
1414 for (size_t i = 0; i < parent.children().size(); ++i) {
1415 LayerImpl* current =
1416 LayerTreeHostCommon::get_layer_as_raw_ptr(parent.children(), i);
1418 if (current->sorted_for_recursion()) {
1419 order_changed = true;
1420 continue;
1423 AddScrollParentChain(out, parent, current);
1426 DCHECK_EQ(parent.children().size(), out->size());
1427 return order_changed;
1430 // Recursively walks the layer tree starting at the given node and computes all
1431 // the necessary transformations, clip rects, render surfaces, etc.
1432 static void CalculateDrawPropertiesInternal(
1433 LayerImpl* layer,
1434 const SubtreeGlobals& globals,
1435 const DataForRecursion& data_from_ancestor,
1436 std::vector<AccumulatedSurfaceState>* accumulated_surface_state) {
1437 // This function computes the new matrix transformations recursively for this
1438 // layer and all its descendants. It also computes the appropriate render
1439 // surfaces.
1440 // Some important points to remember:
1442 // 0. Here, transforms are notated in Matrix x Vector order, and in words we
1443 // describe what the transform does from left to right.
1445 // 1. In our terminology, the "layer origin" refers to the top-left corner of
1446 // a layer, and the positive Y-axis points downwards. This interpretation is
1447 // valid because the orthographic projection applied at draw time flips the Y
1448 // axis appropriately.
1450 // 2. The anchor point, when given as a PointF object, is specified in "unit
1451 // layer space", where the bounds of the layer map to [0, 1]. However, as a
1452 // Transform object, the transform to the anchor point is specified in "layer
1453 // space", where the bounds of the layer map to [bounds.width(),
1454 // bounds.height()].
1456 // 3. Definition of various transforms used:
1457 // M[parent] is the parent matrix, with respect to the nearest render
1458 // surface, passed down recursively.
1460 // M[root] is the full hierarchy, with respect to the root, passed down
1461 // recursively.
1463 // Tr[origin] is the translation matrix from the parent's origin to
1464 // this layer's origin.
1466 // Tr[origin2anchor] is the translation from the layer's origin to its
1467 // anchor point
1469 // Tr[origin2center] is the translation from the layer's origin to its
1470 // center
1472 // M[layer] is the layer's matrix (applied at the anchor point)
1474 // S[layer2content] is the ratio of a layer's content_bounds() to its
1475 // Bounds().
1477 // Some composite transforms can help in understanding the sequence of
1478 // transforms:
1479 // composite_layer_transform = Tr[origin2anchor] * M[layer] *
1480 // Tr[origin2anchor].inverse()
1482 // 4. When a layer (or render surface) is drawn, it is drawn into a "target
1483 // render surface". Therefore the draw transform does not necessarily
1484 // transform from screen space to local layer space. Instead, the draw
1485 // transform is the transform between the "target render surface space" and
1486 // local layer space. Note that render surfaces, except for the root, also
1487 // draw themselves into a different target render surface, and so their draw
1488 // transform and origin transforms are also described with respect to the
1489 // target.
1491 // Using these definitions, then:
1493 // The draw transform for the layer is:
1494 // M[draw] = M[parent] * Tr[origin] * composite_layer_transform *
1495 // S[layer2content] = M[parent] * Tr[layer->position() + anchor] *
1496 // M[layer] * Tr[anchor2origin] * S[layer2content]
1498 // Interpreting the math left-to-right, this transforms from the
1499 // layer's render surface to the origin of the layer in content space.
1501 // The screen space transform is:
1502 // M[screenspace] = M[root] * Tr[origin] * composite_layer_transform *
1503 // S[layer2content]
1504 // = M[root] * Tr[layer->position() + anchor] * M[layer]
1505 // * Tr[anchor2origin] * S[layer2content]
1507 // Interpreting the math left-to-right, this transforms from the root
1508 // render surface's content space to the origin of the layer in content
1509 // space.
1511 // The transform hierarchy that is passed on to children (i.e. the child's
1512 // parent_matrix) is:
1513 // M[parent]_for_child = M[parent] * Tr[origin] *
1514 // composite_layer_transform
1515 // = M[parent] * Tr[layer->position() + anchor] *
1516 // M[layer] * Tr[anchor2origin]
1518 // and a similar matrix for the full hierarchy with respect to the
1519 // root.
1521 // Finally, note that the final matrix used by the shader for the layer is P *
1522 // M[draw] * S . This final product is computed in drawTexturedQuad(), where:
1523 // P is the projection matrix
1524 // S is the scale adjustment (to scale up a canonical quad to the
1525 // layer's size)
1527 // When a render surface has a replica layer, that layer's transform is used
1528 // to draw a second copy of the surface. gfx::Transforms named here are
1529 // relative to the surface, unless they specify they are relative to the
1530 // replica layer.
1532 // We will denote a scale by device scale S[deviceScale]
1534 // The render surface draw transform to its target surface origin is:
1535 // M[surfaceDraw] = M[owningLayer->Draw]
1537 // The render surface origin transform to its the root (screen space) origin
1538 // is:
1539 // M[surface2root] = M[owningLayer->screenspace] *
1540 // S[deviceScale].inverse()
1542 // The replica draw transform to its target surface origin is:
1543 // M[replicaDraw] = S[deviceScale] * M[surfaceDraw] *
1544 // Tr[replica->position() + replica->anchor()] * Tr[replica] *
1545 // Tr[origin2anchor].inverse() * S[contents_scale].inverse()
1547 // The replica draw transform to the root (screen space) origin is:
1548 // M[replica2root] = M[surface2root] * Tr[replica->position()] *
1549 // Tr[replica] * Tr[origin2anchor].inverse()
1552 // It makes no sense to have a non-unit page_scale_factor without specifying
1553 // which layer roots the subtree the scale is applied to.
1554 DCHECK(globals.page_scale_layer || (globals.page_scale_factor == 1.f));
1556 CHECK(!layer->visited());
1557 bool visited = true;
1558 layer->set_visited(visited);
1560 DataForRecursion data_for_children;
1561 data_for_children.in_subtree_of_page_scale_layer =
1562 data_from_ancestor.in_subtree_of_page_scale_layer;
1563 data_for_children.subtree_can_use_lcd_text =
1564 data_from_ancestor.subtree_can_use_lcd_text;
1566 // Layers that are marked as hidden will hide themselves and their subtree.
1567 // Exception: Layers with copy requests, whether hidden or not, must be drawn
1568 // anyway. In this case, we will inform their subtree they are visible to get
1569 // the right results.
1570 const bool layer_is_visible =
1571 data_from_ancestor.subtree_is_visible_from_ancestor &&
1572 !layer->hide_layer_and_subtree();
1573 const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
1575 // The root layer cannot skip CalcDrawProperties.
1576 if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
1577 return;
1580 // We need to circumvent the normal recursive flow of information for clip
1581 // children (they don't inherit their direct ancestor's clip information).
1582 // This is unfortunate, and would be unnecessary if we were to formally
1583 // separate the clipping hierarchy from the layer hierarchy.
1584 bool ancestor_clips_subtree = data_from_ancestor.ancestor_clips_subtree;
1585 gfx::Rect ancestor_clip_rect_in_target_space =
1586 data_from_ancestor.clip_rect_in_target_space;
1588 // Update our clipping state. If we have a clip parent we will need to pull
1589 // from the clip state cache rather than using the clip state passed from our
1590 // immediate ancestor.
1591 UpdateClipRectsForClipChild(layer, &ancestor_clip_rect_in_target_space,
1592 &ancestor_clips_subtree);
1594 // As this function proceeds, these are the properties for the current
1595 // layer that actually get computed. To avoid unnecessary copies
1596 // (particularly for matrices), we do computations directly on these values
1597 // when possible.
1598 DrawProperties& layer_draw_properties = layer->draw_properties();
1600 gfx::Rect clip_rect_in_target_space;
1601 bool layer_or_ancestor_clips_descendants = false;
1603 // This value is cached on the stack so that we don't have to inverse-project
1604 // the surface's clip rect redundantly for every layer. This value is the
1605 // same as the target surface's clip rect, except that instead of being
1606 // described in the target surface's target's space, it is described in the
1607 // current render target's space.
1608 gfx::Rect clip_rect_of_target_surface_in_target_space;
1610 float accumulated_draw_opacity = layer->opacity();
1611 if (layer->parent())
1612 accumulated_draw_opacity *= layer->parent()->draw_opacity();
1614 bool animating_transform_to_screen =
1615 layer->HasPotentiallyRunningTransformAnimation();
1616 if (layer->parent()) {
1617 animating_transform_to_screen |=
1618 layer->parent()->screen_space_transform_is_animating();
1620 gfx::Point3F transform_origin = layer->transform_origin();
1621 gfx::ScrollOffset scroll_offset = GetEffectiveCurrentScrollOffset(layer);
1622 gfx::PointF position =
1623 layer->position() - ScrollOffsetToVector2dF(scroll_offset);
1624 gfx::Transform combined_transform = data_from_ancestor.parent_matrix;
1625 if (!layer->transform().IsIdentity()) {
1626 // LT = Tr[origin] * Tr[origin2transformOrigin]
1627 combined_transform.Translate3d(position.x() + transform_origin.x(),
1628 position.y() + transform_origin.y(),
1629 transform_origin.z());
1630 // LT = Tr[origin] * Tr[origin2origin] * M[layer]
1631 combined_transform.PreconcatTransform(layer->transform());
1632 // LT = Tr[origin] * Tr[origin2origin] * M[layer] *
1633 // Tr[transformOrigin2origin]
1634 combined_transform.Translate3d(
1635 -transform_origin.x(), -transform_origin.y(), -transform_origin.z());
1636 } else {
1637 combined_transform.Translate(position.x(), position.y());
1640 gfx::Vector2dF effective_scroll_delta = GetEffectiveScrollDelta(layer);
1641 if (!animating_transform_to_screen && layer->scrollable() &&
1642 combined_transform.IsScaleOrTranslation()) {
1643 // Align the scrollable layer's position to screen space pixels to avoid
1644 // blurriness. To avoid side-effects, do this only if the transform is
1645 // simple.
1646 gfx::Vector2dF previous_translation = combined_transform.To2dTranslation();
1647 combined_transform.RoundTranslationComponents();
1648 gfx::Vector2dF current_translation = combined_transform.To2dTranslation();
1650 // This rounding changes the scroll delta, and so must be included
1651 // in the scroll compensation matrix. The scaling converts from physical
1652 // coordinates to the scroll delta's CSS coordinates (using the parent
1653 // matrix instead of combined transform since scrolling is applied before
1654 // the layer's transform). For example, if we have a total scale factor of
1655 // 3.0, then 1 physical pixel is only 1/3 of a CSS pixel.
1656 gfx::Vector2dF parent_scales = MathUtil::ComputeTransform2dScaleComponents(
1657 data_from_ancestor.parent_matrix, 1.f);
1658 effective_scroll_delta -=
1659 gfx::ScaleVector2d(current_translation - previous_translation,
1660 1.f / parent_scales.x(),
1661 1.f / parent_scales.y());
1664 // Apply adjustment from position constraints.
1665 ApplyPositionAdjustment(layer, data_from_ancestor.fixed_container,
1666 data_from_ancestor.scroll_compensation_matrix, &combined_transform);
1668 bool combined_is_animating_scale = false;
1669 float combined_maximum_animation_contents_scale = 0.f;
1670 float combined_starting_animation_contents_scale = 0.f;
1671 if (globals.can_adjust_raster_scales) {
1672 CalculateAnimationContentsScale(
1673 layer, data_from_ancestor.ancestor_is_animating_scale,
1674 data_from_ancestor.maximum_animation_contents_scale,
1675 data_from_ancestor.starting_animation_contents_scale,
1676 data_from_ancestor.parent_matrix, combined_transform,
1677 &combined_is_animating_scale,
1678 &combined_maximum_animation_contents_scale,
1679 &combined_starting_animation_contents_scale);
1681 data_for_children.ancestor_is_animating_scale = combined_is_animating_scale;
1682 data_for_children.maximum_animation_contents_scale =
1683 combined_maximum_animation_contents_scale;
1684 data_for_children.starting_animation_contents_scale =
1685 combined_starting_animation_contents_scale;
1687 // Compute the 2d scale components of the transform hierarchy up to the target
1688 // surface. From there, we can decide on a contents scale for the layer.
1689 float layer_scale_factors = globals.device_scale_factor;
1690 if (data_from_ancestor.in_subtree_of_page_scale_layer)
1691 layer_scale_factors *= globals.page_scale_factor;
1692 gfx::Vector2dF combined_transform_scales =
1693 MathUtil::ComputeTransform2dScaleComponents(
1694 combined_transform,
1695 layer_scale_factors);
1697 UpdateLayerScaleDrawProperties(layer,
1698 combined_maximum_animation_contents_scale,
1699 combined_starting_animation_contents_scale);
1701 LayerImpl* mask_layer = layer->mask_layer();
1702 if (mask_layer) {
1703 UpdateLayerScaleDrawProperties(mask_layer,
1704 combined_maximum_animation_contents_scale,
1705 combined_starting_animation_contents_scale);
1708 LayerImpl* replica_mask_layer =
1709 layer->replica_layer() ? layer->replica_layer()->mask_layer() : NULL;
1710 if (replica_mask_layer) {
1711 UpdateLayerScaleDrawProperties(replica_mask_layer,
1712 combined_maximum_animation_contents_scale,
1713 combined_starting_animation_contents_scale);
1716 if (layer == globals.page_scale_layer) {
1717 combined_transform.Scale(globals.page_scale_factor,
1718 globals.page_scale_factor);
1719 data_for_children.in_subtree_of_page_scale_layer = true;
1722 // The draw_transform that gets computed below is effectively the layer's
1723 // draw_transform, unless the layer itself creates a render_surface. In that
1724 // case, the render_surface re-parents the transforms.
1725 layer_draw_properties.target_space_transform = combined_transform;
1727 // The layer's screen_space_transform represents the transform between root
1728 // layer's "screen space" and local content space.
1729 layer_draw_properties.screen_space_transform =
1730 data_from_ancestor.full_hierarchy_matrix;
1731 layer_draw_properties.screen_space_transform.PreconcatTransform
1732 (layer_draw_properties.target_space_transform);
1734 bool layer_can_use_lcd_text = true;
1735 bool subtree_can_use_lcd_text = true;
1736 if (!globals.layers_always_allowed_lcd_text) {
1737 // To avoid color fringing, LCD text should only be used on opaque layers
1738 // with just integral translation.
1739 subtree_can_use_lcd_text = data_from_ancestor.subtree_can_use_lcd_text &&
1740 accumulated_draw_opacity == 1.f &&
1741 layer_draw_properties.target_space_transform
1742 .IsIdentityOrIntegerTranslation();
1743 // Also disable LCD text locally for non-opaque content.
1744 layer_can_use_lcd_text = subtree_can_use_lcd_text &&
1745 layer->contents_opaque();
1748 // full_hierarchy_matrix is the matrix that transforms objects between screen
1749 // space (except projection matrix) and the most recent RenderSurfaceImpl's
1750 // space. next_hierarchy_matrix will only change if this layer uses a new
1751 // RenderSurfaceImpl, otherwise remains the same.
1752 data_for_children.full_hierarchy_matrix =
1753 data_from_ancestor.full_hierarchy_matrix;
1755 bool render_to_separate_surface =
1756 IsRootLayer(layer) ||
1757 (globals.can_render_to_separate_surface && layer->render_surface());
1759 if (render_to_separate_surface) {
1760 DCHECK(layer->render_surface());
1761 // Check back-face visibility before continuing with this surface and its
1762 // subtree
1763 if (!layer->double_sided() &&
1764 IsSurfaceBackFaceVisible(layer, combined_transform)) {
1765 return;
1768 RenderSurfaceImpl* render_surface = layer->render_surface();
1770 if (IsRootLayer(layer)) {
1771 // The root layer's render surface size is predetermined and so the root
1772 // layer can't directly support non-identity transforms. It should just
1773 // forward top-level transforms to the rest of the tree.
1774 data_for_children.parent_matrix = combined_transform;
1775 } else {
1776 // The owning layer's draw transform has a scale from content to layer
1777 // space which we do not want; so here we use the combined_transform
1778 // instead of the draw_transform. However, we do need to add a different
1779 // scale factor that accounts for the surface's pixel dimensions.
1780 // Remove the combined_transform scale from the draw transform.
1781 gfx::Transform draw_transform = combined_transform;
1782 draw_transform.Scale(1.0 / combined_transform_scales.x(),
1783 1.0 / combined_transform_scales.y());
1784 render_surface->SetDrawTransform(draw_transform);
1786 // The owning layer's transform was re-parented by the surface, so the
1787 // layer's new draw_transform only needs to scale the layer to surface
1788 // space.
1789 layer_draw_properties.target_space_transform.MakeIdentity();
1790 layer_draw_properties.target_space_transform.Scale(
1791 combined_transform_scales.x(), combined_transform_scales.y());
1793 // Inside the surface's subtree, we scale everything to the owning layer's
1794 // scale. The sublayer matrix transforms layer rects into target surface
1795 // content space. Conceptually, all layers in the subtree inherit the
1796 // scale at the point of the render surface in the transform hierarchy,
1797 // but we apply it explicitly to the owning layer and the remainder of the
1798 // subtree independently.
1799 DCHECK(data_for_children.parent_matrix.IsIdentity());
1800 data_for_children.parent_matrix.Scale(combined_transform_scales.x(),
1801 combined_transform_scales.y());
1804 // The opacity value is moved from the layer to its surface, so that the
1805 // entire subtree properly inherits opacity.
1806 render_surface->SetDrawOpacity(accumulated_draw_opacity);
1807 layer_draw_properties.opacity = 1.f;
1808 DCHECK_EQ(layer->draw_blend_mode(), SkXfermode::kSrcOver_Mode);
1810 layer_draw_properties.screen_space_transform_is_animating =
1811 animating_transform_to_screen;
1813 // Update the aggregate hierarchy matrix to include the transform of the
1814 // newly created RenderSurfaceImpl.
1815 data_for_children.full_hierarchy_matrix.PreconcatTransform(
1816 render_surface->draw_transform());
1818 // A render surface inherently acts as a flattening point for the content of
1819 // its descendants.
1820 data_for_children.full_hierarchy_matrix.FlattenTo2d();
1822 if (layer->mask_layer()) {
1823 DrawProperties& mask_layer_draw_properties =
1824 layer->mask_layer()->draw_properties();
1825 mask_layer_draw_properties.visible_layer_rect =
1826 gfx::Rect(layer->bounds());
1827 // Temporarily copy the draw transform of the mask's owning layer into the
1828 // mask layer draw properties. This won't actually get used for drawing
1829 // (the render surface uses the mask texture directly), but will get used
1830 // to get the correct contents scale.
1831 // TODO(enne): do something similar for property trees.
1832 mask_layer_draw_properties.target_space_transform =
1833 layer_draw_properties.target_space_transform;
1836 if (layer->replica_layer() && layer->replica_layer()->mask_layer()) {
1837 DrawProperties& replica_mask_draw_properties =
1838 layer->replica_layer()->mask_layer()->draw_properties();
1839 replica_mask_draw_properties.visible_layer_rect =
1840 gfx::Rect(layer->bounds());
1841 replica_mask_draw_properties.target_space_transform =
1842 layer_draw_properties.target_space_transform;
1845 layer_or_ancestor_clips_descendants = false;
1846 bool subtree_is_clipped_by_surface_bounds = false;
1847 if (ancestor_clips_subtree) {
1848 // It may be the layer or the surface doing the clipping of the subtree,
1849 // but in either case, we'll be clipping to the projected clip rect of our
1850 // ancestor.
1851 gfx::Transform inverse_surface_draw_transform(
1852 gfx::Transform::kSkipInitialization);
1853 if (!render_surface->draw_transform().GetInverse(
1854 &inverse_surface_draw_transform)) {
1855 // TODO(shawnsingh): Either we need to handle uninvertible transforms
1856 // here, or DCHECK that the transform is invertible.
1859 gfx::Rect surface_clip_rect_in_target_space = gfx::IntersectRects(
1860 data_from_ancestor.clip_rect_of_target_surface_in_target_space,
1861 ancestor_clip_rect_in_target_space);
1862 gfx::Rect projected_surface_rect = MathUtil::ProjectEnclosingClippedRect(
1863 inverse_surface_draw_transform, surface_clip_rect_in_target_space);
1865 if (layer_draw_properties.num_unclipped_descendants > 0u) {
1866 // If we have unclipped descendants, we cannot count on the render
1867 // surface's bounds clipping our subtree: the unclipped descendants
1868 // could cause us to expand our bounds. In this case, we must rely on
1869 // layer clipping for correctess. NB: since we can only encounter
1870 // translations between a clip child and its clip parent, clipping is
1871 // guaranteed to be exact in this case.
1872 layer_or_ancestor_clips_descendants = true;
1873 clip_rect_in_target_space = projected_surface_rect;
1874 } else {
1875 // The new render_surface here will correctly clip the entire subtree.
1876 // So, we do not need to continue propagating the clipping state further
1877 // down the tree. This way, we can avoid transforming clip rects from
1878 // ancestor target surface space to current target surface space that
1879 // could cause more w < 0 headaches. The render surface clip rect is
1880 // expressed in the space where this surface draws, i.e. the same space
1881 // as clip_rect_from_ancestor_in_ancestor_target_space.
1882 render_surface->SetClipRect(ancestor_clip_rect_in_target_space);
1883 clip_rect_of_target_surface_in_target_space = projected_surface_rect;
1884 subtree_is_clipped_by_surface_bounds = true;
1888 DCHECK(layer->render_surface());
1889 DCHECK(!layer->parent() || layer->parent()->render_target() ==
1890 accumulated_surface_state->back().render_target);
1892 accumulated_surface_state->push_back(AccumulatedSurfaceState(layer));
1894 render_surface->SetIsClipped(subtree_is_clipped_by_surface_bounds);
1895 if (!subtree_is_clipped_by_surface_bounds) {
1896 render_surface->SetClipRect(gfx::Rect());
1897 clip_rect_of_target_surface_in_target_space =
1898 data_from_ancestor.clip_rect_of_target_surface_in_target_space;
1901 // If the new render surface is drawn translucent or with a non-integral
1902 // translation then the subtree that gets drawn on this render surface
1903 // cannot use LCD text.
1904 data_for_children.subtree_can_use_lcd_text = subtree_can_use_lcd_text;
1906 } else {
1907 DCHECK(layer->parent());
1909 // Note: layer_draw_properties.target_space_transform is computed above,
1910 // before this if-else statement.
1911 layer_draw_properties.screen_space_transform_is_animating =
1912 animating_transform_to_screen;
1913 layer_draw_properties.opacity = accumulated_draw_opacity;
1914 DCHECK_EQ(layer->draw_blend_mode(), layer->blend_mode());
1915 data_for_children.parent_matrix = combined_transform;
1917 // Layers without render_surfaces directly inherit the ancestor's clip
1918 // status.
1919 layer_or_ancestor_clips_descendants = ancestor_clips_subtree;
1920 if (ancestor_clips_subtree) {
1921 clip_rect_in_target_space =
1922 ancestor_clip_rect_in_target_space;
1925 // The surface's cached clip rect value propagates regardless of what
1926 // clipping goes on between layers here.
1927 clip_rect_of_target_surface_in_target_space =
1928 data_from_ancestor.clip_rect_of_target_surface_in_target_space;
1931 layer_draw_properties.can_use_lcd_text = layer_can_use_lcd_text;
1933 // The layer bounds() includes the layer's bounds_delta() which we want
1934 // for the clip rect.
1935 gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
1936 layer->draw_transform(), gfx::Rect(layer->bounds()));
1938 if (LayerClipsSubtree(layer)) {
1939 layer_or_ancestor_clips_descendants = true;
1940 if (ancestor_clips_subtree && !render_to_separate_surface) {
1941 // A layer without render surface shares the same target as its ancestor.
1942 clip_rect_in_target_space =
1943 ancestor_clip_rect_in_target_space;
1944 clip_rect_in_target_space.Intersect(rect_in_target_space);
1945 } else {
1946 clip_rect_in_target_space = rect_in_target_space;
1950 // Tell the layer the rect that it's clipped by. In theory we could use a
1951 // tighter clip rect here (drawable_content_rect), but that actually does not
1952 // reduce how much would be drawn, and instead it would create unnecessary
1953 // changes to scissor state affecting GPU performance. Our clip information
1954 // is used in the recursion below, so we must set it beforehand.
1955 DCHECK_EQ(layer_or_ancestor_clips_descendants, layer->is_clipped());
1956 if (layer_or_ancestor_clips_descendants) {
1957 layer_draw_properties.clip_rect = clip_rect_in_target_space;
1958 } else {
1959 // Initialize the clip rect to a safe value that will not clip the
1960 // layer, just in case clipping is still accidentally used.
1961 layer_draw_properties.clip_rect = rect_in_target_space;
1964 if (!layer->children().empty()) {
1965 if (layer == globals.elastic_overscroll_application_layer) {
1966 data_for_children.parent_matrix.Translate(
1967 -globals.elastic_overscroll.x(), -globals.elastic_overscroll.y());
1970 // Flatten to 2D if the layer doesn't preserve 3D.
1971 if (layer->should_flatten_transform())
1972 data_for_children.parent_matrix.FlattenTo2d();
1974 data_for_children.scroll_compensation_matrix =
1975 ComputeScrollCompensationMatrixForChildren(
1976 layer,
1977 data_from_ancestor.parent_matrix,
1978 data_from_ancestor.scroll_compensation_matrix,
1979 effective_scroll_delta);
1980 data_for_children.fixed_container =
1981 layer->IsContainerForFixedPositionLayers() ?
1982 layer : data_from_ancestor.fixed_container;
1984 data_for_children.clip_rect_in_target_space = clip_rect_in_target_space;
1985 data_for_children.clip_rect_of_target_surface_in_target_space =
1986 clip_rect_of_target_surface_in_target_space;
1987 data_for_children.ancestor_clips_subtree =
1988 layer_or_ancestor_clips_descendants;
1989 data_for_children.subtree_is_visible_from_ancestor = layer_is_drawn;
1992 std::vector<LayerImpl*> sorted_children;
1993 if (layer_draw_properties.has_child_with_a_scroll_parent)
1994 SortChildrenForRecursion(&sorted_children, *layer);
1996 for (size_t i = 0; i < layer->children().size(); ++i) {
1997 // If one of layer's children has a scroll parent, then we may have to
1998 // visit the children out of order. The new order is stored in
1999 // sorted_children. Otherwise, we'll grab the child directly from the
2000 // layer's list of children.
2002 LayerImpl* child =
2003 layer_draw_properties.has_child_with_a_scroll_parent
2004 ? sorted_children[i]
2005 : LayerTreeHostCommon::get_layer_as_raw_ptr(layer->children(), i);
2007 CalculateDrawPropertiesInternal(child, globals, data_for_children,
2008 accumulated_surface_state);
2010 if (child->layer_or_descendant_is_drawn()) {
2011 bool layer_or_descendant_is_drawn = true;
2012 layer->set_layer_or_descendant_is_drawn(layer_or_descendant_is_drawn);
2016 // Compute the total drawable_content_rect for this subtree (the rect is in
2017 // target surface space).
2018 gfx::Rect local_drawable_content_rect_of_subtree =
2019 accumulated_surface_state->back().drawable_content_rect;
2020 if (render_to_separate_surface) {
2021 DCHECK(accumulated_surface_state->back().render_target == layer);
2022 accumulated_surface_state->pop_back();
2025 // Compute the layer's drawable content rect (the rect is in target surface
2026 // space).
2027 layer_draw_properties.drawable_content_rect = rect_in_target_space;
2028 if (layer_or_ancestor_clips_descendants) {
2029 layer_draw_properties.drawable_content_rect.Intersect(
2030 clip_rect_in_target_space);
2032 if (layer->DrawsContent()) {
2033 local_drawable_content_rect_of_subtree.Union(
2034 layer_draw_properties.drawable_content_rect);
2037 // Compute the layer's visible content rect (the rect is in content space).
2038 layer_draw_properties.visible_layer_rect = CalculateVisibleLayerRect(
2039 layer, clip_rect_of_target_surface_in_target_space, rect_in_target_space);
2041 // Compute the remaining properties for the render surface, if the layer has
2042 // one.
2043 if (IsRootLayer(layer)) {
2044 // The root layer's surface's content_rect is always the entire viewport.
2045 DCHECK(render_to_separate_surface);
2046 layer->render_surface()->SetContentRect(
2047 ancestor_clip_rect_in_target_space);
2048 } else if (render_to_separate_surface) {
2049 RenderSurfaceImpl* render_surface = layer->render_surface();
2050 gfx::Rect clipped_content_rect = local_drawable_content_rect_of_subtree;
2052 // Don't clip if the layer is reflected as the reflection shouldn't be
2053 // clipped.
2054 if (!layer->replica_layer()) {
2055 // Note, it is correct to use data_from_ancestor.ancestor_clips_subtree
2056 // here, because we are looking at this layer's render_surface, not the
2057 // layer itself.
2058 if (render_surface->is_clipped() && !clipped_content_rect.IsEmpty()) {
2059 gfx::Rect surface_clip_rect = LayerTreeHostCommon::CalculateVisibleRect(
2060 render_surface->clip_rect(),
2061 clipped_content_rect,
2062 render_surface->draw_transform());
2063 clipped_content_rect.Intersect(surface_clip_rect);
2067 // The RenderSurfaceImpl backing texture cannot exceed the maximum supported
2068 // texture size.
2069 clipped_content_rect.set_width(
2070 std::min(clipped_content_rect.width(), globals.max_texture_size));
2071 clipped_content_rect.set_height(
2072 std::min(clipped_content_rect.height(), globals.max_texture_size));
2074 // Layers having a non-default blend mode will blend with the content
2075 // inside its parent's render target. This render target should be
2076 // either root_for_isolated_group, or the root of the layer tree.
2077 // Otherwise, this layer will use an incomplete backdrop, limited to its
2078 // render target and the blending result will be incorrect.
2079 DCHECK(layer->uses_default_blend_mode() || IsRootLayer(layer) ||
2080 !layer->parent()->render_target() ||
2081 IsRootLayer(layer->parent()->render_target()) ||
2082 layer->parent()->render_target()->is_root_for_isolated_group());
2084 render_surface->SetContentRect(clipped_content_rect);
2086 if (clipped_content_rect.IsEmpty()) {
2087 return;
2090 // The owning layer's screen_space_transform has a scale from content to
2091 // layer space which we need to undo and replace with a scale from the
2092 // surface's subtree into layer space.
2093 gfx::Transform screen_space_transform = layer->screen_space_transform();
2094 screen_space_transform.Scale(1.0 / combined_transform_scales.x(),
2095 1.0 / combined_transform_scales.y());
2096 render_surface->SetScreenSpaceTransform(screen_space_transform);
2098 if (layer->replica_layer()) {
2099 gfx::Transform surface_origin_to_replica_origin_transform;
2100 surface_origin_to_replica_origin_transform.Scale(
2101 combined_transform_scales.x(), combined_transform_scales.y());
2102 surface_origin_to_replica_origin_transform.Translate(
2103 layer->replica_layer()->position().x() +
2104 layer->replica_layer()->transform_origin().x(),
2105 layer->replica_layer()->position().y() +
2106 layer->replica_layer()->transform_origin().y());
2107 surface_origin_to_replica_origin_transform.PreconcatTransform(
2108 layer->replica_layer()->transform());
2109 surface_origin_to_replica_origin_transform.Translate(
2110 -layer->replica_layer()->transform_origin().x(),
2111 -layer->replica_layer()->transform_origin().y());
2112 surface_origin_to_replica_origin_transform.Scale(
2113 1.0 / combined_transform_scales.x(),
2114 1.0 / combined_transform_scales.y());
2116 // Compute the replica's "originTransform" that maps from the replica's
2117 // origin space to the target surface origin space.
2118 gfx::Transform replica_origin_transform =
2119 layer->render_surface()->draw_transform() *
2120 surface_origin_to_replica_origin_transform;
2121 render_surface->SetReplicaDrawTransform(replica_origin_transform);
2123 // Compute the replica's "screen_space_transform" that maps from the
2124 // replica's origin space to the screen's origin space.
2125 gfx::Transform replica_screen_space_transform =
2126 layer->render_surface()->screen_space_transform() *
2127 surface_origin_to_replica_origin_transform;
2128 render_surface->SetReplicaScreenSpaceTransform(
2129 replica_screen_space_transform);
2133 SavePaintPropertiesLayer(layer);
2135 UpdateAccumulatedSurfaceState(layer, local_drawable_content_rect_of_subtree,
2136 accumulated_surface_state);
2137 } // NOLINT(readability/fn_size)
2139 static void ProcessCalcDrawPropsInputs(
2140 const LayerTreeHostCommon::CalcDrawPropsImplInputs& inputs,
2141 SubtreeGlobals* globals,
2142 DataForRecursion* data_for_recursion) {
2143 DCHECK(inputs.root_layer);
2144 DCHECK(IsRootLayer(inputs.root_layer));
2145 DCHECK(inputs.render_surface_layer_list);
2147 gfx::Transform identity_matrix;
2149 // The root layer's render_surface should receive the device viewport as the
2150 // initial clip rect.
2151 gfx::Rect device_viewport_rect(inputs.device_viewport_size);
2153 gfx::Vector2dF device_transform_scale_components =
2154 MathUtil::ComputeTransform2dScaleComponents(inputs.device_transform, 1.f);
2155 // Not handling the rare case of different x and y device scale.
2156 float device_transform_scale =
2157 std::max(device_transform_scale_components.x(),
2158 device_transform_scale_components.y());
2160 gfx::Transform scaled_device_transform = inputs.device_transform;
2161 scaled_device_transform.Scale(inputs.device_scale_factor,
2162 inputs.device_scale_factor);
2164 globals->max_texture_size = inputs.max_texture_size;
2165 globals->device_scale_factor =
2166 inputs.device_scale_factor * device_transform_scale;
2167 globals->page_scale_factor = inputs.page_scale_factor;
2168 globals->page_scale_layer = inputs.page_scale_layer;
2169 globals->elastic_overscroll = inputs.elastic_overscroll;
2170 globals->elastic_overscroll_application_layer =
2171 inputs.elastic_overscroll_application_layer;
2172 globals->can_render_to_separate_surface =
2173 inputs.can_render_to_separate_surface;
2174 globals->can_adjust_raster_scales = inputs.can_adjust_raster_scales;
2175 globals->layers_always_allowed_lcd_text =
2176 inputs.layers_always_allowed_lcd_text;
2178 data_for_recursion->parent_matrix = scaled_device_transform;
2179 data_for_recursion->full_hierarchy_matrix = identity_matrix;
2180 data_for_recursion->scroll_compensation_matrix = identity_matrix;
2181 data_for_recursion->fixed_container = inputs.root_layer;
2182 data_for_recursion->clip_rect_in_target_space = device_viewport_rect;
2183 data_for_recursion->clip_rect_of_target_surface_in_target_space =
2184 device_viewport_rect;
2185 data_for_recursion->maximum_animation_contents_scale = 0.f;
2186 data_for_recursion->starting_animation_contents_scale = 0.f;
2187 data_for_recursion->ancestor_is_animating_scale = false;
2188 data_for_recursion->ancestor_clips_subtree = true;
2189 data_for_recursion->in_subtree_of_page_scale_layer = false;
2190 data_for_recursion->subtree_can_use_lcd_text = inputs.can_use_lcd_text;
2191 data_for_recursion->subtree_is_visible_from_ancestor = true;
2194 void LayerTreeHostCommon::UpdateRenderSurface(
2195 Layer* layer,
2196 bool can_render_to_separate_surface,
2197 gfx::Transform* transform,
2198 bool* draw_transform_is_axis_aligned) {
2199 bool preserves_2d_axis_alignment =
2200 transform->Preserves2dAxisAlignment() && *draw_transform_is_axis_aligned;
2201 if (IsRootLayer(layer) || (can_render_to_separate_surface &&
2202 SubtreeShouldRenderToSeparateSurface(
2203 layer, preserves_2d_axis_alignment))) {
2204 // We reset the transform here so that any axis-changing transforms
2205 // will now be relative to this RenderSurface.
2206 transform->MakeIdentity();
2207 *draw_transform_is_axis_aligned = true;
2208 layer->SetHasRenderSurface(true);
2209 return;
2211 layer->SetHasRenderSurface(false);
2214 void LayerTreeHostCommon::UpdateRenderSurfaces(
2215 Layer* layer,
2216 bool can_render_to_separate_surface,
2217 const gfx::Transform& parent_transform,
2218 bool draw_transform_is_axis_aligned) {
2219 gfx::Transform transform_for_children = layer->transform();
2220 transform_for_children *= parent_transform;
2221 draw_transform_is_axis_aligned &= layer->AnimationsPreserveAxisAlignment();
2222 UpdateRenderSurface(layer, can_render_to_separate_surface,
2223 &transform_for_children, &draw_transform_is_axis_aligned);
2225 for (size_t i = 0; i < layer->children().size(); ++i) {
2226 UpdateRenderSurfaces(layer->children()[i].get(),
2227 can_render_to_separate_surface, transform_for_children,
2228 draw_transform_is_axis_aligned);
2232 static bool ApproximatelyEqual(const gfx::Rect& r1, const gfx::Rect& r2) {
2233 // TODO(vollick): This tolerance should be lower: crbug.com/471786
2234 static const int tolerance = 1;
2236 return std::abs(r1.x() - r2.x()) <= tolerance &&
2237 std::abs(r1.y() - r2.y()) <= tolerance &&
2238 std::abs(r1.right() - r2.right()) <= tolerance &&
2239 std::abs(r1.bottom() - r2.bottom()) <= tolerance;
2242 static bool ApproximatelyEqual(const gfx::Transform& a,
2243 const gfx::Transform& b) {
2244 static const float component_tolerance = 0.1f;
2246 // We may have a larger discrepancy in the scroll components due to snapping
2247 // (floating point error might round the other way).
2248 static const float translation_tolerance = 1.f;
2250 for (int row = 0; row < 4; row++) {
2251 for (int col = 0; col < 4; col++) {
2252 const float delta =
2253 std::abs(a.matrix().get(row, col) - b.matrix().get(row, col));
2254 const float tolerance =
2255 col == 3 && row < 3 ? translation_tolerance : component_tolerance;
2256 if (delta > tolerance)
2257 return false;
2261 return true;
2264 void VerifyPropertyTreeValuesForSurface(RenderSurfaceImpl* render_surface,
2265 PropertyTrees* property_trees) {
2266 RenderSurfaceDrawProperties draw_properties;
2267 ComputeSurfaceDrawPropertiesUsingPropertyTrees(render_surface, property_trees,
2268 &draw_properties);
2270 // content_rect has to be computed recursively, so is computed separately from
2271 // other draw properties.
2272 draw_properties.content_rect =
2273 render_surface->content_rect_from_property_trees();
2275 const bool render_surface_draw_transforms_match = ApproximatelyEqual(
2276 render_surface->draw_transform(), draw_properties.draw_transform);
2277 CHECK(render_surface_draw_transforms_match)
2278 << "expected: " << render_surface->draw_transform().ToString()
2279 << " actual: " << draw_properties.draw_transform.ToString();
2281 const bool render_surface_screen_space_transform_match =
2282 ApproximatelyEqual(render_surface->screen_space_transform(),
2283 draw_properties.screen_space_transform);
2284 CHECK(render_surface_screen_space_transform_match)
2285 << "expected: " << render_surface->screen_space_transform().ToString()
2286 << " actual: " << draw_properties.screen_space_transform.ToString();
2288 const bool render_surface_replica_draw_transforms_match =
2289 ApproximatelyEqual(render_surface->replica_draw_transform(),
2290 draw_properties.replica_draw_transform);
2291 CHECK(render_surface_replica_draw_transforms_match)
2292 << "expected: " << render_surface->replica_draw_transform().ToString()
2293 << " actual: " << draw_properties.replica_draw_transform.ToString();
2295 const bool render_surface_replica_screen_space_transforms_match =
2296 ApproximatelyEqual(render_surface->replica_screen_space_transform(),
2297 draw_properties.replica_screen_space_transform);
2298 CHECK(render_surface_replica_screen_space_transforms_match)
2299 << "expected: "
2300 << render_surface->replica_screen_space_transform().ToString()
2301 << " actual: "
2302 << draw_properties.replica_screen_space_transform.ToString();
2304 CHECK_EQ(render_surface->is_clipped(), draw_properties.is_clipped);
2306 const bool render_surface_clip_rects_match = ApproximatelyEqual(
2307 render_surface->clip_rect(), draw_properties.clip_rect);
2308 CHECK(render_surface_clip_rects_match)
2309 << "expected: " << render_surface->clip_rect().ToString()
2310 << " actual: " << draw_properties.clip_rect.ToString();
2312 CHECK_EQ(render_surface->draw_opacity(), draw_properties.draw_opacity);
2314 const bool render_surface_content_rects_match = ApproximatelyEqual(
2315 render_surface->content_rect(), draw_properties.content_rect);
2316 CHECK(render_surface_content_rects_match)
2317 << "expected: " << render_surface->content_rect().ToString()
2318 << " actual: " << draw_properties.content_rect.ToString();
2321 void VerifyPropertyTreeValuesForLayer(LayerImpl* current_layer,
2322 PropertyTrees* property_trees,
2323 bool layers_always_allowed_lcd_text,
2324 bool can_use_lcd_text) {
2325 DrawProperties draw_properties;
2326 ComputeLayerDrawPropertiesUsingPropertyTrees(
2327 current_layer, property_trees, layers_always_allowed_lcd_text,
2328 can_use_lcd_text, &draw_properties);
2330 const bool visible_rects_match = ApproximatelyEqual(
2331 current_layer->visible_layer_rect(), draw_properties.visible_layer_rect);
2332 CHECK(visible_rects_match)
2333 << "expected: " << current_layer->visible_layer_rect().ToString()
2334 << " actual: " << draw_properties.visible_layer_rect.ToString();
2336 const bool draw_transforms_match = ApproximatelyEqual(
2337 current_layer->draw_transform(), draw_properties.target_space_transform);
2338 CHECK(draw_transforms_match)
2339 << "expected: " << current_layer->draw_transform().ToString()
2340 << " actual: " << draw_properties.target_space_transform.ToString();
2342 CHECK_EQ(current_layer->draw_opacity(), draw_properties.opacity);
2343 CHECK_EQ(current_layer->can_use_lcd_text(), draw_properties.can_use_lcd_text);
2344 CHECK_EQ(current_layer->screen_space_transform_is_animating(),
2345 draw_properties.screen_space_transform_is_animating);
2347 const bool drawable_content_rects_match =
2348 ApproximatelyEqual(current_layer->drawable_content_rect(),
2349 draw_properties.drawable_content_rect);
2350 CHECK(drawable_content_rects_match)
2351 << "expected: " << current_layer->drawable_content_rect().ToString()
2352 << " actual: " << draw_properties.drawable_content_rect.ToString();
2354 const bool clip_rects_match =
2355 ApproximatelyEqual(current_layer->clip_rect(), draw_properties.clip_rect);
2356 CHECK(clip_rects_match) << "expected: "
2357 << current_layer->clip_rect().ToString()
2358 << " actual: "
2359 << draw_properties.clip_rect.ToString();
2361 CHECK_EQ(current_layer->draw_properties().maximum_animation_contents_scale,
2362 draw_properties.maximum_animation_contents_scale);
2363 CHECK_EQ(current_layer->draw_properties().starting_animation_contents_scale,
2364 draw_properties.starting_animation_contents_scale);
2367 void VerifyPropertyTreeValues(
2368 LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs) {
2369 LayerIterator it, end;
2370 for (it = LayerIterator::Begin(inputs->render_surface_layer_list),
2371 end = LayerIterator::End(inputs->render_surface_layer_list);
2372 it != end; ++it) {
2373 LayerImpl* current_layer = *it;
2374 if (it.represents_target_render_surface())
2375 VerifyPropertyTreeValuesForSurface(current_layer->render_surface(),
2376 inputs->property_trees);
2377 if (!it.represents_itself() || !current_layer->DrawsContent())
2378 continue;
2379 VerifyPropertyTreeValuesForLayer(current_layer, inputs->property_trees,
2380 inputs->layers_always_allowed_lcd_text,
2381 inputs->can_use_lcd_text);
2385 enum PropertyTreeOption {
2386 BUILD_PROPERTY_TREES_IF_NEEDED,
2387 DONT_BUILD_PROPERTY_TREES
2390 void CalculateRenderTargetInternal(LayerImpl* layer,
2391 bool subtree_visible_from_ancestor,
2392 bool can_render_to_separate_surface) {
2393 const bool layer_is_visible =
2394 subtree_visible_from_ancestor && !layer->hide_layer_and_subtree();
2395 const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
2397 // The root layer cannot be skipped.
2398 if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
2399 layer->draw_properties().render_target = nullptr;
2400 return;
2403 bool render_to_separate_surface =
2404 IsRootLayer(layer) ||
2405 (can_render_to_separate_surface && layer->render_surface());
2407 if (render_to_separate_surface) {
2408 DCHECK(layer->render_surface());
2409 layer->draw_properties().render_target = layer;
2411 if (layer->mask_layer())
2412 layer->mask_layer()->draw_properties().render_target = layer;
2414 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
2415 layer->replica_layer()->mask_layer()->draw_properties().render_target =
2416 layer;
2418 } else {
2419 DCHECK(layer->parent());
2420 layer->draw_properties().render_target = layer->parent()->render_target();
2423 for (size_t i = 0; i < layer->children().size(); ++i) {
2424 CalculateRenderTargetInternal(
2425 LayerTreeHostCommon::get_layer_as_raw_ptr(layer->children(), i),
2426 layer_is_drawn, can_render_to_separate_surface);
2430 void CalculateRenderSurfaceLayerListInternal(
2431 LayerImpl* layer,
2432 PropertyTrees* property_trees,
2433 LayerImplList* render_surface_layer_list,
2434 LayerImplList* descendants,
2435 RenderSurfaceImpl* nearest_occlusion_immune_ancestor,
2436 bool subtree_visible_from_ancestor,
2437 const bool can_render_to_separate_surface,
2438 const int current_render_surface_layer_list_id,
2439 const bool verify_property_trees) {
2440 // This calculates top level Render Surface Layer List, and Layer List for all
2441 // Render Surfaces.
2443 // |layer| is current layer.
2445 // |render_surface_layer_list| is the top level RenderSurfaceLayerList.
2447 // |descendants| is used to determine what's in current layer's render
2448 // surface's layer list.
2450 // |subtree_visible_from_ancestor| is set during recursion to affect current
2451 // layer's subtree.
2453 // |can_render_to_separate_surface| and |current_render_surface_layer_list_id|
2454 // are settings that should stay the same during recursion.
2456 // Layers that are marked as hidden will hide themselves and their subtree.
2457 // Exception: Layers with copy requests, whether hidden or not, must be drawn
2458 // anyway. In this case, we will inform their subtree they are visible to get
2459 // the right results.
2460 const bool layer_is_visible =
2461 subtree_visible_from_ancestor && !layer->hide_layer_and_subtree();
2462 const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
2464 // The root layer cannot be skipped.
2465 if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
2466 if (layer->render_surface())
2467 layer->ClearRenderSurfaceLayerList();
2468 layer->draw_properties().render_target = nullptr;
2469 return;
2472 bool render_to_separate_surface =
2473 IsRootLayer(layer) ||
2474 (can_render_to_separate_surface && layer->render_surface());
2476 if (render_to_separate_surface) {
2477 DCHECK(layer->render_surface());
2478 if (!layer->double_sided() &&
2479 IsSurfaceBackFaceVisible(layer, layer->draw_transform())) {
2480 layer->ClearRenderSurfaceLayerList();
2481 layer->draw_properties().render_target = nullptr;
2482 return;
2484 if (IsRootLayer(layer)) {
2485 // The root surface does not contribute to any other surface, it has no
2486 // target.
2487 layer->render_surface()->set_contributes_to_drawn_surface(false);
2488 } else {
2489 // Even if the |layer_is_drawn|, it only contributes to a drawn surface
2490 // when the |layer_is_visible|.
2491 layer->render_surface()->set_contributes_to_drawn_surface(
2492 layer_is_visible);
2495 // Ignore occlusion from outside the surface when surface contents need to
2496 // be fully drawn. Layers with copy-request need to be complete.
2497 // We could be smarter about layers with replica and exclude regions
2498 // where both layer and the replica are occluded, but this seems like an
2499 // overkill. The same is true for layers with filters that move pixels.
2500 // TODO(senorblanco): make this smarter for the SkImageFilter case (check
2501 // for pixel-moving filters)
2502 if (layer->HasCopyRequest() || layer->has_replica() ||
2503 layer->filters().HasReferenceFilter() ||
2504 layer->filters().HasFilterThatMovesPixels()) {
2505 nearest_occlusion_immune_ancestor = layer->render_surface();
2507 layer->render_surface()->SetNearestOcclusionImmuneAncestor(
2508 nearest_occlusion_immune_ancestor);
2509 layer->ClearRenderSurfaceLayerList();
2511 render_surface_layer_list->push_back(layer);
2513 descendants = &(layer->render_surface()->layer_list());
2516 size_t descendants_size = descendants->size();
2518 bool layer_should_be_skipped = LayerShouldBeSkipped(layer, layer_is_drawn);
2519 if (!layer_should_be_skipped) {
2520 MarkLayerWithRenderSurfaceLayerListId(layer,
2521 current_render_surface_layer_list_id);
2522 descendants->push_back(layer);
2525 // The render surface's content rect is the union of drawable content rects
2526 // of the layers that draw into the surface. If the render surface is clipped,
2527 // it is also intersected with the render's surface clip rect.
2528 if (verify_property_trees) {
2529 if (render_to_separate_surface) {
2530 if (IsRootLayer(layer)) {
2531 // The root layer's surface content rect is always the entire viewport.
2532 gfx::Rect viewport =
2533 gfx::ToEnclosingRect(property_trees->clip_tree.ViewportClip());
2534 layer->render_surface()->SetAccumulatedContentRect(viewport);
2535 } else {
2536 // If the owning layer of a render surface draws content, the content
2537 // rect of the render surface is initialized to the drawable content
2538 // rect of the layer.
2539 gfx::Rect content_rect = layer->DrawsContent()
2540 ? layer->drawable_content_rect()
2541 : gfx::Rect();
2542 layer->render_surface()->SetAccumulatedContentRect(content_rect);
2544 } else if (!layer_should_be_skipped &&
2545 !IsRootLayer(layer->render_target())) {
2546 // In this case, the layer's drawable content rect can expand the
2547 // content rect of the render surface it is drawing into.
2548 gfx::Rect surface_content_rect =
2549 layer->render_target()->render_surface()->accumulated_content_rect();
2550 surface_content_rect.Union(layer->drawable_content_rect());
2551 layer->render_target()->render_surface()->SetAccumulatedContentRect(
2552 surface_content_rect);
2556 for (auto& child_layer : layer->children()) {
2557 CalculateRenderSurfaceLayerListInternal(
2558 child_layer, property_trees, render_surface_layer_list, descendants,
2559 nearest_occlusion_immune_ancestor, layer_is_drawn,
2560 can_render_to_separate_surface, current_render_surface_layer_list_id,
2561 verify_property_trees);
2563 // If the child is its own render target, then it has a render surface.
2564 if (child_layer->render_target() == child_layer &&
2565 !child_layer->render_surface()->layer_list().empty() &&
2566 !child_layer->render_surface()->content_rect().IsEmpty()) {
2567 // This child will contribute its render surface, which means
2568 // we need to mark just the mask layer (and replica mask layer)
2569 // with the id.
2570 MarkMasksWithRenderSurfaceLayerListId(
2571 child_layer, current_render_surface_layer_list_id);
2572 descendants->push_back(child_layer);
2575 if (child_layer->layer_or_descendant_is_drawn()) {
2576 bool layer_or_descendant_is_drawn = true;
2577 layer->set_layer_or_descendant_is_drawn(layer_or_descendant_is_drawn);
2581 if (render_to_separate_surface && !IsRootLayer(layer) &&
2582 layer->render_surface()->layer_list().empty()) {
2583 RemoveSurfaceForEarlyExit(layer, render_surface_layer_list);
2584 return;
2587 if (verify_property_trees && render_to_separate_surface &&
2588 !IsRootLayer(layer)) {
2589 if (!layer->replica_layer() && layer->render_surface()->is_clipped()) {
2590 // Here, we clip the render surface's content rect with its clip rect.
2591 // As the clip rect of render surface is in the surface's target space,
2592 // we first map the content rect into the target space, intersect it with
2593 // clip rect and project back the result to the surface space.
2594 gfx::Rect surface_content_rect =
2595 layer->render_surface()->accumulated_content_rect();
2597 if (!surface_content_rect.IsEmpty()) {
2598 gfx::Rect surface_clip_rect = LayerTreeHostCommon::CalculateVisibleRect(
2599 layer->render_surface()->clip_rect(), surface_content_rect,
2600 layer->render_surface()->draw_transform());
2601 surface_content_rect.Intersect(surface_clip_rect);
2602 layer->render_surface()->SetAccumulatedContentRect(
2603 surface_content_rect);
2606 layer->render_surface()->SetContentRectFromPropertyTrees(
2607 layer->render_surface()->accumulated_content_rect());
2608 if (!IsRootLayer(layer->parent()->render_target())) {
2609 // The surface's drawable content rect may expand the content rect
2610 // of its target's surface(surface's target's surface).
2611 gfx::Rect surface_target_rect = layer->parent()
2612 ->render_target()
2613 ->render_surface()
2614 ->accumulated_content_rect();
2615 surface_target_rect.Union(
2616 gfx::ToEnclosedRect(layer->render_surface()->DrawableContentRect()));
2617 layer->parent()
2618 ->render_target()
2619 ->render_surface()
2620 ->SetAccumulatedContentRect(surface_target_rect);
2624 if (verify_property_trees && IsRootLayer(layer))
2625 layer->render_surface()->SetContentRectFromPropertyTrees(
2626 layer->render_surface()->accumulated_content_rect());
2628 if (render_to_separate_surface && !IsRootLayer(layer) &&
2629 layer->render_surface()->content_rect().IsEmpty()) {
2630 RemoveSurfaceForEarlyExit(layer, render_surface_layer_list);
2631 return;
2634 // If neither this layer nor any of its children were added, early out.
2635 if (descendants_size == descendants->size()) {
2636 DCHECK(!render_to_separate_surface || IsRootLayer(layer));
2637 return;
2640 if (layer->HasContributingDelegatedRenderPasses()) {
2641 layer->render_target()
2642 ->render_surface()
2643 ->AddContributingDelegatedRenderPassLayer(layer);
2647 void CalculateRenderTarget(
2648 LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs) {
2649 CalculateRenderTargetInternal(inputs->root_layer, true,
2650 inputs->can_render_to_separate_surface);
2653 void CalculateRenderSurfaceLayerList(
2654 LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs) {
2655 const bool subtree_visible_from_ancestor = true;
2656 CalculateRenderSurfaceLayerListInternal(
2657 inputs->root_layer, inputs->property_trees,
2658 inputs->render_surface_layer_list, nullptr, nullptr,
2659 subtree_visible_from_ancestor, inputs->can_render_to_separate_surface,
2660 inputs->current_render_surface_layer_list_id,
2661 inputs->verify_property_trees);
2664 void CalculateDrawPropertiesAndVerify(
2665 LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs,
2666 PropertyTreeOption property_tree_option) {
2667 SubtreeGlobals globals;
2668 DataForRecursion data_for_recursion;
2669 inputs->render_surface_layer_list->clear();
2671 ProcessCalcDrawPropsInputs(*inputs, &globals, &data_for_recursion);
2672 UpdateMetaInformationSequenceNumber(inputs->root_layer);
2673 PreCalculateMetaInformationRecursiveData recursive_data;
2674 PreCalculateMetaInformationInternal(inputs->root_layer, &recursive_data);
2676 const bool should_measure_property_tree_performance =
2677 inputs->verify_property_trees &&
2678 (property_tree_option == BUILD_PROPERTY_TREES_IF_NEEDED);
2680 if (inputs->verify_property_trees) {
2681 LayerImplList update_layer_list;
2683 switch (property_tree_option) {
2684 case BUILD_PROPERTY_TREES_IF_NEEDED: {
2685 // The translation from layer to property trees is an intermediate
2686 // state. We will eventually get these data passed directly to the
2687 // compositor.
2688 if (should_measure_property_tree_performance) {
2689 TRACE_EVENT_BEGIN0(
2690 TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
2691 "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
2694 BuildPropertyTreesAndComputeVisibleRects(
2695 inputs->root_layer, inputs->page_scale_layer,
2696 inputs->inner_viewport_scroll_layer,
2697 inputs->outer_viewport_scroll_layer, inputs->page_scale_factor,
2698 inputs->device_scale_factor,
2699 gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
2700 inputs->property_trees, &update_layer_list);
2702 if (should_measure_property_tree_performance) {
2703 TRACE_EVENT_END0(
2704 TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
2705 "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
2708 break;
2710 case DONT_BUILD_PROPERTY_TREES: {
2711 TRACE_EVENT0(
2712 TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
2713 "LayerTreeHostCommon::ComputeJustVisibleRectsWithPropertyTrees");
2714 ComputeVisibleRectsUsingPropertyTrees(
2715 inputs->root_layer, inputs->property_trees, &update_layer_list);
2716 break;
2721 if (should_measure_property_tree_performance) {
2722 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
2723 "LayerTreeHostCommon::CalculateDrawProperties");
2726 std::vector<AccumulatedSurfaceState> accumulated_surface_state;
2727 CalculateRenderTarget(inputs);
2728 CalculateDrawPropertiesInternal(inputs->root_layer, globals,
2729 data_for_recursion,
2730 &accumulated_surface_state);
2731 CalculateRenderSurfaceLayerList(inputs);
2733 if (should_measure_property_tree_performance) {
2734 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
2735 "LayerTreeHostCommon::CalculateDrawProperties");
2738 if (inputs->verify_property_trees)
2739 VerifyPropertyTreeValues(inputs);
2741 // A root layer render_surface should always exist after
2742 // CalculateDrawProperties.
2743 DCHECK(inputs->root_layer->render_surface());
2746 void LayerTreeHostCommon::CalculateDrawProperties(
2747 CalcDrawPropsMainInputs* inputs) {
2748 LayerList update_layer_list;
2749 bool can_render_to_separate_surface = true;
2750 UpdateRenderSurfaces(inputs->root_layer, can_render_to_separate_surface,
2751 gfx::Transform(), false);
2752 PropertyTrees* property_trees =
2753 inputs->root_layer->layer_tree_host()->property_trees();
2754 BuildPropertyTreesAndComputeVisibleRects(
2755 inputs->root_layer, inputs->page_scale_layer,
2756 inputs->inner_viewport_scroll_layer, inputs->outer_viewport_scroll_layer,
2757 inputs->page_scale_factor, inputs->device_scale_factor,
2758 gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
2759 property_trees, &update_layer_list);
2762 void LayerTreeHostCommon::CalculateDrawProperties(
2763 CalcDrawPropsImplInputs* inputs) {
2764 CalculateDrawPropertiesAndVerify(inputs, DONT_BUILD_PROPERTY_TREES);
2767 void LayerTreeHostCommon::CalculateDrawProperties(
2768 CalcDrawPropsImplInputsForTesting* inputs) {
2769 CalculateDrawPropertiesAndVerify(inputs, BUILD_PROPERTY_TREES_IF_NEEDED);
2772 PropertyTrees* GetPropertyTrees(Layer* layer) {
2773 return layer->layer_tree_host()->property_trees();
2776 PropertyTrees* GetPropertyTrees(LayerImpl* layer) {
2777 return layer->layer_tree_impl()->property_trees();
2780 } // namespace cc