| Index: Source/core/rendering/RenderLayer.cpp
|
| diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp
|
| index ef40889fb15879f48508ec0638e98382c9c74ccb..c564aa75a1f60d85ddc62382416319ea3a383fb9 100644
|
| --- a/Source/core/rendering/RenderLayer.cpp
|
| +++ b/Source/core/rendering/RenderLayer.cpp
|
| @@ -1133,23 +1133,49 @@ 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->setAncestorCompositedScrollingLayer(ancestorCompositedScrollingLayer);
|
| +
|
| + return ancestorCompositedScrollingLayer;
|
| }
|
|
|
| RenderLayer* RenderLayer::ancestorScrollingLayer() const
|
| @@ -1677,6 +1703,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 +1719,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,8 +1731,18 @@ 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->ancestorCompositedScrollingLayerDirty() && ancestorCache->ancestorCompositedScrollingLayer() == scrollParent) {
|
| + scrollParent = ancestorCache->scrollParent();
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
| + if (m_ancestorDependentPropertyCache)
|
| + m_ancestorDependentPropertyCache->setScrollParent(scrollParent);
|
| return scrollParent;
|
| }
|
|
|
| @@ -3520,6 +3562,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 +4106,36 @@ DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
|
|
|
| COMPILE_ASSERT(1 << RenderLayer::ViewportConstrainedNotCompositedReasonBits >= RenderLayer::NumNotCompositedReasons, too_many_viewport_constrained_not_compositing_reasons);
|
|
|
| +RenderLayer::AncestorDependentPropertyCache::AncestorDependentPropertyCache()
|
| + : m_ancestorCompositedScrollingLayer(0)
|
| + , m_scrollParent(0)
|
| + , m_ancestorCompositedScrollingLayerDirty(true)
|
| + , m_scrollParentDirty(true) { }
|
| +
|
| +RenderLayer* RenderLayer::AncestorDependentPropertyCache::scrollParent() const
|
| +{
|
| + ASSERT(!m_scrollParentDirty);
|
| + return m_scrollParent;
|
| +}
|
| +
|
| +void RenderLayer::AncestorDependentPropertyCache::setScrollParent(RenderLayer* scrollParent)
|
| +{
|
| + m_scrollParent = scrollParent;
|
| + m_scrollParentDirty = false;
|
| +}
|
| +
|
| +RenderLayer* RenderLayer::AncestorDependentPropertyCache::ancestorCompositedScrollingLayer() const
|
| +{
|
| + ASSERT(!m_ancestorCompositedScrollingLayerDirty);
|
| + return m_ancestorCompositedScrollingLayer;
|
| +}
|
| +
|
| +void RenderLayer::AncestorDependentPropertyCache::setAncestorCompositedScrollingLayer(RenderLayer* layer)
|
| +{
|
| + m_ancestorCompositedScrollingLayer = layer;
|
| + m_ancestorCompositedScrollingLayerDirty = false;
|
| +}
|
| +
|
| } // namespace WebCore
|
|
|
| #ifndef NDEBUG
|
|
|