| Index: Source/core/rendering/compositing/RenderLayerCompositor.cpp
|
| diff --git a/Source/core/rendering/compositing/RenderLayerCompositor.cpp b/Source/core/rendering/compositing/RenderLayerCompositor.cpp
|
| index 66bd5b488179b5cf34a04121d8662ab5b137a1ba..7403f2c30a603277816b2ad08f3a19a10a013b13 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(DoNotForceUpdate)
|
| , m_compositing(false)
|
| , m_compositingLayersNeedRebuild(false)
|
| , m_forceCompositingMode(false)
|
| @@ -369,17 +373,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 = ForceUpdate;
|
| 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 = 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 = ForceUpdate;
|
| break;
|
| case CompositingUpdateAfterCanvasContextChange:
|
| m_needsToUpdateLayerTreeGeometry = true;
|
| @@ -442,6 +452,14 @@ bool RenderLayerCompositor::hasUnresolvedDirtyBits()
|
| return m_needsToRecomputeCompositingRequirements || m_compositingLayersNeedRebuild || m_needsToUpdateLayerTreeGeometry || m_needsUpdateCompositingRequirementsState || m_pendingUpdateType != GraphicsLayerUpdater::DoNotForceUpdate;
|
| }
|
|
|
| +static void assertNeedsRecomputeBoundsBitsCleared(RenderLayer* updateRoot)
|
| +{
|
| + // We don't do overlap testing on the root layer, so we never compute its absolute bounding box.
|
| + ASSERT(updateRoot->isRootLayer() || !updateRoot->needsToRecomputeBounds());
|
| + for (RenderLayer* child = updateRoot->firstChild(); child; child = child->nextSibling())
|
| + assertNeedsRecomputeBoundsBitsCleared(child);
|
| +}
|
| +
|
| void RenderLayerCompositor::updateCompositingLayersInternal()
|
| {
|
| if (isMainFrame() && m_renderView.frameView())
|
| @@ -474,7 +492,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 = DoNotForceUpdate;
|
| bool layersChanged = false;
|
| bool saw3DTransform = false;
|
| {
|
| @@ -488,6 +507,9 @@ void RenderLayerCompositor::updateCompositingLayersInternal()
|
| Vector<RenderLayer*> unclippedDescendants;
|
| IntRect absoluteDecendantBoundingBox;
|
| computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants, absoluteDecendantBoundingBox);
|
| +#if !ASSERT_DISABLED
|
| + assertNeedsRecomputeBoundsBitsCleared(updateRoot);
|
| +#endif
|
| }
|
|
|
| {
|
| @@ -893,7 +915,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;
|
| @@ -971,13 +993,21 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
|
|
|
| IntRect absBounds;
|
| if (overlapMap && !layer->isRootLayer()) {
|
| - absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
|
| + if (currentRecursionData.m_recomputeLayerBoundsUpdateType == ForceUpdate || layer->needsToRecomputeBounds()) {
|
| + // FIXME: If the absolute bounds didn't change, then we don't need to ForceUpdate descendant RenderLayers.
|
| + currentRecursionData.m_recomputeLayerBoundsUpdateType = ForceUpdate;
|
| + absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
|
| + layer->setAbsoluteBoundingBox(absBounds);
|
| + } else {
|
| + absBounds = layer->absoluteBoundingBox();
|
| + }
|
| // 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));
|
| }
|
| +
|
| absoluteDecendantBoundingBox = absBounds;
|
|
|
| if (overlapMap && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons))
|
| @@ -1040,9 +1070,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()->absoluteBoundingBox());
|
| overlapMap->finishCurrentOverlapTestingContext();
|
| overlapMap->geometryMap().popMappingsToAncestor(layer);
|
| }
|
| @@ -1117,8 +1148,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.
|
|
|