Chromium Code Reviews| Index: Source/core/rendering/RenderLayer.cpp |
| diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp |
| index ef40889fb15879f48508ec0638e98382c9c74ccb..8d0bc0e7158601afc9a6cda6207b209d7d9972b3 100644 |
| --- a/Source/core/rendering/RenderLayer.cpp |
| +++ b/Source/core/rendering/RenderLayer.cpp |
| @@ -1133,23 +1133,51 @@ RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot i |
| return 0; |
| } |
| -RenderLayer* RenderLayer::ancestorCompositedScrollingLayer() const |
| +void RenderLayer::clearAncestorDependentPropertyCache() |
| { |
| - ASSERT(isAllowedToQueryCompositingState()); |
| + ASSERT(isInCompositingUpdate()); |
| + m_ancestorDependentPropertyCache.clear(); |
| +} |
| + |
| +void RenderLayer::ensureAncestorDependentPropertyCache() const |
| +{ |
| + ASSERT(isInCompositingUpdate()); |
| + if (m_ancestorDependentPropertyCache) |
| + return; |
| + m_ancestorDependentPropertyCache = adoptPtr(new AncestorDependentPropertyCache()); |
| +} |
| +RenderLayer* RenderLayer::ancestorCompositedScrollingLayer() const |
| +{ |
| if (!renderer()->acceleratedCompositingForOverflowScrollEnabled()) |
| return 0; |
| + ASSERT(isInCompositingUpdate() || !m_ancestorDependentPropertyCache); |
| + |
| + if (m_ancestorDependentPropertyCache && !m_ancestorDependentPropertyCache->ancestorCompositedScrollingLayerDirty) |
| + return m_ancestorDependentPropertyCache->ancestorCompositedScrollingLayer; |
| + |
| RenderObject* containingBlock = renderer()->containingBlock(); |
| if (!containingBlock) |
| return 0; |
| + if (isInCompositingUpdate()) |
| + ensureAncestorDependentPropertyCache(); |
| + |
| + RenderLayer* ancestorCompositedScrollingLayer = 0; |
| for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) { |
| - if (ancestorLayer->needsCompositedScrolling()) |
| - return ancestorLayer; |
| + if (ancestorLayer->needsCompositedScrolling()) { |
| + ancestorCompositedScrollingLayer = ancestorLayer; |
| + break; |
| + } |
| } |
| - return 0; |
| + if (m_ancestorDependentPropertyCache) { |
| + m_ancestorDependentPropertyCache->ancestorCompositedScrollingLayer = ancestorCompositedScrollingLayer; |
| + m_ancestorDependentPropertyCache->ancestorCompositedScrollingLayerDirty = false; |
|
abarth-chromium
2014/03/20 22:49:15
I probably would have made this a setter that enca
Ian Vollick
2014/03/21 00:01:11
Done.
|
| + } |
| + |
| + return ancestorCompositedScrollingLayer; |
| } |
| RenderLayer* RenderLayer::ancestorScrollingLayer() const |
| @@ -1677,6 +1705,10 @@ RenderLayer* RenderLayer::scrollParent() const |
| if (stackingNode()->isNormalFlowOnly()) |
| return 0; |
| + // We should never have an ancestor dependent property cache outside of the |
| + // compositing update phase. |
| + ASSERT(isInCompositingUpdate() || !m_ancestorDependentPropertyCache); |
| + |
| // 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 |
| @@ -1689,8 +1721,10 @@ RenderLayer* RenderLayer::scrollParent() const |
| // 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 = ancestorCompositedScrollingLayer(); |
| + if (m_ancestorDependentPropertyCache && !m_ancestorDependentPropertyCache->scrollParentDirty) |
| + return m_ancestorDependentPropertyCache->scrollParent; |
| + RenderLayer* scrollParent = ancestorCompositedScrollingLayer(); |
| if (!scrollParent || scrollParent->stackingNode()->isStackingContainer()) |
| return 0; |
| @@ -1699,6 +1733,19 @@ RenderLayer* RenderLayer::scrollParent() const |
| for (RenderLayer* ancestor = parent(); ancestor && ancestor != scrollParent; ancestor = ancestor->parent()) { |
| if (ancestor->stackingNode()->isStackingContainer()) |
| return 0; |
| + if (!isInCompositingUpdate()) |
| + continue; |
| + if (AncestorDependentPropertyCache* ancestorCache = ancestor->m_ancestorDependentPropertyCache.get()) { |
| + if (ancestorCache->ancestorCompositedScrollingLayer == scrollParent) { |
|
abarth-chromium
2014/03/20 22:49:15
Don't we need to check the dirty bit here?
Ian Vollick
2014/03/21 00:01:11
Fixed. While I was adding the setters in response
|
| + scrollParent = ancestorCache->scrollParent; |
| + break; |
| + } |
| + } |
| + } |
| + |
| + if (m_ancestorDependentPropertyCache) { |
| + m_ancestorDependentPropertyCache->scrollParent = scrollParent; |
| + m_ancestorDependentPropertyCache->scrollParentDirty = false; |
|
abarth-chromium
2014/03/20 22:49:15
ditto
Ian Vollick
2014/03/21 00:01:11
Done.
|
| } |
| return scrollParent; |
| @@ -3520,6 +3567,11 @@ bool RenderLayer::isAllowedToQueryCompositingState() const |
| return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate; |
| } |
| +bool RenderLayer::isInCompositingUpdate() const |
| +{ |
| + return renderer()->document().lifecycle().state() == DocumentLifecycle::InCompositingUpdate; |
| +} |
| + |
| CompositedLayerMappingPtr RenderLayer::compositedLayerMapping() const |
| { |
| ASSERT(isAllowedToQueryCompositingState()); |
| @@ -4059,6 +4111,12 @@ DisableCompositingQueryAsserts::DisableCompositingQueryAsserts() |
| COMPILE_ASSERT(1 << RenderLayer::ViewportConstrainedNotCompositedReasonBits >= RenderLayer::NumNotCompositedReasons, too_many_viewport_constrained_not_compositing_reasons); |
| +RenderLayer::AncestorDependentPropertyCache::AncestorDependentPropertyCache() |
| + : ancestorCompositedScrollingLayer(0) |
| + , scrollParent(0) |
| + , ancestorCompositedScrollingLayerDirty(true) |
| + , scrollParentDirty(true) { } |
| + |
| } // namespace WebCore |
| #ifndef NDEBUG |