Title: [169972] trunk
Revision
169972
Author
[email protected]
Date
2014-06-14 10:40:49 -0700 (Sat, 14 Jun 2014)

Log Message

Masks disappear when layers become tiled
https://bugs.webkit.org/show_bug.cgi?id=133892
<rdar://problem/17309793>

Reviewed by Tim Horton.

Source/WebCore:
There were several problems with tiled mask layers.

First, when a layer became tiled it failed to re-apply the platform layer
for its mask; fixed by adding MaskLayerChanged to the set of flags in
swapFromOrToTiledLayer().

Secondly, in CA, a mask layer's superlayer is the layer which is it masking,
so the if (oldLayer->superlayer())... code in swapFromOrToTiledLayer() would
erroneously try to swap out a sublayer on the superlayer with the mask.

Thirdly, the mask layer is updated after its host layer, but when the mask layer
become tiled, there was no code that updated the mask platform layer on its
host layer. Fix by:
    1. setting a bit on a layer to note that it's being used as a mask.
    2. setting the parent of such a layer to its host layer (mimicking CA)
    3. when the mask becomes tiled, dirtying the MaskLayerChanged bit on
       its parent and adding a clause to commitLayerChangesAfterSublayers()
       to update the mask layer.

Finally, ASSERTION FAILED: owningGraphicsLayer()->isCommittingChanges() would
fire because we failed to set the m_isCommittingChanges flag while committing
the mask layer. Fix by moving the TemporaryChange<bool> that sets this flag
into commitLayerChangesBeforeSublayers() and commitLayerChangesAfterSublayers().

Also used safe casts in more places in GraphicsLayerCA.

Tests: compositing/masks/become-tiled-mask.html
       compositing/masks/cease-tiled-mask.html
       compositing/masks/tiled-mask.html

* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::GraphicsLayer):
(WebCore::GraphicsLayer::removeFromParent):
(WebCore::GraphicsLayer::setMaskLayer):
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::setIsMaskLayer):
(WebCore::GraphicsLayer::isMaskLayer):
(WebCore::GraphicsLayer::setMaskLayer): Deleted.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::removeFromParent):
(WebCore::GraphicsLayerCA::setMaskLayer):
(WebCore::GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush):
(WebCore::GraphicsLayerCA::recursiveCommitChanges):
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
(WebCore::GraphicsLayerCA::commitLayerChangesAfterSublayers):
(WebCore::GraphicsLayerCA::updateSublayerList):
(WebCore::GraphicsLayerCA::ensureStructuralLayer):
(WebCore::GraphicsLayerCA::updateMaskLayer):
(WebCore::GraphicsLayerCA::replicatedLayerRoot):
(WebCore::GraphicsLayerCA::createFilterAnimationsFromKeyframes):
(WebCore::GraphicsLayerCA::swapFromOrToTiledLayer):
(WebCore::GraphicsLayerCA::propagateLayerChangeToReplicas):
(WebCore::GraphicsLayerCA::fetchCloneLayers):

LayoutTests:
Tests for masking as they go into and out of tiled mode.

* compositing/masks/become-tiled-mask-expected.html: Added.
* compositing/masks/become-tiled-mask.html: Added.
* compositing/masks/cease-tiled-mask-expected.html: Added.
* compositing/masks/cease-tiled-mask.html: Added.
* compositing/masks/tiled-mask-expected.html: Added.
* compositing/masks/tiled-mask.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (169971 => 169972)


--- trunk/LayoutTests/ChangeLog	2014-06-14 17:12:04 UTC (rev 169971)
+++ trunk/LayoutTests/ChangeLog	2014-06-14 17:40:49 UTC (rev 169972)
@@ -1,3 +1,20 @@
+2014-06-14  Simon Fraser  <[email protected]>
+
+        Masks disappear when layers become tiled
+        https://bugs.webkit.org/show_bug.cgi?id=133892
+        <rdar://problem/17309793>
+
+        Reviewed by Tim Horton.
+        
+        Tests for masking as they go into and out of tiled mode.
+
+        * compositing/masks/become-tiled-mask-expected.html: Added.
+        * compositing/masks/become-tiled-mask.html: Added.
+        * compositing/masks/cease-tiled-mask-expected.html: Added.
+        * compositing/masks/cease-tiled-mask.html: Added.
+        * compositing/masks/tiled-mask-expected.html: Added.
+        * compositing/masks/tiled-mask.html: Added.
+
 2014-06-14  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r169963.

Added: trunk/LayoutTests/compositing/masks/become-tiled-mask-expected.html (0 => 169972)


--- trunk/LayoutTests/compositing/masks/become-tiled-mask-expected.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/become-tiled-mask-expected.html	2014-06-14 17:40:49 UTC (rev 169972)
@@ -0,0 +1,37 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <style>
+    .container {
+        height: 300px;
+        width: 400px;
+        border: 2px solid black;
+        overflow: hidden;
+    }
+
+    .box {
+        height: 300px;
+        width: 2800px;
+        border: 1px solid black;
+        background-color: gray;
+    }
+
+    .composited {
+        -webkit-transform: translateZ(0);
+    }
+
+    .masked {
+        -webkit-mask-image: url(../resources/alpha-gradient.png);
+        -webkit-mask-repeat: repeat-x;
+    }
+  </style>
+</head>
+<body>
+
+    <div class="composited container">
+        <div id="box" class="composited masked box"></div> 
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/compositing/masks/become-tiled-mask.html (0 => 169972)


--- trunk/LayoutTests/compositing/masks/become-tiled-mask.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/become-tiled-mask.html	2014-06-14 17:40:49 UTC (rev 169972)
@@ -0,0 +1,56 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <style>
+    .container {
+        height: 300px;
+        width: 400px;
+        border: 2px solid black;
+        overflow: hidden;
+    }
+
+    .box {
+        height: 300px;
+        width: 410px;
+        border: 1px solid black;
+        background-color: gray;
+    }
+
+    .large.box {
+        width: 2800px;
+    }
+
+    .composited {
+        -webkit-transform: translateZ(0);
+    }
+
+    .masked {
+        -webkit-mask-image: url(../resources/alpha-gradient.png);
+        -webkit-mask-repeat: repeat-x;
+    }
+  </style>
+  <script>
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    function doTest()
+    {
+        window.setTimeout(function() {
+            document.getElementById('box').classList.add('large');
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
+    }
+
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+    <div class="composited container">
+        <div id="box" class="composited masked box"></div> 
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/compositing/masks/cease-tiled-mask-expected.html (0 => 169972)


--- trunk/LayoutTests/compositing/masks/cease-tiled-mask-expected.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/cease-tiled-mask-expected.html	2014-06-14 17:40:49 UTC (rev 169972)
@@ -0,0 +1,37 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <style>
+    .container {
+        height: 300px;
+        width: 400px;
+        border: 2px solid black;
+        overflow: hidden;
+    }
+
+    .box {
+        height: 300px;
+        width: 410px;
+        border: 1px solid black;
+        background-color: gray;
+    }
+
+    .composited {
+        -webkit-transform: translateZ(0);
+    }
+
+    .masked {
+        -webkit-mask-image: url(../resources/alpha-gradient.png);
+        -webkit-mask-repeat: repeat-x;
+    }
+  </style>
+</head>
+<body>
+
+    <div class="composited container">
+        <div id="box" class="composited masked box"></div> 
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/compositing/masks/cease-tiled-mask.html (0 => 169972)


--- trunk/LayoutTests/compositing/masks/cease-tiled-mask.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/cease-tiled-mask.html	2014-06-14 17:40:49 UTC (rev 169972)
@@ -0,0 +1,56 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <style>
+    .container {
+        height: 300px;
+        width: 400px;
+        border: 2px solid black;
+        overflow: hidden;
+    }
+
+    .box {
+        height: 300px;
+        width: 410px;
+        border: 1px solid black;
+        background-color: gray;
+    }
+
+    .large.box {
+        width: 2800px;
+    }
+
+    .composited {
+        -webkit-transform: translateZ(0);
+    }
+
+    .masked {
+        -webkit-mask-image: url(../resources/alpha-gradient.png);
+        -webkit-mask-repeat: repeat-x;
+    }
+  </style>
+  <script>
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    function doTest()
+    {
+        window.setTimeout(function() {
+            document.getElementById('box').classList.remove('large');
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
+    }
+
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+    <div class="composited container">
+        <div id="box" class="composited masked large box"></div> 
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/compositing/masks/tiled-mask-expected.html (0 => 169972)


--- trunk/LayoutTests/compositing/masks/tiled-mask-expected.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/tiled-mask-expected.html	2014-06-14 17:40:49 UTC (rev 169972)
@@ -0,0 +1,37 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <style>
+    .container {
+        height: 300px;
+        width: 400px;
+        border: 2px solid black;
+        overflow: hidden;
+    }
+
+    .box {
+        height: 300px;
+        width: 410px;
+        border: 1px solid black;
+        background-color: gray;
+    }
+
+    .composited {
+        -webkit-transform: translateZ(0);
+    }
+
+    .masked {
+        -webkit-mask-image: url(../resources/alpha-gradient.png);
+        -webkit-mask-repeat: repeat-x;
+    }
+  </style>
+</head>
+<body>
+
+    <div class="composited container">
+        <div class="composited masked box"></div> 
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/compositing/masks/tiled-mask.html (0 => 169972)


--- trunk/LayoutTests/compositing/masks/tiled-mask.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/tiled-mask.html	2014-06-14 17:40:49 UTC (rev 169972)
@@ -0,0 +1,37 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <style>
+    .container {
+        height: 300px;
+        width: 400px;
+        border: 2px solid black;
+        overflow: hidden;
+    }
+
+    .box {
+        height: 300px;
+        width: 2800px;
+        border: 1px solid black;
+        background-color: gray;
+    }
+
+    .composited {
+        -webkit-transform: translateZ(0);
+    }
+
+    .masked {
+        -webkit-mask-image: url(../resources/alpha-gradient.png);
+        -webkit-mask-repeat: repeat-x;
+    }
+  </style>
+</head>
+<body>
+
+    <div class="composited container">
+        <div class="composited masked box"></div> 
+    </div>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (169971 => 169972)


--- trunk/Source/WebCore/ChangeLog	2014-06-14 17:12:04 UTC (rev 169971)
+++ trunk/Source/WebCore/ChangeLog	2014-06-14 17:40:49 UTC (rev 169972)
@@ -1,3 +1,65 @@
+2014-06-14  Simon Fraser  <[email protected]>
+
+        Masks disappear when layers become tiled
+        https://bugs.webkit.org/show_bug.cgi?id=133892
+        <rdar://problem/17309793>
+
+        Reviewed by Tim Horton.
+        
+        There were several problems with tiled mask layers.
+        
+        First, when a layer became tiled it failed to re-apply the platform layer
+        for its mask; fixed by adding MaskLayerChanged to the set of flags in
+        swapFromOrToTiledLayer().
+        
+        Secondly, in CA, a mask layer's superlayer is the layer which is it masking,
+        so the if (oldLayer->superlayer())... code in swapFromOrToTiledLayer() would
+        erroneously try to swap out a sublayer on the superlayer with the mask.
+        
+        Thirdly, the mask layer is updated after its host layer, but when the mask layer
+        become tiled, there was no code that updated the mask platform layer on its
+        host layer. Fix by:
+            1. setting a bit on a layer to note that it's being used as a mask.
+            2. setting the parent of such a layer to its host layer (mimicking CA)
+            3. when the mask becomes tiled, dirtying the MaskLayerChanged bit on
+               its parent and adding a clause to commitLayerChangesAfterSublayers()
+               to update the mask layer.
+        
+        Finally, ASSERTION FAILED: owningGraphicsLayer()->isCommittingChanges() would
+        fire because we failed to set the m_isCommittingChanges flag while committing
+        the mask layer. Fix by moving the TemporaryChange<bool> that sets this flag
+        into commitLayerChangesBeforeSublayers() and commitLayerChangesAfterSublayers().
+        
+        Also used safe casts in more places in GraphicsLayerCA.
+
+        Tests: compositing/masks/become-tiled-mask.html
+               compositing/masks/cease-tiled-mask.html
+               compositing/masks/tiled-mask.html
+
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::GraphicsLayer):
+        (WebCore::GraphicsLayer::removeFromParent):
+        (WebCore::GraphicsLayer::setMaskLayer):
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::setIsMaskLayer):
+        (WebCore::GraphicsLayer::isMaskLayer):
+        (WebCore::GraphicsLayer::setMaskLayer): Deleted.
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::removeFromParent):
+        (WebCore::GraphicsLayerCA::setMaskLayer):
+        (WebCore::GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush):
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges):
+        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
+        (WebCore::GraphicsLayerCA::commitLayerChangesAfterSublayers):
+        (WebCore::GraphicsLayerCA::updateSublayerList):
+        (WebCore::GraphicsLayerCA::ensureStructuralLayer):
+        (WebCore::GraphicsLayerCA::updateMaskLayer):
+        (WebCore::GraphicsLayerCA::replicatedLayerRoot):
+        (WebCore::GraphicsLayerCA::createFilterAnimationsFromKeyframes):
+        (WebCore::GraphicsLayerCA::swapFromOrToTiledLayer):
+        (WebCore::GraphicsLayerCA::propagateLayerChangeToReplicas):
+        (WebCore::GraphicsLayerCA::fetchCloneLayers):
+
 2014-06-14  [email protected]  <[email protected]>
 
         [Curl] Compile errors related to http headers.

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (169971 => 169972)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp	2014-06-14 17:12:04 UTC (rev 169971)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp	2014-06-14 17:40:49 UTC (rev 169972)
@@ -90,6 +90,7 @@
     , m_appliesPageScale(false)
     , m_showDebugBorder(false)
     , m_showRepaintCounter(false)
+    , m_isMaskLayer(false)
     , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
     , m_contentsOrientation(CompositingCoordinatesTopDown)
     , m_parent(0)
@@ -260,10 +261,27 @@
             }
         }
 
-        setParent(0);
+        setParent(nullptr);
     }
 }
 
+void GraphicsLayer::setMaskLayer(GraphicsLayer* layer)
+{
+    if (layer == m_maskLayer)
+        return;
+
+    if (layer) {
+        layer->removeFromParent();
+        layer->setParent(this);
+        layer->setIsMaskLayer(true);
+    } else if (m_maskLayer) {
+        m_maskLayer->setParent(nullptr);
+        m_maskLayer->setIsMaskLayer(false);
+    }
+    
+    m_maskLayer = layer;
+}
+
 void GraphicsLayer::noteDeviceOrPageScaleFactorChangedIncludingDescendants()
 {
     deviceOrPageScaleFactorChanged();

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (169971 => 169972)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2014-06-14 17:12:04 UTC (rev 169971)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2014-06-14 17:40:49 UTC (rev 169972)
@@ -261,8 +261,12 @@
     void removeAllChildren();
     virtual void removeFromParent();
 
+    // The parent() of a maskLayer is set to the layer being masked.
     GraphicsLayer* maskLayer() const { return m_maskLayer; }
-    virtual void setMaskLayer(GraphicsLayer* layer) { m_maskLayer = layer; }
+    virtual void setMaskLayer(GraphicsLayer*);
+
+    void setIsMaskLayer(bool isMask) { m_isMaskLayer = isMask; }
+    bool isMaskLayer() const { return m_isMaskLayer; }
     
     // The given layer will replicate this layer and its children; the replica renders behind this layer.
     virtual void setReplicatedByLayer(GraphicsLayer*);
@@ -593,6 +597,7 @@
     bool m_appliesPageScale : 1; // Set for the layer which has the page scale applied to it.
     bool m_showDebugBorder : 1;
     bool m_showRepaintCounter : 1;
+    bool m_isMaskLayer : 1;
     
     GraphicsLayerPaintingPhase m_paintingPhase;
     CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (169971 => 169972)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2014-06-14 17:12:04 UTC (rev 169971)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2014-06-14 17:40:49 UTC (rev 169972)
@@ -456,7 +456,7 @@
 void GraphicsLayerCA::removeFromParent()
 {
     if (m_parent)
-        static_cast<GraphicsLayerCA*>(m_parent)->noteSublayersChanged();
+        toGraphicsLayerCA(m_parent)->noteSublayersChanged();
     GraphicsLayer::removeFromParent();
 }
 
@@ -471,7 +471,7 @@
     propagateLayerChangeToReplicas();
     
     if (m_replicatedLayer)
-        static_cast<GraphicsLayerCA*>(m_replicatedLayer)->propagateLayerChangeToReplicas();
+        toGraphicsLayerCA(m_replicatedLayer)->propagateLayerChangeToReplicas();
 }
 
 void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
@@ -1035,7 +1035,7 @@
     }
 
     if (m_maskLayer) {
-        GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
+        GraphicsLayerCA* maskLayerCA = toGraphicsLayerCA(m_maskLayer);
         if (maskLayerCA->recursiveVisibleRectChangeRequiresFlush(localState))
             return true;
     }
@@ -1044,13 +1044,13 @@
     size_t numChildren = childLayers.size();
     
     for (size_t i = 0; i < numChildren; ++i) {
-        GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+        GraphicsLayerCA* curChild = toGraphicsLayerCA(childLayers[i]);
         if (curChild->recursiveVisibleRectChangeRequiresFlush(localState))
             return true;
     }
 
     if (m_replicaLayer)
-        if (static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveVisibleRectChangeRequiresFlush(localState))
+        if (toGraphicsLayerCA(m_replicaLayer)->recursiveVisibleRectChangeRequiresFlush(localState))
             return true;
     
     return false;
@@ -1150,6 +1150,12 @@
     if (visibleRect != m_visibleRect) {
         m_uncommittedChanges |= VisibleRectChanged;
         m_visibleRect = visibleRect;
+        
+        if (GraphicsLayerCA* maskLayer = toGraphicsLayerCA(m_maskLayer)) {
+            // FIXME: this assumes that the mask layer has the same geometry as this layer (which is currently always true).
+            maskLayer->m_uncommittedChanges |= VisibleRectChanged;
+            maskLayer->m_visibleRect = visibleRect;
+        }
     }
 
 #ifdef VISIBLE_TILE_WASH
@@ -1187,39 +1193,31 @@
     if (affectedByPageScale)
         baseRelativePosition += m_position;
     
-    {
-        TemporaryChange<bool> committingChangesChange(m_isCommittingChanges, true);
-        commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, oldVisibleRect);
-    }
+    commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, oldVisibleRect);
 
     if (isRunningTransformAnimation()) {
         childCommitState.ancestorHasTransformAnimation = true;
         affectedByTransformAnimation = true;
     }
 
-    if (m_maskLayer) {
-        GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
-        maskLayerCA->commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
-    }
+    if (GraphicsLayerCA* maskLayer = toGraphicsLayerCA(m_maskLayer))
+        maskLayer->commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, oldVisibleRect);
 
     const Vector<GraphicsLayer*>& childLayers = children();
     size_t numChildren = childLayers.size();
     
     for (size_t i = 0; i < numChildren; ++i) {
-        GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+        GraphicsLayerCA* curChild = toGraphicsLayerCA(childLayers[i]);
         curChild->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
     }
 
-    if (m_replicaLayer)
-        static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
+    if (GraphicsLayerCA* replicaLayer = toGraphicsLayerCA(m_replicaLayer))
+        replicaLayer->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
 
-    if (m_maskLayer)
-        static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers(childCommitState);
+    if (GraphicsLayerCA* maskLayer = toGraphicsLayerCA(m_maskLayer))
+        maskLayer->commitLayerChangesAfterSublayers(childCommitState);
 
-    {
-        TemporaryChange<bool> committingChangesChange(m_isCommittingChanges, true);
-        commitLayerChangesAfterSublayers(childCommitState);
-    }
+    commitLayerChangesAfterSublayers(childCommitState);
 
     if (affectedByTransformAnimation && m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
         client().notifyFlushBeforeDisplayRefresh(this);
@@ -1270,6 +1268,8 @@
 
 void GraphicsLayerCA::commitLayerChangesBeforeSublayers(CommitState& commitState, float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect)
 {
+    TemporaryChange<bool> committingChangesChange(m_isCommittingChanges, true);
+
     ++commitState.treeDepth;
     if (m_structuralLayer)
         ++commitState.treeDepth;
@@ -1364,8 +1364,12 @@
     if (m_uncommittedChanges & ContentsRectsChanged) // Needs to happen before ChildrenChanged
         updateContentsRects();
 
-    if (m_uncommittedChanges & MaskLayerChanged)
+    if (m_uncommittedChanges & MaskLayerChanged) {
         updateMaskLayer();
+        // If the mask layer becomes tiled it can set this flag again. Clear the flag so that
+        // commitLayerChangesAfterSublayers doesn't update the mask again in the normal case.
+        m_uncommittedChanges &= ~MaskLayerChanged;
+    }
 
     if (m_uncommittedChanges & ContentsNeedsDisplay)
         updateContentsNeedsDisplay();
@@ -1398,6 +1402,11 @@
     if (!m_uncommittedChanges)
         return;
 
+    TemporaryChange<bool> committingChangesChange(m_isCommittingChanges, true);
+
+    if (m_uncommittedChanges & MaskLayerChanged)
+        updateMaskLayer();
+
     if (m_uncommittedChanges & ChildrenChanged)
         updateSublayerList(commitState.treeDepth > cMaxLayerTreeDepth);
 
@@ -1441,7 +1450,7 @@
 
     if (m_structuralLayer) {
         if (m_replicaLayer)
-            structuralLayerChildren.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
+            structuralLayerChildren.append(toGraphicsLayerCA(m_replicaLayer)->primaryLayer());
     
         structuralLayerChildren.append(m_layer);
     }
@@ -1456,7 +1465,7 @@
     const Vector<GraphicsLayer*>& childLayers = children();
     size_t numChildren = childLayers.size();
     for (size_t i = 0; i < numChildren; ++i) {
-        GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+        GraphicsLayerCA* curChild = toGraphicsLayerCA(childLayers[i]);
         PlatformCALayer* childLayer = curChild->layerForSuperlayer();
         childListForSublayers.append(childLayer);
     }
@@ -1741,7 +1750,7 @@
 
     // We've changed the layer that our parent added to its sublayer list, so tell it to update
     // sublayers again in its commitLayerChangesAfterSublayers().
-    static_cast<GraphicsLayerCA*>(parent())->noteSublayersChanged(DontScheduleFlush);
+    toGraphicsLayerCA(parent())->noteSublayersChanged(DontScheduleFlush);
 
     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
@@ -2035,10 +2044,10 @@
 
 void GraphicsLayerCA::updateMaskLayer()
 {
-    PlatformCALayer* maskCALayer = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayer() : 0;
+    PlatformCALayer* maskCALayer = m_maskLayer ? toGraphicsLayerCA(m_maskLayer)->primaryLayer() : 0;
     m_layer->setMask(maskCALayer);
 
-    LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
+    LayerMap* maskLayerCloneMap = m_maskLayer ? toGraphicsLayerCA(m_maskLayer)->primaryLayerClones() : 0;
     
     if (LayerMap* layerCloneMap = m_layerClones.get()) {
         LayerMap::const_iterator end = layerCloneMap->end();
@@ -2091,7 +2100,7 @@
     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
         return 0;
 
-    GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
+    GraphicsLayerCA* replicatedLayer = toGraphicsLayerCA(m_replicatedLayer);
     
     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
     FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
@@ -2423,7 +2432,7 @@
     int listIndex = validateFilterOperations(valueList);
     if (listIndex < 0)
         return false;
-        
+
     const FilterOperations& operations = static_cast<const FilterAnimationValue&>(valueList.at(listIndex)).value();
     // Make sure the platform layer didn't fallback to using software filter compositing instead.
     if (!filtersCanBeComposited(operations))
@@ -3006,11 +3015,17 @@
         m_layer->appendSublayer(m_visibleTileWashLayer.get());
 #endif
 
-    // Skip this step if we don't have a superlayer. This is probably a benign
-    // case that happens while restructuring the layer tree, and also occurs with
-    // WebKit2 page overlays, which can become tiled but are out-of-tree.
-    if (oldLayer->superlayer())
+    if (isMaskLayer()) {
+        // A mask layer's superlayer is the layer that it masks. Set the MaskLayerChanged dirty bit
+        // so that the parent will fix up the platform layers in commitLayerChangesAfterSublayers().
+        if (GraphicsLayer* parentLayer = parent())
+            toGraphicsLayerCA(parentLayer)->noteLayerPropertyChanged(MaskLayerChanged);
+    } else if (oldLayer->superlayer()) {
+        // Skip this step if we don't have a superlayer. This is probably a benign
+        // case that happens while restructuring the layer tree, and also occurs with
+        // WebKit2 page overlays, which can become tiled but are out-of-tree.
         oldLayer->superlayer()->replaceSublayer(oldLayer.get(), m_layer.get());
+    }
 
     m_uncommittedChanges |= ChildrenChanged
         | GeometryChanged
@@ -3023,6 +3038,7 @@
         | ContentsScaleChanged
         | AcceleratesDrawingChanged
         | FiltersChanged
+        | MaskLayerChanged
         | OpacityChanged
         | DebugIndicatorsChanged;
     
@@ -3143,12 +3159,12 @@
 void GraphicsLayerCA::propagateLayerChangeToReplicas()
 {
     for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
-        GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer);
+        GraphicsLayerCA* currLayerCA = toGraphicsLayerCA(currLayer);
         if (!currLayerCA->hasCloneLayers())
             break;
 
         if (currLayerCA->replicaLayer())
-            static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
+            toGraphicsLayerCA(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
     }
 }
 
@@ -3161,7 +3177,7 @@
     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, contentsClippingLayer, cloneLevel);
 
     if (m_maskLayer) {
-        RefPtr<PlatformCALayer> maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
+        RefPtr<PlatformCALayer> maskClone = toGraphicsLayerCA(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
         primaryLayer->setMask(maskClone.get());
     }
 
@@ -3188,7 +3204,7 @@
     if (m_replicaLayer && m_replicaLayer != replicaRoot) {
         // We have nested replicas. Ask the replica layer for a clone of its contents.
         replicaState.setBranchType(ReplicaState::ReplicaBranch);
-        replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
+        replicaLayer = toGraphicsLayerCA(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
         replicaState.setBranchType(ReplicaState::ChildBranch);
     }
 
@@ -3221,7 +3237,7 @@
 
         size_t numChildren = childLayers.size();
         for (size_t i = 0; i < numChildren; ++i) {
-            GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+            GraphicsLayerCA* curChild = toGraphicsLayerCA(childLayers[i]);
 
             RefPtr<PlatformCALayer> childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
             if (childLayer)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to