Commit 7ea51c5c authored by abarth@chromium.org's avatar abarth@chromium.org

Separate the geometry update from rebuilding the GraphicsLayer tree

This CL separates the work we do to update the GraphicsLayer geometry from the
work we do to rebuild the GraphicsLayer tree. We now update the geometry in
tree-order rather than paint order, which fixes a bug in how we're propagating
dirty bits during the tree walk. The bug fix is captured by the
reorder-z-with-style.html test added in this CL.

Review URL: https://codereview.chromium.org/215063006

git-svn-id: svn://svn.chromium.org/blink/trunk@170277 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 9cfa2601
<!DOCTYPE html>
<style>
#container {
height: 300px;
width: 300px;
background-color: green;
-webkit-transform: translateZ(0);
}
#parent {
position: absolute;
left: 400px;
width: 300px;
height: 300px;
background-color: green;
-webkit-transform: translateZ(0);
}
</style>
<body>
<div id="container">
<div id="parent">
</div>
</div>
</body>
<!DOCTYPE html>
<style>
body {
-webkit-transform: translateZ(0);
}
#container {
height: 300px;
width: 300px;
background-color: green;
-webkit-transform: translateZ(0);
}
#parent {
position: absolute;
left: 400px;
width: 300px;
height: 300px;
background-color: green;
-webkit-transform-style: preserve-3d;
}
#child {
position: absolute;
width: 200px;
height: 200px;
z-index: -2;
background-color: red;
-webkit-transform: translateZ(0);
}
</style>
<body>
<div id="container">
<div id="parent">
<div id="child"></div>
</div>
</div>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
requestAnimationFrame(function() {
requestAnimationFrame(function() {
document.getElementById('parent').style.webkitTransformStyle = 'flat';
setTimeout(function() {
testRunner.notifyDone();
});
});
});
</script>
</body>
...@@ -56,7 +56,7 @@ GraphicsLayerUpdater::~GraphicsLayerUpdater() ...@@ -56,7 +56,7 @@ GraphicsLayerUpdater::~GraphicsLayerUpdater()
{ {
} }
void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType, GraphicsLayerVector& childLayersOfEnclosingLayer) void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, GraphicsLayerVector& childLayersOfEnclosingLayer)
{ {
// Make the layer compositing if necessary, and set up clipping and content layers. // 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 // Note that we can only do work here that is independent of whether the descendant layers
...@@ -67,8 +67,6 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType ...@@ -67,8 +67,6 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType
const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping(); const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping(); CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping();
updateType = update(layer, updateType);
// If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers. // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
// Otherwise children continue to append to the child list of the enclosing layer. // Otherwise children continue to append to the child list of the enclosing layer.
GraphicsLayerVector layerChildren; GraphicsLayerVector layerChildren;
...@@ -81,7 +79,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType ...@@ -81,7 +79,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType
if (layer.stackingNode()->isStackingContainer()) { if (layer.stackingNode()->isStackingContainer()) {
RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren); RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
while (RenderLayerStackingNode* curNode = iterator.next()) while (RenderLayerStackingNode* curNode = iterator.next())
rebuildTree(*curNode->layer(), updateType, childList); rebuildTree(*curNode->layer(), childList);
// If a negative z-order child is compositing, we get a foreground layer which needs to get parented. // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer()) if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
...@@ -90,7 +88,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType ...@@ -90,7 +88,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType
RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren); RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
while (RenderLayerStackingNode* curNode = iterator.next()) while (RenderLayerStackingNode* curNode = iterator.next())
rebuildTree(*curNode->layer(), updateType, childList); rebuildTree(*curNode->layer(), childList);
if (hasCompositedLayerMapping) { if (hasCompositedLayerMapping) {
bool parented = false; bool parented = false;
...@@ -124,47 +122,33 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType ...@@ -124,47 +122,33 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType
} }
} }
// This just updates layer geometry without changing the hierarchy. void GraphicsLayerUpdater::update(RenderLayer& layer, UpdateType updateType)
void GraphicsLayerUpdater::updateRecursive(RenderLayer& layer, UpdateType updateType)
{ {
updateType = update(layer, updateType); if (layer.hasCompositedLayerMapping()) {
CompositedLayerMappingPtr mapping = layer.compositedLayerMapping();
#if !ASSERT_DISABLED
LayerListMutationDetector mutationChecker(layer.stackingNode());
#endif
RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), AllChildren); // Note carefully: here we assume that the compositing state of all descendants have been updated already,
while (RenderLayerStackingNode* curNode = iterator.next()) // so it is legitimate to compute and cache the composited bounds for this layer.
updateRecursive(*curNode->layer(), updateType); mapping->updateCompositedBounds(updateType);
}
GraphicsLayerUpdater::UpdateType GraphicsLayerUpdater::update(RenderLayer& layer, UpdateType updateType) if (RenderLayerReflectionInfo* reflection = layer.reflectionInfo()) {
{ if (reflection->reflectionLayer()->hasCompositedLayerMapping())
if (!layer.hasCompositedLayerMapping()) reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds(ForceUpdate);
return updateType; }
CompositedLayerMappingPtr mapping = layer.compositedLayerMapping(); mapping->updateGraphicsLayerConfiguration();
updateType = mapping->updateGraphicsLayerGeometry(updateType);
mapping->clearNeedsGeometryUpdate();
// Note carefully: here we assume that the compositing state of all descendants have been updated already, if (!layer.parent())
// so it is legitimate to compute and cache the composited bounds for this layer. layer.compositor()->updateRootLayerPosition();
mapping->updateCompositedBounds(updateType);
if (RenderLayerReflectionInfo* reflection = layer.reflectionInfo()) { if (mapping->hasUnpositionedOverflowControlsLayers())
if (reflection->reflectionLayer()->hasCompositedLayerMapping()) layer.scrollableArea()->positionOverflowControls();
reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds(ForceUpdate);
} }
mapping->updateGraphicsLayerConfiguration(); for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
updateType = mapping->updateGraphicsLayerGeometry(updateType); update(*child, updateType);
mapping->clearNeedsGeometryUpdate();
if (!layer.parent())
layer.compositor()->updateRootLayerPosition();
if (mapping->hasUnpositionedOverflowControlsLayers())
layer.scrollableArea()->positionOverflowControls();
return updateType;
} }
} // namespace WebCore } // namespace WebCore
...@@ -46,11 +46,8 @@ public: ...@@ -46,11 +46,8 @@ public:
ForceUpdate, ForceUpdate,
}; };
void updateRecursive(RenderLayer&, UpdateType); void update(RenderLayer&, UpdateType);
void rebuildTree(RenderLayer&, UpdateType, GraphicsLayerVector& childLayersOfEnclosingLayer); void rebuildTree(RenderLayer&, GraphicsLayerVector& childLayersOfEnclosingLayer);
private:
UpdateType update(RenderLayer&, UpdateType);
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -520,12 +520,17 @@ void RenderLayerCompositor::updateCompositingLayersInternal() ...@@ -520,12 +520,17 @@ void RenderLayerCompositor::updateCompositingLayersInternal()
needHierarchyAndGeometryUpdate = true; needHierarchyAndGeometryUpdate = true;
} }
if (needGeometryUpdate || needHierarchyAndGeometryUpdate) {
TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
GraphicsLayerUpdater().update(*updateRoot, updateType);
}
if (needHierarchyAndGeometryUpdate) { if (needHierarchyAndGeometryUpdate) {
// Update the hierarchy of the compositing layers. // Update the hierarchy of the compositing layers.
GraphicsLayerVector childList; GraphicsLayerVector childList;
{ {
TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::rebuildTree"); TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::rebuildTree");
GraphicsLayerUpdater().rebuildTree(*updateRoot, updateType, childList); GraphicsLayerUpdater().rebuildTree(*updateRoot, childList);
} }
// Host the document layer in the RenderView's root layer. // Host the document layer in the RenderView's root layer.
...@@ -541,11 +546,6 @@ void RenderLayerCompositor::updateCompositingLayersInternal() ...@@ -541,11 +546,6 @@ void RenderLayerCompositor::updateCompositingLayersInternal()
destroyRootLayer(); destroyRootLayer();
else else
m_rootContentLayer->setChildren(childList); m_rootContentLayer->setChildren(childList);
} 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().
TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
GraphicsLayerUpdater().updateRecursive(*updateRoot, updateType);
} }
ASSERT(updateRoot || !m_compositingLayersNeedRebuild); ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment