OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/layer_tree_host_common.h" | 5 #include "cc/layer_tree_host_common.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "cc/layer.h" | 10 #include "cc/layer.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 NOTREACHED(); | 33 NOTREACHED(); |
34 } | 34 } |
35 | 35 |
36 static void sortLayers(std::vector<LayerImpl*>::iterator first, std::vector<Laye
rImpl*>::iterator end, LayerSorter* layerSorter) | 36 static void sortLayers(std::vector<LayerImpl*>::iterator first, std::vector<Laye
rImpl*>::iterator end, LayerSorter* layerSorter) |
37 { | 37 { |
38 DCHECK(layerSorter); | 38 DCHECK(layerSorter); |
39 TRACE_EVENT0("cc", "layer_tree_host_common::sortLayers"); | 39 TRACE_EVENT0("cc", "layer_tree_host_common::sortLayers"); |
40 layerSorter->sort(first, end); | 40 layerSorter->sort(first, end); |
41 } | 41 } |
42 | 42 |
43 gfx::Rect LayerTreeHostCommon::calculateVisibleRect(const gfx::Rect& targetSurfa
ceRect, const gfx::Rect& layerBoundRect, const gfx::Transform& transform) | 43 inline gfx::Rect calculateVisibleRectWithCachedLayerRect(const gfx::Rect& target
SurfaceRect, const gfx::Rect& layerBoundRect, const gfx::Rect& layerRectInTarget
Space, const gfx::Transform& transform) |
44 { | 44 { |
45 // Is this layer fully contained within the target surface? | 45 // Is this layer fully contained within the target surface? |
46 gfx::Rect layerInSurfaceSpace = MathUtil::mapClippedRect(transform, layerBou
ndRect); | 46 if (targetSurfaceRect.Contains(layerRectInTargetSpace)) |
47 if (targetSurfaceRect.Contains(layerInSurfaceSpace)) | |
48 return layerBoundRect; | 47 return layerBoundRect; |
49 | 48 |
50 // If the layer doesn't fill up the entire surface, then find the part of | 49 // If the layer doesn't fill up the entire surface, then find the part of |
51 // the surface rect where the layer could be visible. This avoids trying to | 50 // the surface rect where the layer could be visible. This avoids trying to |
52 // project surface rect points that are behind the projection point. | 51 // project surface rect points that are behind the projection point. |
53 gfx::Rect minimalSurfaceRect = targetSurfaceRect; | 52 gfx::Rect minimalSurfaceRect = targetSurfaceRect; |
54 minimalSurfaceRect.Intersect(layerInSurfaceSpace); | 53 minimalSurfaceRect.Intersect(layerRectInTargetSpace); |
55 | 54 |
56 // Project the corners of the target surface rect into the layer space. | 55 // Project the corners of the target surface rect into the layer space. |
57 // This bounding rectangle may be larger than it needs to be (being | 56 // This bounding rectangle may be larger than it needs to be (being |
58 // axis-aligned), but is a reasonable filter on the space to consider. | 57 // axis-aligned), but is a reasonable filter on the space to consider. |
59 // Non-invertible transforms will create an empty rect here. | 58 // Non-invertible transforms will create an empty rect here. |
60 const gfx::Transform surfaceToLayer = MathUtil::inverse(transform); | 59 const gfx::Transform surfaceToLayer = MathUtil::inverse(transform); |
61 gfx::Rect layerRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(surf
aceToLayer, gfx::RectF(minimalSurfaceRect))); | 60 gfx::Rect layerRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(surf
aceToLayer, gfx::RectF(minimalSurfaceRect))); |
62 layerRect.Intersect(layerBoundRect); | 61 layerRect.Intersect(layerBoundRect); |
63 return layerRect; | 62 return layerRect; |
64 } | 63 } |
65 | 64 |
| 65 gfx::Rect LayerTreeHostCommon::calculateVisibleRect(const gfx::Rect& targetSurfa
ceRect, const gfx::Rect& layerBoundRect, const gfx::Transform& transform) |
| 66 { |
| 67 gfx::Rect layerInSurfaceSpace = MathUtil::mapClippedRect(transform, layerBou
ndRect); |
| 68 return calculateVisibleRectWithCachedLayerRect(targetSurfaceRect, layerBound
Rect, layerInSurfaceSpace, transform); |
| 69 } |
| 70 |
66 template <typename LayerType> | 71 template <typename LayerType> |
67 static inline bool isRootLayer(LayerType* layer) | 72 static inline bool isRootLayer(LayerType* layer) |
68 { | 73 { |
69 return !layer->parent(); | 74 return !layer->parent(); |
70 } | 75 } |
71 | 76 |
72 template<typename LayerType> | 77 template<typename LayerType> |
73 static inline bool layerIsInExisting3DRenderingContext(LayerType* layer) | 78 static inline bool layerIsInExisting3DRenderingContext(LayerType* layer) |
74 { | 79 { |
75 // According to current W3C spec on CSS transforms, a layer is part of an es
tablished | 80 // According to current W3C spec on CSS transforms, a layer is part of an es
tablished |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 return false; | 124 return false; |
120 } | 125 } |
121 | 126 |
122 template<typename LayerType> | 127 template<typename LayerType> |
123 static inline bool layerClipsSubtree(LayerType* layer) | 128 static inline bool layerClipsSubtree(LayerType* layer) |
124 { | 129 { |
125 return layer->masksToBounds() || layer->maskLayer(); | 130 return layer->masksToBounds() || layer->maskLayer(); |
126 } | 131 } |
127 | 132 |
128 template<typename LayerType> | 133 template<typename LayerType> |
129 static gfx::Rect calculateVisibleContentRect(LayerType* layer) | 134 static gfx::Rect calculateVisibleContentRect(LayerType* layer, const gfx::Rect&
ancestorClipRectInDescendantSurfaceSpace, const gfx::Rect& layerRectInTargetSpac
e) |
130 { | 135 { |
131 DCHECK(layer->renderTarget()); | 136 DCHECK(layer->renderTarget()); |
132 | 137 |
133 // Nothing is visible if the layer bounds are empty. | 138 // Nothing is visible if the layer bounds are empty. |
134 if (!layer->drawsContent() || layer->contentBounds().IsEmpty() || layer->dra
wableContentRect().IsEmpty()) | 139 if (!layer->drawsContent() || layer->contentBounds().IsEmpty() || layer->dra
wableContentRect().IsEmpty()) |
135 return gfx::Rect(); | 140 return gfx::Rect(); |
136 | 141 |
137 gfx::Rect targetSurfaceClipRect; | 142 // Compute visible bounds in target surface space. |
| 143 gfx::Rect visibleRectInTargetSurfaceSpace = layer->drawableContentRect(); |
138 | 144 |
139 // First, compute visible bounds in target surface space. | 145 if (!layer->renderTarget()->renderSurface()->clipRect().IsEmpty()) { |
140 if (layer->renderTarget()->renderSurface()->clipRect().IsEmpty()) | 146 // In this case the target surface does clip layers that contribute to |
141 targetSurfaceClipRect = layer->drawableContentRect(); | 147 // it. So, we have to convert the current surface's clipRect from its |
142 else { | 148 // ancestor surface space to the current (descendant) surface |
143 // In this case the target surface does clip layers that contribute to i
t. So, we | 149 // space. This conversion is done outside this function so that it can |
144 // have convert the current surface's clipRect from its ancestor surface
space to | 150 // be cached instead of computing it redundantly for every layer. |
145 // the current surface space. | 151 visibleRectInTargetSurfaceSpace.Intersect(ancestorClipRectInDescendantSu
rfaceSpace); |
146 targetSurfaceClipRect = gfx::ToEnclosingRect(MathUtil::projectClippedRec
t(MathUtil::inverse(layer->renderTarget()->renderSurface()->drawTransform()), la
yer->renderTarget()->renderSurface()->clipRect())); | |
147 targetSurfaceClipRect.Intersect(layer->drawableContentRect()); | |
148 } | 152 } |
149 | 153 |
150 if (targetSurfaceClipRect.IsEmpty()) | 154 if (visibleRectInTargetSurfaceSpace.IsEmpty()) |
151 return gfx::Rect(); | 155 return gfx::Rect(); |
152 | 156 |
153 return LayerTreeHostCommon::calculateVisibleRect(targetSurfaceClipRect, gfx:
:Rect(gfx::Point(), layer->contentBounds()), layer->drawTransform()); | 157 return calculateVisibleRectWithCachedLayerRect(visibleRectInTargetSurfaceSpa
ce, gfx::Rect(gfx::Point(), layer->contentBounds()), layerRectInTargetSpace, lay
er->drawTransform()); |
154 } | 158 } |
155 | 159 |
156 static inline bool transformToParentIsKnown(LayerImpl*) | 160 static inline bool transformToParentIsKnown(LayerImpl*) |
157 { | 161 { |
158 return true; | 162 return true; |
159 } | 163 } |
160 | 164 |
161 static inline bool transformToParentIsKnown(Layer* layer) | 165 static inline bool transformToParentIsKnown(Layer* layer) |
162 { | 166 { |
163 return !layer->transformIsAnimating(); | 167 return !layer->transformIsAnimating(); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 | 398 |
395 Layer* maskLayer = layer->maskLayer(); | 399 Layer* maskLayer = layer->maskLayer(); |
396 if (maskLayer) | 400 if (maskLayer) |
397 maskLayer->setContentsScale(contentsScale); | 401 maskLayer->setContentsScale(contentsScale); |
398 | 402 |
399 Layer* replicaMaskLayer = layer->replicaLayer() ? layer->replicaLayer()->mas
kLayer() : 0; | 403 Layer* replicaMaskLayer = layer->replicaLayer() ? layer->replicaLayer()->mas
kLayer() : 0; |
400 if (replicaMaskLayer) | 404 if (replicaMaskLayer) |
401 replicaMaskLayer->setContentsScale(contentsScale); | 405 replicaMaskLayer->setContentsScale(contentsScale); |
402 } | 406 } |
403 | 407 |
| 408 template<typename LayerType, typename LayerList> |
| 409 static inline void removeSurfaceForEarlyExit(LayerType* layerToRemove, LayerList
& renderSurfaceLayerList) |
| 410 { |
| 411 DCHECK(layerToRemove->renderSurface()); |
| 412 // Technically, we know that the layer we want to remove should be |
| 413 // at the back of the renderSurfaceLayerList. However, we have had |
| 414 // bugs before that added unnecessary layers here |
| 415 // (https://bugs.webkit.org/show_bug.cgi?id=74147), but that causes |
| 416 // things to crash. So here we proactively remove any additional |
| 417 // layers from the end of the list. |
| 418 while (renderSurfaceLayerList.back() != layerToRemove) { |
| 419 renderSurfaceLayerList.back()->clearRenderSurface(); |
| 420 renderSurfaceLayerList.pop_back(); |
| 421 } |
| 422 DCHECK(renderSurfaceLayerList.back() == layerToRemove); |
| 423 renderSurfaceLayerList.pop_back(); |
| 424 layerToRemove->clearRenderSurface(); |
| 425 } |
| 426 |
404 // Recursively walks the layer tree starting at the given node and computes all
the | 427 // Recursively walks the layer tree starting at the given node and computes all
the |
405 // necessary transformations, clipRects, render surfaces, etc. | 428 // necessary transformations, clipRects, render surfaces, etc. |
406 template<typename LayerType, typename LayerList, typename RenderSurfaceType> | 429 template<typename LayerType, typename LayerList, typename RenderSurfaceType> |
407 static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo
rm& parentMatrix, | 430 static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo
rm& parentMatrix, |
408 const gfx::Transform& fullHierarchyMatrix, const gfx::Transform& currentScro
llCompensationMatrix, | 431 const gfx::Transform& fullHierarchyMatrix, const gfx::Transform& currentScro
llCompensationMatrix, |
409 const gfx::Rect& clipRectFromAncestor, bool ancestorClipsSubtree, | 432 const gfx::Rect& clipRectFromAncestor, const gfx::Rect& clipRectFromAncestor
InDescendantSpace, bool ancestorClipsSubtree, |
410 RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceL
ayerList, LayerList& layerList, | 433 RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceL
ayerList, LayerList& layerList, |
411 LayerSorter* layerSorter, int maxTextureSize, float deviceScaleFactor, float
pageScaleFactor, gfx::Rect& drawableContentRectOfSubtree) | 434 LayerSorter* layerSorter, int maxTextureSize, float deviceScaleFactor, float
pageScaleFactor, gfx::Rect& drawableContentRectOfSubtree) |
412 { | 435 { |
413 // This function computes the new matrix transformations recursively for thi
s | 436 // This function computes the new matrix transformations recursively for thi
s |
414 // layer and all its descendants. It also computes the appropriate render su
rfaces. | 437 // layer and all its descendants. It also computes the appropriate render su
rfaces. |
415 // Some important points to remember: | 438 // Some important points to remember: |
416 // | 439 // |
417 // 0. Here, transforms are notated in Matrix x Vector order, and in words we
describe what | 440 // 0. Here, transforms are notated in Matrix x Vector order, and in words we
describe what |
418 // the transform does from left to right. | 441 // the transform does from left to right. |
419 // | 442 // |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 | 524 |
502 // As this function proceeds, these are the properties for the current | 525 // As this function proceeds, these are the properties for the current |
503 // layer that actually get computed. To avoid unnecessary copies | 526 // layer that actually get computed. To avoid unnecessary copies |
504 // (particularly for matrices), we do computations directly on these values | 527 // (particularly for matrices), we do computations directly on these values |
505 // when possible. | 528 // when possible. |
506 DrawProperties<LayerType, RenderSurfaceType>& layerDrawProperties = layer->d
rawProperties(); | 529 DrawProperties<LayerType, RenderSurfaceType>& layerDrawProperties = layer->d
rawProperties(); |
507 | 530 |
508 gfx::Rect clipRectForSubtree; | 531 gfx::Rect clipRectForSubtree; |
509 bool subtreeShouldBeClipped = false; | 532 bool subtreeShouldBeClipped = false; |
510 | 533 |
| 534 // This value is cached on the stack so that we don't have to inverse-projec
t |
| 535 // the surface's clipRect redundantly for every layer. This value is the |
| 536 // same as the surface's clipRect, except that instead of being described |
| 537 // in the target surface space (i.e. the ancestor surface space), it is |
| 538 // described in the current surface space. |
| 539 gfx::Rect clipRectForSubtreeInDescendantSpace; |
| 540 |
511 float accumulatedDrawOpacity = layer->opacity(); | 541 float accumulatedDrawOpacity = layer->opacity(); |
512 bool drawOpacityIsAnimating = layer->opacityIsAnimating(); | 542 bool drawOpacityIsAnimating = layer->opacityIsAnimating(); |
513 if (layer->parent()) { | 543 if (layer->parent()) { |
514 accumulatedDrawOpacity *= layer->parent()->drawOpacity(); | 544 accumulatedDrawOpacity *= layer->parent()->drawOpacity(); |
515 drawOpacityIsAnimating |= layer->parent()->drawOpacityIsAnimating(); | 545 drawOpacityIsAnimating |= layer->parent()->drawOpacityIsAnimating(); |
516 } | 546 } |
517 | 547 |
518 bool animatingTransformToTarget = layer->transformIsAnimating(); | 548 bool animatingTransformToTarget = layer->transformIsAnimating(); |
519 bool animatingTransformToScreen = animatingTransformToTarget; | 549 bool animatingTransformToScreen = animatingTransformToTarget; |
520 if (layer->parent()) { | 550 if (layer->parent()) { |
521 animatingTransformToTarget |= layer->parent()->drawTransformIsAnimating(
); | 551 animatingTransformToTarget |= layer->parent()->drawTransformIsAnimating(
); |
522 animatingTransformToScreen |= layer->parent()->screenSpaceTransformIsAni
mating(); | 552 animatingTransformToScreen |= layer->parent()->screenSpaceTransformIsAni
mating(); |
523 } | 553 } |
524 | 554 |
525 gfx::Size bounds = layer->bounds(); | 555 gfx::Size bounds = layer->bounds(); |
526 gfx::PointF anchorPoint = layer->anchorPoint(); | 556 gfx::PointF anchorPoint = layer->anchorPoint(); |
527 gfx::PointF position = layer->position() - layer->scrollDelta(); | 557 gfx::PointF position = layer->position() - layer->scrollDelta(); |
528 | 558 |
529 gfx::Transform combinedTransform = parentMatrix; | 559 gfx::Transform combinedTransform = parentMatrix; |
530 // LT = Tr[origin] * Tr[origin2anchor] | 560 if (!layer->transform().IsIdentity()) { |
531 combinedTransform.Translate3d(position.x() + anchorPoint.x() * bounds.width(
), position.y() + anchorPoint.y() * bounds.height(), layer->anchorPointZ()); | 561 // LT = Tr[origin] * Tr[origin2anchor] |
532 // LT = Tr[origin] * Tr[origin2anchor] * M[layer] | 562 combinedTransform.Translate3d(position.x() + anchorPoint.x() * bounds.wi
dth(), position.y() + anchorPoint.y() * bounds.height(), layer->anchorPointZ()); |
533 combinedTransform.PreconcatTransform(layer->transform()); | 563 // LT = Tr[origin] * Tr[origin2anchor] * M[layer] |
534 // LT = Tr[origin] * Tr[origin2anchor] * M[layer] * Tr[anchor2origin] | 564 combinedTransform.PreconcatTransform(layer->transform()); |
535 combinedTransform.Translate3d(-anchorPoint.x() * bounds.width(), -anchorPoin
t.y() * bounds.height(), -layer->anchorPointZ()); | 565 // LT = Tr[origin] * Tr[origin2anchor] * M[layer] * Tr[anchor2origin] |
| 566 combinedTransform.Translate3d(-anchorPoint.x() * bounds.width(), -anchor
Point.y() * bounds.height(), -layer->anchorPointZ()); |
| 567 } else { |
| 568 combinedTransform.Translate(position.x(), position.y()); |
| 569 } |
536 | 570 |
537 // The layer's contentsSize is determined from the combinedTransform, which
then informs the | 571 // The layer's contentsSize is determined from the combinedTransform, which
then informs the |
538 // layer's drawTransform. | 572 // layer's drawTransform. |
539 updateLayerContentsScale(layer, combinedTransform, deviceScaleFactor, pageSc
aleFactor, animatingTransformToScreen); | 573 updateLayerContentsScale(layer, combinedTransform, deviceScaleFactor, pageSc
aleFactor, animatingTransformToScreen); |
540 | 574 |
541 // If there is a transformation from the impl thread then it should be at | 575 // If there is a transformation from the impl thread then it should be at |
542 // the start of the combinedTransform, but we don't want it to affect the | 576 // the start of the combinedTransform, but we don't want it to affect the |
543 // computation of contentsScale above. | 577 // computation of contentsScale above. |
544 // Note carefully: this is Concat, not Preconcat (implTransform * combinedTr
ansform). | 578 // Note carefully: this is Concat, not Preconcat (implTransform * combinedTr
ansform). |
545 combinedTransform.ConcatTransform(layer->implTransform()); | 579 combinedTransform.ConcatTransform(layer->implTransform()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 replicaMaskDrawProperties.visible_content_rect = gfx::Rect(gfx::Poin
t(), layer->contentBounds()); | 670 replicaMaskDrawProperties.visible_content_rect = gfx::Rect(gfx::Poin
t(), layer->contentBounds()); |
637 } | 671 } |
638 | 672 |
639 // FIXME: make this smarter for the SkImageFilter case (check for | 673 // FIXME: make this smarter for the SkImageFilter case (check for |
640 // pixel-moving filters) | 674 // pixel-moving filters) |
641 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) | 675 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) |
642 nearestAncestorThatMovesPixels = renderSurface; | 676 nearestAncestorThatMovesPixels = renderSurface; |
643 | 677 |
644 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. | 678 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. |
645 renderSurface->setIsClipped(ancestorClipsSubtree); | 679 renderSurface->setIsClipped(ancestorClipsSubtree); |
646 if (ancestorClipsSubtree) | 680 if (ancestorClipsSubtree) { |
647 renderSurface->setClipRect(clipRectFromAncestor); | 681 renderSurface->setClipRect(clipRectFromAncestor); |
648 else | 682 clipRectForSubtreeInDescendantSpace = gfx::ToEnclosingRect(MathUtil:
:projectClippedRect(MathUtil::inverse(renderSurface->drawTransform()), renderSur
face->clipRect())); |
| 683 } else { |
649 renderSurface->setClipRect(gfx::Rect()); | 684 renderSurface->setClipRect(gfx::Rect()); |
| 685 clipRectForSubtreeInDescendantSpace = clipRectFromAncestorInDescenda
ntSpace; |
| 686 } |
650 | 687 |
651 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); | 688 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); |
652 | 689 |
653 renderSurfaceLayerList.push_back(layer); | 690 renderSurfaceLayerList.push_back(layer); |
654 } else { | 691 } else { |
655 DCHECK(layer->parent()); | 692 DCHECK(layer->parent()); |
656 | 693 |
657 // Note: layerDrawProperties.target_space_transform is computed above, | 694 // Note: layerDrawProperties.target_space_transform is computed above, |
658 // before this if-else statement. | 695 // before this if-else statement. |
659 layerDrawProperties.target_space_transform_is_animating = animatingTrans
formToTarget; | 696 layerDrawProperties.target_space_transform_is_animating = animatingTrans
formToTarget; |
660 layerDrawProperties.screen_space_transform_is_animating = animatingTrans
formToScreen; | 697 layerDrawProperties.screen_space_transform_is_animating = animatingTrans
formToScreen; |
661 layerDrawProperties.opacity = accumulatedDrawOpacity; | 698 layerDrawProperties.opacity = accumulatedDrawOpacity; |
662 layerDrawProperties.opacity_is_animating = drawOpacityIsAnimating; | 699 layerDrawProperties.opacity_is_animating = drawOpacityIsAnimating; |
663 sublayerMatrix = combinedTransform; | 700 sublayerMatrix = combinedTransform; |
664 | 701 |
665 layer->clearRenderSurface(); | 702 layer->clearRenderSurface(); |
666 | 703 |
667 // Layers without renderSurfaces directly inherit the ancestor's clip st
atus. | 704 // Layers without renderSurfaces directly inherit the ancestor's clip st
atus. |
668 subtreeShouldBeClipped = ancestorClipsSubtree; | 705 subtreeShouldBeClipped = ancestorClipsSubtree; |
669 if (ancestorClipsSubtree) | 706 if (ancestorClipsSubtree) |
670 clipRectForSubtree = clipRectFromAncestor; | 707 clipRectForSubtree = clipRectFromAncestor; |
671 | 708 |
| 709 // The surface's cached clipRect value propagates regardless of what cli
pping goes on between layers here. |
| 710 clipRectForSubtreeInDescendantSpace = clipRectFromAncestorInDescendantSp
ace; |
| 711 |
672 // Layers that are not their own renderTarget will render into the targe
t of their nearest ancestor. | 712 // Layers that are not their own renderTarget will render into the targe
t of their nearest ancestor. |
673 layerDrawProperties.render_target = layer->parent()->renderTarget(); | 713 layerDrawProperties.render_target = layer->parent()->renderTarget(); |
674 } | 714 } |
675 | 715 |
676 gfx::Rect rectInTargetSpace = ToEnclosingRect(MathUtil::mapClippedRect(layer
->drawTransform(), contentRect)); | 716 gfx::Rect rectInTargetSpace = ToEnclosingRect(MathUtil::mapClippedRect(layer
->drawTransform(), contentRect)); |
677 | 717 |
678 if (layerClipsSubtree(layer)) { | 718 if (layerClipsSubtree(layer)) { |
679 subtreeShouldBeClipped = true; | 719 subtreeShouldBeClipped = true; |
680 if (ancestorClipsSubtree && !layer->renderSurface()) { | 720 if (ancestorClipsSubtree && !layer->renderSurface()) { |
681 clipRectForSubtree = clipRectFromAncestor; | 721 clipRectForSubtree = clipRectFromAncestor; |
(...skipping 21 matching lines...) Expand all Loading... |
703 if (!layerShouldBeSkipped(layer)) | 743 if (!layerShouldBeSkipped(layer)) |
704 descendants.push_back(layer); | 744 descendants.push_back(layer); |
705 | 745 |
706 gfx::Transform nextScrollCompensationMatrix = computeScrollCompensationMatri
xForChildren(layer, parentMatrix, currentScrollCompensationMatrix);; | 746 gfx::Transform nextScrollCompensationMatrix = computeScrollCompensationMatri
xForChildren(layer, parentMatrix, currentScrollCompensationMatrix);; |
707 | 747 |
708 gfx::Rect accumulatedDrawableContentRectOfChildren; | 748 gfx::Rect accumulatedDrawableContentRectOfChildren; |
709 for (size_t i = 0; i < layer->children().size(); ++i) { | 749 for (size_t i = 0; i < layer->children().size(); ++i) { |
710 LayerType* child = LayerTreeHostCommon::getChildAsRawPtr(layer->children
(), i); | 750 LayerType* child = LayerTreeHostCommon::getChildAsRawPtr(layer->children
(), i); |
711 gfx::Rect drawableContentRectOfChildSubtree; | 751 gfx::Rect drawableContentRectOfChildSubtree; |
712 calculateDrawPropertiesInternal<LayerType, LayerList, RenderSurfaceType>
(child, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix, | 752 calculateDrawPropertiesInternal<LayerType, LayerList, RenderSurfaceType>
(child, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix, |
713
clipRectForSubtree, subtreeShouldBeClipped, nearestAncestorThatMovesPixels, | 753
clipRectForSubtree, clipRectForSubtreeInDescendantSpace, subtreeShouldBeClipped
, nearestAncestorThatMovesPixels, |
714
renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFa
ctor, pageScaleFactor, drawableContentRectOfChildSubtree); | 754
renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFa
ctor, pageScaleFactor, drawableContentRectOfChildSubtree); |
715 if (!drawableContentRectOfChildSubtree.IsEmpty()) { | 755 if (!drawableContentRectOfChildSubtree.IsEmpty()) { |
716 accumulatedDrawableContentRectOfChildren.Union(drawableContentRectOf
ChildSubtree); | 756 accumulatedDrawableContentRectOfChildren.Union(drawableContentRectOf
ChildSubtree); |
717 if (child->renderSurface()) | 757 if (child->renderSurface()) |
718 descendants.push_back(child); | 758 descendants.push_back(child); |
719 } | 759 } |
720 } | 760 } |
721 | 761 |
| 762 if (layer->renderSurface() && !isRootLayer(layer) && !layer->renderSurface()
->layerList().size()) { |
| 763 removeSurfaceForEarlyExit(layer, renderSurfaceLayerList); |
| 764 return; |
| 765 } |
| 766 |
722 // Compute the total drawableContentRect for this subtree (the rect is in ta
rgetSurface space) | 767 // Compute the total drawableContentRect for this subtree (the rect is in ta
rgetSurface space) |
723 gfx::Rect localDrawableContentRectOfSubtree = accumulatedDrawableContentRect
OfChildren; | 768 gfx::Rect localDrawableContentRectOfSubtree = accumulatedDrawableContentRect
OfChildren; |
724 if (layer->drawsContent()) | 769 if (layer->drawsContent()) |
725 localDrawableContentRectOfSubtree.Union(rectInTargetSpace); | 770 localDrawableContentRectOfSubtree.Union(rectInTargetSpace); |
726 if (subtreeShouldBeClipped) | 771 if (subtreeShouldBeClipped) |
727 localDrawableContentRectOfSubtree.Intersect(clipRectForSubtree); | 772 localDrawableContentRectOfSubtree.Intersect(clipRectForSubtree); |
728 | 773 |
729 // Compute the layer's drawable content rect (the rect is in targetSurface s
pace) | 774 // Compute the layer's drawable content rect (the rect is in targetSurface s
pace) |
730 layerDrawProperties.drawable_content_rect = rectInTargetSpace; | 775 layerDrawProperties.drawable_content_rect = rectInTargetSpace; |
731 if (subtreeShouldBeClipped) | 776 if (subtreeShouldBeClipped) |
732 layerDrawProperties.drawable_content_rect.Intersect(clipRectForSubtree); | 777 layerDrawProperties.drawable_content_rect.Intersect(clipRectForSubtree); |
733 | 778 |
734 // Tell the layer the rect that is clipped by. In theory we could use a | 779 // Tell the layer the rect that is clipped by. In theory we could use a |
735 // tighter clipRect here (drawableContentRect), but that actually does not | 780 // tighter clipRect here (drawableContentRect), but that actually does not |
736 // reduce how much would be drawn, and instead it would create unnecessary | 781 // reduce how much would be drawn, and instead it would create unnecessary |
737 // changes to scissor state affecting GPU performance. | 782 // changes to scissor state affecting GPU performance. |
738 layerDrawProperties.is_clipped = subtreeShouldBeClipped; | 783 layerDrawProperties.is_clipped = subtreeShouldBeClipped; |
739 if (subtreeShouldBeClipped) | 784 if (subtreeShouldBeClipped) |
740 layerDrawProperties.clip_rect = clipRectForSubtree; | 785 layerDrawProperties.clip_rect = clipRectForSubtree; |
741 else { | 786 else { |
742 // Initialize the clipRect to a safe value that will not clip the | 787 // Initialize the clipRect to a safe value that will not clip the |
743 // layer, just in case clipping is still accidentally used. | 788 // layer, just in case clipping is still accidentally used. |
744 layerDrawProperties.clip_rect = rectInTargetSpace; | 789 layerDrawProperties.clip_rect = rectInTargetSpace; |
745 } | 790 } |
746 | 791 |
747 // Compute the layer's visible content rect (the rect is in content space) | 792 // Compute the layer's visible content rect (the rect is in content space) |
748 layerDrawProperties.visible_content_rect = calculateVisibleContentRect(layer
); | 793 layerDrawProperties.visible_content_rect = calculateVisibleContentRect(layer
, clipRectForSubtreeInDescendantSpace, rectInTargetSpace); |
749 | 794 |
750 // Compute the remaining properties for the render surface, if the layer has
one. | 795 // Compute the remaining properties for the render surface, if the layer has
one. |
751 if (isRootLayer(layer)) { | 796 if (isRootLayer(layer)) { |
752 // The root layer's surface's contentRect is always the entire viewport. | 797 // The root layer's surface's contentRect is always the entire viewport. |
753 DCHECK(layer->renderSurface()); | 798 DCHECK(layer->renderSurface()); |
754 layer->renderSurface()->setContentRect(clipRectFromAncestor); | 799 layer->renderSurface()->setContentRect(clipRectFromAncestor); |
755 } else if (layer->renderSurface() && !isRootLayer(layer)) { | 800 } else if (layer->renderSurface() && !isRootLayer(layer)) { |
756 RenderSurfaceType* renderSurface = layer->renderSurface(); | 801 RenderSurfaceType* renderSurface = layer->renderSurface(); |
757 gfx::Rect clippedContentRect = localDrawableContentRectOfSubtree; | 802 gfx::Rect clippedContentRect = localDrawableContentRectOfSubtree; |
758 | 803 |
759 // Don't clip if the layer is reflected as the reflection shouldn't be | 804 // Don't clip if the layer is reflected as the reflection shouldn't be |
760 // clipped. If the layer is animating, then the surface's transform to | 805 // clipped. If the layer is animating, then the surface's transform to |
761 // its target is not known on the main thread, and we should not use it | 806 // its target is not known on the main thread, and we should not use it |
762 // to clip. | 807 // to clip. |
763 if (!layer->replicaLayer() && transformToParentIsKnown(layer)) { | 808 if (!layer->replicaLayer() && transformToParentIsKnown(layer)) { |
764 // Note, it is correct to use ancestorClipsSubtree here, because we
are looking at this layer's renderSurface, not the layer itself. | 809 // Note, it is correct to use ancestorClipsSubtree here, because we
are looking at this layer's renderSurface, not the layer itself. |
765 if (ancestorClipsSubtree && !clippedContentRect.IsEmpty()) { | 810 if (ancestorClipsSubtree && !clippedContentRect.IsEmpty()) { |
766 gfx::Rect surfaceClipRect = LayerTreeHostCommon::calculateVisibl
eRect(renderSurface->clipRect(), clippedContentRect, renderSurface->drawTransfor
m()); | 811 gfx::Rect surfaceClipRect = LayerTreeHostCommon::calculateVisibl
eRect(renderSurface->clipRect(), clippedContentRect, renderSurface->drawTransfor
m()); |
767 clippedContentRect.Intersect(surfaceClipRect); | 812 clippedContentRect.Intersect(surfaceClipRect); |
768 } | 813 } |
769 } | 814 } |
770 | 815 |
771 // The RenderSurfaceImpl backing texture cannot exceed the maximum suppo
rted | 816 // The RenderSurfaceImpl backing texture cannot exceed the maximum suppo
rted |
772 // texture size. | 817 // texture size. |
773 clippedContentRect.set_width(std::min(clippedContentRect.width(), maxTex
tureSize)); | 818 clippedContentRect.set_width(std::min(clippedContentRect.width(), maxTex
tureSize)); |
774 clippedContentRect.set_height(std::min(clippedContentRect.height(), maxT
extureSize)); | 819 clippedContentRect.set_height(std::min(clippedContentRect.height(), maxT
extureSize)); |
775 | 820 |
776 if (clippedContentRect.IsEmpty()) | 821 if (clippedContentRect.IsEmpty()) { |
777 renderSurface->clearLayerLists(); | 822 renderSurface->clearLayerLists(); |
778 | 823 removeSurfaceForEarlyExit(layer, renderSurfaceLayerList); |
| 824 return; |
| 825 } |
| 826 |
779 renderSurface->setContentRect(clippedContentRect); | 827 renderSurface->setContentRect(clippedContentRect); |
780 | 828 |
781 // The owning layer's screenSpaceTransform has a scale from content to l
ayer space which we need to undo and | 829 // The owning layer's screenSpaceTransform has a scale from content to l
ayer space which we need to undo and |
782 // replace with a scale from the surface's subtree into layer space. | 830 // replace with a scale from the surface's subtree into layer space. |
783 gfx::Transform screenSpaceTransform = layer->screenSpaceTransform(); | 831 gfx::Transform screenSpaceTransform = layer->screenSpaceTransform(); |
784 screenSpaceTransform.Scale(layer->contentsScaleX() / renderSurfaceSublay
erScale.x(), layer->contentsScaleY() / renderSurfaceSublayerScale.y()); | 832 screenSpaceTransform.Scale(layer->contentsScaleX() / renderSurfaceSublay
erScale.x(), layer->contentsScaleY() / renderSurfaceSublayerScale.y()); |
785 renderSurface->setScreenSpaceTransform(screenSpaceTransform); | 833 renderSurface->setScreenSpaceTransform(screenSpaceTransform); |
786 | 834 |
787 if (layer->replicaLayer()) { | 835 if (layer->replicaLayer()) { |
788 gfx::Transform surfaceOriginToReplicaOriginTransform; | 836 gfx::Transform surfaceOriginToReplicaOriginTransform; |
789 surfaceOriginToReplicaOriginTransform.Scale(renderSurfaceSublayerSca
le.x(), renderSurfaceSublayerScale.y()); | 837 surfaceOriginToReplicaOriginTransform.Scale(renderSurfaceSublayerSca
le.x(), renderSurfaceSublayerScale.y()); |
790 surfaceOriginToReplicaOriginTransform.Translate(layer->replicaLayer(
)->position().x() + layer->replicaLayer()->anchorPoint().x() * bounds.width(), | 838 surfaceOriginToReplicaOriginTransform.Translate(layer->replicaLayer(
)->position().x() + layer->replicaLayer()->anchorPoint().x() * bounds.width(), |
791 layer->replicaLayer(
)->position().y() + layer->replicaLayer()->anchorPoint().y() * bounds.height()); | 839 layer->replicaLayer(
)->position().y() + layer->replicaLayer()->anchorPoint().y() * bounds.height()); |
792 surfaceOriginToReplicaOriginTransform.PreconcatTransform(layer->repl
icaLayer()->transform()); | 840 surfaceOriginToReplicaOriginTransform.PreconcatTransform(layer->repl
icaLayer()->transform()); |
793 surfaceOriginToReplicaOriginTransform.Translate(-layer->replicaLayer
()->anchorPoint().x() * bounds.width(), -layer->replicaLayer()->anchorPoint().y(
) * bounds.height()); | 841 surfaceOriginToReplicaOriginTransform.Translate(-layer->replicaLayer
()->anchorPoint().x() * bounds.width(), -layer->replicaLayer()->anchorPoint().y(
) * bounds.height()); |
794 surfaceOriginToReplicaOriginTransform.Scale(1 / renderSurfaceSublaye
rScale.x(), 1 / renderSurfaceSublayerScale.y()); | 842 surfaceOriginToReplicaOriginTransform.Scale(1 / renderSurfaceSublaye
rScale.x(), 1 / renderSurfaceSublayerScale.y()); |
795 | 843 |
796 // Compute the replica's "originTransform" that maps from the replic
a's origin space to the target surface origin space. | 844 // Compute the replica's "originTransform" that maps from the replic
a's origin space to the target surface origin space. |
797 gfx::Transform replicaOriginTransform = layer->renderSurface()->draw
Transform() * surfaceOriginToReplicaOriginTransform; | 845 gfx::Transform replicaOriginTransform = layer->renderSurface()->draw
Transform() * surfaceOriginToReplicaOriginTransform; |
798 renderSurface->setReplicaDrawTransform(replicaOriginTransform); | 846 renderSurface->setReplicaDrawTransform(replicaOriginTransform); |
799 | 847 |
800 // Compute the replica's "screenSpaceTransform" that maps from the r
eplica's origin space to the screen's origin space. | 848 // Compute the replica's "screenSpaceTransform" that maps from the r
eplica's origin space to the screen's origin space. |
801 gfx::Transform replicaScreenSpaceTransform = layer->renderSurface()-
>screenSpaceTransform() * surfaceOriginToReplicaOriginTransform; | 849 gfx::Transform replicaScreenSpaceTransform = layer->renderSurface()-
>screenSpaceTransform() * surfaceOriginToReplicaOriginTransform; |
802 renderSurface->setReplicaScreenSpaceTransform(replicaScreenSpaceTran
sform); | 850 renderSurface->setReplicaScreenSpaceTransform(replicaScreenSpaceTran
sform); |
803 } | 851 } |
804 | |
805 // If a render surface has no layer list, then it and none of its childr
en needed to get drawn. | |
806 if (!layer->renderSurface()->layerList().size()) { | |
807 // FIXME: Originally we asserted that this layer was already at the
end of the | |
808 // list, and only needed to remove that layer. For now, we re
move the | |
809 // entire subtree of surfaces to fix a crash bug. The root ca
use is | |
810 // https://bugs.webkit.org/show_bug.cgi?id=74147 and we shoul
d be able | |
811 // to put the original assert after fixing that. | |
812 while (renderSurfaceLayerList.back() != layer) { | |
813 renderSurfaceLayerList.back()->clearRenderSurface(); | |
814 renderSurfaceLayerList.pop_back(); | |
815 } | |
816 DCHECK(renderSurfaceLayerList.back() == layer); | |
817 renderSurfaceLayerList.pop_back(); | |
818 layer->clearRenderSurface(); | |
819 return; | |
820 } | |
821 } | 852 } |
822 | 853 |
823 markLayerAsUpdated(layer); | 854 markLayerAsUpdated(layer); |
824 | 855 |
825 // If neither this layer nor any of its children were added, early out. | 856 // If neither this layer nor any of its children were added, early out. |
826 if (sortingStartIndex == descendants.size()) | 857 if (sortingStartIndex == descendants.size()) |
827 return; | 858 return; |
828 | 859 |
829 // If preserves-3d then sort all the descendants in 3D so that they can be | 860 // If preserves-3d then sort all the descendants in 3D so that they can be |
830 // drawn from back to front. If the preserves-3d property is also set on the
parent then | 861 // drawn from back to front. If the preserves-3d property is also set on the
parent then |
(...skipping 20 matching lines...) Expand all Loading... |
851 | 882 |
852 // The root layer's renderSurface should receive the deviceViewport as the i
nitial clipRect. | 883 // The root layer's renderSurface should receive the deviceViewport as the i
nitial clipRect. |
853 bool subtreeShouldBeClipped = true; | 884 bool subtreeShouldBeClipped = true; |
854 gfx::Rect deviceViewportRect(gfx::Point(), deviceViewportSize); | 885 gfx::Rect deviceViewportRect(gfx::Point(), deviceViewportSize); |
855 | 886 |
856 // This function should have received a root layer. | 887 // This function should have received a root layer. |
857 DCHECK(isRootLayer(rootLayer)); | 888 DCHECK(isRootLayer(rootLayer)); |
858 | 889 |
859 cc::calculateDrawPropertiesInternal<Layer, std::vector<scoped_refptr<Layer>
>, RenderSurface>( | 890 cc::calculateDrawPropertiesInternal<Layer, std::vector<scoped_refptr<Layer>
>, RenderSurface>( |
860 rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, | 891 rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
861 deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, | 892 deviceViewportRect, deviceViewportRect, subtreeShouldBeClipped, 0, rende
rSurfaceLayerList, |
862 dummyLayerList, 0, maxTextureSize, | 893 dummyLayerList, 0, maxTextureSize, |
863 deviceScaleFactor, pageScaleFactor, totalDrawableContentRect); | 894 deviceScaleFactor, pageScaleFactor, totalDrawableContentRect); |
864 | 895 |
865 // The dummy layer list should not have been used. | 896 // The dummy layer list should not have been used. |
866 DCHECK(dummyLayerList.size() == 0); | 897 DCHECK(dummyLayerList.size() == 0); |
867 // A root layer renderSurface should always exist after calculateDrawPropert
ies. | 898 // A root layer renderSurface should always exist after calculateDrawPropert
ies. |
868 DCHECK(rootLayer->renderSurface()); | 899 DCHECK(rootLayer->renderSurface()); |
869 } | 900 } |
870 | 901 |
871 void LayerTreeHostCommon::calculateDrawProperties(LayerImpl* rootLayer, const gf
x::Size& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, int
maxTextureSize, std::vector<LayerImpl*>& renderSurfaceLayerList) | 902 void LayerTreeHostCommon::calculateDrawProperties(LayerImpl* rootLayer, const gf
x::Size& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, int
maxTextureSize, std::vector<LayerImpl*>& renderSurfaceLayerList) |
872 { | 903 { |
873 gfx::Rect totalDrawableContentRect; | 904 gfx::Rect totalDrawableContentRect; |
874 gfx::Transform identityMatrix; | 905 gfx::Transform identityMatrix; |
875 gfx::Transform deviceScaleTransform; | 906 gfx::Transform deviceScaleTransform; |
876 deviceScaleTransform.Scale(deviceScaleFactor, deviceScaleFactor); | 907 deviceScaleTransform.Scale(deviceScaleFactor, deviceScaleFactor); |
877 std::vector<LayerImpl*> dummyLayerList; | 908 std::vector<LayerImpl*> dummyLayerList; |
878 LayerSorter layerSorter; | 909 LayerSorter layerSorter; |
879 | 910 |
880 // The root layer's renderSurface should receive the deviceViewport as the i
nitial clipRect. | 911 // The root layer's renderSurface should receive the deviceViewport as the i
nitial clipRect. |
881 bool subtreeShouldBeClipped = true; | 912 bool subtreeShouldBeClipped = true; |
882 gfx::Rect deviceViewportRect(gfx::Point(), deviceViewportSize); | 913 gfx::Rect deviceViewportRect(gfx::Point(), deviceViewportSize); |
883 | 914 |
884 // This function should have received a root layer. | 915 // This function should have received a root layer. |
885 DCHECK(isRootLayer(rootLayer)); | 916 DCHECK(isRootLayer(rootLayer)); |
886 | 917 |
887 cc::calculateDrawPropertiesInternal<LayerImpl, std::vector<LayerImpl*>, Rend
erSurfaceImpl>( | 918 cc::calculateDrawPropertiesInternal<LayerImpl, std::vector<LayerImpl*>, Rend
erSurfaceImpl>( |
888 rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, | 919 rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
889 deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, | 920 deviceViewportRect, deviceViewportRect, subtreeShouldBeClipped, 0, rende
rSurfaceLayerList, |
890 dummyLayerList, &layerSorter, maxTextureSize, | 921 dummyLayerList, &layerSorter, maxTextureSize, |
891 deviceScaleFactor, pageScaleFactor, totalDrawableContentRect); | 922 deviceScaleFactor, pageScaleFactor, totalDrawableContentRect); |
892 | 923 |
893 // The dummy layer list should not have been used. | 924 // The dummy layer list should not have been used. |
894 DCHECK(dummyLayerList.size() == 0); | 925 DCHECK(dummyLayerList.size() == 0); |
895 // A root layer renderSurface should always exist after calculateDrawPropert
ies. | 926 // A root layer renderSurface should always exist after calculateDrawPropert
ies. |
896 DCHECK(rootLayer->renderSurface()); | 927 DCHECK(rootLayer->renderSurface()); |
897 } | 928 } |
898 | 929 |
899 static bool pointHitsRect(const gfx::PointF& screenSpacePoint, const gfx::Transf
orm& localSpaceToScreenSpaceTransform, gfx::RectF localSpaceRect) | 930 static bool pointHitsRect(const gfx::PointF& screenSpacePoint, const gfx::Transf
orm& localSpaceToScreenSpaceTransform, gfx::RectF localSpaceRect) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 | 1044 |
1014 foundLayer = currentLayer; | 1045 foundLayer = currentLayer; |
1015 break; | 1046 break; |
1016 } | 1047 } |
1017 | 1048 |
1018 // This can potentially return 0, which means the screenSpacePoint did not s
uccessfully hit test any layers, not even the root layer. | 1049 // This can potentially return 0, which means the screenSpacePoint did not s
uccessfully hit test any layers, not even the root layer. |
1019 return foundLayer; | 1050 return foundLayer; |
1020 } | 1051 } |
1021 | 1052 |
1022 } // namespace cc | 1053 } // namespace cc |
OLD | NEW |