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

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

Issue 22419002: Set up clip and scroll parents on the blink side. (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
« no previous file with comments | « Source/core/rendering/RenderLayerCompositor.h ('k') | public/platform/WebLayer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « Source/core/rendering/RenderLayerCompositor.h ('k') | public/platform/WebLayer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698