| Index: Source/core/rendering/RenderLayerCompositor.cpp
|
| diff --git a/Source/core/rendering/RenderLayerCompositor.cpp b/Source/core/rendering/RenderLayerCompositor.cpp
|
| index 7f58b1035337c5b43178d722a2f0026bb408fc6b..618367b150846e86be58ca6dc26bec6e869624fd 100644
|
| --- a/Source/core/rendering/RenderLayerCompositor.cpp
|
| +++ b/Source/core/rendering/RenderLayerCompositor.cpp
|
| @@ -435,9 +435,10 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
|
| if (needHierarchyUpdate) {
|
| // Update the hierarchy of the compositing layers.
|
| Vector<GraphicsLayer*> childList;
|
| + HashSet<RenderLayer*> visited;
|
| {
|
| TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::rebuildCompositingLayerTree");
|
| - rebuildCompositingLayerTree(updateRoot, childList, 0);
|
| + rebuildCompositingLayerTree(updateRoot, childList, visited, 0);
|
| }
|
|
|
| // Host the document layer in the RenderView's root layer.
|
| @@ -452,7 +453,8 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
|
| } else if (needGeometryUpdate) {
|
| // We just need to do a geometry update. This is only used for position:fixed scrolling;
|
| // most of the time, geometry is updated via RenderLayer::styleChanged().
|
| - updateLayerTreeGeometry(updateRoot, 0);
|
| + HashSet<RenderLayer*> visited;
|
| + updateLayerTreeGeometry(updateRoot, visited, 0);
|
| }
|
|
|
| #if !LOG_DISABLED
|
| @@ -1041,7 +1043,31 @@ bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
|
| return o->supportsAcceleratedRendering();
|
| }
|
|
|
| -void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
|
| +void RenderLayerCompositor::rebuildCompositingLayerTreeForLayerAndScrollParents(RenderLayer* curLayer, Vector<GraphicsLayer*>& childList, HashSet<RenderLayer*>& visited, HashMap<RenderLayer*, Vector<GraphicsLayer*> >& scrollParentChildLists, int depth)
|
| +{
|
| + ASSERT(curLayer->zIndex() >= 0 || !visited.contains(curLayer));
|
| + if (visited.contains(curLayer)) {
|
| + HashMap<RenderLayer*, Vector<GraphicsLayer*> >::iterator it = scrollParentChildLists.find(curLayer);
|
| + ASSERT(it != scrollParentChildLists.end());
|
| + childList.append(it->value);
|
| + scrollParentChildLists.remove(it);
|
| + return;
|
| + }
|
| +
|
| + if (requiresCompositingForOverflowScrollingParent(curLayer)) {
|
| + RenderLayer* scrollParent = curLayer->ancestorScrollingLayer();
|
| + if (!visited.contains(scrollParent)) {
|
| + ASSERT(!scrollParentChildLists.contains(scrollParent));
|
| + Vector<GraphicsLayer*> scrollParentChildList;
|
| + rebuildCompositingLayerTreeForLayerAndScrollParents(scrollParent, scrollParentChildList, visited, scrollParentChildLists, depth);
|
| + scrollParentChildLists.add(scrollParent, scrollParentChildList);
|
| + }
|
| + }
|
| +
|
| + rebuildCompositingLayerTree(curLayer, childList, visited, depth);
|
| +}
|
| +
|
| +void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, HashSet<RenderLayer*>& visited, int depth)
|
| {
|
| // Make the layer compositing if necessary, and set up clipping and content layers.
|
| // Note that we can only do work here that is independent of whether the descendant layers
|
| @@ -1057,6 +1083,8 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vect
|
| pixelsAddedByPromotingAllTransitions = 0.0;
|
| }
|
|
|
| + visited.add(layer);
|
| +
|
| RenderLayerBacking* layerBacking = layer->backing();
|
| if (layerBacking) {
|
| // The compositing state of all our children has been updated already, so now
|
| @@ -1099,12 +1127,30 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vect
|
| LayerListMutationDetector mutationChecker(layer);
|
| #endif
|
|
|
| + // Visit the normal flow descendants first. We do this for the sake of scroll
|
| + // parents. A scroll parent is not a stacking context, so it will either appear
|
| + // in the normal flow tree, or in the positive z-order list (if it had a positioned
|
| + // ancestor). Visiting the scroll parent ahead of time if it appears in one
|
| + // of these lists is a simple matter since we have the lists in hand at this
|
| + // level of the recursion, but it's tricker for layers in the normal flow tree,
|
| + // so it will be easier to just process this ahead of time.
|
| + Vector<GraphicsLayer*> normalFlowChildList;
|
| +
|
| + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
|
| + size_t listSize = normalFlowList->size();
|
| + for (size_t i = 0; i < listSize; ++i) {
|
| + RenderLayer* curLayer = normalFlowList->at(i);
|
| + rebuildCompositingLayerTree(curLayer, normalFlowChildList, visited, depth + 1);
|
| + }
|
| + }
|
| +
|
| + HashMap<RenderLayer*, Vector<GraphicsLayer*> > scrollParentChildLists;
|
| if (layer->isStackingContainer()) {
|
| if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
|
| size_t listSize = negZOrderList->size();
|
| for (size_t i = 0; i < listSize; ++i) {
|
| RenderLayer* curLayer = negZOrderList->at(i);
|
| - rebuildCompositingLayerTree(curLayer, childList, depth + 1);
|
| + rebuildCompositingLayerTreeForLayerAndScrollParents(curLayer, childList, visited, scrollParentChildLists, depth + 1);
|
| }
|
| }
|
|
|
| @@ -1113,20 +1159,14 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vect
|
| childList.append(layerBacking->foregroundLayer());
|
| }
|
|
|
| - if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
|
| - size_t listSize = normalFlowList->size();
|
| - for (size_t i = 0; i < listSize; ++i) {
|
| - RenderLayer* curLayer = normalFlowList->at(i);
|
| - rebuildCompositingLayerTree(curLayer, childList, depth + 1);
|
| - }
|
| - }
|
| + childList.append(normalFlowChildList);
|
|
|
| if (layer->isStackingContainer()) {
|
| if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
|
| size_t listSize = posZOrderList->size();
|
| for (size_t i = 0; i < listSize; ++i) {
|
| RenderLayer* curLayer = posZOrderList->at(i);
|
| - rebuildCompositingLayerTree(curLayer, childList, depth + 1);
|
| + rebuildCompositingLayerTreeForLayerAndScrollParents(curLayer, childList, visited, scrollParentChildLists, depth + 1);
|
| }
|
| }
|
| }
|
| @@ -1307,9 +1347,25 @@ bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
|
| return true;
|
| }
|
|
|
| +void RenderLayerCompositor::updateLayerTreeGeometryForLayerAndScrollParents(RenderLayer* layer, HashSet<RenderLayer*>& visited, int depth)
|
| +{
|
| + ASSERT(layer->zIndex() >= 0 || !visited.contains(layer));
|
| + if (visited.contains(layer))
|
| + return;
|
| +
|
| + if (requiresCompositingForOverflowScrollingParent(layer)) {
|
| + RenderLayer* scrollParent = layer->ancestorScrollingLayer();
|
| + if (!visited.contains(scrollParent))
|
| + updateLayerTreeGeometryForLayerAndScrollParents(scrollParent, visited, depth);
|
| + }
|
| +
|
| + updateLayerTreeGeometry(layer, visited, depth);
|
| +}
|
| // This just updates layer geometry without changing the hierarchy.
|
| -void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, int depth)
|
| +void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, HashSet<RenderLayer*>& visited, int depth)
|
| {
|
| + visited.add(layer);
|
| +
|
| if (RenderLayerBacking* layerBacking = layer->backing()) {
|
| // The compositing state of all our children has been updated already, so now
|
| // we can compute and cache the composited bounds for this layer.
|
| @@ -1337,25 +1393,25 @@ void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer, int dept
|
| LayerListMutationDetector mutationChecker(layer);
|
| #endif
|
|
|
| + if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
|
| + size_t listSize = normalFlowList->size();
|
| + for (size_t i = 0; i < listSize; ++i)
|
| + updateLayerTreeGeometry(normalFlowList->at(i), visited, depth + 1);
|
| + }
|
| +
|
| if (layer->isStackingContainer()) {
|
| if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
|
| size_t listSize = negZOrderList->size();
|
| for (size_t i = 0; i < listSize; ++i)
|
| - updateLayerTreeGeometry(negZOrderList->at(i), depth + 1);
|
| + updateLayerTreeGeometryForLayerAndScrollParents(negZOrderList->at(i), visited, depth + 1);
|
| }
|
| }
|
|
|
| - if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
|
| - size_t listSize = normalFlowList->size();
|
| - for (size_t i = 0; i < listSize; ++i)
|
| - updateLayerTreeGeometry(normalFlowList->at(i), depth + 1);
|
| - }
|
| -
|
| if (layer->isStackingContainer()) {
|
| if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
|
| size_t listSize = posZOrderList->size();
|
| for (size_t i = 0; i < listSize; ++i)
|
| - updateLayerTreeGeometry(posZOrderList->at(i), depth + 1);
|
| + updateLayerTreeGeometryForLayerAndScrollParents(posZOrderList->at(i), visited, depth + 1);
|
| }
|
| }
|
| }
|
| @@ -1751,7 +1807,11 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
|
| if (!layer->isComposited() || !layer->parent())
|
| return false;
|
|
|
| - RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
|
| + // Scroll children use their scrolling ancestor as their clip root.
|
| + RenderLayer* compositingAncestor = requiresCompositingForOverflowScrollingParent(layer)
|
| + ? layer->ancestorScrollingLayer()
|
| + : layer->ancestorCompositingLayer();
|
| +
|
| if (!compositingAncestor)
|
| return false;
|
|
|
| @@ -1973,34 +2033,7 @@ bool RenderLayerCompositor::requiresCompositingForBlending(RenderObject* rendere
|
|
|
| bool RenderLayerCompositor::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const
|
| {
|
| - if (!layer->useCompositorDrivenAcceleratedScrolling())
|
| - return false;
|
| -
|
| - // A layer scrolls with its containing block. So to find the overflow scrolling layer
|
| - // that we scroll with respect to, we must ascend the layer tree until we reach the
|
| - // first overflow scrolling div at or above our containing block. I will refer to this
|
| - // layer as our 'scrolling ancestor'.
|
| - //
|
| - // Now, if we reside in a normal flow list, then we will naturally scroll with our scrolling
|
| - // ancestor, and we need not be composited. If, on the other hand, we reside in a z-order
|
| - // list, and on our walk upwards to our scrolling ancestor we find no layer that is a stacking
|
| - // context, then we know that in the stacking tree, we will not be in the subtree rooted at
|
| - // our scrolling ancestor, and we will therefore not scroll with it. In this case, we must
|
| - // be a composited layer since the compositor will need to take special measures to ensure
|
| - // that we scroll with our scrolling ancestor and it cannot do this if we do not promote.
|
| - RenderLayer* scrollParent = layer->ancestorScrollingLayer();
|
| -
|
| - if (!scrollParent || scrollParent->isStackingContext())
|
| - return false;
|
| -
|
| - // If we hit a stacking context on our way up to the ancestor scrolling layer, it will already
|
| - // be composited due to an overflow scrolling parent, so we don't need to.
|
| - for (RenderLayer* ancestor = layer->parent(); ancestor && ancestor != scrollParent; ancestor = ancestor->parent()) {
|
| - if (ancestor->isStackingContext())
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| + return layer->hasScrollParent();
|
| }
|
|
|
| bool RenderLayerCompositor::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const
|
|
|