Title: [166634] trunk
Revision
166634
Author
[email protected]
Date
2014-04-02 00:30:52 -0700 (Wed, 02 Apr 2014)

Log Message

[CSS Blending] Compositing requirements for blending are not computed correctly
https://bugs.webkit.org/show_bug.cgi?id=130664

Patch by Ion Rosca <[email protected]> on 2014-04-02
Reviewed by Dean Jackson.

Source/WebCore:

Tests: css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html
       css3/compositing/blend-mode-with-accelerated-sibling.html

Compositing requirements for blending: if a layer having blend mode
other than normal is composited for any reason, its closest stacking
context ancestor should be composited as well.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
* rendering/RenderLayer.h: added a new field,
m_hasUnisolatedCompositedBlendingDescendants, which is true if the layer
has composited blending descendants not isolated by any stacking context child;
added a new method: isolatesCompositedBlending(), which is true if we should
accelerate that layer in order to perform isolation correctly.

* rendering/RenderLayerCompositor.cpp:
(WebCore::CompositingState::CompositingState): m_subtreeHasBlending was renamed
m_hasUnisolatedCompositedBlendingDescendants in order to be more self-explanatory.
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
computes the isolation requirements for composited blending by
(re)setting RenderLayer::m_hasUnisolatedCompositedBlendingDescendants flag.

(WebCore::RenderLayerCompositor::reasonsForCompositing):
fixed the reason of compositing: isolation instead of blending.

(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason):
* rendering/RenderLayerCompositor.h:

LayoutTests:

* css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts-expected.txt: Added.
* css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html: Added.
* css3/compositing/blend-mode-with-accelerated-sibling-expected.txt: Added.
* css3/compositing/blend-mode-with-accelerated-sibling.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (166633 => 166634)


--- trunk/LayoutTests/ChangeLog	2014-04-02 07:05:14 UTC (rev 166633)
+++ trunk/LayoutTests/ChangeLog	2014-04-02 07:30:52 UTC (rev 166634)
@@ -1,3 +1,15 @@
+2014-04-02  Ion Rosca  <[email protected]>
+
+        [CSS Blending] Compositing requirements for blending are not computed correctly
+        https://bugs.webkit.org/show_bug.cgi?id=130664
+
+        Reviewed by Dean Jackson.
+
+        * css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts-expected.txt: Added.
+        * css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html: Added.
+        * css3/compositing/blend-mode-with-accelerated-sibling-expected.txt: Added.
+        * css3/compositing/blend-mode-with-accelerated-sibling.html: Added.
+
 2014-04-01  Mihnea Ovidenie  <[email protected]>
 
         [CSSRegions] Displaying region's children in another region not supported

Added: trunk/LayoutTests/css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts-expected.txt (0 => 166634)


--- trunk/LayoutTests/css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts-expected.txt	2014-04-02 07:30:52 UTC (rev 166634)
@@ -0,0 +1,23 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 784.00 10.00)
+          (children 1
+            (GraphicsLayer
+              (bounds 10.00 10.00)
+              (blendMode multiply)
+              (contentsOpaque 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html (0 => 166634)


--- trunk/LayoutTests/css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html	                        (rev 0)
+++ trunk/LayoutTests/css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html	2014-04-02 07:30:52 UTC (rev 166634)
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<!-- This test will check that only the direct parent of blending element gets accelerated -->
+<style>
+    .accelerated {
+        -webkit-transform: rotateX(0deg);
+    }
+    .blended {
+        -webkit-mix-blend-mode: multiply;
+    }
+    .child {
+        width: 10px;
+        height: 10px;
+        background-color: green;
+    }
+    .parent {
+        -webkit-isolation: isolate;
+    }
+</style>
+
+<div class="parent">
+    <div class="parent">
+        <div class="accelerated blended child"></div>
+    </div>
+</div>
+<pre id="layerTree"></pre>
+<script>
+    if (window.testRunner)
+        window.testRunner.dumpAsText();
+
+    var text = document.getElementById("layerTree");
+    text.innerHTML = window.internals.layerTreeAsText(document);
+</script>

Added: trunk/LayoutTests/css3/compositing/blend-mode-with-accelerated-sibling-expected.txt (0 => 166634)


--- trunk/LayoutTests/css3/compositing/blend-mode-with-accelerated-sibling-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/css3/compositing/blend-mode-with-accelerated-sibling-expected.txt	2014-04-02 07:30:52 UTC (rev 166634)
@@ -0,0 +1,17 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 10.00 10.00)
+          (contentsOpaque 1)
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/css3/compositing/blend-mode-with-accelerated-sibling.html (0 => 166634)


--- trunk/LayoutTests/css3/compositing/blend-mode-with-accelerated-sibling.html	                        (rev 0)
+++ trunk/LayoutTests/css3/compositing/blend-mode-with-accelerated-sibling.html	2014-04-02 07:30:52 UTC (rev 166634)
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<!-- This test will check that parent is not accelerated when it has non-accelerated blended children -->
+<style>
+    .accelerated {
+        -webkit-transform: rotateX(0deg);
+    }
+    .blended {
+        -webkit-mix-blend-mode: multiply;
+    }
+    .child {
+        width: 10px;
+        height: 10px;
+        background-color: green;
+    }
+    .parent {
+        -webkit-isolation: isolate;
+    }
+</style>
+
+<div class="parent">
+    <div class="accelerated child"></div>
+    <div class="blended child"></div>
+</div>
+<pre id="layerTree"></pre>
+<script>
+    if (window.testRunner)
+        window.testRunner.dumpAsText();
+
+    var text = document.getElementById("layerTree");
+    text.innerHTML = window.internals.layerTreeAsText(document);
+</script>

Modified: trunk/Source/WebCore/ChangeLog (166633 => 166634)


--- trunk/Source/WebCore/ChangeLog	2014-04-02 07:05:14 UTC (rev 166633)
+++ trunk/Source/WebCore/ChangeLog	2014-04-02 07:30:52 UTC (rev 166634)
@@ -1,3 +1,38 @@
+2014-04-02  Ion Rosca  <[email protected]>
+
+        [CSS Blending] Compositing requirements for blending are not computed correctly
+        https://bugs.webkit.org/show_bug.cgi?id=130664
+
+        Reviewed by Dean Jackson.
+
+        Tests: css3/compositing/blend-mode-accelerated-with-multiple-stacking-contexts.html
+               css3/compositing/blend-mode-with-accelerated-sibling.html
+
+        Compositing requirements for blending: if a layer having blend mode
+        other than normal is composited for any reason, its closest stacking
+        context ancestor should be composited as well.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        * rendering/RenderLayer.h: added a new field,
+        m_hasUnisolatedCompositedBlendingDescendants, which is true if the layer
+        has composited blending descendants not isolated by any stacking context child;
+        added a new method: isolatesCompositedBlending(), which is true if we should
+        accelerate that layer in order to perform isolation correctly.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::CompositingState::CompositingState): m_subtreeHasBlending was renamed
+        m_hasUnisolatedCompositedBlendingDescendants in order to be more self-explanatory.
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        computes the isolation requirements for composited blending by
+        (re)setting RenderLayer::m_hasUnisolatedCompositedBlendingDescendants flag.
+
+        (WebCore::RenderLayerCompositor::reasonsForCompositing):
+        fixed the reason of compositing: isolation instead of blending.
+
+        (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason):
+        * rendering/RenderLayerCompositor.h:
+
 2014-04-02  Frédéric Wang  <[email protected]>
 
         Operator stretching: expose a math data API

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (166633 => 166634)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-04-02 07:05:14 UTC (rev 166633)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-04-02 07:30:52 UTC (rev 166634)
@@ -186,6 +186,7 @@
 #endif
 #if ENABLE(CSS_COMPOSITING)
     , m_blendMode(BlendModeNormal)
+    , m_hasUnisolatedCompositedBlendingDescendants(false)
     , m_hasBlendedElementInChildStackingContext(false)
     , m_hasBlendedElementInChildStackingContextStatusDirty(false)
 #endif

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (166633 => 166634)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2014-04-02 07:05:14 UTC (rev 166633)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2014-04-02 07:30:52 UTC (rev 166634)
@@ -790,6 +790,23 @@
     BlendMode blendMode() const { return m_blendMode; }
 #endif
 
+    bool isolatesCompositedBlending() const
+    {
+#if ENABLE(CSS_COMPOSITING)
+        return m_hasUnisolatedCompositedBlendingDescendants && isStackingContext();
+#else
+        return false;
+#endif
+    }
+
+#if ENABLE(CSS_COMPOSITING)
+    bool hasUnisolatedCompositedBlendingDescendants() const { return m_hasUnisolatedCompositedBlendingDescendants; }
+    void setHasUnisolatedCompositedBlendingDescendants(bool hasUnisolatedCompositedBlendingDescendants)
+    {
+        m_hasUnisolatedCompositedBlendingDescendants = hasUnisolatedCompositedBlendingDescendants;
+    }
+#endif
+
     bool isolatesBlending() const
     {
 #if ENABLE(CSS_COMPOSITING)
@@ -1291,6 +1308,7 @@
 
 #if ENABLE(CSS_COMPOSITING)
     BlendMode m_blendMode : 5;
+    bool m_hasUnisolatedCompositedBlendingDescendants : 1;
     bool m_hasBlendedElementInChildStackingContext : 1;
     bool m_hasBlendedElementInChildStackingContextStatusDirty : 1;
 #endif

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (166633 => 166634)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-04-02 07:05:14 UTC (rev 166633)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-04-02 07:30:52 UTC (rev 166634)
@@ -195,7 +195,9 @@
         : m_compositingAncestor(compAncestor)
         , m_subtreeIsCompositing(false)
         , m_testingOverlap(testOverlap)
-        , m_subtreeHasBlending(false)
+#if ENABLE(CSS_COMPOSITING)
+        , m_hasUnisolatedCompositedBlendingDescendants(false)
+#endif
 #ifndef NDEBUG
         , m_depth(0)
 #endif
@@ -206,7 +208,9 @@
         : m_compositingAncestor(other.m_compositingAncestor)
         , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
         , m_testingOverlap(other.m_testingOverlap)
-        , m_subtreeHasBlending(other.m_subtreeHasBlending)
+#if ENABLE(CSS_COMPOSITING)
+        , m_hasUnisolatedCompositedBlendingDescendants(other.m_hasUnisolatedCompositedBlendingDescendants)
+#endif
 #ifndef NDEBUG
         , m_depth(other.m_depth + 1)
 #endif
@@ -216,7 +220,9 @@
     RenderLayer* m_compositingAncestor;
     bool m_subtreeIsCompositing;
     bool m_testingOverlap;
-    bool m_subtreeHasBlending;
+#if ENABLE(CSS_COMPOSITING)
+    bool m_hasUnisolatedCompositedBlendingDescendants;
+#endif
 #ifndef NDEBUG
     int m_depth;
 #endif
@@ -1099,6 +1105,9 @@
     // ancestor with m_subtreeIsCompositing set to false.
     CompositingState childState(compositingState);
     childState.m_subtreeIsCompositing = false;
+#if ENABLE(CSS_COMPOSITING)
+    childState.m_hasUnisolatedCompositedBlendingDescendants = false;
+#endif
 
     bool willBeComposited = needsToBeComposited(layer);
     if (willBeComposited) {
@@ -1172,10 +1181,6 @@
             willBeComposited = true;
     }
     
-    // If the layer composited for other reasons than blending, it is no longer needed to keep track of whether a child was blended.
-    if (compositingState.m_subtreeHasBlending && !layer.hasBlendMode())
-        compositingState.m_subtreeHasBlending = false;
-
     ASSERT(willBeComposited == needsToBeComposited(layer));
 
     // All layers (even ones that aren't being composited) need to get added to
@@ -1184,13 +1189,13 @@
     if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
         addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
 
-    if (childState.m_subtreeHasBlending || layer.hasBlendMode())
-        compositingState.m_subtreeHasBlending = true;
-
+#if ENABLE(CSS_COMPOSITING)
+    layer.setHasUnisolatedCompositedBlendingDescendants(childState.m_hasUnisolatedCompositedBlendingDescendants);
+#endif
     // 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, compositingState.m_subtreeHasBlending, anyDescendantHas3DTransform, indirectCompositingReason)) {
+        && requiresCompositingForIndirectReason(layer.renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
         layer.setIndirectCompositingReason(indirectCompositingReason);
         childState.m_compositingAncestor = &layer;
         if (overlapMap) {
@@ -1234,6 +1239,12 @@
          }
     }
 
+#if ENABLE(CSS_COMPOSITING)
+    if ((willBeComposited && layer.hasBlendMode())
+        || (layer.hasUnisolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
+        compositingState.m_hasUnisolatedCompositedBlendingDescendants = true;
+#endif
+
     if (overlapMap && childState.m_compositingAncestor == &layer && !layer.isRootLayer())
         overlapMap->popCompositingContainer();
 
@@ -2114,8 +2125,10 @@
         if (renderer->hasFilter())
             reasons |= CompositingReasonFilterWithCompositedDescendants;
 
-        if (renderer->hasBlendMode())
+#if ENABLE(CSS_COMPOSITING)
+        if (layer.isolatesCompositedBlending())
             reasons |= CompositingReasonBlendingWithCompositedDescendants;
+#endif
 
     } else if (renderer->layer()->indirectCompositingReason() == RenderLayer::IndirectCompositingForPerspective)
         reasons |= CompositingReasonPerspective;
@@ -2379,13 +2392,13 @@
             || animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyWebkitTransform, activeAnimationState);
 }
 
-bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, bool hasCompositedDescendants, bool hasBlendedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
+bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
 {
     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 descendants.
-    if (hasCompositedDescendants && (hasBlendedDescendants || layer.transform() || renderer.createsGroup() || renderer.hasReflection() || renderer.isRenderNamedFlowFragmentContainer())) {
+    if (hasCompositedDescendants && (layer.isolatesCompositedBlending() || layer.transform() || renderer.createsGroup() || renderer.hasReflection() || renderer.isRenderNamedFlowFragmentContainer())) {
         reason = RenderLayer::IndirectCompositingForGraphicalEffect;
         return true;
     }

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (166633 => 166634)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-04-02 07:05:14 UTC (rev 166633)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-04-02 07:30:52 UTC (rev 166634)
@@ -396,7 +396,7 @@
     bool requiresCompositingForScrollableFrame() const;
     bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RenderLayer::ViewportConstrainedNotCompositedReason* = 0) const;
     bool requiresCompositingForOverflowScrolling(const RenderLayer&) const;
-    bool requiresCompositingForIndirectReason(RenderLayerModelObject&, bool hasCompositedDescendants, bool hasBlendedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
+    bool requiresCompositingForIndirectReason(RenderLayerModelObject&, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
 
 #if PLATFORM(IOS)
     bool requiresCompositingForScrolling(const RenderLayer&) const;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to