Commit 5941ea1b authored by abarth@chromium.org's avatar abarth@chromium.org

Reduce compositing update in Silk's toggle_drawer by 20%

This reduces the amount of time spent in compositing update for Silk's
toggle_drawer test case by 20%. Previously, we would update the geometry for
every composited layer mapping during every compositing update, regardless of
whether any of the inputs to updateGraphicsLayerGeometry had changed. This CL
introduces dirty bits on CompositedLayerMapping to track which RenderLayers
underwent a change that could have resulted in changes during
updateGraphicsLayerGeometry.

This CL takes a basic approach, which is sufficient for toggle_drawer.
Specifically, if a RenderLayer changes style, we mark its
CompositedLayerMapping (and any ancestors and decendants) as needing a geometry
update. If we go through layout or scroll, we trigger a forced update, which
updates the geometry of all graphics layers.

Over time, we can improve this system to track dirtiness during layout. We
might also be able to avoid marking every ancestor dirty if we removed the
downward tree walks during updateGraphicsLayerGeometry. Instead, we could
compute the descendant-dependant information in an earlier phase and detect
whether it changed directly.

R=esprehn@chromium.org, ojan@chromium.org

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

git-svn-id: svn://svn.chromium.org/blink/trunk@168554 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e47c0a10
......@@ -710,8 +710,17 @@ void RenderLayer::setHasVisibleContent()
return;
}
m_visibleContentStatusDirty = false;
m_hasVisibleContent = true;
m_visibleContentStatusDirty = false;
{
// FIXME: We can remove this code once we remove the recursive tree
// walk inside updateGraphicsLayerGeometry.
DisableCompositingQueryAsserts disabler;
if (RenderLayer* compositingLayer = enclosingCompositingLayer())
compositingLayer->compositedLayerMapping()->setNeedsGeometryUpdate();
}
repainter().computeRepaintRects(renderer()->containerForRepaint());
if (!m_stackingNode->isNormalFlowOnly()) {
// We don't collect invisible layers in z-order lists if we are not in compositing mode.
......@@ -848,6 +857,7 @@ void RenderLayer::updateDescendantDependentFlags()
}
if (m_visibleContentStatusDirty) {
bool previouslyHasVisibleCOntent = m_hasVisibleContent;
if (renderer()->style()->visibility() == VISIBLE)
m_hasVisibleContent = true;
else {
......@@ -875,6 +885,14 @@ void RenderLayer::updateDescendantDependentFlags()
}
}
m_visibleContentStatusDirty = false;
// FIXME: We can remove this code once we remove the recursive tree
// walk inside updateGraphicsLayerGeometry.
if (m_hasVisibleContent != previouslyHasVisibleCOntent) {
DisableCompositingQueryAsserts disabler;
if (RenderLayer* compositingLayer = enclosingCompositingLayer())
compositingLayer->compositedLayerMapping()->setNeedsGeometryUpdate();
}
}
}
......@@ -3511,6 +3529,7 @@ CompositedLayerMappingPtr RenderLayer::ensureCompositedLayerMapping()
{
if (!m_compositedLayerMapping) {
m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(this));
m_compositedLayerMapping->setNeedsGeometryUpdate();
updateOrRemoveFilterEffectRenderer();
......@@ -3522,6 +3541,9 @@ CompositedLayerMappingPtr RenderLayer::ensureCompositedLayerMapping()
void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
{
if (!layerBeingDestroyed)
m_compositedLayerMapping->setNeedsGeometryUpdate();
m_compositedLayerMapping.clear();
if (!layerBeingDestroyed)
......@@ -3877,6 +3899,9 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle
// https://code.google.com/p/chromium/issues/detail?id=343756
DisableCompositingQueryAsserts disabler;
if (RenderLayer* compositingLayer = enclosingCompositingLayer())
compositingLayer->compositedLayerMapping()->setNeedsGeometryUpdate();
const RenderStyle* newStyle = renderer()->style();
compositor()->updateLayerCompositingState(this, RenderLayerCompositor::UseChickenEggHacks);
......
......@@ -421,7 +421,7 @@ void CompositedLayerMapping::updateAfterLayout(UpdateAfterLayoutFlags flags)
layerCompositor->updateCompositingDescendantGeometry(m_owningLayer->stackingNode(), m_owningLayer, flags & CompositingChildrenOnly);
if (flags & IsUpdateRoot) {
updateGraphicsLayerGeometry();
updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
layerCompositor->updateRootLayerPosition();
RenderLayerStackingNode* stackingContainer = m_owningLayer->stackingNode()->enclosingStackingContainerNode();
if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer->stackingNode()))
......@@ -617,11 +617,17 @@ void CompositedLayerMapping::updateSquashingLayerGeometry(const IntPoint& delta)
}
}
void CompositedLayerMapping::updateGraphicsLayerGeometry()
GraphicsLayerUpdater::UpdateType CompositedLayerMapping::updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType updateType)
{
// If we haven't built z-order lists yet, wait until later.
if (m_owningLayer->stackingNode()->isStackingContainer() && m_owningLayer->stackingNode()->zOrderListsDirty())
return;
return updateType;
if (!m_needToUpdateGeometry && updateType != GraphicsLayerUpdater::ForceUpdate)
return updateType;
m_needToUpdateGeometry = false;
if (m_needToUpdateGeometryOfAllDecendants)
updateType = GraphicsLayerUpdater::ForceUpdate;
// Set transform property, if it is not animating. We have to do this here because the transform
// is affected by the layer dimensions.
......@@ -783,7 +789,7 @@ void CompositedLayerMapping::updateGraphicsLayerGeometry()
if (m_owningLayer->reflectionInfo() && m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
CompositedLayerMappingPtr reflectionCompositedLayerMapping = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping();
reflectionCompositedLayerMapping->updateGraphicsLayerGeometry();
reflectionCompositedLayerMapping->updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
// The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
// but the reflected layer is the bounds of this layer, so we need to position it appropriately.
......@@ -862,6 +868,8 @@ void CompositedLayerMapping::updateGraphicsLayerGeometry()
registerScrollingLayers();
updateCompositingReasons();
return updateType;
}
void CompositedLayerMapping::registerScrollingLayers()
......@@ -1849,6 +1857,28 @@ void CompositedLayerMapping::setBlendMode(blink::WebBlendMode blendMode)
}
}
void CompositedLayerMapping::setNeedsGeometryUpdate()
{
m_needToUpdateGeometryOfAllDecendants = true;
for (RenderLayer* current = m_owningLayer; current; current = current->ancestorCompositingLayer()) {
// FIXME: We should be able to return early from this function once we
// find a CompositedLayerMapping that has m_needToUpdateGeometry set.
// However, we can't do that until we remove the incremental compositing
// updates because they can clear m_needToUpdateGeometry without walking
// the whole tree.
ASSERT(current->hasCompositedLayerMapping());
CompositedLayerMappingPtr mapping = current->compositedLayerMapping();
mapping->m_needToUpdateGeometry = true;
}
}
void CompositedLayerMapping::clearNeedsGeometryUpdate()
{
m_needToUpdateGeometry = false;
m_needToUpdateGeometryOfAllDecendants = false;
}
struct SetContentsNeedsDisplayFunctor {
void operator() (GraphicsLayer* layer) const
{
......
......@@ -27,6 +27,7 @@
#define CompositedLayerMapping_h
#include "core/rendering/RenderLayer.h"
#include "core/rendering/compositing/GraphicsLayerUpdater.h"
#include "platform/geometry/FloatPoint.h"
#include "platform/geometry/FloatPoint3D.h"
#include "platform/graphics/GraphicsLayer.h"
......@@ -94,7 +95,7 @@ public:
// Returns true if layer configuration changed.
bool updateGraphicsLayerConfiguration();
// Update graphics layer position and bounds.
void updateGraphicsLayerGeometry(); // make private
GraphicsLayerUpdater::UpdateType updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType);
// Update whether layer needs blending.
void updateContentsOpaque();
......@@ -195,6 +196,9 @@ public:
void setBlendMode(blink::WebBlendMode);
void setNeedsGeometryUpdate();
void clearNeedsGeometryUpdate();
virtual String debugName(const GraphicsLayer*) OVERRIDE;
LayoutSize subpixelAccumulation() const { return m_subpixelAccumulation; }
......@@ -353,12 +357,14 @@ private:
LayoutRect m_compositedBounds;
LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of the compositedBounds compared to absolute coordinates.
bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
bool m_isMainFrameRenderViewLayer;
bool m_requiresOwnBackingStoreForIntrinsicReasons;
bool m_requiresOwnBackingStoreForAncestorReasons;
bool m_canCompositeFilters;
bool m_backgroundLayerPaintsFixedRootBackground;
bool m_artificiallyInflatedBounds : 1; // bounds had to be made non-zero to make transform-origin work
bool m_isMainFrameRenderViewLayer : 1;
bool m_requiresOwnBackingStoreForIntrinsicReasons : 1;
bool m_requiresOwnBackingStoreForAncestorReasons : 1;
bool m_canCompositeFilters : 1;
bool m_backgroundLayerPaintsFixedRootBackground : 1;
bool m_needToUpdateGeometry : 1;
bool m_needToUpdateGeometryOfAllDecendants : 1;
};
} // namespace WebCore
......
......@@ -48,7 +48,7 @@ GraphicsLayerUpdater::~GraphicsLayerUpdater()
{
}
void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
{
// Make the layer compositing if necessary, and set up clipping and content layers.
// Note that we can only do work here that is independent of whether the descendant layers
......@@ -60,7 +60,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, Vector<GraphicsLayer*
const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping();
update(layer);
updateType = update(layer, updateType);
// Grab some stats for histograms.
if (hasCompositedLayerMapping) {
......@@ -84,7 +84,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, Vector<GraphicsLayer*
if (layer.stackingNode()->isStackingContainer()) {
RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
while (RenderLayerStackingNode* curNode = iterator.next())
rebuildTree(*curNode->layer(), childList, depth + 1);
rebuildTree(*curNode->layer(), updateType, childList, depth + 1);
// If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
......@@ -93,7 +93,7 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, Vector<GraphicsLayer*
RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
while (RenderLayerStackingNode* curNode = iterator.next())
rebuildTree(*curNode->layer(), childList, depth + 1);
rebuildTree(*curNode->layer(), updateType, childList, depth + 1);
if (hasCompositedLayerMapping) {
bool parented = false;
......@@ -132,9 +132,9 @@ void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, Vector<GraphicsLayer*
}
// This just updates layer geometry without changing the hierarchy.
void GraphicsLayerUpdater::updateRecursive(RenderLayer& layer)
void GraphicsLayerUpdater::updateRecursive(RenderLayer& layer, UpdateType updateType)
{
update(layer);
updateType = update(layer, updateType);
#if !ASSERT_DISABLED
LayerListMutationDetector mutationChecker(layer.stackingNode());
......@@ -142,13 +142,13 @@ void GraphicsLayerUpdater::updateRecursive(RenderLayer& layer)
RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), AllChildren);
while (RenderLayerStackingNode* curNode = iterator.next())
updateRecursive(*curNode->layer());
updateRecursive(*curNode->layer(), updateType);
}
void GraphicsLayerUpdater::update(RenderLayer& layer)
GraphicsLayerUpdater::UpdateType GraphicsLayerUpdater::update(RenderLayer& layer, UpdateType updateType)
{
if (!layer.hasCompositedLayerMapping())
return;
return updateType;
CompositedLayerMappingPtr mapping = layer.compositedLayerMapping();
......@@ -162,13 +162,16 @@ void GraphicsLayerUpdater::update(RenderLayer& layer)
}
mapping->updateGraphicsLayerConfiguration();
mapping->updateGraphicsLayerGeometry();
updateType = mapping->updateGraphicsLayerGeometry(updateType);
mapping->clearNeedsGeometryUpdate();
if (!layer.parent())
layer.compositor()->updateRootLayerPosition();
if (mapping->hasUnpositionedOverflowControlsLayers())
layer.scrollableArea()->positionOverflowControls();
return updateType;
}
} // namespace WebCore
......@@ -41,11 +41,16 @@ public:
explicit GraphicsLayerUpdater(RenderView&);
~GraphicsLayerUpdater();
void updateRecursive(RenderLayer&);
void rebuildTree(RenderLayer&, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth);
enum UpdateType {
DoNotForceUpdate,
ForceUpdate,
};
void updateRecursive(RenderLayer&, UpdateType);
void rebuildTree(RenderLayer&, UpdateType, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth);
private:
void update(RenderLayer&);
UpdateType update(RenderLayer&, UpdateType);
RenderView& m_renderView;
......
......@@ -204,6 +204,7 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
, m_showRepaintCounter(false)
, m_needsToRecomputeCompositingRequirements(false)
, m_needsToUpdateLayerTreeGeometry(false)
, m_pendingUpdateType(GraphicsLayerUpdater::DoNotForceUpdate)
, m_compositing(false)
, m_compositingLayersNeedRebuild(false)
, m_forceCompositingMode(false)
......@@ -362,15 +363,23 @@ void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda
switch (updateType) {
case CompositingUpdateAfterStyleChange:
m_needsToRecomputeCompositingRequirements = true;
break;
case CompositingUpdateAfterLayout:
m_needsToRecomputeCompositingRequirements = true;
// FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
m_pendingUpdateType = GraphicsLayerUpdater::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;
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;
break;
}
......@@ -419,10 +428,14 @@ void RenderLayerCompositor::updateCompositingLayersInternal()
if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate && !needsToUpdateScrollingCoordinator)
return;
GraphicsLayerUpdater::UpdateType updateType = m_pendingUpdateType;
// Only clear the flags if we're updating the entire hierarchy.
m_compositingLayersNeedRebuild = false;
m_needsToUpdateLayerTreeGeometry = false;
m_needsToRecomputeCompositingRequirements = false;
m_pendingUpdateType = GraphicsLayerUpdater::DoNotForceUpdate;
RenderLayer* updateRoot = rootRenderLayer();
if (needCompositingRequirementsUpdate) {
......@@ -471,7 +484,7 @@ void RenderLayerCompositor::updateCompositingLayersInternal()
Vector<GraphicsLayer*> childList;
{
TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::rebuildTree");
GraphicsLayerUpdater(*m_renderView).rebuildTree(*updateRoot, childList, 0);
GraphicsLayerUpdater(*m_renderView).rebuildTree(*updateRoot, updateType, childList, 0);
}
// Host the document layer in the RenderView's root layer.
......@@ -491,7 +504,7 @@ void RenderLayerCompositor::updateCompositingLayersInternal()
// We just need to do a geometry update. This is only used for position:fixed scrolling;
// most of the time, geometry is updated via RenderLayer::styleChanged().
TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
GraphicsLayerUpdater(*m_renderView).updateRecursive(*updateRoot);
GraphicsLayerUpdater(*m_renderView).updateRecursive(*updateRoot, updateType);
}
ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
......@@ -1402,7 +1415,7 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayerStack
reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
}
compositedLayerMapping->updateGraphicsLayerGeometry();
compositedLayerMapping->updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
if (compositedChildrenOnly)
return;
}
......
......@@ -29,6 +29,7 @@
#include "core/page/ChromeClient.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/compositing/CompositingReasonFinder.h"
#include "core/rendering/compositing/GraphicsLayerUpdater.h"
#include "platform/graphics/GraphicsLayerClient.h"
#include "wtf/HashMap.h"
......@@ -340,6 +341,7 @@ private:
// FIXME: This should absolutely not be mutable.
mutable bool m_needsToRecomputeCompositingRequirements;
bool m_needsToUpdateLayerTreeGeometry;
GraphicsLayerUpdater::UpdateType m_pendingUpdateType;
bool m_compositing;
bool m_compositingLayersNeedRebuild;
......
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