| Index: cc/layer_tree_host_common.cc
|
| diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc
|
| index 92b44d1ad2fa5623daf138e22b18010a3ccc7520..b51fd000dbae12bef0289216177458f968e5153c 100644
|
| --- a/cc/layer_tree_host_common.cc
|
| +++ b/cc/layer_tree_host_common.cc
|
| @@ -53,6 +53,12 @@ IntRect LayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurfaceRe
|
| return layerRect;
|
| }
|
|
|
| +template <typename LayerType>
|
| +static inline bool isRootLayer(LayerType* layer)
|
| +{
|
| + return !layer->parent();
|
| +}
|
| +
|
| template<typename LayerType>
|
| static inline bool layerIsInExisting3DRenderingContext(LayerType* layer)
|
| {
|
| @@ -62,7 +68,7 @@ static inline bool layerIsInExisting3DRenderingContext(LayerType* layer)
|
| }
|
|
|
| template<typename LayerType>
|
| -static bool layerIsRootOfNewRenderingContext(LayerType* layer)
|
| +static bool isRootLayerOfNewRenderingContext(LayerType* layer)
|
| {
|
| // According to current W3C spec on CSS transforms (Section 6.1), a layer is the
|
| // beginning of 3d rendering context if its parent does not have transform-style:
|
| @@ -95,7 +101,7 @@ static bool isSurfaceBackFaceVisible(LayerType* layer, const WebTransformationMa
|
| if (layerIsInExisting3DRenderingContext(layer))
|
| return drawTransform.isBackFaceVisible();
|
|
|
| - if (layerIsRootOfNewRenderingContext(layer))
|
| + if (isRootLayerOfNewRenderingContext(layer))
|
| return layer->transform().isBackFaceVisible();
|
|
|
| // If the renderSurface is not part of a new or existing rendering context, then the
|
| @@ -218,18 +224,14 @@ static inline bool subtreeShouldBeSkipped(Layer* layer)
|
| template<typename LayerType>
|
| static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlignedWithRespectToParent)
|
| {
|
| - // The root layer has a special render surface that is set up externally, so
|
| - // it shouldn't be treated as a surface in this code.
|
| - if (!layer->parent())
|
| - return false;
|
| -
|
| - // Cache this value, because otherwise it walks the entire subtree several times.
|
| - bool descendantDrawsContent = layer->descendantDrawsContent();
|
| -
|
| //
|
| // A layer and its descendants should render onto a new RenderSurfaceImpl if any of these rules hold:
|
| //
|
|
|
| + // The root layer should always have a renderSurface.
|
| + if (isRootLayer(layer))
|
| + return true;
|
| +
|
| // If we force it.
|
| if (layer->forceRenderSurface())
|
| return true;
|
| @@ -246,6 +248,9 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig
|
| if (!layer->filters().isEmpty() || !layer->backgroundFilters().isEmpty() || layer->filter())
|
| return true;
|
|
|
| + // Cache this value, because otherwise it walks the entire subtree several times.
|
| + bool descendantDrawsContent = layer->descendantDrawsContent();
|
| +
|
| // If the layer flattens its subtree (i.e. the layer doesn't preserve-3d), but it is
|
| // treated as a 3D object by its parent (i.e. parent does preserve-3d).
|
| if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && descendantDrawsContent)
|
| @@ -307,8 +312,8 @@ WebTransformationMatrix computeScrollCompensationMatrixForChildren(LayerImpl* la
|
| // it is fixed to an ancestor, and is a container for any fixed-position descendants.
|
| // - A layer that is a fixed-position container and has a renderSurface should behave the same as a container
|
| // without a renderSurface, the renderSurface is irrelevant in that case.
|
| - // - A layer that does not have an explicit container is simply fixed to the viewport
|
| - // (i.e. the root renderSurface, and it would still compensate for root layer's scrollDelta).
|
| + // - A layer that does not have an explicit container is simply fixed to the viewport.
|
| + // (i.e. the root renderSurface.)
|
| // - If the fixed-position layer has its own renderSurface, then the renderSurface is
|
| // the one who gets fixed.
|
| //
|
| @@ -377,24 +382,10 @@ static inline void updateLayerContentsScale(Layer* layer, const WebTransformatio
|
| replicaMaskLayer->setContentsScale(contentsScale);
|
| }
|
|
|
| -// Should be called just before the recursive calculateDrawTransformsInternal().
|
| -template<typename LayerType, typename LayerList>
|
| -void setupRootLayerAndSurfaceForRecursion(LayerType* rootLayer, LayerList& renderSurfaceLayerList, const IntSize& deviceViewportSize)
|
| -{
|
| - if (!rootLayer->renderSurface())
|
| - rootLayer->createRenderSurface();
|
| -
|
| - rootLayer->renderSurface()->setContentRect(IntRect(IntPoint::zero(), deviceViewportSize));
|
| - rootLayer->renderSurface()->clearLayerLists();
|
| -
|
| - DCHECK(renderSurfaceLayerList.empty());
|
| - renderSurfaceLayerList.push_back(rootLayer);
|
| -}
|
| -
|
| // Recursively walks the layer tree starting at the given node and computes all the
|
| // necessary transformations, clipRects, render surfaces, etc.
|
| template<typename LayerType, typename LayerList, typename RenderSurfaceType, typename LayerSorter>
|
| -static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLayer, const WebTransformationMatrix& parentMatrix,
|
| +static void calculateDrawTransformsInternal(LayerType* layer, const WebTransformationMatrix& parentMatrix,
|
| const WebTransformationMatrix& fullHierarchyMatrix, const WebTransformationMatrix& currentScrollCompensationMatrix,
|
| const IntRect& clipRectFromAncestor, bool ancestorClipsSubtree,
|
| RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList,
|
| @@ -485,7 +476,8 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
|
| // If we early-exit anywhere in this function, the drawableContentRect of this subtree should be considered empty.
|
| drawableContentRectOfSubtree = IntRect();
|
|
|
| - if (subtreeShouldBeSkipped(layer))
|
| + // The root layer cannot skip calcDrawTransforms.
|
| + if (!isRootLayer(layer) && subtreeShouldBeSkipped(layer))
|
| return;
|
|
|
| IntRect clipRectForSubtree;
|
| @@ -642,6 +634,8 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
|
|
|
| renderSurfaceLayerList.push_back(layer);
|
| } else {
|
| + DCHECK(layer->parent());
|
| +
|
| layer->setDrawTransform(drawTransform);
|
| layer->setDrawTransformIsAnimating(animatingTransformToTarget);
|
| layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen);
|
| @@ -650,25 +644,15 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
|
| layer->setDrawOpacity(drawOpacity);
|
| layer->setDrawOpacityIsAnimating(drawOpacityIsAnimating);
|
|
|
| - if (layer != rootLayer) {
|
| - DCHECK(layer->parent());
|
| - layer->clearRenderSurface();
|
| + layer->clearRenderSurface();
|
|
|
| - // Layers without renderSurfaces directly inherit the ancestor's clip status.
|
| - subtreeShouldBeClipped = ancestorClipsSubtree;
|
| - if (ancestorClipsSubtree)
|
| - clipRectForSubtree = clipRectFromAncestor;
|
| -
|
| - // Layers that are not their own renderTarget will render into the target of their nearest ancestor.
|
| - layer->setRenderTarget(layer->parent()->renderTarget());
|
| - } else {
|
| - // FIXME: This root layer special case code should eventually go away. https://bugs.webkit.org/show_bug.cgi?id=92290
|
| - DCHECK(!layer->parent());
|
| - DCHECK(layer->renderSurface());
|
| - DCHECK(ancestorClipsSubtree);
|
| - layer->renderSurface()->setClipRect(clipRectFromAncestor);
|
| - subtreeShouldBeClipped = false;
|
| - }
|
| + // Layers without renderSurfaces directly inherit the ancestor's clip status.
|
| + subtreeShouldBeClipped = ancestorClipsSubtree;
|
| + if (ancestorClipsSubtree)
|
| + clipRectForSubtree = clipRectFromAncestor;
|
| +
|
| + // Layers that are not their own renderTarget will render into the target of their nearest ancestor.
|
| + layer->setRenderTarget(layer->parent()->renderTarget());
|
| }
|
|
|
| IntRect rectInTargetSpace = enclosingIntRect(MathUtil::mapClippedRect(layer->drawTransform(), contentRect));
|
| @@ -705,7 +689,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
|
| for (size_t i = 0; i < layer->children().size(); ++i) {
|
| LayerType* child = LayerTreeHostCommon::getChildAsRawPtr(layer->children(), i);
|
| IntRect drawableContentRectOfChildSubtree;
|
| - calculateDrawTransformsInternal<LayerType, LayerList, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix,
|
| + calculateDrawTransformsInternal<LayerType, LayerList, RenderSurfaceType, LayerSorter>(child, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix,
|
| clipRectForSubtree, subtreeShouldBeClipped, nearestAncestorThatMovesPixels,
|
| renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFactor, pageScaleFactor, drawableContentRectOfChildSubtree);
|
| if (!drawableContentRectOfChildSubtree.isEmpty()) {
|
| @@ -733,7 +717,11 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
|
| layer->setVisibleContentRect(visibleContentRectOfLayer);
|
|
|
| // Compute the remaining properties for the render surface, if the layer has one.
|
| - if (layer->renderSurface() && layer != rootLayer) {
|
| + if (isRootLayer(layer)) {
|
| + // The root layer's surface's contentRect is always the entire viewport.
|
| + DCHECK(layer->renderSurface());
|
| + layer->renderSurface()->setContentRect(clipRectFromAncestor);
|
| + } else if (layer->renderSurface() && !isRootLayer(layer)) {
|
| RenderSurfaceType* renderSurface = layer->renderSurface();
|
| IntRect clippedContentRect = localDrawableContentRectOfSubtree;
|
|
|
| @@ -830,14 +818,25 @@ void LayerTreeHostCommon::calculateDrawTransforms(Layer* rootLayer, const IntSiz
|
| WebTransformationMatrix identityMatrix;
|
| WebTransformationMatrix deviceScaleTransform;
|
| deviceScaleTransform.scale(deviceScaleFactor);
|
| + std::vector<scoped_refptr<Layer> > dummyLayerList;
|
| +
|
| + // The root layer's renderSurface should receive the deviceViewport as the initial clipRect.
|
| + bool subtreeShouldBeClipped = true;
|
| + IntRect deviceViewportRect(IntPoint::zero(), deviceViewportSize);
|
|
|
| - setupRootLayerAndSurfaceForRecursion<Layer, std::vector<scoped_refptr<Layer> > >(rootLayer, renderSurfaceLayerList, deviceViewportSize);
|
| + // This function should have received a root layer.
|
| + DCHECK(isRootLayer(rootLayer));
|
|
|
| cc::calculateDrawTransformsInternal<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface, void>(
|
| - rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
|
| - rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
|
| - rootLayer->renderSurface()->layerList(), 0, maxTextureSize,
|
| + rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
|
| + deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList,
|
| + dummyLayerList, 0, maxTextureSize,
|
| deviceScaleFactor, pageScaleFactor, totalDrawableContentRect);
|
| +
|
| + // The dummy layer list should not have been used.
|
| + DCHECK(dummyLayerList.size() == 0);
|
| + // A root layer renderSurface should always exist after calculateDrawTransforms.
|
| + DCHECK(rootLayer->renderSurface());
|
| }
|
|
|
| void LayerTreeHostCommon::calculateDrawTransforms(LayerImpl* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, LayerSorter* layerSorter, int maxTextureSize, std::vector<LayerImpl*>& renderSurfaceLayerList)
|
| @@ -846,14 +845,25 @@ void LayerTreeHostCommon::calculateDrawTransforms(LayerImpl* rootLayer, const In
|
| WebTransformationMatrix identityMatrix;
|
| WebTransformationMatrix deviceScaleTransform;
|
| deviceScaleTransform.scale(deviceScaleFactor);
|
| + std::vector<LayerImpl*> dummyLayerList;
|
| +
|
| + // The root layer's renderSurface should receive the deviceViewport as the initial clipRect.
|
| + bool subtreeShouldBeClipped = true;
|
| + IntRect deviceViewportRect(IntPoint::zero(), deviceViewportSize);
|
|
|
| - setupRootLayerAndSurfaceForRecursion<LayerImpl, std::vector<LayerImpl*> >(rootLayer, renderSurfaceLayerList, deviceViewportSize);
|
| + // This function should have received a root layer.
|
| + DCHECK(isRootLayer(rootLayer));
|
|
|
| cc::calculateDrawTransformsInternal<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerSorter>(
|
| - rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
|
| - rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
|
| - rootLayer->renderSurface()->layerList(), layerSorter, maxTextureSize,
|
| + rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
|
| + deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList,
|
| + dummyLayerList, layerSorter, maxTextureSize,
|
| deviceScaleFactor, pageScaleFactor, totalDrawableContentRect);
|
| +
|
| + // The dummy layer list should not have been used.
|
| + DCHECK(dummyLayerList.size() == 0);
|
| + // A root layer renderSurface should always exist after calculateDrawTransforms.
|
| + DCHECK(rootLayer->renderSurface());
|
| }
|
|
|
| static bool pointHitsRect(const IntPoint& screenSpacePoint, const WebTransformationMatrix& localSpaceToScreenSpaceTransform, FloatRect localSpaceRect)
|
|
|