Log Message
Avoid creating compositing layers for preserve-3d without transformed descendants https://bugs.webkit.org/show_bug.cgi?id=88115
Source/WebCore: Reviewed by Antti Koivisto. Avoid creating compositing layers, and therefore using excess backing store, for elements that have -webkit-transform-style: preserve-3d, but no 3D-transformed descendants that would be affected by that preserve-3d. Test: compositing/layer-creation/no-compositing-for-preserve-3d.html * rendering/RenderLayer.h: Replace the "mustOverlap" flag with a enum that describes the different reasons for indirect compositing, so that we can use that information to decide whether to allocate backing store. (WebCore::RenderLayer::setIndirectCompositingReason): (WebCore::RenderLayer::indirectCompositingReason): (WebCore::RenderLayer::mustCompositeForIndirectReasons): * rendering/RenderLayer.cpp: (WebCore::RenderLayer::RenderLayer): Initialize m_indirectCompositingReason * rendering/RenderLayerCompositor.h: New out param for computeCompositingRequirements() that is uses to indicate that a 3d-transformed descendant has been encountered. Rename requiresCompositingWhenDescendantsAreCompositing() to requiresCompositingForIndirectReason(), and return the reason as an out param. * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::updateCompositingLayers): Pass in the saw3DTransform param to computeCompositingRequirements(). (WebCore::RenderLayerCompositor::computeCompositingRequirements): Return a flag from computeCompositingRequirements() that is set to true if we've seen descendants that have 3d transforms. This is later used to decide whether to composite for perspective or preserve-3d. Change the "mustOverlapCompositedLayers" code to use the new "indirect compositing" enum flags. After enumerating children, call requiresCompositingForIndirectReason() and record the reason in the layer. (WebCore::RenderLayerCompositor::needsToBeComposited): Use mustCompositeForIndirectReasons() now. (WebCore::RenderLayerCompositor::requiresOwnBackingStore): Consult the indirect compositing reason rather than just looking for the overlap flag. (WebCore::RenderLayerCompositor::reasonForCompositing): Now that we have more information about indirect compositing reasons, the logging can be more detailed. (WebCore::RenderLayerCompositor::requiresCompositingForTransform): This now only looks for 3d transforms. We now treat perspective and perserve-3d as "indirect" reasons, because whether they composite depends on descendants having non-affine transforms. (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason): Includes the logic previously in requiresCompositingWhenDescendantsAreCompositing(), and now determines whether to composite for preserve-3d and perspective, based on whether we have transformed descendants. LayoutTests: Reviewed by Antti Koivisto. * compositing/backing/no-backing-for-perspective-expected.txt: * compositing/backing/no-backing-for-perspective.html: Change the transform to be non-affine so that we keep making layers for perspective. * compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt: Added. * compositing/layer-creation/no-compositing-for-preserve-3d.html: Copied from LayoutTests/compositing/backing/no-backing-for-perspective.html.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt
- trunk/LayoutTests/compositing/backing/no-backing-for-perspective.html
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/rendering/RenderLayer.cpp
- trunk/Source/WebCore/rendering/RenderLayer.h
- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
- trunk/Source/WebCore/rendering/RenderLayerCompositor.h
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (119528 => 119529)
--- trunk/LayoutTests/ChangeLog 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/LayoutTests/ChangeLog 2012-06-05 22:18:31 UTC (rev 119529)
@@ -1,3 +1,16 @@
+2012-06-05 Simon Fraser <[email protected]>
+
+ Avoid creating compositing layers for preserve-3d without transformed descendants
+ https://bugs.webkit.org/show_bug.cgi?id=88115
+
+ Reviewed by Antti Koivisto.
+
+ * compositing/backing/no-backing-for-perspective-expected.txt:
+ * compositing/backing/no-backing-for-perspective.html: Change the transform to be non-affine so that
+ we keep making layers for perspective.
+ * compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt: Added.
+ * compositing/layer-creation/no-compositing-for-preserve-3d.html: Copied from LayoutTests/compositing/backing/no-backing-for-perspective.html.
+
2012-06-05 Levi Weintraub <[email protected]>
Block selection gaps painted not properly pixel snapped
Modified: trunk/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt (119528 => 119529)
--- trunk/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt 2012-06-05 22:18:31 UTC (rev 119529)
@@ -20,6 +20,7 @@
(position 31.00 49.00)
(bounds 100.00 100.00)
(drawsContent 1)
+ (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 1.00 1.00])
)
)
)
Modified: trunk/LayoutTests/compositing/backing/no-backing-for-perspective.html (119528 => 119529)
--- trunk/LayoutTests/compositing/backing/no-backing-for-perspective.html 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/LayoutTests/compositing/backing/no-backing-for-perspective.html 2012-06-05 22:18:31 UTC (rev 119529)
@@ -21,7 +21,7 @@
}
.composited {
- -webkit-transform: translateZ(0);
+ -webkit-transform: translateZ(1px);
}
</style>
Added: trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt (0 => 119529)
--- trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt 2012-06-05 22:18:31 UTC (rev 119529)
@@ -0,0 +1,28 @@
+This layer should not be composited.
+This layer should not be composited.
+This layer should be composited.
+(GraphicsLayer
+ (bounds 785.00 611.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 785.00 611.00)
+ (children 1
+ (GraphicsLayer
+ (position 18.00 390.00)
+ (bounds 342.00 180.00)
+ (preserves3D 1)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (position 31.00 49.00)
+ (bounds 100.00 100.00)
+ (drawsContent 1)
+ (transform [0.98 0.00 -0.17 0.00] [0.00 1.00 0.00 0.00] [0.17 0.00 0.98 0.00] [0.00 0.00 0.00 1.00])
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Property changes on: trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Copied: trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d.html (from rev 119528, trunk/LayoutTests/compositing/backing/no-backing-for-perspective.html) (0 => 119529)
--- trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/no-compositing-for-preserve-3d.html 2012-06-05 22:18:31 UTC (rev 119529)
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .box {
+ position: relative;
+ height: 100px;
+ width: 100px;
+ margin: 10px;
+ left: 0;
+ top: 0;
+ background-color: silver;
+ }
+
+ .preserve3d {
+ width: 300px;
+ border: 1px solid black;
+ padding: 20px;
+ margin: 10px;
+ -webkit-transform-style: preserve-3d;
+ }
+ </style>
+
+ <script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ function dumpLayers()
+ {
+ var layersResult = document.getElementById('layers');
+ if (window.layoutTestController)
+ layersResult.innerText = layoutTestController.layerTreeAsText();
+
+ }
+ window.addEventListener('load', dumpLayers, false)
+ </script>
+
+</head>
+<body>
+
+ <div class="preserve3d">
+ This layer should not be composited.
+ <div class="box"></div>
+ </div>
+ </div>
+
+ <div class="preserve3d">
+ This layer should not be composited.
+ <div class="box" style="-webkit-transform: rotate(10deg)"></div>
+ </div>
+ </div>
+
+ <div class="preserve3d">
+ This layer should be composited.
+ <div class="box" style="-webkit-transform: rotateY(10deg)"></div>
+ </div>
+<pre id="layers">Layer tree goes here in DRT</pre>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (119528 => 119529)
--- trunk/Source/WebCore/ChangeLog 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/Source/WebCore/ChangeLog 2012-06-05 22:18:31 UTC (rev 119529)
@@ -1,3 +1,53 @@
+2012-06-05 Simon Fraser <[email protected]>
+
+ Avoid creating compositing layers for preserve-3d without transformed descendants
+ https://bugs.webkit.org/show_bug.cgi?id=88115
+
+ Reviewed by Antti Koivisto.
+
+ Avoid creating compositing layers, and therefore using excess backing store,
+ for elements that have -webkit-transform-style: preserve-3d, but no 3D-transformed
+ descendants that would be affected by that preserve-3d.
+
+ Test: compositing/layer-creation/no-compositing-for-preserve-3d.html
+
+ * rendering/RenderLayer.h: Replace the "mustOverlap" flag with a enum
+ that describes the different reasons for indirect compositing, so that
+ we can use that information to decide whether to allocate backing store.
+ (WebCore::RenderLayer::setIndirectCompositingReason):
+ (WebCore::RenderLayer::indirectCompositingReason):
+ (WebCore::RenderLayer::mustCompositeForIndirectReasons):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer): Initialize m_indirectCompositingReason
+
+ * rendering/RenderLayerCompositor.h: New out param for computeCompositingRequirements()
+ that is uses to indicate that a 3d-transformed descendant has been encountered.
+ Rename requiresCompositingWhenDescendantsAreCompositing() to requiresCompositingForIndirectReason(),
+ and return the reason as an out param.
+
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateCompositingLayers): Pass in the saw3DTransform
+ param to computeCompositingRequirements().
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements): Return a flag
+ from computeCompositingRequirements() that is set to true if we've seen descendants
+ that have 3d transforms. This is later used to decide whether to composite for
+ perspective or preserve-3d.
+ Change the "mustOverlapCompositedLayers" code to use the new "indirect compositing"
+ enum flags.
+ After enumerating children, call requiresCompositingForIndirectReason() and
+ record the reason in the layer.
+ (WebCore::RenderLayerCompositor::needsToBeComposited): Use mustCompositeForIndirectReasons() now.
+ (WebCore::RenderLayerCompositor::requiresOwnBackingStore): Consult the indirect compositing
+ reason rather than just looking for the overlap flag.
+ (WebCore::RenderLayerCompositor::reasonForCompositing): Now that we have more information
+ about indirect compositing reasons, the logging can be more detailed.
+ (WebCore::RenderLayerCompositor::requiresCompositingForTransform): This now only looks
+ for 3d transforms. We now treat perspective and perserve-3d as "indirect" reasons, because
+ whether they composite depends on descendants having non-affine transforms.
+ (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason): Includes the logic
+ previously in requiresCompositingWhenDescendantsAreCompositing(), and now determines
+ whether to composite for preserve-3d and perspective, based on whether we have transformed descendants.
+
2012-06-05 Levi Weintraub <[email protected]>
Block selection gaps painted not properly pixel snapped
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (119528 => 119529)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-06-05 22:18:31 UTC (rev 119529)
@@ -142,7 +142,7 @@
, m_has3DTransformedDescendant(false)
#if USE(ACCELERATED_COMPOSITING)
, m_hasCompositingDescendant(false)
- , m_mustOverlapCompositedLayers(false)
+ , m_indirectCompositingReason(NoIndirectCompositingReason)
#endif
, m_containsDirtyOverlayScrollbars(false)
#if !ASSERT_DISABLED
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (119528 => 119529)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2012-06-05 22:18:31 UTC (rev 119529)
@@ -816,8 +816,18 @@
bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
void setHasCompositingDescendant(bool b) { m_hasCompositingDescendant = b; }
- bool mustOverlapCompositedLayers() const { return m_mustOverlapCompositedLayers; }
- void setMustOverlapCompositedLayers(bool b) { m_mustOverlapCompositedLayers = b; }
+ enum IndirectCompositingReason {
+ NoIndirectCompositingReason,
+ IndirectCompositingForOverlap,
+ IndirectCompositingForBackgroundLayer,
+ IndirectCompositingForGraphicalEffect, // opacity, mask, filter, transform etc.
+ IndirectCompositingForPerspective,
+ IndirectCompositingForPreserve3D
+ };
+
+ void setIndirectCompositingReason(IndirectCompositingReason reason) { m_indirectCompositingReason = reason; }
+ IndirectCompositingReason indirectCompositingReason() const { return static_cast<IndirectCompositingReason>(m_indirectCompositingReason); }
+ bool mustCompositeForIndirectReasons() const { return m_indirectCompositingReason; }
#endif
friend class RenderLayerBacking;
@@ -875,7 +885,7 @@
// in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
#if USE(ACCELERATED_COMPOSITING)
bool m_hasCompositingDescendant : 1; // In the z-order tree.
- bool m_mustOverlapCompositedLayers : 1;
+ unsigned m_indirectCompositingReason : 3;
#endif
bool m_containsDirtyOverlayScrollbars : 1;
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (119528 => 119529)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2012-06-05 22:18:31 UTC (rev 119529)
@@ -401,11 +401,12 @@
// FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
CompositingState compState(updateRoot, m_compositingConsultsOverlap);
bool layersChanged = false;
+ bool saw3DTransform = false;
if (m_compositingConsultsOverlap) {
OverlapMap overlapTestRequestMap;
- computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged);
+ computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged, saw3DTransform);
} else
- computeCompositingRequirements(0, updateRoot, 0, compState, layersChanged);
+ computeCompositingRequirements(0, updateRoot, 0, compState, layersChanged, saw3DTransform);
needHierarchyUpdate |= layersChanged;
}
@@ -716,7 +717,7 @@
// must be compositing so that its contents render over that child.
// This implies that its positive z-index children must also be compositing.
//
-void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged)
+void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform)
{
layer->updateLayerListsIfNeeded();
@@ -741,7 +742,7 @@
mustOverlapCompositedLayers = overlapMap->overlapsLayers(absBounds);
}
- layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
+ layer->setIndirectCompositingReason(mustOverlapCompositedLayers ? RenderLayer::IndirectCompositingForOverlap : RenderLayer::NoIndirectCompositingReason);
// The children of this layer don't need to composite, unless there is
// a compositing layer among them, so start by inheriting the compositing
@@ -777,18 +778,20 @@
LayerListMutationDetector mutationChecker(layer);
#endif
+ bool anyDescendantHas3DTransform = false;
+
if (layer->isStackingContext()) {
if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged);
+ computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
// If we have to make a layer for this child, make one now so we can have a contents layer
// (since we need to ensure that the -ve z-order child renders underneath our contents).
if (!willBeComposited && childState.m_subtreeIsCompositing) {
// make layer compositing
- layer->setMustOverlapCompositedLayers(true);
+ layer->setIndirectCompositingReason(RenderLayer::IndirectCompositingForBackgroundLayer);
childState.m_compositingAncestor = layer;
if (overlapMap)
overlapMap->pushCompositingContainer();
@@ -802,7 +805,7 @@
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged);
+ computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
}
}
@@ -811,7 +814,7 @@
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged);
+ computeCompositingRequirements(layer, curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
}
}
}
@@ -830,11 +833,11 @@
if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
- // If we have a software transform, and we have layers under us, we need to also
- // be composited. Also, if we have opacity < 1, then we need to be a layer so that
- // the child layers are opaque, then rendered with opacity on this layer.
- if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) {
- layer->setMustOverlapCompositedLayers(true);
+ // Now check for reasons to become composited that depend on the state of descendant layers.
+ RenderLayer::IndirectCompositingReason indirectCompositingReason;
+ if (!willBeComposited && canBeComposited(layer)
+ && requiresCompositingForIndirectReason(layer->renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
+ layer->setIndirectCompositingReason(indirectCompositingReason);
childState.m_compositingAncestor = layer;
if (overlapMap) {
overlapMap->pushCompositingContainer();
@@ -842,11 +845,11 @@
}
willBeComposited = true;
}
-
+
ASSERT(willBeComposited == needsToBeComposited(layer));
if (layer->reflectionLayer()) {
// FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
- layer->reflectionLayer()->setMustOverlapCompositedLayers(willBeComposited);
+ layer->reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingForOverlap : RenderLayer::NoIndirectCompositingReason);
}
// Subsequent layers in the parent stacking context also need to composite.
@@ -899,6 +902,8 @@
if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow))
layersChanged = true;
+ descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
+
if (overlapMap)
overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer ? ancestorLayer->renderer() : 0);
}
@@ -1417,7 +1422,7 @@
if (!canBeComposited(layer))
return false;
- return requiresCompositingLayer(layer) || layer->mustOverlapCompositedLayers() || (inCompositingMode() && layer->isRootLayer());
+ return requiresCompositingLayer(layer) || layer->mustCompositeForIndirectReasons() || (inCompositingMode() && layer->isRootLayer());
}
// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
@@ -1460,7 +1465,7 @@
|| compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
return true;
- return layer->isRootLayer()
+ if (layer->isRootLayer()
|| layer->transform() // note: excludes perspective and transformStyle3D.
|| requiresCompositingForVideo(renderer)
|| requiresCompositingForCanvas(renderer)
@@ -1473,8 +1478,18 @@
|| renderer->isTransparent()
|| renderer->hasMask()
|| renderer->hasReflection()
- || renderer->hasFilter()
- || layer->mustOverlapCompositedLayers();
+ || renderer->hasFilter())
+ return true;
+
+
+ if (layer->mustCompositeForIndirectReasons()) {
+ RenderLayer::IndirectCompositingReason reason = layer->indirectCompositingReason();
+ return reason == RenderLayer::IndirectCompositingForOverlap
+ || reason == RenderLayer::IndirectCompositingForBackgroundLayer
+ || reason == RenderLayer::IndirectCompositingForGraphicalEffect
+ || reason == RenderLayer::IndirectCompositingForPreserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect.
+ }
+ return false;
}
#if !LOG_DISABLED
@@ -1486,15 +1501,9 @@
layer = toRenderBoxModelObject(renderer)->layer();
}
- if (renderer->hasTransform() && renderer->style()->hasPerspective())
- return "perspective";
+ if (requiresCompositingForTransform(renderer))
+ return "3D transform";
- if (renderer->hasTransform() && (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D))
- return "preserve-3d";
-
- if (renderer->hasTransform())
- return "transform";
-
if (requiresCompositingForVideo(renderer))
return "video";
@@ -1523,9 +1532,35 @@
return "position: fixed";
// This includes layers made composited by requiresCompositingWhenDescendantsAreCompositing().
- if (layer->mustOverlapCompositedLayers())
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForOverlap)
return "overlap/stacking";
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForBackgroundLayer)
+ return "negative z-index children";
+
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForGraphicalEffect) {
+ if (layer->transform())
+ return "transform with composited descendants";
+
+ if (renderer->isTransparent())
+ return "opacity with composited descendants";
+
+ if (renderer->hasMask())
+ return "mask with composited descendants";
+
+ if (renderer->hasReflection())
+ return "reflection with composited descendants";
+
+ if (renderer->hasFilter())
+ return "filter with composited descendants";
+ }
+
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForPerspective)
+ return "perspective";
+
+ if (layer->indirectCompositingReason() == RenderLayer::IndirectCompositingForPreserve3D)
+ return "preserve-3d";
+
if (inCompositingMode() && layer->isRootLayer())
return "root";
@@ -1593,7 +1628,7 @@
RenderStyle* style = renderer->style();
// Note that we ask the renderer if it has a transform, because the style may have transforms,
// but the renderer may be an inline that doesn't suppport them.
- return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
+ return renderer->hasTransform() && style->transform().has3DOperation();
}
bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
@@ -1701,11 +1736,35 @@
return false;
}
-bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const
+bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
{
- return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter();
+ RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
+
+ // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
+ // via compositing so that they also apply to those composited descdendants.
+ if (hasCompositedDescendants && (layer->transform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection() || renderer->hasFilter())) {
+ reason = RenderLayer::IndirectCompositingForGraphicalEffect;
+ return true;
+ }
+
+ // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
+ // will be affected by the preserve-3d or perspective.
+ if (has3DTransformedDescendants) {
+ if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D) {
+ reason = RenderLayer::IndirectCompositingForPreserve3D;
+ return true;
+ }
+
+ if (renderer->style()->hasPerspective()) {
+ reason = RenderLayer::IndirectCompositingForPerspective;
+ return true;
+ }
+ }
+
+ reason = RenderLayer::NoIndirectCompositingReason;
+ return false;
}
-
+
bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
{
#if ENABLE(CSS_FILTERS)
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (119528 => 119529)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h 2012-06-05 21:56:24 UTC (rev 119528)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h 2012-06-05 22:18:31 UTC (rev 119529)
@@ -246,7 +246,7 @@
void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
// Returns true if any layer's compositing changed
- void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);
+ void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged, bool& descendantHas3DTransform);
// Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
void rebuildCompositingLayerTree(RenderLayer*, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth);
@@ -286,10 +286,10 @@
bool requiresCompositingForCanvas(RenderObject*) const;
bool requiresCompositingForPlugin(RenderObject*) const;
bool requiresCompositingForFrame(RenderObject*) const;
- bool requiresCompositingWhenDescendantsAreCompositing(RenderObject*) const;
bool requiresCompositingForFilters(RenderObject*) const;
bool requiresCompositingForScrollableFrame() const;
bool requiresCompositingForPosition(RenderObject*, const RenderLayer*) const;
+ bool requiresCompositingForIndirectReason(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
bool requiresScrollLayer(RootLayerAttachment) const;
bool requiresHorizontalScrollbarLayer() const;
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
