Changeset 245974 in webkit


Ignore:
Timestamp:
May 31, 2019 11:55:14 AM (5 years ago)
Author:
Simon Fraser
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:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245973 r245974  
    88        * webgpu/whlsl-store-to-property-updates-properly-expected.html: Added.
    99        * webgpu/whlsl-store-to-property-updates-properly.html: Added.
     10
     112019-05-31  Simon Fraser  <simon.fraser@apple.com>
     12
     13        [Async overflow scrolling] Flashes of missing layer backing store when scrolling an overflow
     14        https://bugs.webkit.org/show_bug.cgi?id=198363
     15
     16        Reviewed by Tim Horton.
     17
     18        Reset results.
     19
     20        * fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt:
     21        * tiled-drawing/tiled-backing-in-window-expected.txt:
    1022
    11232019-05-31  Ryan Haddad  <ryanhaddad@apple.com>
  • trunk/LayoutTests/fast/scrolling/ios/reconcile-layer-position-recursive-expected.txt

    r244628 r245974  
    4040                  (drawsContent 1)
    4141                  (visible rect 0.00, 13.00 300.00 x 287.00)
    42                   (coverage rect 0.00, 13.00 300.00 x 287.00)
     42                  (coverage rect 0.00, 12.00 300.00 x 288.00)
    4343                  (intersects coverage rect 1)
    4444                  (contentsScale 2.00)
     
    4949                      (drawsContent 1)
    5050                      (visible rect 0.00, 0.00 210.00 x 250.00)
    51                       (coverage rect -50.00, -37.00 300.00 x 287.00)
     51                      (coverage rect -50.00, -38.00 300.00 x 288.00)
    5252                      (intersects coverage rect 1)
    5353                      (contentsScale 2.00)
  • trunk/LayoutTests/tiled-drawing/tiled-backing-in-window-expected.txt

    r211750 r245974  
    6464          (drawsContent 1)
    6565          (visible rect 0.00, 0.00 777.00 x 200.00)
    66           (coverage rect -8.00, -8.00 785.00 x 585.00)
     66          (coverage rect 0.00, 0.00 777.00 x 200.00)
    6767          (intersects coverage rect 1)
    6868          (contentsScale 1.00)
  • trunk/Source/WebCore/ChangeLog

    r245973 r245974  
    2121        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
    2222        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
     23
     242019-05-31  Simon Fraser  <simon.fraser@apple.com>
     25
     26        [Async overflow scrolling] Flashes of missing layer backing store when scrolling an overflow
     27        https://bugs.webkit.org/show_bug.cgi?id=198363
     28
     29        Reviewed by Tim Horton.
     30
     31        When the contents of an overflow:scroll did not use a tiled backing layer, GraphicsLayerCA::adjustCoverageRect()
     32        would do no coverage rect expansion for scrolling, which meant that backing store attachment for
     33        descendant layers would just use the visible rect from their scrolling ancestor which made it easy
     34        to scroll into view a layer whose backing store was not yet attached.
     35       
     36        Since this only affects non-tiled layers, re-use the generic TileController::adjustTileCoverageRect()
     37        code by moving it down to GraphicsLayer, and call it for a scrolled contents layer which does not
     38        have tiled backing.
     39       
     40        Tested by fast/scrolling/ios/reconcile-layer-position-recursive.html
     41
     42        * platform/graphics/GraphicsLayer.cpp:
     43        (WebCore::GraphicsLayer::adjustCoverageRectForMovement):
     44        * platform/graphics/GraphicsLayer.h:
     45        * platform/graphics/ca/GraphicsLayerCA.cpp:
     46        (WebCore::GraphicsLayerCA::adjustCoverageRect const):
     47        * platform/graphics/ca/TileController.cpp:
     48        (WebCore::TileController::adjustTileCoverageRect):
    2349
    24502019-05-31  Geoffrey Garen  <ggaren@apple.com>
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp

    r245950 r245974  
    501501
    502502    client().paintContents(this, context, m_paintingPhase, clipRect, layerPaintBehavior);
     503}
     504
     505FloatRect GraphicsLayer::adjustCoverageRectForMovement(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect)
     506{
     507    // If the old visible rect is empty, we have no information about how the visible area is changing
     508    // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand if the rects don't overlap.
     509    if (previousVisibleRect.isEmpty() || !currentVisibleRect.intersects(previousVisibleRect))
     510        return unionRect(coverageRect, currentVisibleRect);
     511
     512    const float paddingMultiplier = 2;
     513
     514    float leftEdgeDelta = paddingMultiplier * (currentVisibleRect.x() - previousVisibleRect.x());
     515    float rightEdgeDelta = paddingMultiplier * (currentVisibleRect.maxX() - previousVisibleRect.maxX());
     516
     517    float topEdgeDelta = paddingMultiplier * (currentVisibleRect.y() - previousVisibleRect.y());
     518    float bottomEdgeDelta = paddingMultiplier * (currentVisibleRect.maxY() - previousVisibleRect.maxY());
     519   
     520    FloatRect expandedRect = currentVisibleRect;
     521
     522    // More exposed on left side.
     523    if (leftEdgeDelta < 0) {
     524        float newLeft = expandedRect.x() + leftEdgeDelta;
     525        // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
     526        if (newLeft < previousVisibleRect.x())
     527            expandedRect.shiftXEdgeTo(newLeft);
     528        else
     529            expandedRect.shiftXEdgeTo(previousVisibleRect.x());
     530    }
     531
     532    // More exposed on right.
     533    if (rightEdgeDelta > 0) {
     534        float newRight = expandedRect.maxX() + rightEdgeDelta;
     535        // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
     536        if (newRight > previousVisibleRect.maxX())
     537            expandedRect.setWidth(newRight - expandedRect.x());
     538        else
     539            expandedRect.setWidth(previousVisibleRect.maxX() - expandedRect.x());
     540    }
     541
     542    // More exposed at top.
     543    if (topEdgeDelta < 0) {
     544        float newTop = expandedRect.y() + topEdgeDelta;
     545        if (newTop < previousVisibleRect.y())
     546            expandedRect.shiftYEdgeTo(newTop);
     547        else
     548            expandedRect.shiftYEdgeTo(previousVisibleRect.y());
     549    }
     550
     551    // More exposed on bottom.
     552    if (bottomEdgeDelta > 0) {
     553        float newBottom = expandedRect.maxY() + bottomEdgeDelta;
     554        if (newBottom > previousVisibleRect.maxY())
     555            expandedRect.setHeight(newBottom - expandedRect.y());
     556        else
     557            expandedRect.setHeight(previousVisibleRect.maxY() - expandedRect.y());
     558    }
     559   
     560    return unionRect(coverageRect, expandedRect);
    503561}
    504562
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.h

    r245950 r245974  
    577577    virtual bool visibleRectChangeRequiresFlush(const FloatRect& /* clipRect */) const { return false; }
    578578
     579    static FloatRect adjustCoverageRectForMovement(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect);
     580
    579581    // Return a string with a human readable form of the layer tree, If debug is true
    580582    // pointers for the layers and timing data will be included in the returned string.
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r245837 r245974  
    14511451        if (m_layer->usesTiledBackingLayer())
    14521452            coverageRect = tiledBacking()->adjustTileCoverageRectForScrolling(coverageRect, size(), oldVisibleRect, rects.visibleRect, pageScaleFactor() * deviceScaleFactor());
     1453        else {
     1454            // Even if we don't have tiled backing, we want to expand coverage so that contained layers get attached backing store.
     1455            coverageRect = adjustCoverageRectForMovement(coverageRect, oldVisibleRect, rects.visibleRect);
     1456        }
    14531457        break;
    14541458    case Type::Normal:
  • trunk/Source/WebCore/platform/graphics/ca/TileController.cpp

    r245837 r245974  
    2929#if USE(CG)
    3030
     31#include "GraphicsLayer.h"
    3132#include "IntRect.h"
    3233#include "Logging.h"
     
    365366FloatRect TileController::adjustTileCoverageRect(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect, bool sizeChanged)
    366367{
    367     // If the old visible rect is empty, we have no information about how the visible area is changing
    368     // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
    369     // if the size changed or the rects don't overlap.
    370     if (previousVisibleRect.isEmpty() || sizeChanged  || !currentVisibleRect.intersects(previousVisibleRect))
     368    if (sizeChanged || MemoryPressureHandler::singleton().isUnderMemoryPressure())
    371369        return unionRect(coverageRect, currentVisibleRect);
    372370
    373     if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
    374         return unionRect(coverageRect, currentVisibleRect);
    375 
    376     const float paddingMultiplier = 2;
    377 
    378     float leftEdgeDelta = paddingMultiplier * (currentVisibleRect.x() - previousVisibleRect.x());
    379     float rightEdgeDelta = paddingMultiplier * (currentVisibleRect.maxX() - previousVisibleRect.maxX());
    380 
    381     float topEdgeDelta = paddingMultiplier * (currentVisibleRect.y() - previousVisibleRect.y());
    382     float bottomEdgeDelta = paddingMultiplier * (currentVisibleRect.maxY() - previousVisibleRect.maxY());
    383    
    384     FloatRect expandedRect = currentVisibleRect;
    385 
    386     // More exposed on left side.
    387     if (leftEdgeDelta < 0) {
    388         float newLeft = expandedRect.x() + leftEdgeDelta;
    389         // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
    390         if (newLeft < previousVisibleRect.x())
    391             expandedRect.shiftXEdgeTo(newLeft);
    392         else
    393             expandedRect.shiftXEdgeTo(previousVisibleRect.x());
    394     }
    395 
    396     // More exposed on right.
    397     if (rightEdgeDelta > 0) {
    398         float newRight = expandedRect.maxX() + rightEdgeDelta;
    399         // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
    400         if (newRight > previousVisibleRect.maxX())
    401             expandedRect.setWidth(newRight - expandedRect.x());
    402         else
    403             expandedRect.setWidth(previousVisibleRect.maxX() - expandedRect.x());
    404     }
    405 
    406     // More exposed at top.
    407     if (topEdgeDelta < 0) {
    408         float newTop = expandedRect.y() + topEdgeDelta;
    409         if (newTop < previousVisibleRect.y())
    410             expandedRect.shiftYEdgeTo(newTop);
    411         else
    412             expandedRect.shiftYEdgeTo(previousVisibleRect.y());
    413     }
    414 
    415     // More exposed on bottom.
    416     if (bottomEdgeDelta > 0) {
    417         float newBottom = expandedRect.maxY() + bottomEdgeDelta;
    418         if (newBottom > previousVisibleRect.maxY())
    419             expandedRect.setHeight(newBottom - expandedRect.y());
    420         else
    421             expandedRect.setHeight(previousVisibleRect.maxY() - expandedRect.y());
    422     }
    423    
    424     expandedRect.intersect(boundsWithoutMargin());
    425     return unionRect(coverageRect, expandedRect);
     371    auto expandedCoverageRect = GraphicsLayer::adjustCoverageRectForMovement(coverageRect, previousVisibleRect, currentVisibleRect);
     372    return intersection(expandedCoverageRect, boundsWithoutMargin());
    426373}
    427374
Note: See TracChangeset for help on using the changeset viewer.