Title: [245974] trunk
Revision
245974
Author
simon.fra...@apple.com
Date
2019-05-31 11:55:14 -0700 (Fri, 31 May 2019)

Log Message

[Async overflow scrolling] Flashes of missing layer backing store when scrolling an overflow
https://bugs.webkit.org/show_bug.cgi?id=198363

Reviewed by Tim Horton.

Source/WebCore:

When the contents of an overflow:scroll did not use a tiled backing layer, GraphicsLayerCA::adjustCoverageRect()
would do no coverage rect expansion for scrolling, which meant that backing store attachment for
descendant layers would just use the visible rect from their scrolling ancestor which made it easy
to scroll into view a layer whose backing store was not yet attached.

Since this only affects non-tiled layers, re-use the generic TileController::adjustTileCoverageRect()
code by moving it down to GraphicsLayer, and call it for a scrolled contents layer which does not
have tiled backing.

Tested by fast/scrolling/ios/reconcile-layer-position-recursive.html

* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::adjustCoverageRectForMovement):
* platform/graphics/GraphicsLayer.h:
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::adjustCoverageRect const):
* platform/graphics/ca/TileController.cpp:
(WebCore::TileController::adjustTileCoverageRect):

LayoutTests:

Reset results.

* fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt:
* tiled-drawing/tiled-backing-in-window-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (245973 => 245974)


--- trunk/LayoutTests/ChangeLog	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/LayoutTests/ChangeLog	2019-05-31 18:55:14 UTC (rev 245974)
@@ -8,6 +8,18 @@
         * webgpu/whlsl-store-to-property-updates-properly-expected.html: Added.
         * webgpu/whlsl-store-to-property-updates-properly.html: Added.
 
+2019-05-31  Simon Fraser  <simon.fra...@apple.com>
+
+        [Async overflow scrolling] Flashes of missing layer backing store when scrolling an overflow
+        https://bugs.webkit.org/show_bug.cgi?id=198363
+
+        Reviewed by Tim Horton.
+
+        Reset results.
+
+        * fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt:
+        * tiled-drawing/tiled-backing-in-window-expected.txt:
+
 2019-05-31  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, rolling out r245946.

Modified: trunk/LayoutTests/fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt (245973 => 245974)


--- trunk/LayoutTests/fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/LayoutTests/fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt	2019-05-31 18:55:14 UTC (rev 245974)
@@ -39,7 +39,7 @@
                   (bounds 300.00 510.00)
                   (drawsContent 1)
                   (visible rect 0.00, 13.00 300.00 x 287.00)
-                  (coverage rect 0.00, 13.00 300.00 x 287.00)
+                  (coverage rect 0.00, 12.00 300.00 x 288.00)
                   (intersects coverage rect 1)
                   (contentsScale 2.00)
                   (children 1
@@ -48,7 +48,7 @@
                       (bounds 210.00 410.00)
                       (drawsContent 1)
                       (visible rect 0.00, 0.00 210.00 x 250.00)
-                      (coverage rect -50.00, -37.00 300.00 x 287.00)
+                      (coverage rect -50.00, -38.00 300.00 x 288.00)
                       (intersects coverage rect 1)
                       (contentsScale 2.00)
                       (children 1

Modified: trunk/LayoutTests/tiled-drawing/tiled-backing-in-window-expected.txt (245973 => 245974)


--- trunk/LayoutTests/tiled-drawing/tiled-backing-in-window-expected.txt	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/LayoutTests/tiled-drawing/tiled-backing-in-window-expected.txt	2019-05-31 18:55:14 UTC (rev 245974)
@@ -63,7 +63,7 @@
           (usingTiledLayer 1)
           (drawsContent 1)
           (visible rect 0.00, 0.00 777.00 x 200.00)
-          (coverage rect -8.00, -8.00 785.00 x 585.00)
+          (coverage rect 0.00, 0.00 777.00 x 200.00)
           (intersects coverage rect 1)
           (contentsScale 1.00)
           (tile cache coverage 0, 0 1024 x 200)

Modified: trunk/Source/WebCore/ChangeLog (245973 => 245974)


--- trunk/Source/WebCore/ChangeLog	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/Source/WebCore/ChangeLog	2019-05-31 18:55:14 UTC (rev 245974)
@@ -21,6 +21,32 @@
         * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
         (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
 
+2019-05-31  Simon Fraser  <simon.fra...@apple.com>
+
+        [Async overflow scrolling] Flashes of missing layer backing store when scrolling an overflow
+        https://bugs.webkit.org/show_bug.cgi?id=198363
+
+        Reviewed by Tim Horton.
+
+        When the contents of an overflow:scroll did not use a tiled backing layer, GraphicsLayerCA::adjustCoverageRect()
+        would do no coverage rect expansion for scrolling, which meant that backing store attachment for
+        descendant layers would just use the visible rect from their scrolling ancestor which made it easy
+        to scroll into view a layer whose backing store was not yet attached.
+        
+        Since this only affects non-tiled layers, re-use the generic TileController::adjustTileCoverageRect()
+        code by moving it down to GraphicsLayer, and call it for a scrolled contents layer which does not
+        have tiled backing.
+        
+        Tested by fast/scrolling/ios/reconcile-layer-position-recursive.html
+
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::adjustCoverageRectForMovement):
+        * platform/graphics/GraphicsLayer.h:
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::adjustCoverageRect const):
+        * platform/graphics/ca/TileController.cpp:
+        (WebCore::TileController::adjustTileCoverageRect):
+
 2019-05-31  Geoffrey Garen  <gga...@apple.com>
 
         Some WeakPtr cleanup

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (245973 => 245974)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp	2019-05-31 18:55:14 UTC (rev 245974)
@@ -502,6 +502,64 @@
     client().paintContents(this, context, m_paintingPhase, clipRect, layerPaintBehavior);
 }
 
+FloatRect GraphicsLayer::adjustCoverageRectForMovement(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect)
+{
+    // If the old visible rect is empty, we have no information about how the visible area is changing
+    // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand if the rects don't overlap.
+    if (previousVisibleRect.isEmpty() || !currentVisibleRect.intersects(previousVisibleRect))
+        return unionRect(coverageRect, currentVisibleRect);
+
+    const float paddingMultiplier = 2;
+
+    float leftEdgeDelta = paddingMultiplier * (currentVisibleRect.x() - previousVisibleRect.x());
+    float rightEdgeDelta = paddingMultiplier * (currentVisibleRect.maxX() - previousVisibleRect.maxX());
+
+    float topEdgeDelta = paddingMultiplier * (currentVisibleRect.y() - previousVisibleRect.y());
+    float bottomEdgeDelta = paddingMultiplier * (currentVisibleRect.maxY() - previousVisibleRect.maxY());
+    
+    FloatRect expandedRect = currentVisibleRect;
+
+    // More exposed on left side.
+    if (leftEdgeDelta < 0) {
+        float newLeft = expandedRect.x() + leftEdgeDelta;
+        // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
+        if (newLeft < previousVisibleRect.x())
+            expandedRect.shiftXEdgeTo(newLeft);
+        else
+            expandedRect.shiftXEdgeTo(previousVisibleRect.x());
+    }
+
+    // More exposed on right.
+    if (rightEdgeDelta > 0) {
+        float newRight = expandedRect.maxX() + rightEdgeDelta;
+        // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
+        if (newRight > previousVisibleRect.maxX())
+            expandedRect.setWidth(newRight - expandedRect.x());
+        else
+            expandedRect.setWidth(previousVisibleRect.maxX() - expandedRect.x());
+    }
+
+    // More exposed at top.
+    if (topEdgeDelta < 0) {
+        float newTop = expandedRect.y() + topEdgeDelta;
+        if (newTop < previousVisibleRect.y())
+            expandedRect.shiftYEdgeTo(newTop);
+        else
+            expandedRect.shiftYEdgeTo(previousVisibleRect.y());
+    }
+
+    // More exposed on bottom.
+    if (bottomEdgeDelta > 0) {
+        float newBottom = expandedRect.maxY() + bottomEdgeDelta;
+        if (newBottom > previousVisibleRect.maxY())
+            expandedRect.setHeight(newBottom - expandedRect.y());
+        else
+            expandedRect.setHeight(previousVisibleRect.maxY() - expandedRect.y());
+    }
+    
+    return unionRect(coverageRect, expandedRect);
+}
+
 String GraphicsLayer::animationNameForTransition(AnimatedPropertyID property)
 {
     // | is not a valid identifier character in CSS, so this can never conflict with a keyframe identifier.

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (245973 => 245974)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2019-05-31 18:55:14 UTC (rev 245974)
@@ -576,6 +576,8 @@
     // for example to allocate new tiles.
     virtual bool visibleRectChangeRequiresFlush(const FloatRect& /* clipRect */) const { return false; }
 
+    static FloatRect adjustCoverageRectForMovement(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect);
+
     // Return a string with a human readable form of the layer tree, If debug is true
     // pointers for the layers and timing data will be included in the returned string.
     WEBCORE_EXPORT String layerTreeAsText(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const;

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


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2019-05-31 18:55:14 UTC (rev 245974)
@@ -1450,6 +1450,10 @@
     case Type::ScrolledContents:
         if (m_layer->usesTiledBackingLayer())
             coverageRect = tiledBacking()->adjustTileCoverageRectForScrolling(coverageRect, size(), oldVisibleRect, rects.visibleRect, pageScaleFactor() * deviceScaleFactor());
+        else {
+            // Even if we don't have tiled backing, we want to expand coverage so that contained layers get attached backing store.
+            coverageRect = adjustCoverageRectForMovement(coverageRect, oldVisibleRect, rects.visibleRect);
+        }
         break;
     case Type::Normal:
         if (m_layer->usesTiledBackingLayer())

Modified: trunk/Source/WebCore/platform/graphics/ca/TileController.cpp (245973 => 245974)


--- trunk/Source/WebCore/platform/graphics/ca/TileController.cpp	2019-05-31 18:16:45 UTC (rev 245973)
+++ trunk/Source/WebCore/platform/graphics/ca/TileController.cpp	2019-05-31 18:55:14 UTC (rev 245974)
@@ -28,6 +28,7 @@
 
 #if USE(CG)
 
+#include "GraphicsLayer.h"
 #include "IntRect.h"
 #include "Logging.h"
 #include "PlatformCALayer.h"
@@ -364,65 +365,11 @@
 
 FloatRect TileController::adjustTileCoverageRect(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect, bool sizeChanged)
 {
-    // If the old visible rect is empty, we have no information about how the visible area is changing
-    // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
-    // if the size changed or the rects don't overlap.
-    if (previousVisibleRect.isEmpty() || sizeChanged  || !currentVisibleRect.intersects(previousVisibleRect))
+    if (sizeChanged || MemoryPressureHandler::singleton().isUnderMemoryPressure())
         return unionRect(coverageRect, currentVisibleRect);
 
-    if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
-        return unionRect(coverageRect, currentVisibleRect);
-
-    const float paddingMultiplier = 2;
-
-    float leftEdgeDelta = paddingMultiplier * (currentVisibleRect.x() - previousVisibleRect.x());
-    float rightEdgeDelta = paddingMultiplier * (currentVisibleRect.maxX() - previousVisibleRect.maxX());
-
-    float topEdgeDelta = paddingMultiplier * (currentVisibleRect.y() - previousVisibleRect.y());
-    float bottomEdgeDelta = paddingMultiplier * (currentVisibleRect.maxY() - previousVisibleRect.maxY());
-    
-    FloatRect expandedRect = currentVisibleRect;
-
-    // More exposed on left side.
-    if (leftEdgeDelta < 0) {
-        float newLeft = expandedRect.x() + leftEdgeDelta;
-        // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
-        if (newLeft < previousVisibleRect.x())
-            expandedRect.shiftXEdgeTo(newLeft);
-        else
-            expandedRect.shiftXEdgeTo(previousVisibleRect.x());
-    }
-
-    // More exposed on right.
-    if (rightEdgeDelta > 0) {
-        float newRight = expandedRect.maxX() + rightEdgeDelta;
-        // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
-        if (newRight > previousVisibleRect.maxX())
-            expandedRect.setWidth(newRight - expandedRect.x());
-        else
-            expandedRect.setWidth(previousVisibleRect.maxX() - expandedRect.x());
-    }
-
-    // More exposed at top.
-    if (topEdgeDelta < 0) {
-        float newTop = expandedRect.y() + topEdgeDelta;
-        if (newTop < previousVisibleRect.y())
-            expandedRect.shiftYEdgeTo(newTop);
-        else
-            expandedRect.shiftYEdgeTo(previousVisibleRect.y());
-    }
-
-    // More exposed on bottom.
-    if (bottomEdgeDelta > 0) {
-        float newBottom = expandedRect.maxY() + bottomEdgeDelta;
-        if (newBottom > previousVisibleRect.maxY())
-            expandedRect.setHeight(newBottom - expandedRect.y());
-        else
-            expandedRect.setHeight(previousVisibleRect.maxY() - expandedRect.y());
-    }
-    
-    expandedRect.intersect(boundsWithoutMargin());
-    return unionRect(coverageRect, expandedRect);
+    auto expandedCoverageRect = GraphicsLayer::adjustCoverageRectForMovement(coverageRect, previousVisibleRect, currentVisibleRect);
+    return intersection(expandedCoverageRect, boundsWithoutMargin());
 }
 
 #if !PLATFORM(IOS_FAMILY)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to