Skip to content

Commit

Permalink
Make compositingState explicit (re-land #2 with bogus ASSERT removed)
Browse files Browse the repository at this point in the history
A lot of code uses isComposited() and compositedLayerMapping()
as booleans to check the compositing state of a RenderLayer or
RenderObject. However, in the code there are actually 3 different
states:

(1) not composited (paints into CompositedLayerMapping of a
    composited ancestor)
(2) paints into own CompositedLayerMapping
(3) has its own CompositedLayerMapping but actually still paints
    into composited ancestor.

Furthermore, upcoming changes to compositing will add a
fourth state:

(4) paints into a GraphicsLayer that is shared by a group of
    layers.

This patch removes isComposited() boolean check, and
replaces it with compositingState() that returns an enum.

Most call sites outside of RenderLayer, CompositedLayerMapping,
and RenderLayerCompositor have been updated to reflect
what states they really intended to check for.  Remaining call
sites have been replaced with the compositedLayerMapping()
accessor for now, which is exactly equivalent to the old
isComposited() boolean, and those sites will be updated in
follow-up patches.

BUG=261605
R=jamesr@chromium.org, jchaffraix@chromium.org, vollick@chromium.org

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

git-svn-id: svn://svn.chromium.org/blink/trunk@159118 bbb929c8-8fbe-4397-9dbb-9b2b20218538
  • Loading branch information
shawnsingh@chromium.org committed Oct 8, 2013
1 parent b6d574a commit db8f4a6
Show file tree
Hide file tree
Showing 24 changed files with 192 additions and 118 deletions.
3 changes: 2 additions & 1 deletion Source/core/css/CSSComputedStyleDeclaration.cpp
Expand Up @@ -1616,7 +1616,8 @@ PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPrope
Node* styledNode = this->styledNode();
ASSERT(styledNode);
RenderObject* renderer = styledNode->renderer();
if (renderer && renderer->isComposited() && !RuntimeEnabledFeatures::webAnimationsCSSEnabled() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
if (renderer && renderer->compositingState() == PaintsIntoOwnBacking
&& !RuntimeEnabledFeatures::webAnimationsCSSEnabled() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
AnimationUpdateBlock animationUpdateBlock(renderer->animation());
if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
// FIXME: This cached pseudo style will only exist if the animation has been run at least once.
Expand Down
2 changes: 1 addition & 1 deletion Source/core/inspector/InspectorLayerTreeAgent.cpp
Expand Up @@ -204,7 +204,7 @@ void InspectorLayerTreeAgent::getLayers(ErrorString* errorString, const int* nod

void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(ErrorString* errorString, RenderLayer* root, LayerIdToNodeIdMap& layerIdToNodeIdMap)
{
if (root->isComposited()) {
if (root->compositedLayerMapping()) {
if (Node* node = root->renderer()->generatingNode()) {
GraphicsLayer* graphicsLayer = root->compositedLayerMapping()->childForSuperlayers();
layerIdToNodeIdMap.set(graphicsLayer->platformLayer()->id(), idForNode(errorString, node));
Expand Down
10 changes: 5 additions & 5 deletions Source/core/page/FrameView.cpp
Expand Up @@ -1255,7 +1255,7 @@ void FrameView::updateCanBlitOnScrollRecursively()
bool FrameView::contentsInCompositedLayer() const
{
RenderView* renderView = this->renderView();
if (renderView && renderView->isComposited()) {
if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) {
GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->mainGraphicsLayer();
if (layer && layer->drawsContent())
return true;
Expand Down Expand Up @@ -1372,10 +1372,10 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
ASSERT(renderer->hasLayer());
RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();

// Composited layers may still actually paint into their ancestor.
// If that happens, the viewport constrained object needs to be
// repainted on scroll.
if (layer->isComposited() && !layer->compositedLayerMapping()->paintsIntoCompositedAncestor())
// Layers that paint into their ancestor or into a grouped backing will still need
// to apply a repaint invalidation. If the layer paints into its own backing, then
// it does not need repainting just to scroll.
if (layer->compositingState() == PaintsIntoOwnBacking)
continue;

if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
Expand Down
5 changes: 3 additions & 2 deletions Source/core/page/animation/AnimationBase.cpp
Expand Up @@ -555,8 +555,9 @@ void AnimationBase::freezeAtTime(double t)
else
m_pauseTime = m_startTime + t - m_animation->delay();

// It is possible that m_isAccelerated is true and m_object->isComposited() is false, because of style change.
if (m_object && m_object->isComposited() && isAccelerated())
// It is possible that m_isAccelerated is true and m_object->compositingState() is NotComposited, because of style change.
// So, both conditions need to be checked.
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
toRenderBoxModelObject(m_object)->suspendAnimations(m_pauseTime);
}

Expand Down
6 changes: 3 additions & 3 deletions Source/core/page/animation/ImplicitAnimation.cpp
Expand Up @@ -104,7 +104,7 @@ void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)

void ImplicitAnimation::startAnimation(double timeOffset)
{
if (m_object && m_object->isComposited())
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking)
m_isAccelerated = toRenderBoxModelObject(m_object)->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
}

Expand All @@ -113,7 +113,7 @@ void ImplicitAnimation::pauseAnimation(double timeOffset)
if (!m_object)
return;

if (m_object && m_object->isComposited() && isAccelerated())
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
toRenderBoxModelObject(m_object)->transitionPaused(timeOffset, m_animatingProperty);

// Restore the original (unanimated) style
Expand All @@ -123,7 +123,7 @@ void ImplicitAnimation::pauseAnimation(double timeOffset)

void ImplicitAnimation::endAnimation()
{
if (m_object && m_object->isComposited() && isAccelerated())
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
toRenderBoxModelObject(m_object)->transitionFinished(m_animatingProperty);
m_isAccelerated = false;
}
Expand Down
6 changes: 3 additions & 3 deletions Source/core/page/animation/KeyframeAnimation.cpp
Expand Up @@ -239,7 +239,7 @@ bool KeyframeAnimation::hasAnimationForProperty(CSSPropertyID property) const

void KeyframeAnimation::startAnimation(double timeOffset)
{
if (m_object && m_object->isComposited())
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking)
m_isAccelerated = toRenderBoxModelObject(m_object)->startAnimation(timeOffset, m_animation.get(), m_keyframes);
}

Expand All @@ -248,7 +248,7 @@ void KeyframeAnimation::pauseAnimation(double timeOffset)
if (!m_object)
return;

if (m_object && m_object->isComposited() && isAccelerated())
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
toRenderBoxModelObject(m_object)->animationPaused(timeOffset, m_keyframes.animationName());

// Restore the original (unanimated) style
Expand All @@ -261,7 +261,7 @@ void KeyframeAnimation::endAnimation()
if (!m_object)
return;

if (m_object && m_object->isComposited() && isAccelerated())
if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
toRenderBoxModelObject(m_object)->animationFinished(m_keyframes.animationName());
m_isAccelerated = false;

Expand Down
11 changes: 7 additions & 4 deletions Source/core/page/scrolling/ScrollingCoordinator.cpp
Expand Up @@ -159,7 +159,7 @@ static void clearPositionConstraintExceptForLayer(GraphicsLayer* layer, Graphics

static WebLayerPositionConstraint computePositionConstraint(const RenderLayer* layer)
{
ASSERT(layer->isComposited());
ASSERT(layer->compositedLayerMapping());
do {
if (layer->renderer()->style()->position() == FixedPosition) {
const RenderObject* fixedPositionObject = layer->renderer();
Expand All @@ -169,7 +169,10 @@ static WebLayerPositionConstraint computePositionConstraint(const RenderLayer* l
}

layer = layer->parent();
} while (layer && !layer->isComposited());

// Composited layers that inherit a fixed position state will be positioned with respect to the nearest compositedLayerMapping's GraphicsLayer.
// So, once we find a layer that has its own compositedLayerMapping, we can stop searching for a fixed position RenderObject.
} while (layer && layer->compositedLayerMapping());
return WebLayerPositionConstraint();
}

Expand Down Expand Up @@ -806,12 +809,12 @@ bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects(Frame
return true;
RenderLayer* layer = toRenderBoxModelObject(viewportConstrainedObject)->layer();
// Any explicit reason that a fixed position element is not composited shouldn't cause slow scrolling.
if (!layer->isComposited() && layer->viewportConstrainedNotCompositedReason() == RenderLayer::NoNotCompositedReason)
if (layer->compositingState() != PaintsIntoOwnBacking && layer->viewportConstrainedNotCompositedReason() == RenderLayer::NoNotCompositedReason)
return true;

// Composited layers that actually paint into their enclosing ancestor
// must also force main thread scrolling.
if (layer->isComposited() && layer->compositedLayerMapping()->paintsIntoCompositedAncestor())
if (layer->compositingState() == HasOwnBackingButPaintsIntoAncestor)
return true;
}
return false;
Expand Down
25 changes: 17 additions & 8 deletions Source/core/rendering/CompositedLayerMapping.cpp
Expand Up @@ -696,7 +696,7 @@ void CompositedLayerMapping::updateGraphicsLayerGeometry()
m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
}

if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->compositedLayerMapping()) {
CompositedLayerMapping* reflectionCompositedLayerMapping = m_owningLayer->reflectionLayer()->compositedLayerMapping();
reflectionCompositedLayerMapping->updateGraphicsLayerGeometry();

Expand Down Expand Up @@ -1197,9 +1197,16 @@ float CompositedLayerMapping::compositingOpacity(float rendererOpacity) const
if (!curr->isStackingContainer())
continue;

// If we found a compositing layer, we want to compute opacity
// relative to it. So we can break here.
if (curr->isComposited())
// If we found a composited layer, regardless of whether it actually
// paints into it, we want to compute opacity relative to it. So we can
// break here.
//
// FIXME: with grouped backings, a composited descendant will have to
// continue past the grouped (squashed) layers that its parents may
// contribute to. This whole confusion can be avoided by specifying
// explicitly the composited ancestor where we would stop accumulating
// opacity.
if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == HasOwnBackingButPaintsIntoAncestor)
break;

finalOpacity *= curr->renderer()->opacity();
Expand Down Expand Up @@ -1337,7 +1344,7 @@ static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
if (!curLayer->isComposited()
if (!curLayer->compositedLayerMapping()
&& (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
return true;
}
Expand All @@ -1352,7 +1359,7 @@ static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
if (!curLayer->isComposited()
if (!curLayer->compositedLayerMapping()
&& (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
return true;
}
Expand All @@ -1362,7 +1369,7 @@ static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
if (!curLayer->isComposited()
if (!curLayer->compositedLayerMapping()
&& (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
return true;
}
Expand All @@ -1372,7 +1379,9 @@ static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
return false;
}

// Conservative test for having no rendered children.
// FIXME: By name the implementation is correct. But the code that uses this function means something
// very slightly different - the implementation needs to also include composited descendants that
// don't paint into their own backing, and instead paint into this backing.
bool CompositedLayerMapping::hasVisibleNonCompositingDescendantLayers() const
{
return hasVisibleNonCompositingDescendant(m_owningLayer);
Expand Down
25 changes: 25 additions & 0 deletions Source/core/rendering/CompositingState.h
@@ -0,0 +1,25 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CompositingState_h
#define CompositingState_h

namespace WebCore {

enum CompositingState {
// The layer paints into its enclosing composited ancestor.
NotComposited = 0,

// The layer is composited, but its contents still paint into enclosing composited ancestor.
// In this state, repaint invalidations must be sent to the enclosing composited ancestor.
// Typically this happens when a layer's properties need to be represented in the compositor
// output data structures, but it doesn't actually have any other reasons to be composited.
HasOwnBackingButPaintsIntoAncestor = 1,

PaintsIntoOwnBacking = 2,
};

} // namespace WebCore

#endif // CompositingState_h
9 changes: 7 additions & 2 deletions Source/core/rendering/RenderBox.cpp
Expand Up @@ -1257,7 +1257,8 @@ static bool isCandidateForOpaquenessTest(RenderBox* childBox)
if (!childBox->width() || !childBox->height())
return false;
if (RenderLayer* childLayer = childBox->layer()) {
if (childLayer->isComposited())
// FIXME: perhaps this could be less conservative?
if (childLayer->compositingState() != NotComposited)
return false;
// FIXME: Deal with z-index.
if (!childStyle->hasAutoZIndex())
Expand Down Expand Up @@ -1352,9 +1353,13 @@ void RenderBox::paintClippingMask(PaintInfo& paintInfo, const LayoutPoint& paint
if (!paintInfo.shouldPaintWithinRoot(this) || style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseClippingMask || paintInfo.context->paintingDisabled())
return;

if (!layer() || !layer()->isComposited())
if (!layer() || layer()->compositingState() != PaintsIntoOwnBacking)
return;

// We should never have this state in this function. A layer with a mask
// should have always created its own backing if it became composited.
ASSERT(layer()->compositingState() != HasOwnBackingButPaintsIntoAncestor);

LayoutRect paintRect = LayoutRect(paintOffset, size());
paintInfo.context->fillRect(pixelSnappedIntRect(paintRect), Color::black);
}
Expand Down
16 changes: 8 additions & 8 deletions Source/core/rendering/RenderBoxModelObject.cpp
Expand Up @@ -102,49 +102,49 @@ bool RenderBoxModelObject::hasAcceleratedCompositing() const
bool RenderBoxModelObject::startTransition(double timeOffset, CSSPropertyID propertyId, const RenderStyle* fromStyle, const RenderStyle* toStyle)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
return layer()->compositedLayerMapping()->startTransition(timeOffset, propertyId, fromStyle, toStyle);
}

void RenderBoxModelObject::transitionPaused(double timeOffset, CSSPropertyID propertyId)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
layer()->compositedLayerMapping()->transitionPaused(timeOffset, propertyId);
}

void RenderBoxModelObject::transitionFinished(CSSPropertyID propertyId)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
layer()->compositedLayerMapping()->transitionFinished(propertyId);
}

bool RenderBoxModelObject::startAnimation(double timeOffset, const CSSAnimationData* animation, const KeyframeList& keyframes)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
return layer()->compositedLayerMapping()->startAnimation(timeOffset, animation, keyframes);
}

void RenderBoxModelObject::animationPaused(double timeOffset, const String& name)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
layer()->compositedLayerMapping()->animationPaused(timeOffset, name);
}

void RenderBoxModelObject::animationFinished(const String& name)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
layer()->compositedLayerMapping()->animationFinished(name);
}

void RenderBoxModelObject::suspendAnimations(double time)
{
ASSERT(hasLayer());
ASSERT(isComposited());
ASSERT(compositingState() == PaintsIntoOwnBacking);
layer()->compositedLayerMapping()->suspendAnimations(time);
}

Expand Down Expand Up @@ -985,7 +985,7 @@ bool RenderBoxModelObject::fixedBackgroundPaintsInLocalCoordinates() const
return false;

RenderLayer* rootLayer = view()->layer();
if (!rootLayer || !rootLayer->isComposited())
if (!rootLayer || rootLayer->compositingState() == NotComposited)
return false;

return rootLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground();
Expand Down

0 comments on commit db8f4a6

Please sign in to comment.