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 | 5 |
6 #include "config.h" | 6 #include "config.h" |
7 | 7 |
8 #include "CCLayerTreeHostCommon.h" | 8 #include "CCLayerTreeHostCommon.h" |
9 | 9 |
10 #include "CCLayerImpl.h" | 10 #include "CCLayerImpl.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 static inline bool layerClipsSubtree(LayerType* layer) | 107 static inline bool layerClipsSubtree(LayerType* layer) |
108 { | 108 { |
109 return layer->masksToBounds() || layer->maskLayer(); | 109 return layer->masksToBounds() || layer->maskLayer(); |
110 } | 110 } |
111 | 111 |
112 template<typename LayerType> | 112 template<typename LayerType> |
113 static IntRect calculateVisibleContentRect(LayerType* layer) | 113 static IntRect calculateVisibleContentRect(LayerType* layer) |
114 { | 114 { |
115 ASSERT(layer->renderTarget()); | 115 ASSERT(layer->renderTarget()); |
116 | 116 |
117 IntRect targetSurfaceRect = layer->renderTarget()->renderSurface()->contentR ect(); | 117 // Nothing is visible if the layer bounds are empty. |
118 | 118 if (!layer->drawsContent() || layer->contentBounds().isEmpty() || layer->dra wableContentRect().isEmpty()) |
119 targetSurfaceRect.intersect(layer->drawableContentRect()); | |
120 | |
121 if (targetSurfaceRect.isEmpty() || layer->contentBounds().isEmpty()) | |
122 return IntRect(); | 119 return IntRect(); |
123 | 120 |
124 const IntRect contentRect = IntRect(IntPoint(), layer->contentBounds()); | 121 IntRect targetSurfaceClipRect; |
125 IntRect visibleContentRect = CCLayerTreeHostCommon::calculateVisibleRect(tar getSurfaceRect, contentRect, layer->drawTransform()); | 122 |
126 return visibleContentRect; | 123 // First, compute visible bounds in target surface space. |
124 if (layer->renderTarget()->renderSurface()->clipRect().isEmpty()) | |
125 targetSurfaceClipRect = layer->drawableContentRect(); | |
epenner
2012/10/10 18:35:59
I don't understand how this doesn't allow for poss
shawnsingh
2012/10/10 19:54:56
Aside from the max texture size safety, you're rig
epenner
2012/10/10 21:13:59
Done.
epenner
2012/10/10 21:13:59
IIUC The max texture size will limit the size of a
shawnsingh
2012/10/10 22:35:42
Looks like the root of the problem is that we are
| |
126 else { | |
127 // In this case the target surface does clip layers that contribute to i t. So, we | |
128 // have convert the current surface's clipRect from its ancestor surface space to | |
129 // the current surface space. | |
130 targetSurfaceClipRect = enclosingIntRect(CCMathUtil::projectClippedRect( layer->renderTarget()->renderSurface()->drawTransform().inverse(), layer->render Target()->renderSurface()->clipRect())); | |
131 targetSurfaceClipRect.intersect(layer->drawableContentRect()); | |
132 } | |
133 | |
134 if (targetSurfaceClipRect.isEmpty()) | |
135 return IntRect(); | |
136 | |
137 return CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceClipRect, In tRect(IntPoint(), layer->contentBounds()), layer->drawTransform()); | |
127 } | 138 } |
128 | 139 |
129 static bool isScaleOrTranslation(const WebTransformationMatrix& m) | 140 static bool isScaleOrTranslation(const WebTransformationMatrix& m) |
130 { | 141 { |
131 return !m.m12() && !m.m13() && !m.m14() | 142 return !m.m12() && !m.m13() && !m.m14() |
132 && !m.m21() && !m.m23() && !m.m24() | 143 && !m.m21() && !m.m23() && !m.m24() |
133 && !m.m31() && !m.m32() && !m.m43() | 144 && !m.m31() && !m.m32() && !m.m43() |
134 && m.m44(); | 145 && m.m44(); |
135 } | 146 } |
136 | 147 |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
561 // Update the aggregate hierarchy matrix to include the transform of the | 572 // Update the aggregate hierarchy matrix to include the transform of the |
562 // newly created RenderSurface. | 573 // newly created RenderSurface. |
563 nextHierarchyMatrix.multiply(renderSurface->drawTransform()); | 574 nextHierarchyMatrix.multiply(renderSurface->drawTransform()); |
564 | 575 |
565 // The new renderSurface here will correctly clip the entire subtree. So , we do | 576 // The new renderSurface here will correctly clip the entire subtree. So , we do |
566 // not need to continue propagating the clipping state further down the tree. This | 577 // not need to continue propagating the clipping state further down the tree. This |
567 // way, we can avoid transforming clipRects from ancestor target surface space to | 578 // way, we can avoid transforming clipRects from ancestor target surface space to |
568 // current target surface space that could cause more w < 0 headaches. | 579 // current target surface space that could cause more w < 0 headaches. |
569 subtreeShouldBeClipped = false; | 580 subtreeShouldBeClipped = false; |
570 | 581 |
571 if (layer->maskLayer()) | 582 if (layer->maskLayer()) { |
572 layer->maskLayer()->setRenderTarget(layer); | 583 layer->maskLayer()->setRenderTarget(layer); |
584 layer->maskLayer()->setVisibleContentRect(IntRect(IntPoint(), layer- >contentBounds())); | |
585 } | |
573 | 586 |
574 if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) | 587 if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) { |
575 layer->replicaLayer()->maskLayer()->setRenderTarget(layer); | 588 layer->replicaLayer()->maskLayer()->setRenderTarget(layer); |
589 layer->replicaLayer()->maskLayer()->setVisibleContentRect(IntRect(In tPoint(), layer->contentBounds())); | |
590 } | |
576 | 591 |
577 if (layer->filters().hasFilterThatMovesPixels()) | 592 if (layer->filters().hasFilterThatMovesPixels()) |
578 nearestAncestorThatMovesPixels = renderSurface; | 593 nearestAncestorThatMovesPixels = renderSurface; |
579 | 594 |
595 // The render surface clipRect is expressed in the space where this surf ace draws, i.e. the same space as clipRectFromAncestor. | |
596 if (ancestorClipsSubtree) | |
597 renderSurface->setClipRect(clipRectFromAncestor); | |
598 else | |
599 renderSurface->setClipRect(IntRect()); | |
600 | |
580 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove sPixels); | 601 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove sPixels); |
581 | 602 |
582 renderSurfaceLayerList.append(layer); | 603 renderSurfaceLayerList.append(layer); |
583 } else { | 604 } else { |
584 layer->setDrawTransform(drawTransform); | 605 layer->setDrawTransform(drawTransform); |
585 layer->setDrawTransformIsAnimating(animatingTransformToTarget); | 606 layer->setDrawTransformIsAnimating(animatingTransformToTarget); |
586 layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen); | 607 layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen); |
587 sublayerMatrix = combinedTransform; | 608 sublayerMatrix = combinedTransform; |
588 | 609 |
589 layer->setDrawOpacity(drawOpacity); | 610 layer->setDrawOpacity(drawOpacity); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
661 localDrawableContentRectOfSubtree.unite(rectInTargetSpace); | 682 localDrawableContentRectOfSubtree.unite(rectInTargetSpace); |
662 if (subtreeShouldBeClipped) | 683 if (subtreeShouldBeClipped) |
663 localDrawableContentRectOfSubtree.intersect(clipRectForSubtree); | 684 localDrawableContentRectOfSubtree.intersect(clipRectForSubtree); |
664 | 685 |
665 // Compute the layer's drawable content rect (the rect is in targetSurface s pace) | 686 // Compute the layer's drawable content rect (the rect is in targetSurface s pace) |
666 IntRect drawableContentRectOfLayer = rectInTargetSpace; | 687 IntRect drawableContentRectOfLayer = rectInTargetSpace; |
667 if (subtreeShouldBeClipped) | 688 if (subtreeShouldBeClipped) |
668 drawableContentRectOfLayer.intersect(clipRectForSubtree); | 689 drawableContentRectOfLayer.intersect(clipRectForSubtree); |
669 layer->setDrawableContentRect(drawableContentRectOfLayer); | 690 layer->setDrawableContentRect(drawableContentRectOfLayer); |
670 | 691 |
692 // Compute the layer's visible content rect (the rect is in content space) | |
693 IntRect visibleContentRectOfLayer = calculateVisibleContentRect(layer); | |
694 layer->setVisibleContentRect(visibleContentRectOfLayer); | |
695 | |
671 // Compute the remaining properties for the render surface, if the layer has one. | 696 // Compute the remaining properties for the render surface, if the layer has one. |
672 if (layer->renderSurface() && layer != rootLayer) { | 697 if (layer->renderSurface() && layer != rootLayer) { |
673 RenderSurfaceType* renderSurface = layer->renderSurface(); | 698 RenderSurfaceType* renderSurface = layer->renderSurface(); |
674 IntRect clippedContentRect = localDrawableContentRectOfSubtree; | 699 IntRect clippedContentRect = localDrawableContentRectOfSubtree; |
675 | 700 |
676 // The render surface clipRect is expressed in the space where this surf ace draws, i.e. the same space as clipRectFromAncestor. | |
677 if (ancestorClipsSubtree) | |
epenner
2012/10/10 18:35:59
It looks like this code intends to only set an emp
shawnsingh
2012/10/10 19:54:56
Yes... this is how we're encoding two different po
epenner
2012/10/10 21:13:59
It looks like line 124 checks clipRect().isEmpty()
shawnsingh
2012/10/10 22:35:42
I see what you are saying now - thanks for catchin
| |
678 renderSurface->setClipRect(clipRectFromAncestor); | |
679 else | |
680 renderSurface->setClipRect(IntRect()); | |
681 | |
682 // Don't clip if the layer is reflected as the reflection shouldn't be | 701 // Don't clip if the layer is reflected as the reflection shouldn't be |
683 // clipped. If the layer is animating, then the surface's transform to | 702 // clipped. If the layer is animating, then the surface's transform to |
684 // its target is not known on the main thread, and we should not use it | 703 // its target is not known on the main thread, and we should not use it |
685 // to clip. | 704 // to clip. |
686 if (!layer->replicaLayer() && transformToParentIsKnown(layer)) { | 705 if (!layer->replicaLayer() && transformToParentIsKnown(layer)) { |
687 // Note, it is correct to use ancestorClipsSubtree here, because we are looking at this layer's renderSurface, not the layer itself. | 706 // Note, it is correct to use ancestorClipsSubtree here, because we are looking at this layer's renderSurface, not the layer itself. |
688 if (ancestorClipsSubtree && !clippedContentRect.isEmpty()) { | 707 if (ancestorClipsSubtree && !clippedContentRect.isEmpty()) { |
689 IntRect surfaceClipRect = CCLayerTreeHostCommon::calculateVisibl eRect(renderSurface->clipRect(), clippedContentRect, renderSurface->drawTransfor m()); | 708 IntRect surfaceClipRect = CCLayerTreeHostCommon::calculateVisibl eRect(renderSurface->clipRect(), clippedContentRect, renderSurface->drawTransfor m()); |
690 clippedContentRect.intersect(surfaceClipRect); | 709 clippedContentRect.intersect(surfaceClipRect); |
691 } | 710 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
750 | 769 |
751 if (layer->renderSurface()) | 770 if (layer->renderSurface()) |
752 drawableContentRectOfSubtree = enclosingIntRect(layer->renderSurface()-> drawableContentRect()); | 771 drawableContentRectOfSubtree = enclosingIntRect(layer->renderSurface()-> drawableContentRect()); |
753 else | 772 else |
754 drawableContentRectOfSubtree = localDrawableContentRectOfSubtree; | 773 drawableContentRectOfSubtree = localDrawableContentRectOfSubtree; |
755 | 774 |
756 if (layer->hasContributingDelegatedRenderPasses()) | 775 if (layer->hasContributingDelegatedRenderPasses()) |
757 layer->renderTarget()->renderSurface()->addContributingDelegatedRenderPa ssLayer(layer); | 776 layer->renderTarget()->renderSurface()->addContributingDelegatedRenderPa ssLayer(layer); |
758 } | 777 } |
759 | 778 |
760 // FIXME: Instead of using the following function to set visibility rects on a s econd | |
761 // tree pass, revise calculateVisibleContentRect() so that this can be done in a single | |
762 // pass inside calculateDrawTransformsInternal<>(). | |
763 template<typename LayerType, typename LayerList, typename RenderSurfaceType> | |
764 static void calculateVisibleRectsInternal(const LayerList& renderSurfaceLayerLis t) | |
765 { | |
766 // Use BackToFront since it's cheap and this isn't order-dependent. | |
767 typedef CCLayerIterator<LayerType, LayerList, RenderSurfaceType, CCLayerIter atorActions::BackToFront> CCLayerIteratorType; | |
768 | |
769 CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList); | |
770 for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayer List); it != end; ++it) { | |
771 if (it.representsTargetRenderSurface()) { | |
772 LayerType* maskLayer = it->maskLayer(); | |
773 if (maskLayer) | |
774 maskLayer->setVisibleContentRect(IntRect(IntPoint(), it->content Bounds())); | |
775 LayerType* replicaMaskLayer = it->replicaLayer() ? it->replicaLayer( )->maskLayer() : 0; | |
776 if (replicaMaskLayer) | |
777 replicaMaskLayer->setVisibleContentRect(IntRect(IntPoint(), it-> contentBounds())); | |
778 } else if (it.representsItself()) { | |
779 IntRect visibleContentRect = calculateVisibleContentRect(*it); | |
780 it->setVisibleContentRect(visibleContentRect); | |
781 } | |
782 } | |
783 } | |
784 | |
785 void CCLayerTreeHostCommon::calculateDrawTransforms(LayerChromium* rootLayer, co nst IntSize& deviceViewportSize, float deviceScaleFactor, int maxTextureSize, Ve ctor<RefPtr<LayerChromium> >& renderSurfaceLayerList) | 779 void CCLayerTreeHostCommon::calculateDrawTransforms(LayerChromium* rootLayer, co nst IntSize& deviceViewportSize, float deviceScaleFactor, int maxTextureSize, Ve ctor<RefPtr<LayerChromium> >& renderSurfaceLayerList) |
786 { | 780 { |
787 IntRect totalDrawableContentRect; | 781 IntRect totalDrawableContentRect; |
788 WebTransformationMatrix identityMatrix; | 782 WebTransformationMatrix identityMatrix; |
789 WebTransformationMatrix deviceScaleTransform; | 783 WebTransformationMatrix deviceScaleTransform; |
790 deviceScaleTransform.scale(deviceScaleFactor); | 784 deviceScaleTransform.scale(deviceScaleFactor); |
791 | 785 |
792 setupRootLayerAndSurfaceForRecursion<LayerChromium, Vector<RefPtr<LayerChrom ium> > >(rootLayer, renderSurfaceLayerList, deviceViewportSize); | 786 setupRootLayerAndSurfaceForRecursion<LayerChromium, Vector<RefPtr<LayerChrom ium> > >(rootLayer, renderSurfaceLayerList, deviceViewportSize); |
793 | 787 |
794 cc::calculateDrawTransformsInternal<LayerChromium, Vector<RefPtr<LayerChromi um> >, RenderSurfaceChromium, void>(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, | 788 cc::calculateDrawTransformsInternal<LayerChromium, Vector<RefPtr<LayerChromi um> >, RenderSurfaceChromium, void>(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
795 rootLayer->renderSurface()->contentRect (), true, 0, renderSurfaceLayerList, | 789 rootLayer->renderSurface()->contentRect (), true, 0, renderSurfaceLayerList, |
796 rootLayer->renderSurface()->layerList() , 0, maxTextureSize, deviceScaleFactor, totalDrawableContentRect); | 790 rootLayer->renderSurface()->layerList() , 0, maxTextureSize, deviceScaleFactor, totalDrawableContentRect); |
797 } | 791 } |
798 | 792 |
799 void CCLayerTreeHostCommon::calculateDrawTransforms(CCLayerImpl* rootLayer, cons t IntSize& deviceViewportSize, float deviceScaleFactor, CCLayerSorter* layerSort er, int maxTextureSize, Vector<CCLayerImpl*>& renderSurfaceLayerList) | 793 void CCLayerTreeHostCommon::calculateDrawTransforms(CCLayerImpl* rootLayer, cons t IntSize& deviceViewportSize, float deviceScaleFactor, CCLayerSorter* layerSort er, int maxTextureSize, Vector<CCLayerImpl*>& renderSurfaceLayerList) |
800 { | 794 { |
801 IntRect totalDrawableContentRect; | 795 IntRect totalDrawableContentRect; |
802 WebTransformationMatrix identityMatrix; | 796 WebTransformationMatrix identityMatrix; |
803 WebTransformationMatrix deviceScaleTransform; | 797 WebTransformationMatrix deviceScaleTransform; |
804 deviceScaleTransform.scale(deviceScaleFactor); | 798 deviceScaleTransform.scale(deviceScaleFactor); |
805 | 799 |
806 setupRootLayerAndSurfaceForRecursion<CCLayerImpl, Vector<CCLayerImpl*> >(roo tLayer, renderSurfaceLayerList, deviceViewportSize); | 800 setupRootLayerAndSurfaceForRecursion<CCLayerImpl, Vector<CCLayerImpl*> >(roo tLayer, renderSurfaceLayerList, deviceViewportSize); |
807 | 801 |
808 cc::calculateDrawTransformsInternal<CCLayerImpl, Vector<CCLayerImpl*>, CCRen derSurface, CCLayerSorter>(rootLayer, rootLayer, deviceScaleTransform, identityM atrix, identityMatrix, | 802 cc::calculateDrawTransformsInternal<CCLayerImpl, Vector<CCLayerImpl*>, CCRen derSurface, CCLayerSorter>(rootLayer, rootLayer, deviceScaleTransform, identityM atrix, identityMatrix, |
809 rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList, | 803 rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList, |
810 rootLayer->renderSurface()->layerList(), layerSo rter, maxTextureSize, deviceScaleFactor, totalDrawableContentRect); | 804 rootLayer->renderSurface()->layerList(), layerSo rter, maxTextureSize, deviceScaleFactor, totalDrawableContentRect); |
811 } | 805 } |
812 | 806 |
813 void CCLayerTreeHostCommon::calculateVisibleRects(Vector<RefPtr<LayerChromium> > & renderSurfaceLayerList) | |
814 { | |
815 calculateVisibleRectsInternal<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium>(renderSurfaceLayerList); | |
816 } | |
817 | |
818 void CCLayerTreeHostCommon::calculateVisibleRects(Vector<CCLayerImpl*>& renderSu rfaceLayerList) | |
819 { | |
820 calculateVisibleRectsInternal<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSur face>(renderSurfaceLayerList); | |
821 } | |
822 | |
823 static bool pointHitsRect(const IntPoint& viewportPoint, const WebTransformation Matrix& localSpaceToScreenSpaceTransform, FloatRect localSpaceRect) | 807 static bool pointHitsRect(const IntPoint& viewportPoint, const WebTransformation Matrix& localSpaceToScreenSpaceTransform, FloatRect localSpaceRect) |
824 { | 808 { |
825 // If the transform is not invertible, then assume that this point doesn't h it this rect. | 809 // If the transform is not invertible, then assume that this point doesn't h it this rect. |
826 if (!localSpaceToScreenSpaceTransform.isInvertible()) | 810 if (!localSpaceToScreenSpaceTransform.isInvertible()) |
827 return false; | 811 return false; |
828 | 812 |
829 // Transform the hit test point from screen space to the local space of the given rect. | 813 // Transform the hit test point from screen space to the local space of the given rect. |
830 bool clipped = false; | 814 bool clipped = false; |
831 FloatPoint hitTestPointInLocalSpace = CCMathUtil::projectPoint(localSpaceToS creenSpaceTransform.inverse(), FloatPoint(viewportPoint), clipped); | 815 FloatPoint hitTestPointInLocalSpace = CCMathUtil::projectPoint(localSpaceToS creenSpaceTransform.inverse(), FloatPoint(viewportPoint), clipped); |
832 | 816 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
885 | 869 |
886 foundLayer = currentLayer; | 870 foundLayer = currentLayer; |
887 break; | 871 break; |
888 } | 872 } |
889 | 873 |
890 // This can potentially return 0, which means the viewportPoint did not succ essfully hit test any layers, not even the root layer. | 874 // This can potentially return 0, which means the viewportPoint did not succ essfully hit test any layers, not even the root layer. |
891 return foundLayer; | 875 return foundLayer; |
892 } | 876 } |
893 | 877 |
894 } // namespace cc | 878 } // namespace cc |
OLD | NEW |