Commit 154b8d7e authored by abarth@chromium.org's avatar abarth@chromium.org

Move computation of RenderLayer::isUnclippedDescendant into CompositingPropertyUpdater

Prior to this CL, we computed RenderLayer::isUnclippedDescendant in a separate
O(n^2) walk of the out-of-flow RenderLayers. On workloads like famo.us, this
walk is quite expensive because everything is out-of-flow positioned, and
O(n^2) is large.

After this CL, we compute this information as we walk down the tree in the
CompositingPropertyUpdater, which means we can compute the information in
linear time and we can entirely remove the separate tree walk. Moving this
computation also lets us rip out a large amount of machinery that existed to
prune the extra tree walk that this CL removes.

Now that we compute this information with the CompositingPropertyUpdater,
we compute it even when composited overflow scrolling is off.  This confused
some tests that used Internals to poke this state.  I've added a workaround to
keep theses tests working identically.  I'll remove the work around and update
the tests in the next CL.

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

git-svn-id: svn://svn.chromium.org/blink/trunk@175225 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 4aaa715f
...@@ -109,9 +109,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type) ...@@ -109,9 +109,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
: m_layerType(type) : m_layerType(type)
, m_hasSelfPaintingLayerDescendant(false) , m_hasSelfPaintingLayerDescendant(false)
, m_hasSelfPaintingLayerDescendantDirty(false) , m_hasSelfPaintingLayerDescendantDirty(false)
, m_hasOutOfFlowPositionedDescendant(false)
, m_hasOutOfFlowPositionedDescendantDirty(true)
, m_isUnclippedDescendant(false)
, m_isRootLayer(renderer->isRenderView()) , m_isRootLayer(renderer->isRenderView())
, m_usedTransparency(false) , m_usedTransparency(false)
, m_visibleContentStatusDirty(true) , m_visibleContentStatusDirty(true)
...@@ -162,9 +159,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type) ...@@ -162,9 +159,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
RenderLayer::~RenderLayer() RenderLayer::~RenderLayer()
{ {
if (!m_renderer->documentBeingDestroyed())
compositor()->removeOutOfFlowPositionedLayer(this);
if (renderer()->frame() && renderer()->frame()->page()) { if (renderer()->frame() && renderer()->frame()->page()) {
if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator()) if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
scrollingCoordinator->willDestroyRenderLayer(this); scrollingCoordinator->willDestroyRenderLayer(this);
...@@ -352,31 +346,6 @@ void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() ...@@ -352,31 +346,6 @@ void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
} }
} }
void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant()
{
for (RenderLayer* layer = this; layer; layer = layer->parent()) {
if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFlowPositionedDescendant())
break;
layer->setHasOutOfFlowPositionedDescendantDirty(false);
layer->setHasOutOfFlowPositionedDescendant(true);
}
}
void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus()
{
for (RenderLayer* layer = this; layer; layer = layer->parent()) {
layer->setHasOutOfFlowPositionedDescendantDirty(true);
// If we have reached an out of flow positioned layer, we know our parent should have an out-of-flow positioned descendant.
// In this case, there is no need to dirty our ancestors further.
if (layer->renderer()->isOutOfFlowPositioned()) {
ASSERT(!parent() || parent()->m_hasOutOfFlowPositionedDescendantDirty || parent()->hasOutOfFlowPositionedDescendant());
break;
}
}
}
bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
{ {
const EPosition position = renderer()->style()->position(); const EPosition position = renderer()->style()->position();
...@@ -802,35 +771,6 @@ void RenderLayer::setAncestorChainHasVisibleDescendant() ...@@ -802,35 +771,6 @@ void RenderLayer::setAncestorChainHasVisibleDescendant()
} }
} }
void RenderLayer::updateIsUnclippedDescendant()
{
TRACE_EVENT0("blink_rendering", "RenderLayer::updateIsUnclippedDescendant");
ASSERT(renderer()->isOutOfFlowPositioned());
if (!m_hasVisibleContent && !m_hasVisibleDescendant)
return;
FrameView* frameView = renderer()->view()->frameView();
if (!frameView)
return;
setIsUnclippedDescendant(false);
const RenderObject* containingBlock = renderer()->containingBlock();
for (RenderLayer* ancestor = parent(); ancestor && ancestor->renderer() != containingBlock; ancestor = ancestor->parent()) {
// TODO(vollick): This isn't quite right. Whenever ancestor is composited and clips
// overflow, we're technically unclipped. However, this will currently cause a huge
// number of layers to report that they are unclipped. Eventually, when we've formally
// separated the clipping, transform, opacity, and stacking trees here and in the
// compositor, we will be able to relax this restriction without it being prohibitively
// expensive (currently, we have to do a lot of work in the compositor to honor a
// clip child/parent relationship).
if (ancestor->scrollsOverflow()) {
setIsUnclippedDescendant(true);
return;
}
}
}
// FIXME: this is quite brute-force. We could be more efficient if we were to // FIXME: this is quite brute-force. We could be more efficient if we were to
// track state and update it as appropriate as changes are made in the Render tree. // track state and update it as appropriate as changes are made in the Render tree.
void RenderLayer::updateScrollingStateAfterCompositingChange() void RenderLayer::updateScrollingStateAfterCompositingChange()
...@@ -853,36 +793,27 @@ void RenderLayer::updateScrollingStateAfterCompositingChange() ...@@ -853,36 +793,27 @@ void RenderLayer::updateScrollingStateAfterCompositingChange()
} }
} }
static bool subtreeContainsOutOfFlowPositionedLayer(const RenderLayer* subtreeRoot)
{
return (subtreeRoot->renderer() && subtreeRoot->renderer()->isOutOfFlowPositioned()) || subtreeRoot->hasOutOfFlowPositionedDescendant();
}
void RenderLayer::updateDescendantDependentFlags() void RenderLayer::updateDescendantDependentFlags()
{ {
if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty) {
m_hasVisibleDescendant = false; m_hasVisibleDescendant = false;
m_hasSelfPaintingLayerDescendant = false; m_hasSelfPaintingLayerDescendant = false;
m_hasOutOfFlowPositionedDescendant = false;
for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
child->updateDescendantDependentFlags(); child->updateDescendantDependentFlags();
bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant; bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant(); bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
bool hasOutOfFlowPositionedDescendant = subtreeContainsOutOfFlowPositionedLayer(child);
m_hasVisibleDescendant |= hasVisibleDescendant; m_hasVisibleDescendant |= hasVisibleDescendant;
m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && hasOutOfFlowPositionedDescendant) if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant)
break; break;
} }
m_visibleDescendantStatusDirty = false; m_visibleDescendantStatusDirty = false;
m_hasSelfPaintingLayerDescendantDirty = false; m_hasSelfPaintingLayerDescendantDirty = false;
m_hasOutOfFlowPositionedDescendantDirty = false;
} }
if (m_blendInfo.childLayerHasBlendModeStatusDirty()) { if (m_blendInfo.childLayerHasBlendModeStatusDirty()) {
...@@ -1470,15 +1401,6 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild) ...@@ -1470,15 +1401,6 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
if (child->blendInfo().hasBlendMode() || child->blendInfo().childLayerHasBlendMode()) if (child->blendInfo().hasBlendMode() || child->blendInfo().childLayerHasBlendMode())
m_blendInfo.setAncestorChainBlendedDescendant(); m_blendInfo.setAncestorChainBlendedDescendant();
if (subtreeContainsOutOfFlowPositionedLayer(child)) {
// Now that the out of flow positioned descendant is in the tree, we
// need to tell the compositor to reevaluate the compositing
// requirements since we may be able to mark more layers as having
// an 'unclipped' descendant.
compositor()->setNeedsUpdateCompositingRequirementsState();
setAncestorChainHasOutOfFlowPositionedDescendant();
}
compositor()->layerWasAdded(this, child); compositor()->layerWasAdded(this, child);
} }
...@@ -1516,13 +1438,6 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) ...@@ -1516,13 +1438,6 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
oldChild->m_parent = 0; oldChild->m_parent = 0;
oldChild->updateDescendantDependentFlags(); oldChild->updateDescendantDependentFlags();
if (subtreeContainsOutOfFlowPositionedLayer(oldChild)) {
// It may now be the case that a layer no longer has an unclipped
// descendant. Let the compositor know that it needs to reevaluate
// its compositing requirements to check this.
compositor()->setNeedsUpdateCompositingRequirementsState();
dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
}
if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
dirtyAncestorChainVisibleDescendantStatus(); dirtyAncestorChainVisibleDescendantStatus();
...@@ -3737,38 +3652,6 @@ bool RenderLayer::isVisuallyNonEmpty() const ...@@ -3737,38 +3652,6 @@ bool RenderLayer::isVisuallyNonEmpty() const
return false; return false;
} }
void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
{
ASSERT(!oldStyle || renderer()->style()->position() != oldStyle->position());
bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsolutePosition || oldStyle->position() == FixedPosition);
bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned();
if (!wasOutOfFlowPositioned && !isOutOfFlowPositioned)
return;
// Ensures that we reset the above bits correctly.
compositor()->setNeedsUpdateCompositingRequirementsState();
if (wasOutOfFlowPositioned && isOutOfFlowPositioned)
return;
if (isOutOfFlowPositioned) {
setAncestorChainHasOutOfFlowPositionedDescendant();
compositor()->addOutOfFlowPositionedLayer(this);
} else {
dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
compositor()->removeOutOfFlowPositionedLayer(this);
// We need to reset the isUnclippedDescendant bit here because normally
// the "unclipped-ness" property is only updated in
// RenderLayerCompositor::updateCompositingRequirementsState(). However,
// it is only updated for layers which are known to be out of flow.
// Since this is no longer out of flow, we have to explicitly ensure
// that it doesn't think it is unclipped.
setIsUnclippedDescendant(false);
}
}
static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle) static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
{ {
ASSERT(newStyle); ASSERT(newStyle);
...@@ -3847,20 +3730,10 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle ...@@ -3847,20 +3730,10 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle
if (m_scrollableArea) if (m_scrollableArea)
m_scrollableArea->updateAfterStyleChange(oldStyle); m_scrollableArea->updateAfterStyleChange(oldStyle);
if (!oldStyle || oldStyle->visibility() != renderer()->style()->visibility()) {
ASSERT(!oldStyle || diff.needsRepaint() || diff.needsLayout());
compositor()->setNeedsUpdateCompositingRequirementsState();
}
// Overlay scrollbars can make this layer self-painting so we need // Overlay scrollbars can make this layer self-painting so we need
// to recompute the bit once scrollbars have been updated. // to recompute the bit once scrollbars have been updated.
updateSelfPaintingLayer(); updateSelfPaintingLayer();
if (!oldStyle || renderer()->style()->position() != oldStyle->position()) {
ASSERT(!oldStyle || diff.needsFullLayout());
updateOutOfFlowPositioned(oldStyle);
}
if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) { if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
ASSERT(!oldStyle || diff.needsFullLayout()); ASSERT(!oldStyle || diff.needsFullLayout());
updateReflectionInfo(oldStyle); updateReflectionInfo(oldStyle);
......
...@@ -206,15 +206,6 @@ public: ...@@ -206,15 +206,6 @@ public:
// Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates. // Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates.
bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; } bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; }
// FIXME: We should ASSERT(!m_hasOutOfFlowPositionedDescendantDirty) here. See above.
bool hasOutOfFlowPositionedDescendant() const { return m_hasOutOfFlowPositionedDescendant; }
void setHasOutOfFlowPositionedDescendant(bool hasDescendant) { m_hasOutOfFlowPositionedDescendant = hasDescendant; }
void setHasOutOfFlowPositionedDescendantDirty(bool dirty) { m_hasOutOfFlowPositionedDescendantDirty = dirty; }
void updateIsUnclippedDescendant();
bool isUnclippedDescendant() const { return m_isUnclippedDescendant; }
// Will ensure that hasNonCompositiedChild are up to date. // Will ensure that hasNonCompositiedChild are up to date.
void updateScrollingStateAfterCompositingChange(); void updateScrollingStateAfterCompositingChange();
bool hasVisibleNonLayerContent() const { return m_hasVisibleNonLayerContent; } bool hasVisibleNonLayerContent() const { return m_hasVisibleNonLayerContent; }
...@@ -461,12 +452,14 @@ public: ...@@ -461,12 +452,14 @@ public:
: opacityAncestor(0) : opacityAncestor(0)
, transformAncestor(0) , transformAncestor(0)
, filterAncestor(0) , filterAncestor(0)
, isUnclippedDescendant(false)
{ } { }
IntRect clippedAbsoluteBoundingBox; IntRect clippedAbsoluteBoundingBox;
const RenderLayer* opacityAncestor; const RenderLayer* opacityAncestor;
const RenderLayer* transformAncestor; const RenderLayer* transformAncestor;
const RenderLayer* filterAncestor; const RenderLayer* filterAncestor;
unsigned isUnclippedDescendant : 1;
}; };
void setNeedsToUpdateAncestorDependentProperties(); void setNeedsToUpdateAncestorDependentProperties();
...@@ -478,6 +471,9 @@ public: ...@@ -478,6 +471,9 @@ public:
const AncestorDependentProperties& ancestorDependentProperties() const { ASSERT(!m_needsToUpdateAncestorDependentProperties); return m_ancestorDependentProperties; } const AncestorDependentProperties& ancestorDependentProperties() const { ASSERT(!m_needsToUpdateAncestorDependentProperties); return m_ancestorDependentProperties; }
// FIXME: Remove this function.
bool potentiallyStaleIsUnclippedDescendant() const { return m_ancestorDependentProperties.isUnclippedDescendant; }
bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; } bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; }
void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; } void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; }
...@@ -510,19 +506,12 @@ private: ...@@ -510,19 +506,12 @@ private:
bool hasOverflowControls() const; bool hasOverflowControls() const;
void setIsUnclippedDescendant(bool isUnclippedDescendant) { m_isUnclippedDescendant = isUnclippedDescendant; }
void setAncestorChainHasSelfPaintingLayerDescendant(); void setAncestorChainHasSelfPaintingLayerDescendant();
void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
void setAncestorChainHasOutOfFlowPositionedDescendant();
void dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, PaintLayerFlags, BorderRadiusClippingRule = IncludeSelfForBorderRadius); void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, PaintLayerFlags, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&); void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
void updateOutOfFlowPositioned(const RenderStyle* oldStyle);
// Returns true if the position changed. // Returns true if the position changed.
bool updateLayerPosition(); bool updateLayerPosition();
...@@ -637,11 +626,6 @@ private: ...@@ -637,11 +626,6 @@ private:
unsigned m_hasSelfPaintingLayerDescendant : 1; unsigned m_hasSelfPaintingLayerDescendant : 1;
unsigned m_hasSelfPaintingLayerDescendantDirty : 1; unsigned m_hasSelfPaintingLayerDescendantDirty : 1;
unsigned m_hasOutOfFlowPositionedDescendant : 1;
unsigned m_hasOutOfFlowPositionedDescendantDirty : 1;
unsigned m_isUnclippedDescendant : 1;
const unsigned m_isRootLayer : 1; const unsigned m_isRootLayer : 1;
unsigned m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether unsigned m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
......
...@@ -114,10 +114,8 @@ void RenderLayerStackingNode::dirtyZOrderLists() ...@@ -114,10 +114,8 @@ void RenderLayerStackingNode::dirtyZOrderLists()
m_descendantsAreContiguousInStackingOrderDirty = true; m_descendantsAreContiguousInStackingOrderDirty = true;
if (!renderer()->documentBeingDestroyed()) { if (!renderer()->documentBeingDestroyed())
compositor()->setNeedsUpdateCompositingRequirementsState();
compositor()->setCompositingLayersNeedRebuild(); compositor()->setCompositingLayersNeedRebuild();
}
} }
void RenderLayerStackingNode::dirtyStackingContextZOrderLists() void RenderLayerStackingNode::dirtyStackingContextZOrderLists()
...@@ -317,8 +315,6 @@ void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderSt ...@@ -317,8 +315,6 @@ void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderSt
dirtyZOrderLists(); dirtyZOrderLists();
else else
clearZOrderLists(); clearZOrderLists();
compositor()->setNeedsUpdateCompositingRequirementsState();
} }
bool RenderLayerStackingNode::shouldBeNormalFlowOnly() const bool RenderLayerStackingNode::shouldBeNormalFlowOnly() const
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "config.h" #include "config.h"
#include "core/rendering/compositing/CompositingPropertyUpdater.h" #include "core/rendering/compositing/CompositingPropertyUpdater.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderLayer.h" #include "core/rendering/RenderLayer.h"
#include "core/rendering/compositing/CompositedLayerMapping.h" #include "core/rendering/compositing/CompositedLayerMapping.h"
...@@ -21,7 +22,7 @@ CompositingPropertyUpdater::~CompositingPropertyUpdater() ...@@ -21,7 +22,7 @@ CompositingPropertyUpdater::~CompositingPropertyUpdater()
{ {
} }
void CompositingPropertyUpdater::updateAncestorDependentProperties(RenderLayer* layer, UpdateType updateType, RenderLayer* enclosingCompositedLayer) void CompositingPropertyUpdater::updateAncestorDependentProperties(RenderLayer* layer, UpdateType updateType, AncestorInfo info)
{ {
if (!layer->childNeedsToUpdateAncestorDependantProperties() && updateType != ForceUpdate) if (!layer->childNeedsToUpdateAncestorDependantProperties() && updateType != ForceUpdate)
return; return;
...@@ -29,11 +30,11 @@ void CompositingPropertyUpdater::updateAncestorDependentProperties(RenderLayer* ...@@ -29,11 +30,11 @@ void CompositingPropertyUpdater::updateAncestorDependentProperties(RenderLayer*
m_geometryMap.pushMappingsToAncestor(layer, layer->parent()); m_geometryMap.pushMappingsToAncestor(layer, layer->parent());
if (layer->hasCompositedLayerMapping()) if (layer->hasCompositedLayerMapping())
enclosingCompositedLayer = layer; info.enclosingCompositedLayer = layer;
if (layer->needsToUpdateAncestorDependentProperties()) { if (layer->needsToUpdateAncestorDependentProperties()) {
if (enclosingCompositedLayer) if (info.enclosingCompositedLayer)
enclosingCompositedLayer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(); info.enclosingCompositedLayer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate();
updateType = ForceUpdate; updateType = ForceUpdate;
} }
...@@ -55,13 +56,22 @@ void CompositingPropertyUpdater::updateAncestorDependentProperties(RenderLayer* ...@@ -55,13 +56,22 @@ void CompositingPropertyUpdater::updateAncestorDependentProperties(RenderLayer*
properties.opacityAncestor = parent->isTransparent() ? parent : parent->ancestorDependentProperties().opacityAncestor; properties.opacityAncestor = parent->isTransparent() ? parent : parent->ancestorDependentProperties().opacityAncestor;
properties.transformAncestor = parent->hasTransform() ? parent : parent->ancestorDependentProperties().transformAncestor; properties.transformAncestor = parent->hasTransform() ? parent : parent->ancestorDependentProperties().transformAncestor;
properties.filterAncestor = parent->hasFilter() ? parent : parent->ancestorDependentProperties().filterAncestor; properties.filterAncestor = parent->hasFilter() ? parent : parent->ancestorDependentProperties().filterAncestor;
if (layer->renderer()->isOutOfFlowPositioned() && info.ancestorScrollingLayer && !layer->subtreeIsInvisible()) {
const RenderObject* container = layer->renderer()->containingBlock();
const RenderObject* scroller = info.ancestorScrollingLayer->renderer();
properties.isUnclippedDescendant = scroller != container && scroller->isDescendantOf(container);
}
} }
layer->updateAncestorDependentProperties(properties); layer->updateAncestorDependentProperties(properties);
} }
if (layer->scrollsOverflow())
info.ancestorScrollingLayer = layer;
for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling()) for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
updateAncestorDependentProperties(child, updateType, enclosingCompositedLayer); updateAncestorDependentProperties(child, updateType, info);
m_geometryMap.popMappingsToAncestor(layer->parent()); m_geometryMap.popMappingsToAncestor(layer->parent());
......
...@@ -12,6 +12,18 @@ namespace WebCore { ...@@ -12,6 +12,18 @@ namespace WebCore {
class RenderLayer; class RenderLayer;
class CompositingPropertyUpdater { class CompositingPropertyUpdater {
private:
struct AncestorInfo {
AncestorInfo()
: enclosingCompositedLayer(0)
, ancestorScrollingLayer(0)
{
}
RenderLayer* enclosingCompositedLayer;
RenderLayer* ancestorScrollingLayer;
};
public: public:
explicit CompositingPropertyUpdater(RenderLayer* rootRenderLayer); explicit CompositingPropertyUpdater(RenderLayer* rootRenderLayer);
~CompositingPropertyUpdater(); ~CompositingPropertyUpdater();
...@@ -21,7 +33,7 @@ public: ...@@ -21,7 +33,7 @@ public:
ForceUpdate, ForceUpdate,
}; };
void updateAncestorDependentProperties(RenderLayer*, UpdateType, RenderLayer* enclosingCompositedLayer); void updateAncestorDependentProperties(RenderLayer*, UpdateType, AncestorInfo = AncestorInfo());
#if !ASSERT_DISABLED #if !ASSERT_DISABLED
static void assertNeedsToUpdateAncestorDependantPropertiesBitsCleared(RenderLayer*); static void assertNeedsToUpdateAncestorDependantPropertiesBitsCleared(RenderLayer*);
......
...@@ -142,7 +142,10 @@ CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(cons ...@@ -142,7 +142,10 @@ CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(cons
RenderObject* renderer = layer->renderer(); RenderObject* renderer = layer->renderer();
if (hasOverflowScrollTrigger()) { if (hasOverflowScrollTrigger()) {
if (layer->isUnclippedDescendant()) // IsUnclippedDescendant is only actually stale during the chicken/egg code path.
// FIXME: Use ancestorDependentProperties().isUnclippedDescendant to ASSERT that
// this value isn't stale.
if (layer->potentiallyStaleIsUnclippedDescendant())
directReasons |= CompositingReasonOutOfFlowClipping; directReasons |= CompositingReasonOutOfFlowClipping;
if (layer->scrollParent()) if (layer->scrollParent())
......
...@@ -116,7 +116,6 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) ...@@ -116,7 +116,6 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
, m_compositing(false) , m_compositing(false)
, m_compositingLayersNeedRebuild(false) , m_compositingLayersNeedRebuild(false)
, m_rootShouldAlwaysCompositeDirty(true) , m_rootShouldAlwaysCompositeDirty(true)
, m_needsUpdateCompositingRequirementsState(false)
, m_needsUpdateFixedBackground(false) , m_needsUpdateFixedBackground(false)
, m_isTrackingRepaints(false) , m_isTrackingRepaints(false)
, m_rootLayerAttachment(RootLayerUnattached) , m_rootLayerAttachment(RootLayerUnattached)
...@@ -228,21 +227,6 @@ void RenderLayerCompositor::setCompositingLayersNeedRebuild() ...@@ -228,21 +227,6 @@ void RenderLayerCompositor::setCompositingLayersNeedRebuild()
lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean); lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
} }
void RenderLayerCompositor::updateCompositingRequirementsState()
{
if (!m_needsUpdateCompositingRequirementsState)
return;
TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerCompositor::updateCompositingRequirementsState");
m_needsUpdateCompositingRequirementsState = false;
if (!rootRenderLayer() || !acceleratedCompositingForOverflowScrollEnabled())
return;
for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it)
(*it)->updateIsUnclippedDescendant();
}
static RenderVideo* findFullscreenVideoRenderer(Document& document) static RenderVideo* findFullscreenVideoRenderer(Document& document)
{ {
Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document); Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document);
...@@ -311,7 +295,6 @@ void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda ...@@ -311,7 +295,6 @@ void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda
void RenderLayerCompositor::assertNoUnresolvedDirtyBits() void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
{ {
ASSERT(!compositingLayersNeedRebuild()); ASSERT(!compositingLayersNeedRebuild());
ASSERT(!m_needsUpdateCompositingRequirementsState);
ASSERT(m_pendingUpdateType == CompositingUpdateNone); ASSERT(m_pendingUpdateType == CompositingUpdateNone);
ASSERT(!m_rootShouldAlwaysCompositeDirty); ASSERT(!m_rootShouldAlwaysCompositeDirty);
ASSERT(!m_needsToRecomputeCompositingRequirements); ASSERT(!m_needsToRecomputeCompositingRequirements);
...@@ -356,7 +339,6 @@ void RenderLayerCompositor::updateIfNeeded() ...@@ -356,7 +339,6 @@ void RenderLayerCompositor::updateIfNeeded()
// We'll need to remove DeprecatedDirtyCompositingDuringCompositingUpdate // We'll need to remove DeprecatedDirtyCompositingDuringCompositingUpdate
// before moving this function after checking the dirty bits. // before moving this function after checking the dirty bits.
DeprecatedDirtyCompositingDuringCompositingUpdate marker(lifecycle()); DeprecatedDirtyCompositingDuringCompositingUpdate marker(lifecycle());
updateCompositingRequirementsState();
// FIXME: enableCompositingModeIfNeeded can call setCompositingLayersNeedRebuild, // FIXME: enableCompositingModeIfNeeded can call setCompositingLayersNeedRebuild,
// which asserts that it's not InCompositingUpdate. // which asserts that it's not InCompositingUpdate.
...@@ -394,7 +376,7 @@ void RenderLayerCompositor::updateIfNeeded() ...@@ -394,7 +376,7 @@ void RenderLayerCompositor::updateIfNeeded()
{ {
TRACE_EVENT0("blink_rendering", "CompositingPropertyUpdater::updateAncestorDependentProperties"); TRACE_EVENT0("blink_rendering", "CompositingPropertyUpdater::updateAncestorDependentProperties");
CompositingPropertyUpdater(updateRoot).updateAncestorDependentProperties(updateRoot, compositingPropertyUpdateType, 0); CompositingPropertyUpdater(updateRoot).updateAncestorDependentProperties(updateRoot, compositingPropertyUpdateType);
#if ASSERT_ENABLED #if ASSERT_ENABLED
CompositingPropertyUpdater::assertNeedsToUpdateAncestorDependantPropertiesBitsCleared(updateRoot); CompositingPropertyUpdater::assertNeedsToUpdateAncestorDependantPropertiesBitsCleared(updateRoot);
#endif #endif
...@@ -468,16 +450,6 @@ void RenderLayerCompositor::updateIfNeeded() ...@@ -468,16 +450,6 @@ void RenderLayerCompositor::updateIfNeeded()
InspectorInstrumentation::layerTreeDidChange(m_renderView.frame()); InspectorInstrumentation::layerTreeDidChange(m_renderView.frame());
} }
void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer)
{
m_outOfFlowPositionedLayers.add(layer);
}
void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer)
{
m_outOfFlowPositionedLayers.remove(layer);
}
bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate) bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
{ {
bool compositedLayerMappingChanged = false; bool compositedLayerMappingChanged = false;
......
...@@ -101,10 +101,6 @@ public: ...@@ -101,10 +101,6 @@ public:
// created, destroyed or re-parented). // created, destroyed or re-parented).
void setCompositingLayersNeedRebuild(); void setCompositingLayersNeedRebuild();
// Updating properties required for determining if compositing is necessary.
void updateCompositingRequirementsState();
void setNeedsUpdateCompositingRequirementsState() { m_needsUpdateCompositingRequirementsState = true; }
// Used to indicate that a compositing update will be needed for the next frame that gets drawn. // Used to indicate that a compositing update will be needed for the next frame that gets drawn.
void setNeedsCompositingUpdate(CompositingUpdateType); void setNeedsCompositingUpdate(CompositingUpdateType);
...@@ -180,9 +176,6 @@ public: ...@@ -180,9 +176,6 @@ public:
GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); } GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); } GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
void addOutOfFlowPositionedLayer(RenderLayer*);
void removeOutOfFlowPositionedLayer(RenderLayer*);
void resetTrackedRepaintRects(); void resetTrackedRepaintRects();
void setTracksRepaints(bool); void setTracksRepaints(bool);
...@@ -280,7 +273,6 @@ private: ...@@ -280,7 +273,6 @@ private:
// except the one in updateIfNeeded, then rename this to // except the one in updateIfNeeded, then rename this to
// m_compositingDirty. // m_compositingDirty.
bool m_rootShouldAlwaysCompositeDirty; bool m_rootShouldAlwaysCompositeDirty;
bool m_needsUpdateCompositingRequirementsState;
bool m_needsUpdateFixedBackground; bool m_needsUpdateFixedBackground;
bool m_isTrackingRepaints; // Used for testing. bool m_isTrackingRepaints; // Used for testing.
...@@ -290,10 +282,6 @@ private: ...@@ -290,10 +282,6 @@ private:
OwnPtr<GraphicsLayer> m_containerLayer; OwnPtr<GraphicsLayer> m_containerLayer;
OwnPtr<GraphicsLayer> m_scrollLayer; OwnPtr<GraphicsLayer> m_scrollLayer;
// This is used in updateCompositingRequirementsState to avoid full tree
// walks while determining if layers have unclipped descendants.
HashSet<RenderLayer*> m_outOfFlowPositionedLayers;
// Enclosing layer for overflow controls and the clipping layer // Enclosing layer for overflow controls and the clipping layer
OwnPtr<GraphicsLayer> m_overflowControlsHostLayer; OwnPtr<GraphicsLayer> m_overflowControlsHostLayer;
......
...@@ -1690,7 +1690,13 @@ bool Internals::isUnclippedDescendant(Element* element, ExceptionState& exceptio ...@@ -1690,7 +1690,13 @@ bool Internals::isUnclippedDescendant(Element* element, ExceptionState& exceptio
return 0; return 0;
} }
return layer->isUnclippedDescendant(); // We used to compute isUnclippedDescendant only when acceleratedCompositingForOverflowScrollEnabled,
// but now we compute it all the time.
// FIXME: Remove this if statement and rebaseline the tests that make this assumption.
if (!layer->compositor()->acceleratedCompositingForOverflowScrollEnabled())
return false;
return layer->ancestorDependentProperties().isUnclippedDescendant;
} }
String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionState& exceptionState) const String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionState& exceptionState) const
......
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