Index: Source/core/rendering/compositing/RenderLayerCompositor.cpp |
diff --git a/Source/core/rendering/compositing/RenderLayerCompositor.cpp b/Source/core/rendering/compositing/RenderLayerCompositor.cpp |
index 32563e506ffc7042cd66ec0c7de38d3caf1fb4bb..810b4ae465e8cd57c6f905bf1d5ec142fe5d5a29 100644 |
--- a/Source/core/rendering/compositing/RenderLayerCompositor.cpp |
+++ b/Source/core/rendering/compositing/RenderLayerCompositor.cpp |
@@ -163,9 +163,10 @@ private: |
}; |
struct CompositingRecursionData { |
- CompositingRecursionData(RenderLayer* compAncestor, RenderLayer* mostRecentCompositedLayer, bool testOverlap) |
+ CompositingRecursionData(RenderLayer* compAncestor, RenderLayer* mostRecentCompositedLayer, RenderLayerCompositor::BoundsUpdateType boundsUpdateType, bool testOverlap) |
: m_compositingAncestor(compAncestor) |
, m_mostRecentCompositedLayer(mostRecentCompositedLayer) |
+ , m_recomputeLayerBoundsUpdateType(boundsUpdateType) |
, m_subtreeIsCompositing(false) |
, m_hasUnisolatedCompositedBlendingDescendant(false) |
, m_testingOverlap(testOverlap) |
@@ -178,6 +179,7 @@ struct CompositingRecursionData { |
CompositingRecursionData(const CompositingRecursionData& other) |
: m_compositingAncestor(other.m_compositingAncestor) |
, m_mostRecentCompositedLayer(other.m_mostRecentCompositedLayer) |
+ , m_recomputeLayerBoundsUpdateType(other.m_recomputeLayerBoundsUpdateType) |
, m_subtreeIsCompositing(other.m_subtreeIsCompositing) |
, m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompositedBlendingDescendant) |
, m_testingOverlap(other.m_testingOverlap) |
@@ -189,6 +191,7 @@ struct CompositingRecursionData { |
RenderLayer* m_compositingAncestor; |
RenderLayer* m_mostRecentCompositedLayer; // in paint order regardless of hierarchy. |
+ RenderLayerCompositor::BoundsUpdateType m_recomputeLayerBoundsUpdateType; |
bool m_subtreeIsCompositing; |
bool m_hasUnisolatedCompositedBlendingDescendant; |
bool m_testingOverlap; |
@@ -205,6 +208,7 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) |
, m_needsToRecomputeCompositingRequirements(false) |
, m_needsToUpdateLayerTreeGeometry(false) |
, m_pendingUpdateType(GraphicsLayerUpdater::DoNotForceUpdate) |
+ , m_recomputeLayerBoundsUpdateType(RenderLayerCompositor::DoNotForceUpdate) |
, m_compositing(false) |
, m_compositingLayersNeedRebuild(false) |
, m_forceCompositingMode(false) |
@@ -368,17 +372,23 @@ void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda |
m_needsToRecomputeCompositingRequirements = true; |
// FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here. |
m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate; |
+ // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here. |
+ m_recomputeLayerBoundsUpdateType = RenderLayerCompositor::ForceUpdate; |
esprehn
2014/03/21 23:28:01
This is the RLC, you don't need the RenderLayerCom
ojan
2014/03/22 00:25:43
Done.
|
break; |
case CompositingUpdateOnScroll: |
m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates. |
m_needsToUpdateLayerTreeGeometry = true; |
// FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here. |
m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate; |
+ // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here. |
+ m_recomputeLayerBoundsUpdateType = RenderLayerCompositor::ForceUpdate; |
break; |
case CompositingUpdateOnCompositedScroll: |
m_needsToUpdateLayerTreeGeometry = true; |
// FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here. |
m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate; |
+ // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here. |
+ m_recomputeLayerBoundsUpdateType = RenderLayerCompositor::ForceUpdate; |
break; |
case CompositingUpdateAfterCanvasContextChange: |
m_needsToUpdateLayerTreeGeometry = true; |
@@ -411,6 +421,13 @@ void RenderLayerCompositor::updateCompositingLayers() |
ASSERT(m_renderView.document().lifecycle().state() == DocumentLifecycle::CompositingClean); |
} |
+static void assertNeedsRecomputeBoundsBitsCleared(RenderLayer* updateRoot) |
+{ |
+ ASSERT(!updateRoot->needsToRecomputeBounds()); |
+ for (RenderLayer* child = updateRoot->firstChild(); child; child = child->nextSibling()) |
+ assertNeedsRecomputeBoundsBitsCleared(child); |
+} |
+ |
void RenderLayerCompositor::updateCompositingLayersInternal() |
{ |
if (isMainFrame() && m_renderView.frameView()) |
@@ -443,7 +460,8 @@ void RenderLayerCompositor::updateCompositingLayersInternal() |
if (needCompositingRequirementsUpdate) { |
// Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. |
// FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. |
- CompositingRecursionData recursionData(updateRoot, 0, true); |
+ CompositingRecursionData recursionData(updateRoot, 0, m_recomputeLayerBoundsUpdateType, true); |
+ m_recomputeLayerBoundsUpdateType = RenderLayerCompositor::DoNotForceUpdate; |
bool layersChanged = false; |
bool saw3DTransform = false; |
{ |
@@ -457,6 +475,9 @@ void RenderLayerCompositor::updateCompositingLayersInternal() |
Vector<RenderLayer*> unclippedDescendants; |
IntRect absoluteDecendantBoundingBox; |
computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants, absoluteDecendantBoundingBox); |
+#if !ASSERT_DISABLED |
+ assertNeedsRecomputeBoundsBitsCleared(updateRoot); |
+#endif |
} |
{ |
@@ -862,7 +883,7 @@ void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* |
setCompositingLayersNeedRebuild(); |
} |
-void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds) |
+void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, const IntRect& layerBounds) |
{ |
if (layer->isRootLayer()) |
return; |
@@ -940,13 +961,23 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor |
IntRect absBounds; |
if (overlapMap && !layer->isRootLayer()) { |
- absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds())); |
+ if (currentRecursionData.m_recomputeLayerBoundsUpdateType == RenderLayerCompositor::ForceUpdate || layer->needsToRecomputeBounds()) { |
+ // FIXME: If the absolute bounds didn't change, then we don't need to ForceUpdate descendant RenderLayers. |
+ currentRecursionData.m_recomputeLayerBoundsUpdateType = RenderLayerCompositor::ForceUpdate; |
+ absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds())); |
+ layer->setAbsoluteBoundingBoxForOverlap(absBounds); |
+ } else { |
+ absBounds = layer->cachedAbsoluteBoundingBox(); |
+ } |
// Setting the absBounds to 1x1 instead of 0x0 makes very little sense, |
// but removing this code will make JSGameBench sad. |
// See https://codereview.chromium.org/13912020/ |
if (absBounds.isEmpty()) |
absBounds.setSize(IntSize(1, 1)); |
+ } else { |
+ layer->clearNeedsToRecomputeBounds(); |
esprehn
2014/03/21 23:28:01
Can we just unconditionally call this?
ojan
2014/03/22 00:25:43
I changed assertNeedsRecomputeBoundsBitsCleared to
|
} |
+ |
absoluteDecendantBoundingBox = absBounds; |
if (overlapMap && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons)) |
@@ -1009,9 +1040,10 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor |
// negative z-index child's bounds to the new overlap context. |
if (overlapMap) { |
overlapMap->geometryMap().pushMappingsToAncestor(curNode->layer(), layer); |
- IntRect childAbsBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(curNode->layer()->overlapBounds())); |
+ // The above call to computeCompositinRequirements will have already updated this layer's absolute bounding box. |
overlapMap->beginNewOverlapTestingContext(); |
- addToOverlapMap(*overlapMap, curNode->layer(), childAbsBounds); |
+ ASSERT(!curNode->layer()->needsToRecomputeBounds()); |
+ addToOverlapMap(*overlapMap, curNode->layer(), curNode->layer()->cachedAbsoluteBoundingBox()); |
overlapMap->finishCurrentOverlapTestingContext(); |
overlapMap->geometryMap().popMappingsToAncestor(layer); |
} |
@@ -1086,8 +1118,10 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor |
// If the original layer is composited, the reflection needs to be, too. |
if (layer->reflectionInfo()) { |
// FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer? |
+ RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer(); |
+ reflectionLayer->clearNeedsToRecomputeBounds(); |
CompositingReasons reflectionCompositingReason = willBeCompositedOrSquashed ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone; |
- layer->reflectionInfo()->reflectionLayer()->setCompositingReasons(layer->reflectionInfo()->reflectionLayer()->compositingReasons() | reflectionCompositingReason); |
+ reflectionLayer->setCompositingReasons(reflectionLayer->compositingReasons() | reflectionCompositingReason); |
} |
// Subsequent layers in the parent's stacking context may also need to composite. |