[CSS Blending] Isolation descendant dependent flags are not updated correctly
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Apr 2014 08:42:53 +0000 (08:42 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Apr 2014 08:42:53 +0000 (08:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=130892

Patch by Ion Rosca <rosca@adobe.com> on 2014-04-17
Reviewed by Dean Jackson.

Source/WebCore:
The isolation descendant dependent flag (m_hasUnisolatedBlendingDescendants)
will help us to determine if a layer should isolate blending descendants or not.
The m_hasUnisolatedBlendingDescendants flag should be set for layers that have blending descendant layers
not isolated by descendant stacking contexts.
An element isolatesBlending() if it has this flag set and creates stacking context.

Tests: css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html
       css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html
       css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html
       css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html
       css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html
       css3/compositing/blend-mode-isolation-flags-turn-off-blending.html
       css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html
       css3/compositing/blend-mode-isolation-flags-turn-on-blending.html
       css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateBlendMode):
(WebCore::RenderLayer::updateAncestorChainHasBlendingDescendants):
    When a layer has blending and it hasn't had it before, we set the isolation
flag for all its ancestors up to the first layer creating stacking context.
I removed the isComposited() check here. Isolation flags should be correct regardless
of compositing state. Moreover, if this method is called from styleChanged(),
the compositing state might not be accurate, it's going to be recalculated afterwards.
(WebCore::RenderLayer::dirtyAncestorChainHasBlendingDescendants):
    When a layer doesn't have blending, but it used to have it before, we mark
the isolation flag as dirty for all its ancestors up to the first layer
creating stacking context. The isolation flags will be recalculated by
RenderLayer::updateDescendantDependentFlags.
(WebCore::RenderLayer::updateDescendantDependentFlags):
    Evaluates if the layer has unisolated blending descendants by traversing
the layer subtree.
(WebCore::RenderLayer::addChild):
    When adding a subtree that has blending or has some unisolated descendants,
we set the flag for all the ancestors, up to the stacking context layer.
(WebCore::RenderLayer::removeChild):
    When removing a subtree that had blending or had some unisolated descendants,
we dirty the flag so that it could be reevaluated.
(WebCore::RenderLayer::calculateClipRects):
(WebCore::RenderLayer::updateTransform):
* rendering/RenderLayer.h:
    Rename m_hasBlendedElementInChildStackingContext => m_hasUnisolatedBlendingDescendants
and m_hasBlendedElementInChildStackingContextStatusDirty => m_hasUnisolatedBlendingDescendantsStatusDirty,
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
    Add an assert to make sure that if m_hasUnisolatedCompositedBlendingDescendants is true,
then m_hasUnisolatedBlendingDescendants is true as well.

LayoutTests:
* css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html: Added.
* css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html: Added.
* css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html: Added.
* css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html: Added.
* css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html: Added.
* css3/compositing/blend-mode-isolation-flags-turn-off-blending.html: Added.
* css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html: Added.
* css3/compositing/blend-mode-isolation-flags-turn-on-blending.html: Added.
* css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html: Added.
* platform/mac/css3/compositing/blend-mode-background-expected.txt:
* platform/mac/css3/compositing/blend-mode-isolated-group-1-expected.txt:
* platform/mac/css3/compositing/blend-mode-isolated-group-2-expected.txt:
* platform/mac/css3/compositing/blend-mode-isolated-group-3-expected.txt:
* platform/mac/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-blending-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context-expected.txt: Added.
* platform/mac/css3/compositing/blend-mode-layers-expected.txt:
* platform/mac/css3/compositing/blend-mode-reflection-expected.txt:
* platform/mac/css3/compositing/blend-mode-simple-composited-expected.txt:
* platform/mac/css3/compositing/blend-mode-simple-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@167424 268f45cc-cd09-0410-ab3c-d52691b4dbfc

31 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-blending.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-on-blending.html [new file with mode: 0644]
LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-background-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-isolated-group-1-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-isolated-group-2-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-isolated-group-3-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-blending-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/css3/compositing/blend-mode-layers-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-reflection-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-simple-composited-expected.txt
LayoutTests/platform/mac/css3/compositing/blend-mode-simple-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerCompositor.cpp

index 0dbc383..a9da385 100644 (file)
@@ -1,3 +1,37 @@
+2014-04-17  Ion Rosca  <rosca@adobe.com>
+
+        [CSS Blending] Isolation descendant dependent flags are not updated correctly
+        https://bugs.webkit.org/show_bug.cgi?id=130892
+
+        Reviewed by Dean Jackson.
+
+        * css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-turn-off-blending.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-turn-on-blending.html: Added.
+        * css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html: Added.
+        * platform/mac/css3/compositing/blend-mode-background-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-isolated-group-1-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-isolated-group-2-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-isolated-group-3-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-blending-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context-expected.txt: Added.
+        * platform/mac/css3/compositing/blend-mode-layers-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-reflection-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-simple-composited-expected.txt:
+        * platform/mac/css3/compositing/blend-mode-simple-expected.txt:
+
 2014-04-16  Brian J. Burg  <burg@cs.washington.edu>
 
         Web Replay: memoize fallback time values for document.lastModified
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html
new file mode 100644 (file)
index 0000000..8481d86
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed when we append a subtree
+          having blending elements. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+
+            .leaf {
+                background-color: #ff00ff;
+                left:-25px;
+            }
+
+            .append-root {
+                background-color: #ffff44;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div id="target" style="background-color: #ffff00; left: 50px;"></div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var blendingElement = document.createElement("div");
+                blendingElement.className = "blending leaf";
+
+                var toAppend = document.createElement("div");
+                toAppend.className = "append-root";
+                toAppend.appendChild(blendingElement);
+
+                var target = document.getElementById("target");
+                target.appendChild(toAppend);
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html
new file mode 100644 (file)
index 0000000..f7936b3
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed when we append a subtree
+            having blending elements and the root of this subtree creates a stacking context. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+
+            .leaf {
+                background-color: #ff00ff;
+                left:-25px;
+            }
+
+            .append-root {
+                background-color: #ffff44;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div id="target" style="background-color: #ffff00; left: 50px;"></div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var blendingElement = document.createElement("div");
+                blendingElement.className = "blending leaf";
+
+                var toAppend = document.createElement("div");
+                toAppend.appendChild(blendingElement);
+                toAppend.className = "stacking-context append-root";
+
+                var target = document.getElementById("target");
+                target.appendChild(toAppend);
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html
new file mode 100644 (file)
index 0000000..c43b5cd
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed when we remove a subtree
+            having blending elements. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+
+            .leaf {
+                background-color: #ff00ff;
+                left:-25px;
+            }
+
+            .append-root {
+                background-color: #ffff44;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div style="background-color: #ffff00; left: 50px;">
+                <div id="toremove" class="append-root">
+                    <div class="blending leaf"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var toremove = document.getElementById("toremove");
+                toremove.parentNode.removeChild(toremove);
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html
new file mode 100644 (file)
index 0000000..d5d0fc6
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed when we remove a subtree
+            having blending elements and the root of this subtree creates a stacking context. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+
+            .leaf {
+                background-color: #ff00ff;
+                left:-25px;
+            }
+
+            .append-root {
+                background-color: #ffff44;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div style="background-color: #ffff00; left: 50px;">
+                <div id="toremove" class="stacking-context append-root">
+                    <div class="blending leaf"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var toremove = document.getElementById("toremove");
+                toremove.parentNode.removeChild(toremove);
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html
new file mode 100644 (file)
index 0000000..ef31b91
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is on after removing mix-blend-mode
+            from an element if the isolating element has other blending descendants. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00; top: 50px;">
+            <div class="stacking-context" style="background-color: #ffff00; left: 50px;">
+                <div>
+                    <div class="blending" style="background-color: #ff00ff;left:-25px; top: -50px;"></div>
+                </div>
+                <div>
+                    <div id="target" class="blending" style="background-color: #ff00ff;left:-25px; top: -50px;"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var target = document.getElementById("target");
+                target.className = "";
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-blending.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-blending.html
new file mode 100644 (file)
index 0000000..ea0d338
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly removed when we remove
+            the mix-blend-mode property from its descendants. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div id="target" class="blending stacking-context" style="background-color: #ffff00; left: 50px;">
+                <div>
+                    <div class="blending" style="background-color: #ff00ff;left:-25px;"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var target = document.getElementById("target");
+                target.className = "stacking-context";
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html
new file mode 100644 (file)
index 0000000..855a11b
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed when we remove
+            the stacking context status from the isolating element. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div id="target" class="stacking-context" style="background-color: #ffff00; left: 50px;">
+                <div>
+                    <div class="blending" style="background-color: #ff00ff; left:-25px;"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var target = document.getElementById("target");
+                target.className = "";
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-on-blending.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-on-blending.html
new file mode 100644 (file)
index 0000000..6fede42
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed
+        when set mix-blend-mode to an element. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+            <div id="target" class="stacking-context" style="background-color: #ffff00; left: 50px;">
+                <div>
+                    <div class="blending" style="background-color: #ff00ff; left:-25px;"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+               var target = document.getElementById("target");
+               target.className = "blending stacking-context";
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
diff --git a/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html b/LayoutTests/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html
new file mode 100644 (file)
index 0000000..17f03fc
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <!-- This test will check if the isolation flag is properly computed
+        when we set another element to be the isolating stacking context. -->
+        <style>
+            div {
+                width: 100px;
+                height: 100px;
+                /* This forces render layers, avoiding normal flow only issues */
+                position: relative;
+            }
+
+            .stacking-context {
+                -webkit-isolation: isolate;
+                isolation: isolate;
+            }
+
+            .blending {
+                -webkit-mix-blend-mode: difference;
+                mix-blend-mode: difference;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="stacking-context" style="background-color: #00ff00;">
+           <div id="target" class="" style="background-color: #ffff00; left: 50px;">
+                <div>
+                    <div class="blending" style="background-color: #ff00ff; left:-25px;"></div>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            if (window.testRunner)
+                window.testRunner.waitUntilDone();
+
+            function change() {
+                var target = document.getElementById("target");
+                target.className = "stacking-context";
+
+                if (window.testRunner)
+                    window.testRunner.notifyDone();
+            }
+
+            window.setTimeout("change()", 10);
+        </script>
+    </body>
+</html>
index 44f0542..b9dbd1d 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x100
+layer at (0,0) size 800x100 isolatesBlending
   RenderBlock {HTML} at (0,0) size 800x100
     RenderBody {BODY} at (8,20) size 784x60 [bgcolor=#0000FF]
 layer at (28,20) size 60x60 blendMode: difference
index 597f765..9d8a4ac 100644 (file)
@@ -7,15 +7,15 @@ layer at (28,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (20,20) size 60x60 [bgcolor=#EE82EE]
 layer at (48,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
-layer at (128,28) size 60x60
+layer at (128,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (120,20) size 60x60 [bgcolor=#EE82EE]
 layer at (148,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
-layer at (228,28) size 60x60
+layer at (228,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (220,20) size 60x60 [bgcolor=#EE82EE]
 layer at (248,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
-layer at (328,28) size 60x60
+layer at (328,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (320,20) size 60x60 [bgcolor=#EE82EE]
 layer at (348,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
index 597f765..9d8a4ac 100644 (file)
@@ -7,15 +7,15 @@ layer at (28,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (20,20) size 60x60 [bgcolor=#EE82EE]
 layer at (48,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
-layer at (128,28) size 60x60
+layer at (128,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (120,20) size 60x60 [bgcolor=#EE82EE]
 layer at (148,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
-layer at (228,28) size 60x60
+layer at (228,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (220,20) size 60x60 [bgcolor=#EE82EE]
 layer at (248,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
-layer at (328,28) size 60x60
+layer at (328,28) size 60x60 isolatesBlending
   RenderBlock (floating) {DIV} at (320,20) size 60x60 [bgcolor=#EE82EE]
 layer at (348,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
index 3cd549c..92300d8 100644 (file)
@@ -7,19 +7,19 @@ layer at (48,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
 layer at (68,68) size 60x60
   RenderBlock (positioned) {DIV} at (40,40) size 60x60 [bgcolor=#FFA500]
-layer at (128,28) size 60x60
+layer at (128,28) size 60x60 isolatesBlending
   RenderBlock (floating) zI: -1 {DIV} at (120,20) size 60x60 [bgcolor=#EE82EE]
 layer at (148,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
 layer at (168,68) size 60x60
   RenderBlock (positioned) {DIV} at (40,40) size 60x60 [bgcolor=#FFA500]
-layer at (228,28) size 60x60
+layer at (228,28) size 60x60 isolatesBlending
   RenderBlock (floating) zI: -1 {DIV} at (220,20) size 60x60 [bgcolor=#EE82EE]
 layer at (248,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
 layer at (268,68) size 60x60
   RenderBlock (positioned) {DIV} at (20,20) size 60x60 [bgcolor=#FFA500]
-layer at (328,28) size 60x60
+layer at (328,28) size 60x60 isolatesBlending
   RenderBlock (floating) zI: -1 {DIV} at (320,20) size 60x60 [bgcolor=#EE82EE]
 layer at (348,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
@@ -31,19 +31,19 @@ layer at (448,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
 layer at (468,68) size 60x60
   RenderBlock (positioned) {DIV} at (40,40) size 60x60 [bgcolor=#FFA500]
-layer at (528,28) size 60x60
+layer at (528,28) size 60x60 isolatesBlending
   RenderBlock (floating) zI: -1 {DIV} at (520,20) size 60x60 [bgcolor=#EE82EE]
 layer at (548,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
 layer at (568,68) size 60x60
   RenderBlock (positioned) {DIV} at (40,40) size 60x60 [bgcolor=#FFA500]
-layer at (628,28) size 60x60
+layer at (628,28) size 60x60 isolatesBlending
   RenderBlock (floating) zI: -1 {DIV} at (620,20) size 60x60 [bgcolor=#EE82EE]
 layer at (648,48) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
 layer at (668,68) size 60x60
   RenderBlock (positioned) {DIV} at (20,20) size 60x60 [bgcolor=#FFA500]
-layer at (28,128) size 60x60
+layer at (28,128) size 60x60 isolatesBlending
   RenderBlock (floating) zI: -1 {DIV} at (20,120) size 60x60 [bgcolor=#EE82EE]
 layer at (48,148) size 60x60 blendMode: multiply
   RenderBlock {DIV} at (20,20) size 60x60 [bgcolor=#008000]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending-expected.txt
new file mode 100644 (file)
index 0000000..df05058
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF44]
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending-expected.txt
new file mode 100644 (file)
index 0000000..4bab37b
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,8) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF44]
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending-expected.txt
new file mode 100644 (file)
index 0000000..f217f56
--- /dev/null
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending-expected.txt
new file mode 100644 (file)
index 0000000..f217f56
--- /dev/null
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-expected.txt
new file mode 100644 (file)
index 0000000..9ad2e12
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation-expected.txt
new file mode 100644 (file)
index 0000000..c566318
--- /dev/null
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,58) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,58) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,58) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
+layer at (58,158) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,100) size 100x100
+layer at (33,108) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context-expected.txt
new file mode 100644 (file)
index 0000000..e039fbd
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-blending-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-blending-expected.txt
new file mode 100644 (file)
index 0000000..fa5e70f
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100 isolatesBlending blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
diff --git a/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context-expected.txt b/LayoutTests/platform/mac/css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context-expected.txt
new file mode 100644 (file)
index 0000000..9ad2e12
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+layer at (8,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#00FF00]
+layer at (58,8) size 100x100 isolatesBlending
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FFFF00]
+layer at (58,8) size 100x100
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100
+layer at (33,8) size 100x100 blendMode: difference
+  RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF00FF]
index 36ce708..86cb300 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x366
+layer at (0,0) size 800x366 isolatesBlending
   RenderBlock {HTML} at (0,0) size 800x366
     RenderBody {BODY} at (8,16) size 784x0
       RenderBlock {UL} at (0,0) size 784x0
@@ -37,7 +37,7 @@ layer at (73,206) size 160x160 blendMode: multiply
   RenderBlock (relative positioned) {DIV} at (0,0) size 160x160
 layer at (53,216) size 80x150
   RenderBlock (relative positioned) {DIV} at (0,0) size 80x150 [bgcolor=#FFFF00]
-layer at (223,246) size 160x75
+layer at (223,246) size 160x75 isolatesBlending
   RenderBlock {DIV} at (0,50) size 160x75 [bgcolor=#00FFFF]
 layer at (243,206) size 160x160 blendMode: multiply
   RenderBlock (relative positioned) {DIV} at (0,0) size 160x160
index e5feeb6..9816d8f 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x286
+layer at (0,0) size 800x286 isolatesBlending
   RenderBlock {HTML} at (0,0) size 800x286
     RenderBody {BODY} at (8,16) size 784x0
       RenderBlock {UL} at (0,0) size 784x0
index 72dab61..3aab18d 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x576
+layer at (0,0) size 800x576 isolatesBlending
   RenderBlock {HTML} at (0,0) size 800x576
     RenderBody {BODY} at (8,16) size 784x0
       RenderBlock {UL} at (0,0) size 784x0
index f50182e..af4b6e6 100644 (file)
@@ -1,6 +1,6 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x576
+layer at (0,0) size 800x576 isolatesBlending
   RenderBlock {HTML} at (0,0) size 800x576
     RenderBody {BODY} at (8,16) size 784x0
       RenderBlock {UL} at (0,0) size 784x0
index 1f93344..9d7596e 100644 (file)
@@ -1,3 +1,59 @@
+2014-04-17  Ion Rosca  <rosca@adobe.com>
+
+        [CSS Blending] Isolation descendant dependent flags are not updated correctly
+        https://bugs.webkit.org/show_bug.cgi?id=130892
+
+        Reviewed by Dean Jackson.
+
+        The isolation descendant dependent flag (m_hasUnisolatedBlendingDescendants)
+        will help us to determine if a layer should isolate blending descendants or not.
+        The m_hasUnisolatedBlendingDescendants flag should be set for layers that have blending descendant layers
+        not isolated by descendant stacking contexts.
+        An element isolatesBlending() if it has this flag set and creates stacking context.
+
+        Tests: css3/compositing/blend-mode-isolation-flags-append-non-stacking-context-blending.html
+               css3/compositing/blend-mode-isolation-flags-append-stacking-context-blending.html
+               css3/compositing/blend-mode-isolation-flags-remove-non-stacking-context-blending.html
+               css3/compositing/blend-mode-isolation-flags-remove-stacking-context-blending.html
+               css3/compositing/blend-mode-isolation-flags-turn-off-blending-no-isolation.html
+               css3/compositing/blend-mode-isolation-flags-turn-off-blending.html
+               css3/compositing/blend-mode-isolation-flags-turn-off-stacking-context.html
+               css3/compositing/blend-mode-isolation-flags-turn-on-blending.html
+               css3/compositing/blend-mode-isolation-flags-turn-on-stacking-context.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        (WebCore::RenderLayer::updateBlendMode):
+        (WebCore::RenderLayer::updateAncestorChainHasBlendingDescendants):
+            When a layer has blending and it hasn't had it before, we set the isolation
+        flag for all its ancestors up to the first layer creating stacking context.
+        I removed the isComposited() check here. Isolation flags should be correct regardless
+        of compositing state. Moreover, if this method is called from styleChanged(),
+        the compositing state might not be accurate, it's going to be recalculated afterwards.  
+        (WebCore::RenderLayer::dirtyAncestorChainHasBlendingDescendants):
+            When a layer doesn't have blending, but it used to have it before, we mark
+        the isolation flag as dirty for all its ancestors up to the first layer
+        creating stacking context. The isolation flags will be recalculated by
+        RenderLayer::updateDescendantDependentFlags.
+        (WebCore::RenderLayer::updateDescendantDependentFlags):
+            Evaluates if the layer has unisolated blending descendants by traversing
+        the layer subtree.
+        (WebCore::RenderLayer::addChild):
+            When adding a subtree that has blending or has some unisolated descendants,
+        we set the flag for all the ancestors, up to the stacking context layer.
+        (WebCore::RenderLayer::removeChild):
+            When removing a subtree that had blending or had some unisolated descendants,
+        we dirty the flag so that it could be reevaluated.
+        (WebCore::RenderLayer::calculateClipRects):
+        (WebCore::RenderLayer::updateTransform):
+        * rendering/RenderLayer.h:
+            Rename m_hasBlendedElementInChildStackingContext => m_hasUnisolatedBlendingDescendants
+        and m_hasBlendedElementInChildStackingContextStatusDirty => m_hasUnisolatedBlendingDescendantsStatusDirty,
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+            Add an assert to make sure that if m_hasUnisolatedCompositedBlendingDescendants is true,
+        then m_hasUnisolatedBlendingDescendants is true as well.
+
 2014-04-17  Tim Horton  <timothy_horton@apple.com>
 
         Uninline blend(Color, Color) to get AnimationUtilities out of Color.h
index c20d76e..f8a62fe 100644 (file)
@@ -187,8 +187,8 @@ RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
 #if ENABLE(CSS_COMPOSITING)
     , m_blendMode(BlendModeNormal)
     , m_hasUnisolatedCompositedBlendingDescendants(false)
-    , m_hasBlendedElementInChildStackingContext(false)
-    , m_hasBlendedElementInChildStackingContextStatusDirty(false)
+    , m_hasUnisolatedBlendingDescendants(false)
+    , m_hasUnisolatedBlendingDescendantsStatusDirty(false)
 #endif
     , m_renderer(rendererLayerModelObject)
     , m_parent(0)
@@ -808,11 +808,11 @@ void RenderLayer::positionNewlyCreatedOverflowControls()
 void RenderLayer::updateBlendMode()
 {
     bool hadBlendMode = m_blendMode != BlendModeNormal;
-    if (hadBlendMode != hasBlendMode()) {
+    if (parent() && hadBlendMode != hasBlendMode()) {
         if (hasBlendMode())
-            updateNonCompositedParentStackingContextHasBlendedChild(true);
+            parent()->updateAncestorChainHasBlendingDescendants();
         else
-            dirtyAncestorParentStackingContextHasBlendedElement();
+            parent()->dirtyAncestorChainHasBlendingDescendants();
     }
 
     BlendMode newBlendMode = renderer().style().blendMode();
@@ -820,39 +820,31 @@ void RenderLayer::updateBlendMode()
         m_blendMode = newBlendMode;
 }
 
-void RenderLayer::updateNonCompositedParentStackingContextHasBlendedChild(bool hasBlendedChild)
+void RenderLayer::updateAncestorChainHasBlendingDescendants()
 {
-    if (isComposited())
-        return;
-
-    for (auto ancestor = parent(); ancestor && !ancestor->isComposited() && !ancestor->renderer().isRoot(); ancestor = ancestor->parent()) {
-        ancestor->m_hasBlendedElementInChildStackingContext = hasBlendedChild;
+    for (auto layer = this; layer; layer = layer->parent()) {
+        if (!layer->hasUnisolatedBlendingDescendantsStatusDirty() && layer->hasUnisolatedBlendingDescendants())
+            break;
+        layer->m_hasUnisolatedBlendingDescendants = true;
+        layer->m_hasUnisolatedBlendingDescendantsStatusDirty = false;
 
-        if (ancestor->isStackingContext())
+        if (layer->isStackingContext())
             break;
     }
 }
 
-void RenderLayer::dirtyAncestorParentStackingContextHasBlendedElement()
+void RenderLayer::dirtyAncestorChainHasBlendingDescendants()
 {
-    for (auto layer = this; layer && !layer->isComposited() && !layer->m_hasBlendedElementInChildStackingContextStatusDirty; layer = layer->parent()) {
-        layer->m_hasBlendedElementInChildStackingContextStatusDirty = true;
+    for (auto layer = this; layer; layer = layer->parent()) {
+        if (layer->hasUnisolatedBlendingDescendantsStatusDirty())
+            break;
+        
+        layer->m_hasUnisolatedBlendingDescendantsStatusDirty = true;
 
         if (layer->isStackingContext())
             break;
     }
 }
-
-bool RenderLayer::nonCompositedParentStackingContextHasBlendedChild() const
-{
-    for (auto ancestor = parent(); ancestor && !ancestor->isComposited() && !ancestor->renderer().isRoot(); ancestor = ancestor->parent()) {
-        if (ancestor->isStackingContext())
-            return ancestor->hasBlendedElementInChildStackingContext();
-    }
-
-    return false;
-}
-
 #endif
 
 void RenderLayer::updateTransform()
@@ -1097,11 +1089,13 @@ void RenderLayer::setAncestorChainHasVisibleDescendant()
 
 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks)
 {
-    if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty || hasBlendedElementInChildStackingContextStatusDirty()) {
+    if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty || hasUnisolatedBlendingDescendantsStatusDirty()) {
         m_hasVisibleDescendant = false;
         m_hasSelfPaintingLayerDescendant = false;
         m_hasOutOfFlowPositionedDescendant = false;
-        setHasBlendedElementInChildStackingContext(false);
+#if ENABLE(CSS_COMPOSITING)
+        m_hasUnisolatedBlendingDescendants = false;
+#endif
 
         HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
@@ -1121,14 +1115,20 @@ void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* o
             bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
             bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
             bool hasOutOfFlowPositionedDescendant = !childOutOfFlowDescendantContainingBlocks.isEmpty();
-            bool hasBlendedElementInChildStackingContext = child->hasBlendMode() || child->hasBlendedElementInChildStackingContext();
+#if ENABLE(CSS_COMPOSITING)
+            bool hasUnisolatedBlendingDescendants = child->hasBlendMode() || (child->hasUnisolatedBlendingDescendants() && !child->isolatesBlending());
 
+            m_hasUnisolatedBlendingDescendants |= hasUnisolatedBlendingDescendants;
+#endif
             m_hasVisibleDescendant |= hasVisibleDescendant;
             m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
             m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
-            setHasBlendedElementInChildStackingContext(this->hasBlendedElementInChildStackingContext() | hasBlendedElementInChildStackingContext);
 
-            if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_hasOutOfFlowPositionedDescendant && this->hasBlendedElementInChildStackingContext())
+            bool allFlagsSet = m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_hasOutOfFlowPositionedDescendant;
+#if ENABLE(CSS_COMPOSITING)
+            allFlagsSet &= m_hasUnisolatedBlendingDescendants;
+#endif
+            if (allFlagsSet)
                 break;
         }
 
@@ -1142,8 +1142,9 @@ void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* o
             updateNeedsCompositedScrolling();
 
         m_hasOutOfFlowPositionedDescendantDirty = false;
-
-        setHasBlendedElementInChildStackingContextStatusDirty(false);
+#if ENABLE(CSS_COMPOSITING)
+        m_hasUnisolatedBlendingDescendantsStatusDirty = false;
+#endif
     }
 
     if (m_visibleContentStatusDirty) {
@@ -1800,8 +1801,8 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
         setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer().containingBlock());
 
 #if ENABLE(CSS_COMPOSITING)
-    if (child->hasBlendMode() || (!child->isStackingContext() && child->hasBlendedElementInChildStackingContext()))
-        child->updateNonCompositedParentStackingContextHasBlendedChild(true);
+    if (child->hasBlendMode() || (child->hasUnisolatedBlendingDescendants() && !child->isolatesBlending()))
+        updateAncestorChainHasBlendingDescendants();
 #endif
 
     compositor().layerWasAdded(*this, *child);
@@ -1847,8 +1848,8 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
         dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
 
 #if ENABLE(CSS_COMPOSITING)
-    if (oldChild->hasBlendMode() || oldChild->isolatesBlending())
-        dirtyAncestorParentStackingContextHasBlendedElement();
+    if (oldChild->hasBlendMode() || (oldChild->hasUnisolatedBlendingDescendants() && !oldChild->isolatesBlending()))
+        dirtyAncestorChainHasBlendingDescendants();
 #endif
 
     return oldChild;
@@ -6429,8 +6430,17 @@ void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldS
             clearZOrderLists();
 
 #if ENABLE(CSS_COMPOSITING)
-            m_hasBlendedElementInChildStackingContext = isStackingContext ? nonCompositedParentStackingContextHasBlendedChild() : false;
-            dirtyAncestorParentStackingContextHasBlendedElement();
+        if (parent()) {
+            if (isStackingContext) {
+                if (!hasUnisolatedBlendingDescendantsStatusDirty() && hasUnisolatedBlendingDescendants())
+                    parent()->dirtyAncestorChainHasBlendingDescendants();
+            } else {
+                if (hasUnisolatedBlendingDescendantsStatusDirty())
+                    parent()->dirtyAncestorChainHasBlendingDescendants();
+                else if (hasUnisolatedBlendingDescendants())
+                    parent()->updateAncestorChainHasBlendingDescendants();
+            }
+        }
 #endif
 
         return;
index 38d9db1..c538652 100644 (file)
@@ -777,80 +777,30 @@ public:
     bool hasFilter() const { return false; }
 #endif
 
-    bool hasBlendMode() const
-    {
-#if ENABLE(CSS_COMPOSITING)
-        return renderer().hasBlendMode();
-#else
-        return false;
-#endif
-    }
-
 #if ENABLE(CSS_COMPOSITING)
+    bool hasBlendMode() const { return renderer().hasBlendMode(); }
     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 isolatesCompositedBlending() const { return m_hasUnisolatedCompositedBlendingDescendants && isStackingContext(); }
     bool hasUnisolatedCompositedBlendingDescendants() const { return m_hasUnisolatedCompositedBlendingDescendants; }
     void setHasUnisolatedCompositedBlendingDescendants(bool hasUnisolatedCompositedBlendingDescendants)
     {
         m_hasUnisolatedCompositedBlendingDescendants = hasUnisolatedCompositedBlendingDescendants;
     }
-#endif
-
-    bool isolatesBlending() const
-    {
-#if ENABLE(CSS_COMPOSITING)
-        return m_hasBlendedElementInChildStackingContext && isStackingContext();
-#else
-        return false;
-#endif
-    }
-
-    bool hasBlendedElementInChildStackingContext() const
-    {
-#if ENABLE(CSS_COMPOSITING)
-        return m_hasBlendedElementInChildStackingContext;
-#else
-        return false;
-#endif
-    }
-
-    void setHasBlendedElementInChildStackingContext(bool hasBlendedElementInChildStackingContext)
-    {
-#if ENABLE(CSS_COMPOSITING)
-        m_hasBlendedElementInChildStackingContext = hasBlendedElementInChildStackingContext;
-#else
-        UNUSED_PARAM(hasBlendedElementInChildStackingContext);
-#endif
-    }
 
-    bool hasBlendedElementInChildStackingContextStatusDirty() const
+    bool isolatesBlending() const { return hasUnisolatedBlendingDescendants() && isStackingContext(); }
+    bool hasUnisolatedBlendingDescendants() const
     {
-#if ENABLE(CSS_COMPOSITING)
-        return m_hasBlendedElementInChildStackingContextStatusDirty;
-#else
-        return false;
-#endif
+        ASSERT(!m_hasUnisolatedBlendingDescendantsStatusDirty);
+        return m_hasUnisolatedBlendingDescendants;
     }
-
-    void setHasBlendedElementInChildStackingContextStatusDirty(bool hasBlendedElementInChildStackingContextStatusDirty)
-    {
-#if ENABLE(CSS_COMPOSITING)
-        m_hasBlendedElementInChildStackingContextStatusDirty = hasBlendedElementInChildStackingContextStatusDirty;
+    bool hasUnisolatedBlendingDescendantsStatusDirty() const { return m_hasUnisolatedBlendingDescendantsStatusDirty; }
 #else
-        UNUSED_PARAM(hasBlendedElementInChildStackingContextStatusDirty);
+    bool hasBlendMode() const { return false; }
+    bool isolatesCompositedBlending() const { return false; }
+    bool isolatesBlending() const { return false; }
+    bool hasUnisolatedBlendingDescendantsStatusDirty() const { return false; }
 #endif
-    }
 
     bool isComposited() const { return m_backing != 0; }
     bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
@@ -1166,9 +1116,8 @@ private:
 #endif
 
 #if ENABLE(CSS_COMPOSITING)
-    void updateNonCompositedParentStackingContextHasBlendedChild(bool hasBlendedChild);
-    void dirtyAncestorParentStackingContextHasBlendedElement();
-    bool nonCompositedParentStackingContextHasBlendedChild() const;
+    void updateAncestorChainHasBlendingDescendants();
+    void dirtyAncestorChainHasBlendingDescendants();
 #endif
 
     void parentClipRects(const ClipRectsContext&, ClipRects&) const;
@@ -1310,8 +1259,8 @@ private:
 #if ENABLE(CSS_COMPOSITING)
     BlendMode m_blendMode : 5;
     bool m_hasUnisolatedCompositedBlendingDescendants : 1;
-    bool m_hasBlendedElementInChildStackingContext : 1;
-    bool m_hasBlendedElementInChildStackingContextStatusDirty : 1;
+    bool m_hasUnisolatedBlendingDescendants : 1;
+    bool m_hasUnisolatedBlendingDescendantsStatusDirty : 1;
 #endif
 
     RenderLayerModelObject& m_renderer;
index 9e5247c..b3bfe41 100644 (file)
@@ -1251,6 +1251,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
 
 #if ENABLE(CSS_COMPOSITING)
     layer.setHasUnisolatedCompositedBlendingDescendants(childState.m_hasUnisolatedCompositedBlendingDescendants);
+    ASSERT(!layer.hasUnisolatedCompositedBlendingDescendants() || layer.hasUnisolatedBlendingDescendants());
 #endif
     // Now check for reasons to become composited that depend on the state of descendant layers.
     RenderLayer::IndirectCompositingReason indirectCompositingReason;