Fix build break
[chromium-blink-merge.git] / cc / trees / layer_tree_host_common.cc
blob7548cd293bbf1a2212062e961bc269fa34b0f08e
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/debug/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.h"
16 #include "cc/layers/render_surface_impl.h"
17 #include "cc/trees/layer_sorter.h"
18 #include "cc/trees/layer_tree_impl.h"
19 #include "ui/gfx/point_conversions.h"
20 #include "ui/gfx/rect_conversions.h"
21 #include "ui/gfx/transform.h"
23 namespace cc {
25 ScrollAndScaleSet::ScrollAndScaleSet() {}
27 ScrollAndScaleSet::~ScrollAndScaleSet() {}
29 static void SortLayers(LayerList::iterator forst,
30 LayerList::iterator end,
31 void* layer_sorter) {
32 NOTREACHED();
35 static void SortLayers(LayerImplList::iterator first,
36 LayerImplList::iterator end,
37 LayerSorter* layer_sorter) {
38 DCHECK(layer_sorter);
39 TRACE_EVENT0("cc", "LayerTreeHostCommon::SortLayers");
40 layer_sorter->Sort(first, end);
43 inline gfx::Rect CalculateVisibleRectWithCachedLayerRect(
44 gfx::Rect target_surface_rect,
45 gfx::Rect layer_bound_rect,
46 gfx::Rect layer_rect_in_target_space,
47 const gfx::Transform& transform) {
48 // Is this layer fully contained within the target surface?
49 if (target_surface_rect.Contains(layer_rect_in_target_space))
50 return layer_bound_rect;
52 // If the layer doesn't fill up the entire surface, then find the part of
53 // the surface rect where the layer could be visible. This avoids trying to
54 // project surface rect points that are behind the projection point.
55 gfx::Rect minimal_surface_rect = target_surface_rect;
56 minimal_surface_rect.Intersect(layer_rect_in_target_space);
58 // Project the corners of the target surface rect into the layer space.
59 // This bounding rectangle may be larger than it needs to be (being
60 // axis-aligned), but is a reasonable filter on the space to consider.
61 // Non-invertible transforms will create an empty rect here.
63 gfx::Transform surface_to_layer(gfx::Transform::kSkipInitialization);
64 if (!transform.GetInverse(&surface_to_layer)) {
65 // TODO(shawnsingh): Some uninvertible transforms may be visible, but
66 // their behaviour is undefined thoughout the compositor. Make their
67 // behaviour well-defined and allow the visible content rect to be non-
68 // empty when needed.
69 return gfx::Rect();
72 gfx::Rect layer_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
73 surface_to_layer, gfx::RectF(minimal_surface_rect)));
74 layer_rect.Intersect(layer_bound_rect);
75 return layer_rect;
78 gfx::Rect LayerTreeHostCommon::CalculateVisibleRect(
79 gfx::Rect target_surface_rect,
80 gfx::Rect layer_bound_rect,
81 const gfx::Transform& transform) {
82 gfx::Rect layer_in_surface_space =
83 MathUtil::MapClippedRect(transform, layer_bound_rect);
84 return CalculateVisibleRectWithCachedLayerRect(
85 target_surface_rect, layer_bound_rect, layer_in_surface_space, transform);
88 template <typename LayerType> static inline bool IsRootLayer(LayerType* layer) {
89 return !layer->parent();
92 template <typename LayerType>
93 static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) {
94 // According to current W3C spec on CSS transforms, a layer is part of an
95 // established 3d rendering context if its parent has transform-style of
96 // preserves-3d.
97 return layer->parent() && layer->parent()->preserves_3d();
100 template <typename LayerType>
101 static bool IsRootLayerOfNewRenderingContext(LayerType* layer) {
102 // According to current W3C spec on CSS transforms (Section 6.1), a layer is
103 // the beginning of 3d rendering context if its parent does not have
104 // transform-style: preserve-3d, but this layer itself does.
105 if (layer->parent())
106 return !layer->parent()->preserves_3d() && layer->preserves_3d();
108 return layer->preserves_3d();
111 template <typename LayerType>
112 static bool IsLayerBackFaceVisible(LayerType* layer) {
113 // The current W3C spec on CSS transforms says that backface visibility should
114 // be determined differently depending on whether the layer is in a "3d
115 // rendering context" or not. For Chromium code, we can determine whether we
116 // are in a 3d rendering context by checking if the parent preserves 3d.
118 if (LayerIsInExisting3DRenderingContext(layer))
119 return layer->draw_transform().IsBackFaceVisible();
121 // In this case, either the layer establishes a new 3d rendering context, or
122 // is not in a 3d rendering context at all.
123 return layer->transform().IsBackFaceVisible();
126 template <typename LayerType>
127 static bool IsSurfaceBackFaceVisible(LayerType* layer,
128 const gfx::Transform& draw_transform) {
129 if (LayerIsInExisting3DRenderingContext(layer))
130 return draw_transform.IsBackFaceVisible();
132 if (IsRootLayerOfNewRenderingContext(layer))
133 return layer->transform().IsBackFaceVisible();
135 // If the render_surface is not part of a new or existing rendering context,
136 // then the layers that contribute to this surface will decide back-face
137 // visibility for themselves.
138 return false;
141 template <typename LayerType>
142 static inline bool LayerClipsSubtree(LayerType* layer) {
143 return layer->masks_to_bounds() || layer->mask_layer();
146 template <typename LayerType>
147 static gfx::Rect CalculateVisibleContentRect(
148 LayerType* layer,
149 gfx::Rect ancestor_clip_rect_in_descendant_surface_space,
150 gfx::Rect layer_rect_in_target_space) {
151 DCHECK(layer->render_target());
153 // Nothing is visible if the layer bounds are empty.
154 if (!layer->DrawsContent() || layer->content_bounds().IsEmpty() ||
155 layer->drawable_content_rect().IsEmpty())
156 return gfx::Rect();
158 // Compute visible bounds in target surface space.
159 gfx::Rect visible_rect_in_target_surface_space =
160 layer->drawable_content_rect();
162 if (!layer->render_target()->render_surface()->clip_rect().IsEmpty()) {
163 // In this case the target surface does clip layers that contribute to
164 // it. So, we have to convert the current surface's clip rect from its
165 // ancestor surface space to the current (descendant) surface
166 // space. This conversion is done outside this function so that it can
167 // be cached instead of computing it redundantly for every layer.
168 visible_rect_in_target_surface_space.Intersect(
169 ancestor_clip_rect_in_descendant_surface_space);
172 if (visible_rect_in_target_surface_space.IsEmpty())
173 return gfx::Rect();
175 return CalculateVisibleRectWithCachedLayerRect(
176 visible_rect_in_target_surface_space,
177 gfx::Rect(layer->content_bounds()),
178 layer_rect_in_target_space,
179 layer->draw_transform());
182 static inline bool TransformToParentIsKnown(LayerImpl* layer) { return true; }
184 static inline bool TransformToParentIsKnown(Layer* layer) {
185 return !layer->TransformIsAnimating();
188 static inline bool TransformToScreenIsKnown(LayerImpl* layer) { return true; }
190 static inline bool TransformToScreenIsKnown(Layer* layer) {
191 return !layer->screen_space_transform_is_animating();
194 template <typename LayerType>
195 static bool LayerShouldBeSkipped(LayerType* layer) {
196 // Layers can be skipped if any of these conditions are met.
197 // - does not draw content.
198 // - is transparent
199 // - has empty bounds
200 // - the layer is not double-sided, but its back face is visible.
202 // Some additional conditions need to be computed at a later point after the
203 // recursion is finished.
204 // - the intersection of render_surface content and layer clip_rect is empty
205 // - the visible_content_rect is empty
207 // Note, if the layer should not have been drawn due to being fully
208 // transparent, we would have skipped the entire subtree and never made it
209 // into this function, so it is safe to omit this check here.
211 if (!layer->DrawsContent() || layer->bounds().IsEmpty())
212 return true;
214 LayerType* backface_test_layer = layer;
215 if (layer->use_parent_backface_visibility()) {
216 DCHECK(layer->parent());
217 DCHECK(!layer->parent()->use_parent_backface_visibility());
218 backface_test_layer = layer->parent();
221 // The layer should not be drawn if (1) it is not double-sided and (2) the
222 // back of the layer is known to be facing the screen.
223 if (!backface_test_layer->double_sided() &&
224 TransformToScreenIsKnown(backface_test_layer) &&
225 IsLayerBackFaceVisible(backface_test_layer))
226 return true;
228 return false;
231 static inline bool SubtreeShouldBeSkipped(LayerImpl* layer) {
232 // If layer is on the pending tree and opacity is being animated then
233 // this subtree can't be skipped as we need to create, prioritize and
234 // include tiles for this layer when deciding if tree can be activated.
235 if (layer->layer_tree_impl()->IsPendingTree() && layer->OpacityIsAnimating())
236 return false;
238 // The opacity of a layer always applies to its children (either implicitly
239 // via a render surface or explicitly if the parent preserves 3D), so the
240 // entire subtree can be skipped if this layer is fully transparent.
241 return !layer->opacity();
244 static inline bool SubtreeShouldBeSkipped(Layer* layer) {
245 // If the opacity is being animated then the opacity on the main thread is
246 // unreliable (since the impl thread may be using a different opacity), so it
247 // should not be trusted.
248 // In particular, it should not cause the subtree to be skipped.
249 // Similarly, for layers that might animate opacity using an impl-only
250 // animation, their subtree should also not be skipped.
251 return !layer->opacity() && !layer->OpacityIsAnimating() &&
252 !layer->OpacityCanAnimateOnImplThread();
255 // Called on each layer that could be drawn after all information from
256 // CalcDrawProperties has been updated on that layer. May have some false
257 // positives (e.g. layers get this called on them but don't actually get drawn).
258 static inline void UpdateTilePrioritiesForLayer(LayerImpl* layer) {
259 layer->UpdateTilePriorities();
261 // Mask layers don't get this call, so explicitly update them so they can
262 // kick off tile rasterization.
263 if (layer->mask_layer())
264 layer->mask_layer()->UpdateTilePriorities();
265 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
266 layer->replica_layer()->mask_layer()->UpdateTilePriorities();
269 static inline void UpdateTilePrioritiesForLayer(Layer* layer) {}
271 static inline void SavePaintPropertiesLayer(LayerImpl* layer) {}
273 static inline void SavePaintPropertiesLayer(Layer* layer) {
274 layer->SavePaintProperties();
276 if (layer->mask_layer())
277 layer->mask_layer()->SavePaintProperties();
278 if (layer->replica_layer() && layer->replica_layer()->mask_layer())
279 layer->replica_layer()->mask_layer()->SavePaintProperties();
282 template <typename LayerType>
283 static bool SubtreeShouldRenderToSeparateSurface(
284 LayerType* layer,
285 bool axis_aligned_with_respect_to_parent) {
287 // A layer and its descendants should render onto a new RenderSurfaceImpl if
288 // any of these rules hold:
291 // The root layer should always have a render_surface.
292 if (IsRootLayer(layer))
293 return true;
295 // If we force it.
296 if (layer->force_render_surface())
297 return true;
299 // If the layer uses a mask.
300 if (layer->mask_layer())
301 return true;
303 // If the layer has a reflection.
304 if (layer->replica_layer())
305 return true;
307 // If the layer uses a CSS filter.
308 if (!layer->filters().isEmpty() || !layer->background_filters().isEmpty() ||
309 layer->filter())
310 return true;
312 int num_descendants_that_draw_content =
313 layer->draw_properties().num_descendants_that_draw_content;
315 // If the layer flattens its subtree (i.e. the layer doesn't preserve-3d), but
316 // it is treated as a 3D object by its parent (i.e. parent does preserve-3d).
317 if (LayerIsInExisting3DRenderingContext(layer) && !layer->preserves_3d() &&
318 num_descendants_that_draw_content > 0) {
319 TRACE_EVENT_INSTANT0(
320 "cc",
321 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface flattening",
322 TRACE_EVENT_SCOPE_THREAD);
323 return true;
326 // If the layer clips its descendants but it is not axis-aligned with respect
327 // to its parent.
328 bool layer_clips_external_content =
329 LayerClipsSubtree(layer) || layer->HasDelegatedContent();
330 if (layer_clips_external_content && !axis_aligned_with_respect_to_parent &&
331 !layer->draw_properties().descendants_can_clip_selves) {
332 TRACE_EVENT_INSTANT0(
333 "cc",
334 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface clipping",
335 TRACE_EVENT_SCOPE_THREAD);
336 return true;
339 // If the layer has some translucency and does not have a preserves-3d
340 // transform style. This condition only needs a render surface if two or more
341 // layers in the subtree overlap. But checking layer overlaps is unnecessarily
342 // costly so instead we conservatively create a surface whenever at least two
343 // layers draw content for this subtree.
344 bool at_least_two_layers_in_subtree_draw_content =
345 num_descendants_that_draw_content > 0 &&
346 (layer->DrawsContent() || num_descendants_that_draw_content > 1);
348 if (layer->opacity() != 1.f && !layer->preserves_3d() &&
349 at_least_two_layers_in_subtree_draw_content) {
350 TRACE_EVENT_INSTANT0(
351 "cc",
352 "LayerTreeHostCommon::SubtreeShouldRenderToSeparateSurface opacity",
353 TRACE_EVENT_SCOPE_THREAD);
354 return true;
357 return false;
360 static LayerImpl* NextTargetSurface(LayerImpl* layer) {
361 return layer->parent() ? layer->parent()->render_target() : 0;
364 // This function returns a translation matrix that can be applied on a vector
365 // that's in the layer's target surface coordinate, while the position offset is
366 // specified in some ancestor layer's coordinate.
367 gfx::Transform ComputeSizeDeltaCompensation(
368 LayerImpl* layer,
369 LayerImpl* container,
370 const gfx::Vector2dF& position_offset) {
371 gfx::Transform result_transform;
373 // To apply a translate in the container's layer space,
374 // the following steps need to be done:
375 // Step 1a. transform from target surface space to the container's target
376 // surface space
377 // Step 1b. transform from container's target surface space to the
378 // container's layer space
379 // Step 2. apply the compensation
380 // Step 3. transform back to target surface space
382 gfx::Transform target_surface_space_to_container_layer_space;
383 // Calculate step 1a
384 LayerImpl* container_target_surface =
385 container ? container->render_target() : 0;
386 for (LayerImpl* current_target_surface = NextTargetSurface(layer);
387 current_target_surface &&
388 current_target_surface != container_target_surface;
389 current_target_surface = NextTargetSurface(current_target_surface)) {
390 // Note: Concat is used here to convert the result coordinate space from
391 // current render surface to the next render surface.
392 target_surface_space_to_container_layer_space.ConcatTransform(
393 current_target_surface->render_surface()->draw_transform());
395 // Calculate step 1b
396 if (container) {
397 gfx::Transform container_layer_space_to_container_target_surface_space =
398 container->draw_transform();
399 container_layer_space_to_container_target_surface_space.Scale(
400 container->contents_scale_x(), container->contents_scale_y());
402 gfx::Transform container_target_surface_space_to_container_layer_space;
403 if (container_layer_space_to_container_target_surface_space.GetInverse(
404 &container_target_surface_space_to_container_layer_space)) {
405 // Note: Again, Concat is used to conver the result coordinate space from
406 // the container render surface to the container layer.
407 target_surface_space_to_container_layer_space.ConcatTransform(
408 container_target_surface_space_to_container_layer_space);
412 // Apply step 3
413 gfx::Transform container_layer_space_to_target_surface_space;
414 if (target_surface_space_to_container_layer_space.GetInverse(
415 &container_layer_space_to_target_surface_space))
416 result_transform.PreconcatTransform(
417 container_layer_space_to_target_surface_space);
418 else {
419 // FIXME: A non-invertible matrix could still make meaningful projection.
420 // For example ScaleZ(0) is non-invertible but the layer is still visible.
421 return gfx::Transform();
424 // Apply step 2
425 result_transform.Translate(position_offset.x(), position_offset.y());
427 // Apply step 1
428 result_transform.PreconcatTransform(
429 target_surface_space_to_container_layer_space);
431 return result_transform;
434 void ApplyPositionAdjustment(
435 Layer* layer,
436 Layer* container,
437 const gfx::Transform& scroll_compensation,
438 gfx::Transform* combined_transform) { }
439 void ApplyPositionAdjustment(
440 LayerImpl* layer,
441 LayerImpl* container,
442 const gfx::Transform& scroll_compensation,
443 gfx::Transform* combined_transform)
445 if (!layer->position_constraint().is_fixed_position())
446 return;
448 // Special case: this layer is a composited fixed-position layer; we need to
449 // explicitly compensate for all ancestors' nonzero scroll_deltas to keep
450 // this layer fixed correctly.
451 // Note carefully: this is Concat, not Preconcat
452 // (current_scroll_compensation * combined_transform).
453 combined_transform->ConcatTransform(scroll_compensation);
455 // For right-edge or bottom-edge anchored fixed position layers,
456 // the layer should relocate itself if the container changes its size.
457 bool fixed_to_right_edge =
458 layer->position_constraint().is_fixed_to_right_edge();
459 bool fixed_to_bottom_edge =
460 layer->position_constraint().is_fixed_to_bottom_edge();
461 gfx::Vector2dF position_offset =
462 container ? container->fixed_container_size_delta() : gfx::Vector2dF();
463 position_offset.set_x(fixed_to_right_edge ? position_offset.x() : 0);
464 position_offset.set_y(fixed_to_bottom_edge ? position_offset.y() : 0);
465 if (position_offset.IsZero())
466 return;
468 // Note: Again, this is Concat. The compensation matrix will be applied on
469 // the vector in target surface space.
470 combined_transform->ConcatTransform(
471 ComputeSizeDeltaCompensation(layer, container, position_offset));
474 gfx::Transform ComputeScrollCompensationForThisLayer(
475 LayerImpl* scrolling_layer,
476 const gfx::Transform& parent_matrix) {
477 // For every layer that has non-zero scroll_delta, we have to compute a
478 // transform that can undo the scroll_delta translation. In particular, we
479 // want this matrix to premultiply a fixed-position layer's parent_matrix, so
480 // we design this transform in three steps as follows. The steps described
481 // here apply from right-to-left, so Step 1 would be the right-most matrix:
483 // Step 1. transform from target surface space to the exact space where
484 // scroll_delta is actually applied.
485 // -- this is inverse of the matrix in step 3
486 // Step 2. undo the scroll_delta
487 // -- this is just a translation by scroll_delta.
488 // Step 3. transform back to target surface space.
489 // -- this transform is the "partial_layer_origin_transform" =
490 // (parent_matrix * scale(layer->pageScaleDelta()));
492 // These steps create a matrix that both start and end in target surface
493 // space. So this matrix can pre-multiply any fixed-position layer's
494 // draw_transform to undo the scroll_deltas -- as long as that fixed position
495 // layer is fixed onto the same render_target as this scrolling_layer.
498 gfx::Transform partial_layer_origin_transform = parent_matrix;
499 partial_layer_origin_transform.PreconcatTransform(
500 scrolling_layer->impl_transform());
502 gfx::Transform scroll_compensation_for_this_layer =
503 partial_layer_origin_transform; // Step 3
504 scroll_compensation_for_this_layer.Translate(
505 scrolling_layer->scroll_delta().x(),
506 scrolling_layer->scroll_delta().y()); // Step 2
508 gfx::Transform inverse_partial_layer_origin_transform(
509 gfx::Transform::kSkipInitialization);
510 if (!partial_layer_origin_transform.GetInverse(
511 &inverse_partial_layer_origin_transform)) {
512 // TODO(shawnsingh): Either we need to handle uninvertible transforms
513 // here, or DCHECK that the transform is invertible.
515 scroll_compensation_for_this_layer.PreconcatTransform(
516 inverse_partial_layer_origin_transform); // Step 1
517 return scroll_compensation_for_this_layer;
520 gfx::Transform ComputeScrollCompensationMatrixForChildren(
521 Layer* current_layer,
522 const gfx::Transform& current_parent_matrix,
523 const gfx::Transform& current_scroll_compensation) {
524 // The main thread (i.e. Layer) does not need to worry about scroll
525 // compensation. So we can just return an identity matrix here.
526 return gfx::Transform();
529 gfx::Transform ComputeScrollCompensationMatrixForChildren(
530 LayerImpl* layer,
531 const gfx::Transform& parent_matrix,
532 const gfx::Transform& current_scroll_compensation_matrix) {
533 // "Total scroll compensation" is the transform needed to cancel out all
534 // scroll_delta translations that occurred since the nearest container layer,
535 // even if there are render_surfaces in-between.
537 // There are some edge cases to be aware of, that are not explicit in the
538 // code:
539 // - A layer that is both a fixed-position and container should not be its
540 // own container, instead, that means it is fixed to an ancestor, and is a
541 // container for any fixed-position descendants.
542 // - A layer that is a fixed-position container and has a render_surface
543 // should behave the same as a container without a render_surface, the
544 // render_surface is irrelevant in that case.
545 // - A layer that does not have an explicit container is simply fixed to the
546 // viewport. (i.e. the root render_surface.)
547 // - If the fixed-position layer has its own render_surface, then the
548 // render_surface is the one who gets fixed.
550 // This function needs to be called AFTER layers create their own
551 // render_surfaces.
554 // Avoid the overheads (including stack allocation and matrix
555 // initialization/copy) if we know that the scroll compensation doesn't need
556 // to be reset or adjusted.
557 if (!layer->IsContainerForFixedPositionLayers() &&
558 layer->scroll_delta().IsZero() && !layer->render_surface())
559 return current_scroll_compensation_matrix;
561 // Start as identity matrix.
562 gfx::Transform next_scroll_compensation_matrix;
564 // If this layer is not a container, then it inherits the existing scroll
565 // compensations.
566 if (!layer->IsContainerForFixedPositionLayers())
567 next_scroll_compensation_matrix = current_scroll_compensation_matrix;
569 // If the current layer has a non-zero scroll_delta, then we should compute
570 // its local scroll compensation and accumulate it to the
571 // next_scroll_compensation_matrix.
572 if (!layer->scroll_delta().IsZero()) {
573 gfx::Transform scroll_compensation_for_this_layer =
574 ComputeScrollCompensationForThisLayer(layer, parent_matrix);
575 next_scroll_compensation_matrix.PreconcatTransform(
576 scroll_compensation_for_this_layer);
579 // If the layer created its own render_surface, we have to adjust
580 // next_scroll_compensation_matrix. The adjustment allows us to continue
581 // using the scroll compensation on the next surface.
582 // Step 1 (right-most in the math): transform from the new surface to the
583 // original ancestor surface
584 // Step 2: apply the scroll compensation
585 // Step 3: transform back to the new surface.
586 if (layer->render_surface() &&
587 !next_scroll_compensation_matrix.IsIdentity()) {
588 gfx::Transform inverse_surface_draw_transform(
589 gfx::Transform::kSkipInitialization);
590 if (!layer->render_surface()->draw_transform().GetInverse(
591 &inverse_surface_draw_transform)) {
592 // TODO(shawnsingh): Either we need to handle uninvertible transforms
593 // here, or DCHECK that the transform is invertible.
595 next_scroll_compensation_matrix =
596 inverse_surface_draw_transform * next_scroll_compensation_matrix *
597 layer->render_surface()->draw_transform();
600 return next_scroll_compensation_matrix;
603 template <typename LayerType>
604 static inline void CalculateContentsScale(LayerType* layer,
605 float contents_scale,
606 bool animating_transform_to_screen) {
607 layer->CalculateContentsScale(contents_scale,
608 animating_transform_to_screen,
609 &layer->draw_properties().contents_scale_x,
610 &layer->draw_properties().contents_scale_y,
611 &layer->draw_properties().content_bounds);
613 LayerType* mask_layer = layer->mask_layer();
614 if (mask_layer) {
615 mask_layer->CalculateContentsScale(
616 contents_scale,
617 animating_transform_to_screen,
618 &mask_layer->draw_properties().contents_scale_x,
619 &mask_layer->draw_properties().contents_scale_y,
620 &mask_layer->draw_properties().content_bounds);
623 LayerType* replica_mask_layer =
624 layer->replica_layer() ? layer->replica_layer()->mask_layer() : NULL;
625 if (replica_mask_layer) {
626 replica_mask_layer->CalculateContentsScale(
627 contents_scale,
628 animating_transform_to_screen,
629 &replica_mask_layer->draw_properties().contents_scale_x,
630 &replica_mask_layer->draw_properties().contents_scale_y,
631 &replica_mask_layer->draw_properties().content_bounds);
635 static inline void UpdateLayerContentsScale(
636 LayerImpl* layer,
637 const gfx::Transform& combined_transform,
638 float device_scale_factor,
639 float page_scale_factor,
640 bool animating_transform_to_screen) {
641 gfx::Vector2dF transform_scale = MathUtil::ComputeTransform2dScaleComponents(
642 combined_transform, device_scale_factor * page_scale_factor);
643 float contents_scale = std::max(transform_scale.x(), transform_scale.y());
644 CalculateContentsScale(layer, contents_scale, animating_transform_to_screen);
647 static inline void UpdateLayerContentsScale(
648 Layer* layer,
649 const gfx::Transform& combined_transform,
650 float device_scale_factor,
651 float page_scale_factor,
652 bool animating_transform_to_screen) {
653 float raster_scale = layer->raster_scale();
655 if (layer->automatically_compute_raster_scale()) {
656 gfx::Vector2dF transform_scale =
657 MathUtil::ComputeTransform2dScaleComponents(combined_transform, 0.f);
658 float combined_scale = std::max(transform_scale.x(), transform_scale.y());
659 float ideal_raster_scale = combined_scale / device_scale_factor;
660 if (!layer->bounds_contain_page_scale())
661 ideal_raster_scale /= page_scale_factor;
663 bool need_to_set_raster_scale = !raster_scale;
665 // If we've previously saved a raster_scale but the ideal changes, things
666 // are unpredictable and we should just use 1.
667 if (raster_scale && raster_scale != 1.f &&
668 ideal_raster_scale != raster_scale) {
669 ideal_raster_scale = 1.f;
670 need_to_set_raster_scale = true;
673 if (need_to_set_raster_scale) {
674 bool use_and_save_ideal_scale =
675 ideal_raster_scale >= 1.f && !animating_transform_to_screen;
676 if (use_and_save_ideal_scale) {
677 raster_scale = ideal_raster_scale;
678 layer->SetRasterScale(raster_scale);
683 if (!raster_scale)
684 raster_scale = 1.f;
686 float contents_scale = raster_scale * device_scale_factor;
687 if (!layer->bounds_contain_page_scale())
688 contents_scale *= page_scale_factor;
690 CalculateContentsScale(layer, contents_scale, animating_transform_to_screen);
693 template <typename LayerType, typename LayerList>
694 static inline void RemoveSurfaceForEarlyExit(
695 LayerType* layer_to_remove,
696 LayerList* render_surface_layer_list) {
697 DCHECK(layer_to_remove->render_surface());
698 // Technically, we know that the layer we want to remove should be
699 // at the back of the render_surface_layer_list. However, we have had
700 // bugs before that added unnecessary layers here
701 // (https://bugs.webkit.org/show_bug.cgi?id=74147), but that causes
702 // things to crash. So here we proactively remove any additional
703 // layers from the end of the list.
704 while (render_surface_layer_list->back() != layer_to_remove) {
705 render_surface_layer_list->back()->ClearRenderSurface();
706 render_surface_layer_list->pop_back();
708 DCHECK_EQ(render_surface_layer_list->back(), layer_to_remove);
709 render_surface_layer_list->pop_back();
710 layer_to_remove->ClearRenderSurface();
713 // Recursively walks the layer tree to compute any information that is needed
714 // before doing the main recursion.
715 template <typename LayerType>
716 static void PreCalculateMetaInformation(LayerType* layer) {
717 if (layer->HasDelegatedContent()) {
718 // Layers with delegated content need to be treated as if they have as many
719 // children as the number of layers they own delegated quads for. Since we
720 // don't know this number right now, we choose one that acts like infinity
721 // for our purposes.
722 layer->draw_properties().num_descendants_that_draw_content = 1000;
723 layer->draw_properties().descendants_can_clip_selves = false;
724 return;
727 int num_descendants_that_draw_content = 0;
728 bool descendants_can_clip_selves = true;
729 bool sublayer_transform_prevents_clip =
730 !layer->sublayer_transform().IsPositiveScaleOrTranslation();
732 for (size_t i = 0; i < layer->children().size(); ++i) {
733 LayerType* child_layer = layer->children()[i];
734 PreCalculateMetaInformation<LayerType>(child_layer);
736 num_descendants_that_draw_content += child_layer->DrawsContent() ? 1 : 0;
737 num_descendants_that_draw_content +=
738 child_layer->draw_properties().num_descendants_that_draw_content;
740 if ((child_layer->DrawsContent() && !child_layer->CanClipSelf()) ||
741 !child_layer->draw_properties().descendants_can_clip_selves ||
742 sublayer_transform_prevents_clip ||
743 !child_layer->transform().IsPositiveScaleOrTranslation())
744 descendants_can_clip_selves = false;
747 layer->draw_properties().num_descendants_that_draw_content =
748 num_descendants_that_draw_content;
749 layer->draw_properties().descendants_can_clip_selves =
750 descendants_can_clip_selves;
753 static void RoundTranslationComponents(gfx::Transform* transform) {
754 transform->matrix().
755 setDouble(0, 3, MathUtil::Round(transform->matrix().getDouble(0, 3)));
756 transform->matrix().
757 setDouble(1, 3, MathUtil::Round(transform->matrix().getDouble(1, 3)));
760 // Recursively walks the layer tree starting at the given node and computes all
761 // the necessary transformations, clip rects, render surfaces, etc.
762 template <typename LayerType, typename LayerList, typename RenderSurfaceType>
763 static void CalculateDrawPropertiesInternal(
764 LayerType* layer,
765 const gfx::Transform& parent_matrix,
766 const gfx::Transform& full_hierarchy_matrix,
767 const gfx::Transform& current_scroll_compensation_matrix,
768 LayerType* current_fixed_container,
769 gfx::Rect clip_rect_from_ancestor,
770 gfx::Rect clip_rect_from_ancestor_in_descendant_space,
771 bool ancestor_clips_subtree,
772 RenderSurfaceType* nearest_ancestor_that_moves_pixels,
773 LayerList* render_surface_layer_list,
774 LayerList* layer_list,
775 LayerSorter* layer_sorter,
776 int max_texture_size,
777 float device_scale_factor,
778 float page_scale_factor,
779 bool subtree_can_use_lcd_text,
780 gfx::Rect* drawable_content_rect_of_subtree,
781 bool update_tile_priorities) {
782 // This function computes the new matrix transformations recursively for this
783 // layer and all its descendants. It also computes the appropriate render
784 // surfaces.
785 // Some important points to remember:
787 // 0. Here, transforms are notated in Matrix x Vector order, and in words we
788 // describe what the transform does from left to right.
790 // 1. In our terminology, the "layer origin" refers to the top-left corner of
791 // a layer, and the positive Y-axis points downwards. This interpretation is
792 // valid because the orthographic projection applied at draw time flips the Y
793 // axis appropriately.
795 // 2. The anchor point, when given as a PointF object, is specified in "unit
796 // layer space", where the bounds of the layer map to [0, 1]. However, as a
797 // Transform object, the transform to the anchor point is specified in "layer
798 // space", where the bounds of the layer map to [bounds.width(),
799 // bounds.height()].
801 // 3. Definition of various transforms used:
802 // M[parent] is the parent matrix, with respect to the nearest render
803 // surface, passed down recursively.
805 // M[root] is the full hierarchy, with respect to the root, passed down
806 // recursively.
808 // Tr[origin] is the translation matrix from the parent's origin to
809 // this layer's origin.
811 // Tr[origin2anchor] is the translation from the layer's origin to its
812 // anchor point
814 // Tr[origin2center] is the translation from the layer's origin to its
815 // center
817 // M[layer] is the layer's matrix (applied at the anchor point)
819 // M[sublayer] is the layer's sublayer transform (also applied at the
820 // layer's anchor point)
822 // S[layer2content] is the ratio of a layer's content_bounds() to its
823 // Bounds().
825 // Some composite transforms can help in understanding the sequence of
826 // transforms:
827 // composite_layer_transform = Tr[origin2anchor] * M[layer] *
828 // Tr[origin2anchor].inverse()
830 // composite_sublayer_transform = Tr[origin2anchor] * M[sublayer] *
831 // Tr[origin2anchor].inverse()
833 // 4. When a layer (or render surface) is drawn, it is drawn into a "target
834 // render surface". Therefore the draw transform does not necessarily
835 // transform from screen space to local layer space. Instead, the draw
836 // transform is the transform between the "target render surface space" and
837 // local layer space. Note that render surfaces, except for the root, also
838 // draw themselves into a different target render surface, and so their draw
839 // transform and origin transforms are also described with respect to the
840 // target.
842 // Using these definitions, then:
844 // The draw transform for the layer is:
845 // M[draw] = M[parent] * Tr[origin] * composite_layer_transform *
846 // S[layer2content] = M[parent] * Tr[layer->position() + anchor] *
847 // M[layer] * Tr[anchor2origin] * S[layer2content]
849 // Interpreting the math left-to-right, this transforms from the
850 // layer's render surface to the origin of the layer in content space.
852 // The screen space transform is:
853 // M[screenspace] = M[root] * Tr[origin] * composite_layer_transform *
854 // S[layer2content]
855 // = M[root] * Tr[layer->position() + anchor] * M[layer]
856 // * Tr[anchor2origin] * S[layer2content]
858 // Interpreting the math left-to-right, this transforms from the root
859 // render surface's content space to the origin of the layer in content
860 // space.
862 // The transform hierarchy that is passed on to children (i.e. the child's
863 // parent_matrix) is:
864 // M[parent]_for_child = M[parent] * Tr[origin] *
865 // composite_layer_transform * composite_sublayer_transform
866 // = M[parent] * Tr[layer->position() + anchor] *
867 // M[layer] * Tr[anchor2origin] *
868 // composite_sublayer_transform
870 // and a similar matrix for the full hierarchy with respect to the
871 // root.
873 // Finally, note that the final matrix used by the shader for the layer is P *
874 // M[draw] * S . This final product is computed in drawTexturedQuad(), where:
875 // P is the projection matrix
876 // S is the scale adjustment (to scale up a canonical quad to the
877 // layer's size)
879 // When a render surface has a replica layer, that layer's transform is used
880 // to draw a second copy of the surface. gfx::Transforms named here are
881 // relative to the surface, unless they specify they are relative to the
882 // replica layer.
884 // We will denote a scale by device scale S[deviceScale]
886 // The render surface draw transform to its target surface origin is:
887 // M[surfaceDraw] = M[owningLayer->Draw]
889 // The render surface origin transform to its the root (screen space) origin
890 // is:
891 // M[surface2root] = M[owningLayer->screenspace] *
892 // S[deviceScale].inverse()
894 // The replica draw transform to its target surface origin is:
895 // M[replicaDraw] = S[deviceScale] * M[surfaceDraw] *
896 // Tr[replica->position() + replica->anchor()] * Tr[replica] *
897 // Tr[origin2anchor].inverse() * S[contents_scale].inverse()
899 // The replica draw transform to the root (screen space) origin is:
900 // M[replica2root] = M[surface2root] * Tr[replica->position()] *
901 // Tr[replica] * Tr[origin2anchor].inverse()
904 // If we early-exit anywhere in this function, the drawable_content_rect of
905 // this subtree should be considered empty.
906 *drawable_content_rect_of_subtree = gfx::Rect();
908 // The root layer cannot skip CalcDrawProperties.
909 if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer))
910 return;
912 // As this function proceeds, these are the properties for the current
913 // layer that actually get computed. To avoid unnecessary copies
914 // (particularly for matrices), we do computations directly on these values
915 // when possible.
916 DrawProperties<LayerType, RenderSurfaceType>& layer_draw_properties =
917 layer->draw_properties();
919 gfx::Rect clip_rect_for_subtree;
920 bool subtree_should_be_clipped = false;
922 // This value is cached on the stack so that we don't have to inverse-project
923 // the surface's clip rect redundantly for every layer. This value is the
924 // same as the surface's clip rect, except that instead of being described
925 // in the target surface space (i.e. the ancestor surface space), it is
926 // described in the current surface space.
927 gfx::Rect clip_rect_for_subtree_in_descendant_space;
929 float accumulated_draw_opacity = layer->opacity();
930 bool animating_opacity_to_target = layer->OpacityIsAnimating();
931 bool animating_opacity_to_screen = animating_opacity_to_target;
932 if (layer->parent()) {
933 accumulated_draw_opacity *= layer->parent()->draw_opacity();
934 animating_opacity_to_target |= layer->parent()->draw_opacity_is_animating();
935 animating_opacity_to_screen |=
936 layer->parent()->screen_space_opacity_is_animating();
939 bool animating_transform_to_target = layer->TransformIsAnimating();
940 bool animating_transform_to_screen = animating_transform_to_target;
941 if (layer->parent()) {
942 animating_transform_to_target |=
943 layer->parent()->draw_transform_is_animating();
944 animating_transform_to_screen |=
945 layer->parent()->screen_space_transform_is_animating();
948 gfx::Size bounds = layer->bounds();
949 gfx::PointF anchor_point = layer->anchor_point();
950 gfx::PointF position = layer->position() - layer->scroll_delta();
952 gfx::Transform combined_transform = parent_matrix;
953 if (!layer->transform().IsIdentity()) {
954 // LT = Tr[origin] * Tr[origin2anchor]
955 combined_transform.Translate3d(
956 position.x() + anchor_point.x() * bounds.width(),
957 position.y() + anchor_point.y() * bounds.height(),
958 layer->anchor_point_z());
959 // LT = Tr[origin] * Tr[origin2anchor] * M[layer]
960 combined_transform.PreconcatTransform(layer->transform());
961 // LT = Tr[origin] * Tr[origin2anchor] * M[layer] * Tr[anchor2origin]
962 combined_transform.Translate3d(-anchor_point.x() * bounds.width(),
963 -anchor_point.y() * bounds.height(),
964 -layer->anchor_point_z());
965 } else {
966 combined_transform.Translate(position.x(), position.y());
969 // The layer's contents_scale is determined from the combined_transform, which
970 // then informs the layer's draw_transform.
971 UpdateLayerContentsScale(layer,
972 combined_transform,
973 device_scale_factor,
974 page_scale_factor,
975 animating_transform_to_screen);
977 // If there is a transformation from the impl thread then it should be at
978 // the start of the combined_transform, but we don't want it to affect the
979 // computation of contents_scale above.
980 // Note carefully: this is Concat, not Preconcat (impl_transform *
981 // combined_transform).
982 combined_transform.ConcatTransform(layer->impl_transform());
984 if (!animating_transform_to_target && layer->scrollable() &&
985 combined_transform.IsScaleOrTranslation()) {
986 // Align the scrollable layer's position to screen space pixels to avoid
987 // blurriness. To avoid side-effects, do this only if the transform is
988 // simple.
989 RoundTranslationComponents(&combined_transform);
992 // Apply adjustment from position constraints.
993 ApplyPositionAdjustment(layer, current_fixed_container,
994 current_scroll_compensation_matrix, &combined_transform);
996 // The draw_transform that gets computed below is effectively the layer's
997 // draw_transform, unless the layer itself creates a render_surface. In that
998 // case, the render_surface re-parents the transforms.
999 layer_draw_properties.target_space_transform = combined_transform;
1000 // M[draw] = M[parent] * LT * S[layer2content]
1001 layer_draw_properties.target_space_transform.Scale
1002 (1.f / layer->contents_scale_x(), 1.f / layer->contents_scale_y());
1004 // The layer's screen_space_transform represents the transform between root
1005 // layer's "screen space" and local content space.
1006 layer_draw_properties.screen_space_transform = full_hierarchy_matrix;
1007 if (!layer->preserves_3d())
1008 layer_draw_properties.screen_space_transform.FlattenTo2d();
1009 layer_draw_properties.screen_space_transform.PreconcatTransform
1010 (layer_draw_properties.target_space_transform);
1012 // Adjusting text AA method during animation may cause repaints, which in-turn
1013 // causes jank.
1014 bool adjust_text_aa =
1015 !animating_opacity_to_screen && !animating_transform_to_screen;
1016 // To avoid color fringing, LCD text should only be used on opaque layers with
1017 // just integral translation.
1018 bool layer_can_use_lcd_text =
1019 subtree_can_use_lcd_text && (accumulated_draw_opacity == 1.f) &&
1020 layer_draw_properties.target_space_transform.
1021 IsIdentityOrIntegerTranslation();
1023 gfx::RectF content_rect(layer->content_bounds());
1025 // full_hierarchy_matrix is the matrix that transforms objects between screen
1026 // space (except projection matrix) and the most recent RenderSurfaceImpl's
1027 // space. next_hierarchy_matrix will only change if this layer uses a new
1028 // RenderSurfaceImpl, otherwise remains the same.
1029 gfx::Transform next_hierarchy_matrix = full_hierarchy_matrix;
1030 gfx::Transform sublayer_matrix;
1032 gfx::Vector2dF render_surface_sublayer_scale =
1033 MathUtil::ComputeTransform2dScaleComponents(
1034 combined_transform, device_scale_factor * page_scale_factor);
1036 if (SubtreeShouldRenderToSeparateSurface(
1037 layer, combined_transform.IsScaleOrTranslation())) {
1038 // Check back-face visibility before continuing with this surface and its
1039 // subtree
1040 if (!layer->double_sided() && TransformToParentIsKnown(layer) &&
1041 IsSurfaceBackFaceVisible(layer, combined_transform))
1042 return;
1044 if (!layer->render_surface())
1045 layer->CreateRenderSurface();
1047 RenderSurfaceType* render_surface = layer->render_surface();
1048 render_surface->ClearLayerLists();
1050 // The owning layer's draw transform has a scale from content to layer
1051 // space which we do not want; so here we use the combined_transform
1052 // instead of the draw_transform. However, we do need to add a different
1053 // scale factor that accounts for the surface's pixel dimensions.
1054 combined_transform.Scale(1.0 / render_surface_sublayer_scale.x(),
1055 1.0 / render_surface_sublayer_scale.y());
1056 render_surface->SetDrawTransform(combined_transform);
1058 // The owning layer's transform was re-parented by the surface, so the
1059 // layer's new draw_transform only needs to scale the layer to surface
1060 // space.
1061 layer_draw_properties.target_space_transform.MakeIdentity();
1062 layer_draw_properties.target_space_transform.
1063 Scale(render_surface_sublayer_scale.x() / layer->contents_scale_x(),
1064 render_surface_sublayer_scale.y() / layer->contents_scale_y());
1066 // Inside the surface's subtree, we scale everything to the owning layer's
1067 // scale. The sublayer matrix transforms layer rects into target surface
1068 // content space.
1069 DCHECK(sublayer_matrix.IsIdentity());
1070 sublayer_matrix.Scale(render_surface_sublayer_scale.x(),
1071 render_surface_sublayer_scale.y());
1073 // The opacity value is moved from the layer to its surface, so that the
1074 // entire subtree properly inherits opacity.
1075 render_surface->SetDrawOpacity(accumulated_draw_opacity);
1076 render_surface->SetDrawOpacityIsAnimating(animating_opacity_to_target);
1077 animating_opacity_to_target = false;
1078 layer_draw_properties.opacity = 1.f;
1079 layer_draw_properties.opacity_is_animating = animating_opacity_to_target;
1080 layer_draw_properties.screen_space_opacity_is_animating =
1081 animating_opacity_to_screen;
1083 render_surface->SetTargetSurfaceTransformsAreAnimating(
1084 animating_transform_to_target);
1085 render_surface->SetScreenSpaceTransformsAreAnimating(
1086 animating_transform_to_screen);
1087 animating_transform_to_target = false;
1088 layer_draw_properties.target_space_transform_is_animating =
1089 animating_transform_to_target;
1090 layer_draw_properties.screen_space_transform_is_animating =
1091 animating_transform_to_screen;
1093 // Update the aggregate hierarchy matrix to include the transform of the
1094 // newly created RenderSurfaceImpl.
1095 next_hierarchy_matrix.PreconcatTransform(render_surface->draw_transform());
1097 // The new render_surface here will correctly clip the entire subtree. So,
1098 // we do not need to continue propagating the clipping state further down
1099 // the tree. This way, we can avoid transforming clip rects from ancestor
1100 // target surface space to current target surface space that could cause
1101 // more w < 0 headaches.
1102 subtree_should_be_clipped = false;
1104 if (layer->mask_layer()) {
1105 DrawProperties<LayerType, RenderSurfaceType>& mask_layer_draw_properties =
1106 layer->mask_layer()->draw_properties();
1107 mask_layer_draw_properties.render_target = layer;
1108 mask_layer_draw_properties.visible_content_rect =
1109 gfx::Rect(layer->content_bounds());
1112 if (layer->replica_layer() && layer->replica_layer()->mask_layer()) {
1113 DrawProperties<LayerType, RenderSurfaceType>&
1114 replica_mask_draw_properties =
1115 layer->replica_layer()->mask_layer()->draw_properties();
1116 replica_mask_draw_properties.render_target = layer;
1117 replica_mask_draw_properties.visible_content_rect =
1118 gfx::Rect(layer->content_bounds());
1121 // TODO(senorblanco): make this smarter for the SkImageFilter case (check
1122 // for pixel-moving filters)
1123 if (layer->filters().hasFilterThatMovesPixels() || layer->filter())
1124 nearest_ancestor_that_moves_pixels = render_surface;
1126 // The render surface clip rect is expressed in the space where this surface
1127 // draws, i.e. the same space as clip_rect_from_ancestor.
1128 render_surface->SetIsClipped(ancestor_clips_subtree);
1129 if (ancestor_clips_subtree) {
1130 render_surface->SetClipRect(clip_rect_from_ancestor);
1132 gfx::Transform inverse_surface_draw_transform(
1133 gfx::Transform::kSkipInitialization);
1134 if (!render_surface->draw_transform().GetInverse(
1135 &inverse_surface_draw_transform)) {
1136 // TODO(shawnsingh): Either we need to handle uninvertible transforms
1137 // here, or DCHECK that the transform is invertible.
1139 clip_rect_for_subtree_in_descendant_space =
1140 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
1141 inverse_surface_draw_transform, render_surface->clip_rect()));
1142 } else {
1143 render_surface->SetClipRect(gfx::Rect());
1144 clip_rect_for_subtree_in_descendant_space =
1145 clip_rect_from_ancestor_in_descendant_space;
1148 render_surface->SetNearestAncestorThatMovesPixels(
1149 nearest_ancestor_that_moves_pixels);
1151 // If the new render surface is drawn translucent or with a non-integral
1152 // translation then the subtree that gets drawn on this render surface
1153 // cannot use LCD text.
1154 subtree_can_use_lcd_text = layer_can_use_lcd_text;
1156 render_surface_layer_list->push_back(layer);
1157 } else {
1158 DCHECK(layer->parent());
1160 // Note: layer_draw_properties.target_space_transform is computed above,
1161 // before this if-else statement.
1162 layer_draw_properties.target_space_transform_is_animating =
1163 animating_transform_to_target;
1164 layer_draw_properties.screen_space_transform_is_animating =
1165 animating_transform_to_screen;
1166 layer_draw_properties.opacity = accumulated_draw_opacity;
1167 layer_draw_properties.opacity_is_animating = animating_opacity_to_target;
1168 layer_draw_properties.screen_space_opacity_is_animating =
1169 animating_opacity_to_screen;
1170 sublayer_matrix = combined_transform;
1172 layer->ClearRenderSurface();
1174 // Layers without render_surfaces directly inherit the ancestor's clip
1175 // status.
1176 subtree_should_be_clipped = ancestor_clips_subtree;
1177 if (ancestor_clips_subtree)
1178 clip_rect_for_subtree = clip_rect_from_ancestor;
1180 // The surface's cached clip rect value propagates regardless of what
1181 // clipping goes on between layers here.
1182 clip_rect_for_subtree_in_descendant_space =
1183 clip_rect_from_ancestor_in_descendant_space;
1185 // Layers that are not their own render_target will render into the target
1186 // of their nearest ancestor.
1187 layer_draw_properties.render_target = layer->parent()->render_target();
1190 if (adjust_text_aa)
1191 layer_draw_properties.can_use_lcd_text = layer_can_use_lcd_text;
1193 gfx::Rect rect_in_target_space = ToEnclosingRect(
1194 MathUtil::MapClippedRect(layer->draw_transform(), content_rect));
1196 if (LayerClipsSubtree(layer)) {
1197 subtree_should_be_clipped = true;
1198 if (ancestor_clips_subtree && !layer->render_surface()) {
1199 clip_rect_for_subtree = clip_rect_from_ancestor;
1200 clip_rect_for_subtree.Intersect(rect_in_target_space);
1201 } else {
1202 clip_rect_for_subtree = rect_in_target_space;
1206 // Flatten to 2D if the layer doesn't preserve 3D.
1207 if (!layer->preserves_3d())
1208 sublayer_matrix.FlattenTo2d();
1210 // Apply the sublayer transform at the anchor point of the layer.
1211 if (!layer->sublayer_transform().IsIdentity()) {
1212 sublayer_matrix.Translate(layer->anchor_point().x() * bounds.width(),
1213 layer->anchor_point().y() * bounds.height());
1214 sublayer_matrix.PreconcatTransform(layer->sublayer_transform());
1215 sublayer_matrix.Translate(-layer->anchor_point().x() * bounds.width(),
1216 -layer->anchor_point().y() * bounds.height());
1219 LayerList& descendants =
1220 (layer->render_surface() ? layer->render_surface()->layer_list()
1221 : *layer_list);
1223 // Any layers that are appended after this point are in the layer's subtree
1224 // and should be included in the sorting process.
1225 size_t sorting_start_index = descendants.size();
1227 if (!LayerShouldBeSkipped(layer))
1228 descendants.push_back(layer);
1230 gfx::Transform next_scroll_compensation_matrix =
1231 ComputeScrollCompensationMatrixForChildren(
1232 layer, parent_matrix, current_scroll_compensation_matrix);
1233 LayerType* next_fixed_container =
1234 layer->IsContainerForFixedPositionLayers() ?
1235 layer : current_fixed_container;
1237 gfx::Rect accumulated_drawable_content_rect_of_children;
1238 for (size_t i = 0; i < layer->children().size(); ++i) {
1239 LayerType* child =
1240 LayerTreeHostCommon::get_child_as_raw_ptr(layer->children(), i);
1241 gfx::Rect drawable_content_rect_of_child_subtree;
1242 CalculateDrawPropertiesInternal<LayerType, LayerList, RenderSurfaceType>(
1243 child,
1244 sublayer_matrix,
1245 next_hierarchy_matrix,
1246 next_scroll_compensation_matrix,
1247 next_fixed_container,
1248 clip_rect_for_subtree,
1249 clip_rect_for_subtree_in_descendant_space,
1250 subtree_should_be_clipped,
1251 nearest_ancestor_that_moves_pixels,
1252 render_surface_layer_list,
1253 &descendants,
1254 layer_sorter,
1255 max_texture_size,
1256 device_scale_factor,
1257 page_scale_factor,
1258 subtree_can_use_lcd_text,
1259 &drawable_content_rect_of_child_subtree,
1260 update_tile_priorities);
1261 if (!drawable_content_rect_of_child_subtree.IsEmpty()) {
1262 accumulated_drawable_content_rect_of_children.Union(
1263 drawable_content_rect_of_child_subtree);
1264 if (child->render_surface())
1265 descendants.push_back(child);
1269 if (layer->render_surface() && !IsRootLayer(layer) &&
1270 layer->render_surface()->layer_list().empty()) {
1271 RemoveSurfaceForEarlyExit(layer, render_surface_layer_list);
1272 return;
1275 // Compute the total drawable_content_rect for this subtree (the rect is in
1276 // target surface space).
1277 gfx::Rect local_drawable_content_rect_of_subtree =
1278 accumulated_drawable_content_rect_of_children;
1279 if (layer->DrawsContent())
1280 local_drawable_content_rect_of_subtree.Union(rect_in_target_space);
1281 if (subtree_should_be_clipped)
1282 local_drawable_content_rect_of_subtree.Intersect(clip_rect_for_subtree);
1284 // Compute the layer's drawable content rect (the rect is in target surface
1285 // space).
1286 layer_draw_properties.drawable_content_rect = rect_in_target_space;
1287 if (subtree_should_be_clipped) {
1288 layer_draw_properties.drawable_content_rect.
1289 Intersect(clip_rect_for_subtree);
1292 // Tell the layer the rect that is clipped by. In theory we could use a
1293 // tighter clip rect here (drawable_content_rect), but that actually does not
1294 // reduce how much would be drawn, and instead it would create unnecessary
1295 // changes to scissor state affecting GPU performance.
1296 layer_draw_properties.is_clipped = subtree_should_be_clipped;
1297 if (subtree_should_be_clipped) {
1298 layer_draw_properties.clip_rect = clip_rect_for_subtree;
1299 } else {
1300 // Initialize the clip rect to a safe value that will not clip the
1301 // layer, just in case clipping is still accidentally used.
1302 layer_draw_properties.clip_rect = rect_in_target_space;
1305 // Compute the layer's visible content rect (the rect is in content space)
1306 layer_draw_properties.visible_content_rect = CalculateVisibleContentRect(
1307 layer, clip_rect_for_subtree_in_descendant_space, rect_in_target_space);
1309 // Compute the remaining properties for the render surface, if the layer has
1310 // one.
1311 if (IsRootLayer(layer)) {
1312 // The root layer's surface's content_rect is always the entire viewport.
1313 DCHECK(layer->render_surface());
1314 layer->render_surface()->SetContentRect(clip_rect_from_ancestor);
1315 } else if (layer->render_surface() && !IsRootLayer(layer)) {
1316 RenderSurfaceType* render_surface = layer->render_surface();
1317 gfx::Rect clipped_content_rect = local_drawable_content_rect_of_subtree;
1319 // Don't clip if the layer is reflected as the reflection shouldn't be
1320 // clipped. If the layer is animating, then the surface's transform to
1321 // its target is not known on the main thread, and we should not use it
1322 // to clip.
1323 if (!layer->replica_layer() && TransformToParentIsKnown(layer)) {
1324 // Note, it is correct to use ancestor_clips_subtree here, because we are
1325 // looking at this layer's render_surface, not the layer itself.
1326 if (ancestor_clips_subtree && !clipped_content_rect.IsEmpty()) {
1327 gfx::Rect surface_clip_rect = LayerTreeHostCommon::CalculateVisibleRect(
1328 render_surface->clip_rect(),
1329 clipped_content_rect,
1330 render_surface->draw_transform());
1331 clipped_content_rect.Intersect(surface_clip_rect);
1335 // The RenderSurfaceImpl backing texture cannot exceed the maximum supported
1336 // texture size.
1337 clipped_content_rect.set_width(
1338 std::min(clipped_content_rect.width(), max_texture_size));
1339 clipped_content_rect.set_height(
1340 std::min(clipped_content_rect.height(), max_texture_size));
1342 if (clipped_content_rect.IsEmpty()) {
1343 render_surface->ClearLayerLists();
1344 RemoveSurfaceForEarlyExit(layer, render_surface_layer_list);
1345 return;
1348 render_surface->SetContentRect(clipped_content_rect);
1350 // The owning layer's screen_space_transform has a scale from content to
1351 // layer space which we need to undo and replace with a scale from the
1352 // surface's subtree into layer space.
1353 gfx::Transform screen_space_transform = layer->screen_space_transform();
1354 screen_space_transform.Scale(
1355 layer->contents_scale_x() / render_surface_sublayer_scale.x(),
1356 layer->contents_scale_y() / render_surface_sublayer_scale.y());
1357 render_surface->SetScreenSpaceTransform(screen_space_transform);
1359 if (layer->replica_layer()) {
1360 gfx::Transform surface_origin_to_replica_origin_transform;
1361 surface_origin_to_replica_origin_transform.Scale(
1362 render_surface_sublayer_scale.x(), render_surface_sublayer_scale.y());
1363 surface_origin_to_replica_origin_transform.Translate(
1364 layer->replica_layer()->position().x() +
1365 layer->replica_layer()->anchor_point().x() * bounds.width(),
1366 layer->replica_layer()->position().y() +
1367 layer->replica_layer()->anchor_point().y() * bounds.height());
1368 surface_origin_to_replica_origin_transform.PreconcatTransform(
1369 layer->replica_layer()->transform());
1370 surface_origin_to_replica_origin_transform.Translate(
1371 -layer->replica_layer()->anchor_point().x() * bounds.width(),
1372 -layer->replica_layer()->anchor_point().y() * bounds.height());
1373 surface_origin_to_replica_origin_transform.Scale(
1374 1.0 / render_surface_sublayer_scale.x(),
1375 1.0 / render_surface_sublayer_scale.y());
1377 // Compute the replica's "originTransform" that maps from the replica's
1378 // origin space to the target surface origin space.
1379 gfx::Transform replica_origin_transform =
1380 layer->render_surface()->draw_transform() *
1381 surface_origin_to_replica_origin_transform;
1382 render_surface->SetReplicaDrawTransform(replica_origin_transform);
1384 // Compute the replica's "screen_space_transform" that maps from the
1385 // replica's origin space to the screen's origin space.
1386 gfx::Transform replica_screen_space_transform =
1387 layer->render_surface()->screen_space_transform() *
1388 surface_origin_to_replica_origin_transform;
1389 render_surface->SetReplicaScreenSpaceTransform(
1390 replica_screen_space_transform);
1394 if (update_tile_priorities)
1395 UpdateTilePrioritiesForLayer(layer);
1397 // If neither this layer nor any of its children were added, early out.
1398 if (sorting_start_index == descendants.size())
1399 return;
1401 // If preserves-3d then sort all the descendants in 3D so that they can be
1402 // drawn from back to front. If the preserves-3d property is also set on the
1403 // parent then skip the sorting as the parent will sort all the descendants
1404 // anyway.
1405 if (layer_sorter && descendants.size() && layer->preserves_3d() &&
1406 (!layer->parent() || !layer->parent()->preserves_3d())) {
1407 SortLayers(descendants.begin() + sorting_start_index,
1408 descendants.end(),
1409 layer_sorter);
1412 if (layer->render_surface()) {
1413 *drawable_content_rect_of_subtree =
1414 gfx::ToEnclosingRect(layer->render_surface()->DrawableContentRect());
1415 } else {
1416 *drawable_content_rect_of_subtree = local_drawable_content_rect_of_subtree;
1419 if (layer->HasContributingDelegatedRenderPasses()) {
1420 layer->render_target()->render_surface()->
1421 AddContributingDelegatedRenderPassLayer(layer);
1424 SavePaintPropertiesLayer(layer);
1427 void LayerTreeHostCommon::CalculateDrawProperties(
1428 Layer* root_layer,
1429 gfx::Size device_viewport_size,
1430 float device_scale_factor,
1431 float page_scale_factor,
1432 int max_texture_size,
1433 bool can_use_lcd_text,
1434 LayerList* render_surface_layer_list) {
1435 gfx::Rect total_drawable_content_rect;
1436 gfx::Transform identity_matrix;
1437 gfx::Transform device_scale_transform;
1438 device_scale_transform.Scale(device_scale_factor, device_scale_factor);
1439 LayerList dummy_layer_list;
1441 // The root layer's render_surface should receive the device viewport as the
1442 // initial clip rect.
1443 bool subtree_should_be_clipped = true;
1444 gfx::Rect device_viewport_rect(device_viewport_size);
1445 bool update_tile_priorities = false;
1447 // This function should have received a root layer.
1448 DCHECK(IsRootLayer(root_layer));
1450 PreCalculateMetaInformation<Layer>(root_layer);
1451 CalculateDrawPropertiesInternal<Layer,
1452 LayerList,
1453 RenderSurface>(root_layer,
1454 device_scale_transform,
1455 identity_matrix,
1456 identity_matrix,
1457 NULL,
1458 device_viewport_rect,
1459 device_viewport_rect,
1460 subtree_should_be_clipped,
1461 NULL,
1462 render_surface_layer_list,
1463 &dummy_layer_list,
1464 NULL,
1465 max_texture_size,
1466 device_scale_factor,
1467 page_scale_factor,
1468 can_use_lcd_text,
1469 &total_drawable_content_rect,
1470 update_tile_priorities);
1472 // The dummy layer list should not have been used.
1473 DCHECK_EQ(0u, dummy_layer_list.size());
1474 // A root layer render_surface should always exist after
1475 // CalculateDrawProperties.
1476 DCHECK(root_layer->render_surface());
1479 void LayerTreeHostCommon::CalculateDrawProperties(
1480 LayerImpl* root_layer,
1481 gfx::Size device_viewport_size,
1482 float device_scale_factor,
1483 float page_scale_factor,
1484 int max_texture_size,
1485 bool can_use_lcd_text,
1486 LayerImplList* render_surface_layer_list,
1487 bool update_tile_priorities) {
1488 gfx::Rect total_drawable_content_rect;
1489 gfx::Transform identity_matrix;
1490 gfx::Transform device_scale_transform;
1491 device_scale_transform.Scale(device_scale_factor, device_scale_factor);
1492 LayerImplList dummy_layer_list;
1493 LayerSorter layer_sorter;
1495 // The root layer's render_surface should receive the device viewport as the
1496 // initial clip rect.
1497 bool subtree_should_be_clipped = true;
1498 gfx::Rect device_viewport_rect(device_viewport_size);
1500 // This function should have received a root layer.
1501 DCHECK(IsRootLayer(root_layer));
1503 PreCalculateMetaInformation<LayerImpl>(root_layer);
1504 CalculateDrawPropertiesInternal<LayerImpl,
1505 LayerImplList,
1506 RenderSurfaceImpl>(
1507 root_layer,
1508 device_scale_transform,
1509 identity_matrix,
1510 identity_matrix,
1511 NULL,
1512 device_viewport_rect,
1513 device_viewport_rect,
1514 subtree_should_be_clipped,
1515 NULL,
1516 render_surface_layer_list,
1517 &dummy_layer_list,
1518 &layer_sorter,
1519 max_texture_size,
1520 device_scale_factor,
1521 page_scale_factor,
1522 can_use_lcd_text,
1523 &total_drawable_content_rect,
1524 update_tile_priorities);
1526 // The dummy layer list should not have been used.
1527 DCHECK_EQ(0u, dummy_layer_list.size());
1528 // A root layer render_surface should always exist after
1529 // CalculateDrawProperties.
1530 DCHECK(root_layer->render_surface());
1533 static bool PointHitsRect(
1534 gfx::PointF screen_space_point,
1535 const gfx::Transform& local_space_to_screen_space_transform,
1536 gfx::RectF local_space_rect) {
1537 // If the transform is not invertible, then assume that this point doesn't hit
1538 // this rect.
1539 gfx::Transform inverse_local_space_to_screen_space(
1540 gfx::Transform::kSkipInitialization);
1541 if (!local_space_to_screen_space_transform.GetInverse(
1542 &inverse_local_space_to_screen_space))
1543 return false;
1545 // Transform the hit test point from screen space to the local space of the
1546 // given rect.
1547 bool clipped = false;
1548 gfx::PointF hit_test_point_in_local_space = MathUtil::ProjectPoint(
1549 inverse_local_space_to_screen_space, screen_space_point, &clipped);
1551 // If ProjectPoint could not project to a valid value, then we assume that
1552 // this point doesn't hit this rect.
1553 if (clipped)
1554 return false;
1556 return local_space_rect.Contains(hit_test_point_in_local_space);
1559 static bool PointHitsRegion(gfx::PointF screen_space_point,
1560 const gfx::Transform& screen_space_transform,
1561 const Region& layer_space_region,
1562 float layer_content_scale_x,
1563 float layer_content_scale_y) {
1564 // If the transform is not invertible, then assume that this point doesn't hit
1565 // this region.
1566 gfx::Transform inverse_screen_space_transform(
1567 gfx::Transform::kSkipInitialization);
1568 if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
1569 return false;
1571 // Transform the hit test point from screen space to the local space of the
1572 // given region.
1573 bool clipped = false;
1574 gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
1575 inverse_screen_space_transform, screen_space_point, &clipped);
1576 gfx::PointF hit_test_point_in_layer_space =
1577 gfx::ScalePoint(hit_test_point_in_content_space,
1578 1.f / layer_content_scale_x,
1579 1.f / layer_content_scale_y);
1581 // If ProjectPoint could not project to a valid value, then we assume that
1582 // this point doesn't hit this region.
1583 if (clipped)
1584 return false;
1586 return layer_space_region.Contains(
1587 gfx::ToRoundedPoint(hit_test_point_in_layer_space));
1590 static bool PointIsClippedBySurfaceOrClipRect(gfx::PointF screen_space_point,
1591 LayerImpl* layer) {
1592 LayerImpl* current_layer = layer;
1594 // Walk up the layer tree and hit-test any render_surfaces and any layer
1595 // clip rects that are active.
1596 while (current_layer) {
1597 if (current_layer->render_surface() &&
1598 !PointHitsRect(
1599 screen_space_point,
1600 current_layer->render_surface()->screen_space_transform(),
1601 current_layer->render_surface()->content_rect()))
1602 return true;
1604 // Note that drawable content rects are actually in target surface space, so
1605 // the transform we have to provide is the target surface's
1606 // screen_space_transform.
1607 LayerImpl* render_target = current_layer->render_target();
1608 if (LayerClipsSubtree(current_layer) &&
1609 !PointHitsRect(
1610 screen_space_point,
1611 render_target->render_surface()->screen_space_transform(),
1612 current_layer->drawable_content_rect()))
1613 return true;
1615 current_layer = current_layer->parent();
1618 // If we have finished walking all ancestors without having already exited,
1619 // then the point is not clipped by any ancestors.
1620 return false;
1623 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPoint(
1624 gfx::PointF screen_space_point,
1625 const LayerImplList& render_surface_layer_list) {
1626 LayerImpl* found_layer = NULL;
1628 typedef LayerIterator<LayerImpl,
1629 LayerImplList,
1630 RenderSurfaceImpl,
1631 LayerIteratorActions::FrontToBack> LayerIteratorType;
1632 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
1634 for (LayerIteratorType
1635 it = LayerIteratorType::Begin(&render_surface_layer_list);
1636 it != end;
1637 ++it) {
1638 // We don't want to consider render_surfaces for hit testing.
1639 if (!it.represents_itself())
1640 continue;
1642 LayerImpl* current_layer = (*it);
1644 gfx::RectF content_rect(current_layer->content_bounds());
1645 if (!PointHitsRect(screen_space_point,
1646 current_layer->screen_space_transform(),
1647 content_rect))
1648 continue;
1650 // At this point, we think the point does hit the layer, but we need to walk
1651 // up the parents to ensure that the layer was not clipped in such a way
1652 // that the hit point actually should not hit the layer.
1653 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, current_layer))
1654 continue;
1656 // Skip the HUD layer.
1657 if (current_layer == current_layer->layer_tree_impl()->hud_layer())
1658 continue;
1660 found_layer = current_layer;
1661 break;
1664 // This can potentially return NULL, which means the screen_space_point did
1665 // not successfully hit test any layers, not even the root layer.
1666 return found_layer;
1669 LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
1670 gfx::PointF screen_space_point,
1671 const LayerImplList& render_surface_layer_list) {
1672 LayerImpl* found_layer = NULL;
1674 typedef LayerIterator<LayerImpl,
1675 LayerImplList,
1676 RenderSurfaceImpl,
1677 LayerIteratorActions::FrontToBack> LayerIteratorType;
1678 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
1680 for (LayerIteratorType
1681 it = LayerIteratorType::Begin(&render_surface_layer_list);
1682 it != end;
1683 ++it) {
1684 // We don't want to consider render_surfaces for hit testing.
1685 if (!it.represents_itself())
1686 continue;
1688 LayerImpl* current_layer = (*it);
1690 if (!LayerHasTouchEventHandlersAt(screen_space_point, current_layer))
1691 continue;
1693 found_layer = current_layer;
1694 break;
1697 // This can potentially return NULL, which means the screen_space_point did
1698 // not successfully hit test any layers, not even the root layer.
1699 return found_layer;
1702 bool LayerTreeHostCommon::LayerHasTouchEventHandlersAt(
1703 gfx::PointF screen_space_point,
1704 LayerImpl* layer_impl) {
1705 if (layer_impl->touch_event_handler_region().IsEmpty())
1706 return false;
1708 if (!PointHitsRegion(screen_space_point,
1709 layer_impl->screen_space_transform(),
1710 layer_impl->touch_event_handler_region(),
1711 layer_impl->contents_scale_x(),
1712 layer_impl->contents_scale_y()))
1713 return false;
1715 // At this point, we think the point does hit the touch event handler region
1716 // on the layer, but we need to walk up the parents to ensure that the layer
1717 // was not clipped in such a way that the hit point actually should not hit
1718 // the layer.
1719 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
1720 return false;
1722 return true;
1724 } // namespace cc