Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1477)

Unified Diff: Source/core/rendering/RenderLayerCompositor.cpp

Issue 23903012: Set up scroll and clip parents (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: . Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/RenderLayerCompositor.cpp
diff --git a/Source/core/rendering/RenderLayerCompositor.cpp b/Source/core/rendering/RenderLayerCompositor.cpp
index e7b5a0f21a3d37333f34d10368c69e0914d43ea4..8f6d8c420b42507052c5b0e7cf8aecb2e08b22bf 100644
--- a/Source/core/rendering/RenderLayerCompositor.cpp
+++ b/Source/core/rendering/RenderLayerCompositor.cpp
@@ -439,9 +439,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.
@@ -456,7 +457,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
@@ -1045,7 +1047,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)
hartmanng 2013/09/06 01:46:38 I think this function could use an explanation in
Ian Vollick 2013/09/06 02:38:11 Done.
hartmanng 2013/09/06 20:35:20 Much better, I think this makes the purpose of the
Ian Vollick 2013/09/06 23:00:59 Done.
+{
+ 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
@@ -1061,6 +1087,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
@@ -1103,12 +1131,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);
}
}
@@ -1117,20 +1163,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);
}
}
}
@@ -1311,9 +1351,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.
@@ -1341,25 +1397,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);
}
}
}
@@ -1755,7 +1811,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;
@@ -1977,34 +2037,7 @@ bool RenderLayerCompositor::requiresCompositingForBlending(RenderObject* rendere
bool RenderLayerCompositor::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const
{
- if (!layer->compositorDrivenAcceleratedScrollingEnabled())
- 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->scrollParent();
}
bool RenderLayerCompositor::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const

Powered by Google App Engine
This is Rietveld 408576698