Title: [183970] trunk/Source/WebCore
Revision
183970
Author
simon.fra...@apple.com
Date
2015-05-07 18:46:59 -0700 (Thu, 07 May 2015)

Log Message

REGRESSION (r183300): Fixed elements flash when scrolling
https://bugs.webkit.org/show_bug.cgi?id=144778
rdar://problem/20769741

Reviewed by Dean Jackson.

After r183300 we can detached layer backing store when outside the coverage region.
However, position:fixed layers are moved around by the ScrollingCoordinator behind
GraphicsLayer's back, so we can do layer flushes with stale information about layer
geometry.

To avoid dropping backing store for layers in this situation, prevent backing
store detachment on layers registered with the ScrollingCoordinator as viewport-constrained
layers. Preventing detachment on a layer also prevents detachment on all descendant
layers.

* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::setAllowsBackingStoreDetachment):
(WebCore::GraphicsLayer::allowsBackingStoreDetachment):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::GraphicsLayerCA):
(WebCore::GraphicsLayerCA::setVisibleAndCoverageRects): Set m_intersectsCoverageRect to true
if backing store detachment is prevented.
(WebCore::GraphicsLayerCA::recursiveCommitChanges): Set a bit in the CommitState to
communicate to descendants that detachment is prevented.
* platform/graphics/ca/GraphicsLayerCA.h:
(WebCore::GraphicsLayerCA::CommitState::CommitState): Deleted.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole):
* rendering/RenderLayerBacking.h:
(WebCore::RenderLayerBacking::setScrollingNodeIDForRole): If registering with a non-zero
nodeID for the ViewportConstrained role, turn off backing store detachment.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (183969 => 183970)


--- trunk/Source/WebCore/ChangeLog	2015-05-08 01:23:49 UTC (rev 183969)
+++ trunk/Source/WebCore/ChangeLog	2015-05-08 01:46:59 UTC (rev 183970)
@@ -1,3 +1,38 @@
+2015-05-07  Simon Fraser  <simon.fra...@apple.com>
+
+        REGRESSION (r183300): Fixed elements flash when scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=144778
+        rdar://problem/20769741
+
+        Reviewed by Dean Jackson.
+
+        After r183300 we can detached layer backing store when outside the coverage region.
+        However, position:fixed layers are moved around by the ScrollingCoordinator behind
+        GraphicsLayer's back, so we can do layer flushes with stale information about layer
+        geometry.
+        
+        To avoid dropping backing store for layers in this situation, prevent backing
+        store detachment on layers registered with the ScrollingCoordinator as viewport-constrained
+        layers. Preventing detachment on a layer also prevents detachment on all descendant
+        layers.
+
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::setAllowsBackingStoreDetachment):
+        (WebCore::GraphicsLayer::allowsBackingStoreDetachment):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::GraphicsLayerCA):
+        (WebCore::GraphicsLayerCA::setVisibleAndCoverageRects): Set m_intersectsCoverageRect to true
+        if backing store detachment is prevented.
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges): Set a bit in the CommitState to 
+        communicate to descendants that detachment is prevented.
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        (WebCore::GraphicsLayerCA::CommitState::CommitState): Deleted.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole):
+        * rendering/RenderLayerBacking.h:
+        (WebCore::RenderLayerBacking::setScrollingNodeIDForRole): If registering with a non-zero
+        nodeID for the ViewportConstrained role, turn off backing store detachment.
+
 2015-05-07  Sam Weinig  <s...@webkit.org>
 
         Consider implementing Document.scrollingElement

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (183969 => 183970)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2015-05-08 01:23:49 UTC (rev 183969)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2015-05-08 01:46:59 UTC (rev 183970)
@@ -490,6 +490,10 @@
 
     float pageScaleFactor() const { return m_client.pageScaleFactor(); }
     float deviceScaleFactor() const { return m_client.deviceScaleFactor(); }
+    
+    // Whether this layer (and descendants) can detach backing store when outside the coverage area.
+    virtual void setAllowsBackingStoreDetachment(bool) { }
+    virtual bool allowsBackingStoreDetachment() const { return true; }
 
     virtual void deviceOrPageScaleFactorChanged() { }
     WEBCORE_EXPORT void noteDeviceOrPageScaleFactorChangedIncludingDescendants();

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


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2015-05-08 01:23:49 UTC (rev 183969)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2015-05-08 01:46:59 UTC (rev 183970)
@@ -353,6 +353,7 @@
     : GraphicsLayer(layerType, client)
     , m_needsFullRepaint(false)
     , m_usingBackdropLayerType(false)
+    , m_allowsBackingStoreDetachment(true)
     , m_intersectsCoverageRect(true)
 {
 }
@@ -1252,7 +1253,7 @@
     return true;
 }
 
-void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects)
+void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool allowBackingStoreDetachment)
 {
     bool visibleRectChanged = rects.visibleRect != m_visibleRect;
     bool coverageRectChanged = rects.coverageRect != m_coverageRect;
@@ -1275,7 +1276,7 @@
         m_coverageRect = rects.coverageRect;
 
         // FIXME: we need to take reflections into account when determining whether this layer intersects the coverage rect.
-        m_intersectsCoverageRect = m_coverageRect.intersects(FloatRect(m_boundsOrigin, size()));
+        m_intersectsCoverageRect = !allowBackingStoreDetachment || m_coverageRect.intersects(FloatRect(m_boundsOrigin, size()));
 
         if (GraphicsLayerCA* maskLayer = downcast<GraphicsLayerCA>(m_maskLayer)) {
             maskLayer->m_uncommittedChanges |= CoverageRectChanged;
@@ -1300,7 +1301,7 @@
             localState.setLastPlanarSecondaryQuad(&secondaryQuad);
         }
     }
-    setVisibleAndCoverageRects(rects);
+    setVisibleAndCoverageRects(rects, m_allowsBackingStoreDetachment && commitState.ancestorsAllowBackingStoreDetachment);
 
 #ifdef VISIBLE_TILE_WASH
     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
@@ -1343,6 +1344,8 @@
         childCommitState.ancestorHasTransformAnimation = true;
         affectedByTransformAnimation = true;
     }
+    
+    childCommitState.ancestorsAllowBackingStoreDetachment &= m_allowsBackingStoreDetachment;
 
     if (GraphicsLayerCA* maskLayer = downcast<GraphicsLayerCA>(m_maskLayer))
         maskLayer->commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition);
@@ -3625,6 +3628,15 @@
     }
 }
 
+void GraphicsLayerCA::setAllowsBackingStoreDetachment(bool allowDetachment)
+{
+    if (allowDetachment == m_allowsBackingStoreDetachment)
+        return;
+
+    m_allowsBackingStoreDetachment = allowDetachment;
+    noteLayerPropertyChanged(CoverageRectChanged);
+}
+
 void GraphicsLayerCA::deviceOrPageScaleFactorChanged()
 {
     noteChangesForScaleSensitiveProperties();

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (183969 => 183970)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2015-05-08 01:23:49 UTC (rev 183969)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2015-05-08 01:46:59 UTC (rev 183970)
@@ -148,12 +148,9 @@
     virtual FloatSize pixelAlignmentOffset() const override { return m_pixelAlignmentOffset; }
 
     struct CommitState {
-        bool ancestorHasTransformAnimation;
-        int treeDepth;
-        CommitState()
-            : ancestorHasTransformAnimation(false)
-            , treeDepth(0)
-        { }
+        int treeDepth { 0 };
+        bool ancestorHasTransformAnimation { false };
+        bool ancestorsAllowBackingStoreDetachment { true };
     };
     void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
 
@@ -197,6 +194,9 @@
 
     virtual bool isCommittingChanges() const override { return m_isCommittingChanges; }
 
+    WEBCORE_EXPORT virtual void setAllowsBackingStoreDetachment(bool) override;
+    WEBCORE_EXPORT virtual bool allowsBackingStoreDetachment() const override { return m_allowsBackingStoreDetachment; }
+
     WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const override;
 
     WEBCORE_EXPORT virtual bool shouldRepaintOnSizeChange() const override;
@@ -293,7 +293,7 @@
     const FloatRect& visibleRect() const { return m_visibleRect; }
     const FloatRect& coverageRect() const { return m_coverageRect; }
 
-    void setVisibleAndCoverageRects(const VisibleAndCoverageRects&);
+    void setVisibleAndCoverageRects(const VisibleAndCoverageRects&, bool allowBackingStoreDetachment);
     
     static FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize);
 
@@ -510,6 +510,7 @@
     ContentsLayerPurpose m_contentsLayerPurpose { NoContentsLayer };
     bool m_needsFullRepaint : 1;
     bool m_usingBackdropLayerType : 1;
+    bool m_allowsBackingStoreDetachment : 1;
     bool m_intersectsCoverageRect : 1;
 
     Color m_contentsSolidColor;

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (183969 => 183970)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2015-05-08 01:23:49 UTC (rev 183969)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2015-05-08 01:46:59 UTC (rev 183970)
@@ -1569,6 +1569,11 @@
     }
 }
 
+void RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole(bool viewportCoordinated)
+{
+    m_graphicsLayer->setAllowsBackingStoreDetachment(!viewportCoordinated);
+}
+
 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
 {
     unsigned phase = 0;

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (183969 => 183970)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2015-05-08 01:23:49 UTC (rev 183969)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2015-05-08 01:46:59 UTC (rev 183970)
@@ -126,12 +126,15 @@
             break;
         case ViewportConstrained:
             m_viewportConstrainedNodeID = nodeID;
+            setIsScrollCoordinatedWithViewportConstrainedRole(nodeID);
             break;
         }
     }
     
     ScrollingNodeID scrollingNodeIDForChildren() const { return m_scrollingNodeID ? m_scrollingNodeID : m_viewportConstrainedNodeID; }
 
+    void setIsScrollCoordinatedWithViewportConstrainedRole(bool);
+
     bool hasMaskLayer() const { return m_maskLayer != 0; }
     bool hasChildClippingMaskLayer() const { return m_childClippingMaskLayer != nullptr; }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to