Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Unified Diff: Source/core/rendering/RenderLayerCompositor.cpp

Issue 88863002: Land layer squashing behind a flag (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Addressed reviewer feedback Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/RenderLayerCompositor.cpp
diff --git a/Source/core/rendering/RenderLayerCompositor.cpp b/Source/core/rendering/RenderLayerCompositor.cpp
index 09084ed814cd94e77220d8a4c2544b9a43907d86..0d8a58279a85c07a2d59a2b6e82a23f5b8453a7e 100644
--- a/Source/core/rendering/RenderLayerCompositor.cpp
+++ b/Source/core/rendering/RenderLayerCompositor.cpp
@@ -440,15 +440,22 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
// scrolling and animation bounds is implemented (crbug.com/252472).
Vector<RenderLayer*> unclippedDescendants;
computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants);
+ }
+ {
+ TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayersToBackings");
assignLayersToBackings(updateRoot, layersChanged);
+ }
+ {
+ TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateHasVisibleNonLayerContent");
const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
if (scrollableAreas) {
for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
(*it)->updateHasVisibleNonLayerContent();
}
}
+
needHierarchyAndGeometryUpdate |= layersChanged;
}
@@ -477,6 +484,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
else
m_rootContentLayer->setChildren(childList);
} else if (needGeometryUpdate) {
+
// 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().
updateLayerTreeGeometry(updateRoot);
@@ -503,11 +511,23 @@ void RenderLayerCompositor::layerBecameNonComposited(const RenderLayer* renderLa
--m_compositedLayerCount;
}
-static bool requiresCompositing(CompositingReasons reasons)
+static bool requiresCompositingOrSquashing(CompositingReasons reasons)
{
return reasons != CompositingReasonNone;
}
+static bool requiresCompositing(CompositingReasons reasons)
+{
+ // Any reasons other than overlap or assumed overlap will require the layer to be separately compositing.
+ return reasons & ~CompositingReasonComboAllOverlapReasons;
+}
+
+static bool requiresSquashing(CompositingReasons reasons)
+{
+ // If the layer has overlap or assumed overlap, but no other reasons, then it should be squashed.
Ian Vollick 2013/12/02 21:17:05 Can we also allow CompositingReasonOverflowScrolli
shawnsingh 2013/12/05 17:55:24 I don't think we can yet. If you remember we had
+ return !requiresCompositing(reasons) && (reasons & CompositingReasonComboAllOverlapReasons);
+}
+
void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer)
{
m_outOfFlowPositionedLayers.add(layer);
@@ -543,6 +563,14 @@ bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* l
scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
}
+ // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
+ // that computing repaint rects will know the layer's correct compositingState.
+ // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
+ // where are we doing that, again?
+ // and what happens when the groupedMapping may have changed under our feet based on previou CLMs being allocated/de-allocated?
Ian Vollick 2013/12/02 21:17:05 We've got ptrs going in both directions right? We
shawnsingh 2013/12/05 17:55:24 Short answer - yes. longer answer - I want to bra
+ layer->setGroupedMapping(0);
+
+ // FIXME: it seems premature to compute this before all compositing state has been updated?
// This layer and all of its descendants have cached repaints rects that are relative to
// the repaint container, so change when compositing changes; we need to update them here.
if (layer->parent())
@@ -609,6 +637,9 @@ bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer)
updateDirectCompositingReasons(layer);
bool layerChanged = allocateOrClearCompositedLayerMapping(layer);
+ // FIXME: this is not correct... info may be out of date and squashing returning true doesn't indicate that the layer changed
+ layerChanged = requiresSquashing(layer->compositingReasons());
+
// See if we need content or clipping layers. Methods called here should assume
// that the compositing state of descendant layers has not been updated yet.
if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateGraphicsLayerConfiguration())
@@ -635,15 +666,19 @@ void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, cons
{
RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/);
if (compositedAncestor) {
- ASSERT(compositedAncestor->compositingState() == PaintsIntoOwnBacking);
-
+ // FIXME: make sure repaintRect is computed correctly for squashed scenario
LayoutPoint offset;
layer->convertToLayerCoords(compositedAncestor, offset);
LayoutRect repaintRect = rect;
repaintRect.moveBy(offset);
- compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
+ if (compositedAncestor->compositingState() == PaintsIntoOwnBacking)
+ compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
+ else if (compositedAncestor->compositingState() == PaintsIntoGroupedBacking)
+ compositedAncestor->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect);
+ else
+ ASSERT_NOT_REACHED();
}
}
@@ -665,11 +700,14 @@ IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* laye
void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
{
+ // FIXME: possibly need to do something here for squashed layers...
setCompositingLayersNeedRebuild();
}
void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
{
+ // FIXME: almost certainly need to do something here for squashed layers...
+
if (!child->hasCompositedLayerMapping() || parent->renderer()->documentBeingDestroyed())
return;
@@ -806,7 +844,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
bool haveComputedBounds = false;
IntRect absBounds;
// If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map.
- if (overlapMap && !overlapMap->isEmpty() && currentRecursionData.m_testingOverlap && !requiresCompositing(directReasons)) {
+ if (overlapMap && !overlapMap->isEmpty() && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons)) {
// If we're testing for overlap, we only need to composite if we overlap something that is already composited.
absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
@@ -825,7 +863,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
CompositingRecursionData childRecursionData(currentRecursionData);
childRecursionData.m_subtreeIsCompositing = false;
- bool willBeComposited = canBeComposited(layer) && requiresCompositing(reasonsToComposite);
+ bool willBeComposited = canBeComposited(layer) && requiresCompositingOrSquashing(reasonsToComposite);
if (willBeComposited) {
// Tell the parent it has compositing descendants.
currentRecursionData.m_subtreeIsCompositing = true;
@@ -914,10 +952,15 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+ // At this point, we definitely have computed the absolute bounds for the layers if it needs to be squashed or composited.
+ // FIXME: can we do something cleaner?
+ if (haveComputedBounds)
+ layer->setAbsoluteBounds(absBounds);
+
// Now check for reasons to become composited that depend on the state of descendant layers.
CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform);
reasonsToComposite |= subtreeCompositingReasons;
- if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtreeCompositingReasons)) {
+ if (!willBeComposited && canBeComposited(layer) && requiresCompositingOrSquashing(subtreeCompositingReasons)) {
childRecursionData.m_compositingAncestor = layer;
if (overlapMap) {
// FIXME: this context push is effectively a no-op but needs to exist for
@@ -956,7 +999,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
if (layer->isRootLayer()) {
// The root layer needs to be composited if anything else in the tree is composited.
// Otherwise, we can disable compositing entirely.
- if (childRecursionData.m_subtreeIsCompositing || requiresCompositing(reasonsToComposite) || m_forceCompositingMode) {
+ if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || m_forceCompositingMode) {
willBeComposited = true;
reasonsToComposite |= CompositingReasonRoot;
} else {
@@ -978,7 +1021,27 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
}
-void RenderLayerCompositor::assignLayersToBackings(RenderLayer* layer, bool& layersChanged)
+void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, IntSize newAbsToLocalOffset)
+{
+ // The most recent backing is done accumulating any more squashing layers.
+ if (hasMostRecentMapping)
+ mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIndex);
+
+ nextSquashedLayerIndex = 0;
+ mostRecentMapping = newCompositedLayerMapping;
+ hasMostRecentMapping = hasNewCompositedLayerMapping;
+ absToLocalOffset = newAbsToLocalOffset;
+}
+
+void RenderLayerCompositor::assignLayersToBackings(RenderLayer* updateRoot, bool& layersChanged)
+{
+ SquashingState squashingState;
+ assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged);
+ if (squashingState.hasMostRecentMapping)
+ squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex);
+}
+
+void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged)
{
if (allocateOrClearCompositedLayerMapping(layer))
layersChanged = true;
@@ -986,21 +1049,49 @@ void RenderLayerCompositor::assignLayersToBackings(RenderLayer* layer, bool& lay
if (layer->reflectionInfo() && updateLayerCompositingState(layer->reflectionInfo()->reflectionLayer()))
layersChanged = true;
- // FIXME: squashing code here: if a layer requiresSquashing(), then assign this layer to the most recent
- // squashing layer and update recursion state of this function.
+ // Add this layer to a squashing backing if needed.
+ if (isLayerSquashingEnabled()) {
+ // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than
+ // the layer's own primary contents. This would happen when we have a composited negative z-index element that needs to
+ // paint on top of the background, but below the layer's main contents. For now, because we always composite layers
+ // when they have a composited negative z-index child, such layers will never need squashing so it is not yet an issue.
+ if (requiresSquashing(layer->compositingReasons())) {
+ // A layer that is squashed with other layers cannot have its own CompositedLayerMapping.
+ ASSERT(!layer->hasCompositedLayerMapping());
+ ASSERT(squashingState.hasMostRecentMapping);
+
+ IntRect absBounds = layer->absoluteBounds();
+
+ // FIXME: see if we can refactor this to be clearer
+ IntSize offsetFromTargetBacking(absBounds.x() + squashingState.absToLocalOffset.width(),
+ absBounds.y() + squashingState.absToLocalOffset.height());
trchen 2013/12/02 22:56:55 I don't quite understand this, but doing a linear
shawnsingh 2013/12/05 17:55:24 New patch works for transforms =) (I have the tes
+
+ squashingState.mostRecentMapping->addRenderLayerToSquashingGraphicsLayer(layer, offsetFromTargetBacking, squashingState.nextSquashedLayerIndex);
+ squashingState.nextSquashedLayerIndex++;
+
+ // FIXME: does this need to be true here? Do we need more logic to decide when it should be true?
Ian Vollick 2013/12/02 21:17:05 I think we'll need to plumb a boolean out of addRe
shawnsingh 2013/12/05 17:55:24 Agreed - but not yet done in latest patch =/
+ layersChanged = true;
+ }
+ }
if (layer->stackingNode()->isStackingContainer()) {
RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
while (RenderLayerStackingNode* curNode = iterator.next())
- assignLayersToBackings(curNode->layer(), layersChanged);
+ assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
}
- // FIXME: squashing code here: if this layer actually becomes separately composited, then we need to update the
- // squashing layer that subsequent overlapping layers will contribute to.
+ if (isLayerSquashingEnabled()) {
+ // At this point, if the layer is to be "separately" composited, then its backing becomes the most recent in paint-order.
+ if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
+ ASSERT(!requiresSquashing(layer->compositingReasons()));
+ IntRect absBounds = layer->absoluteBounds();
+ squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), IntSize(-absBounds.x(), -absBounds.y()));
+ }
+ }
RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
while (RenderLayerStackingNode* curNode = iterator.next())
- assignLayersToBackings(curNode->layer(), layersChanged);
+ assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
}
void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
@@ -1027,6 +1118,9 @@ void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, Render
void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
{
ASSERT(layer->hasCompositedLayerMapping());
+ // FIXME: this is probably not necessary, a leftover from the hacked prototype.
+ if (!layer->hasCompositedLayerMapping())
+ return;
GraphicsLayer* hostingLayer = layer->compositedLayerMapping()->parentForSublayers();
hostingLayer->removeAllChildren();
@@ -1499,7 +1593,10 @@ bool RenderLayerCompositor::needsOwnBacking(const RenderLayer* layer) const
if (!canBeComposited(layer))
return false;
- return requiresCompositing(layer->compositingReasons()) || (inCompositingMode() && layer->isRootLayer());
+ // If squashing is disabled, then layers that would have been squashed should just be separately composited.
+ bool needsOwnBackingDueToOverlap = !isLayerSquashingEnabled() && requiresSquashing(layer->compositingReasons());
+
+ return requiresCompositing(layer->compositingReasons()) || needsOwnBackingDueToOverlap || (inCompositingMode() && layer->isRootLayer());
}
bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
@@ -1564,6 +1661,7 @@ bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const
if (!layer->hasCompositedLayerMapping() || !layer->parent())
return false;
+ // FIXME: need to see if new semantics of ancestorCompositingLayer() work correctly here?
const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
if (!compositingAncestor)
return false;

Powered by Google App Engine
This is Rietveld 408576698