Chromium Code Reviews| 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 |