Should get rid of TileController's CoverageForSlowScrolling mode
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Feb 2014 02:12:43 +0000 (02:12 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Feb 2014 02:12:43 +0000 (02:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128339

Reviewed by Simon Fraser.

Source/WebCore:

This patch gets rid of CoverageForSlowScrolling in the TileController. It also
makes sure that margin tiles are properly invalidated on pages with slow repaint
objects that cause slow scrolling.

When we invalidate because of slow scrolling, don’t clip the update rect to the
layer bounds.
* page/FrameView.cpp:
(WebCore::FrameView::scrollContentsSlowPath):

Call new RenderObject paint function repaintSlowRepaintObject() instead of the
more-generic repaint().
(WebCore::FrameView::repaintSlowRepaintObjects):

Remove CoverageForSlowScrolling.
* platform/graphics/TiledBacking.h:
* platform/graphics/ca/mac/TileController.h:
* platform/graphics/ca/mac/TileController.mm:
(WebCore::TileController::tilesWouldChangeForVisibleRect):
(WebCore::TileController::computeTileCoverageRect):
(WebCore::TileController::revalidateTiles):
* rendering/RenderLayerBacking.cpp:
(WebCore::computeTileCoverage):

Handle repainting a slow repaint object. Don’t clip when we shouldn’t, use the
RenderView’s backgroundRect as a repaintRect when this is the root background
since that will take the extended background rect into consideration.
* rendering/RenderObject.cpp:
(WebCore::RenderObject::repaintSlowRepaintObject):
* rendering/RenderObject.h:

LayoutTests:

Slow scrolling no longer creates tiles of a different size.

* platform/mac-wk2/tiled-drawing/fixed-background/fixed-non-propagated-body-background-expected.txt:
* platform/mac-wk2/tiled-drawing/tile-coverage-slow-scrolling-expected.txt:
* platform/mac-wk2/tiled-drawing/tile-size-slow-zoomed-expected.txt:

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background/fixed-non-propagated-body-background-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/tile-coverage-slow-scrolling-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/tile-size-slow-zoomed-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/platform/graphics/TiledBacking.h
Source/WebCore/platform/graphics/ca/mac/TileController.h
Source/WebCore/platform/graphics/ca/mac/TileController.mm
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h

index 6340fbf..ac2ea5e 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-07  Beth Dakin  <bdakin@apple.com>
+
+        Should get rid of TileController's CoverageForSlowScrolling mode
+        https://bugs.webkit.org/show_bug.cgi?id=128339
+
+        Reviewed by Simon Fraser.
+
+        Slow scrolling no longer creates tiles of a different size.
+
+        * platform/mac-wk2/tiled-drawing/fixed-background/fixed-non-propagated-body-background-expected.txt:
+        * platform/mac-wk2/tiled-drawing/tile-coverage-slow-scrolling-expected.txt:
+        * platform/mac-wk2/tiled-drawing/tile-size-slow-zoomed-expected.txt:
+
 2014-02-07  Brady Eidson  <beidson@apple.com>
 
         IDB: Some Mozilla cursor mutation tests fail
index ca4df10..d263b3d 100644 (file)
@@ -5,9 +5,9 @@
       (bounds 785.00 1700.00)
       (contentsOpaque 1)
       (backgroundColor #C0C0C0)
-      (tile cache coverage 0, 0 785 x 1200)
-      (tile size 785 x 600)
-      (top left tile 0, 0 tiles grid 1 x 2)
+      (tile cache coverage 0, 0 785 x 1024)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
     )
   )
 )
index a0465d5..0a31c06 100644 (file)
@@ -9,8 +9,8 @@
       (visible rect 0.00, 0.00 800.00 x 600.00)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 800 x 600)
-      (tile size 800 x 600)
-      (top left tile 0, 0 tiles grid 1 x 1)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
     )
   )
 )
index 17bbb71..1c9ac8c 100644 (file)
@@ -10,9 +10,9 @@
       (transform [1.70 0.00 0.00 0.00] [0.00 1.70 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 0.00 1.00])
       (visible rect 0.00, 0.00 461.76 x 344.12)
       (contentsScale 1.00)
-      (tile cache coverage 0, 0 461 x 344)
-      (tile size 785 x 585)
-      (top left tile 0, 0 tiles grid 1 x 1)
+      (tile cache coverage 0, 0 602 x 585)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
     )
   )
 )
index cd3f3f4..acbe233 100644 (file)
@@ -1,3 +1,40 @@
+2014-02-07  Beth Dakin  <bdakin@apple.com>
+
+        Should get rid of TileController's CoverageForSlowScrolling mode
+        https://bugs.webkit.org/show_bug.cgi?id=128339
+
+        Reviewed by Simon Fraser.
+
+        This patch gets rid of CoverageForSlowScrolling in the TileController. It also 
+        makes sure that margin tiles are properly invalidated on pages with slow repaint 
+        objects that cause slow scrolling. 
+
+        When we invalidate because of slow scrolling, don’t clip the update rect to the 
+        layer bounds.
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollContentsSlowPath):
+
+        Call new RenderObject paint function repaintSlowRepaintObject() instead of the 
+        more-generic repaint().
+        (WebCore::FrameView::repaintSlowRepaintObjects):
+
+        Remove CoverageForSlowScrolling.
+        * platform/graphics/TiledBacking.h:
+        * platform/graphics/ca/mac/TileController.h:
+        * platform/graphics/ca/mac/TileController.mm:
+        (WebCore::TileController::tilesWouldChangeForVisibleRect):
+        (WebCore::TileController::computeTileCoverageRect):
+        (WebCore::TileController::revalidateTiles):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::computeTileCoverage):
+
+        Handle repainting a slow repaint object. Don’t clip when we shouldn’t, use the 
+        RenderView’s backgroundRect as a repaintRect when this is the root background 
+        since that will take the extended background rect into consideration.
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::repaintSlowRepaintObject):
+        * rendering/RenderObject.h:
+
 2014-02-06  Filip Pizlo  <fpizlo@apple.com>
 
         More FTL build scaffolding
index 047f620..584f0fb 100644 (file)
@@ -1710,7 +1710,7 @@ void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
         updateRect.scale(1 / frame().frameScaleFactor());
 
         ASSERT(renderView());
-        renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
+        renderView()->layer()->setBackingNeedsRepaintInRect(updateRect, GraphicsLayer::DoNotClipToLayer);
     }
 
     repaintSlowRepaintObjects();
@@ -1736,7 +1736,7 @@ void FrameView::repaintSlowRepaintObjects()
     // Renderers with fixed backgrounds may be in compositing layers, so we need to explicitly
     // repaint them after scrolling.
     for (auto& renderer : *m_slowRepaintObjects)
-        renderer->repaint();
+        renderer->repaintSlowRepaintObject();
 }
 
 // Note that this gets called at painting time.
index d40e5ed..e0165e0 100644 (file)
@@ -60,7 +60,6 @@ public:
         CoverageForVisibleArea = 0,
         CoverageForVerticalScrolling = 1 << 0,
         CoverageForHorizontalScrolling = 1 << 1,
-        CoverageForSlowScrolling = 1 << 2, // Indicates that we expect to paint a lot on scrolling.
         CoverageForScrolling = CoverageForVerticalScrolling | CoverageForHorizontalScrolling
     };
     typedef unsigned TileCoverage;
index 449eee2..5ee227b 100644 (file)
@@ -159,7 +159,6 @@ private:
     void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight) const;
 
     FloatRect computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const;
-    IntSize computeTileSize() const;
 
     void scheduleTileRevalidation(double interval);
     void tileRevalidationTimerFired(Timer<TileController>*);
index fb93afa..419b395 100644 (file)
@@ -299,11 +299,6 @@ bool TileController::tilesWouldChangeForVisibleRect(const FloatRect& newVisibleR
     scaledRect.scale(m_scale);
     IntRect currentCoverageRectInTileCoords(enclosingIntRect(scaledRect));
 
-    IntSize newTileSize = computeTileSize();
-    bool tileSizeChanged = newTileSize != m_tileSize;
-    if (tileSizeChanged)
-        return true;
-
     TileIndex topLeft;
     TileIndex bottomRight;
     getTileIndexRangeForRect(currentCoverageRectInTileCoords, topLeft, bottomRight);
@@ -499,38 +494,6 @@ FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisib
     if (!m_isInWindow)
         return visibleRect;
 
-    // If our tile coverage is just for slow-scrolling, then we want to limit the tile coverage to the visible rect, but
-    // we should include the margin tiles if we're close to an edge.
-    if (m_tileCoverage & CoverageForSlowScrolling) {
-        FloatSize coverageSize = visibleRect.size();
-        FloatPoint coverageOrigin = visibleRect.location();
-        float tileWidth = visibleRect.width();
-        float tileHeight = visibleRect.height();
-
-        // We're within one tile from the top, so we should make sure we have a top-margin tile.
-        if (visibleRect.y() < tileHeight) {
-            coverageSize.setHeight(coverageSize.height() + topMarginHeight());
-            coverageOrigin.setY(coverageOrigin.y() - topMarginHeight());
-        }
-
-        // We're within one tile from the left edge, so we should make sure we have a left-margin tile.
-        if (visibleRect.x() < tileWidth) {
-            coverageSize.setWidth(coverageSize.width() + leftMarginWidth());
-            coverageOrigin.setX(coverageOrigin.x() - leftMarginWidth());
-        }
-
-        IntSize layerSize = expandedIntSize(m_tileCacheLayer->bounds().size());
-        // We're within one tile from the bottom edge, so we should make sure we have a bottom-margin tile.
-        if (visibleRect.y() + tileHeight > layerSize.height() - tileHeight)
-            coverageSize.setHeight(coverageSize.height() + bottomMarginHeight());
-
-        // We're within one tile from the right edge, so we should make sure we have a right-margin tile.
-        if (visibleRect.x() + tileWidth > layerSize.width() - tileWidth)
-            coverageSize.setWidth(coverageSize.width() + rightMarginWidth());
-
-        return FloatRect(coverageOrigin, coverageSize);
-    }
-
     bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);
     
     // FIXME: look at how far the document can scroll in each dimension.
@@ -561,17 +524,6 @@ FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisib
     return FloatRect(coverageLeft, coverageTop, coverageHorizontalSize, coverageVerticalSize);
 }
 
-IntSize TileController::computeTileSize() const
-{
-    if (m_tileCoverage & CoverageForSlowScrolling) {
-        FloatSize tileSize = m_visibleRect.size();
-        tileSize.scale(m_scale);
-        return expandedIntSize(tileSize);
-    }
-
-    return IntSize(defaultTileWidth, defaultTileHeight);
-}
-
 void TileController::scheduleTileRevalidation(double interval)
 {
     if (m_tileRevalidationTimer.isActive() && m_tileRevalidationTimer.nextFireInterval() < interval)
@@ -710,50 +662,41 @@ void TileController::revalidateTiles(TileValidationPolicyFlags foregroundValidat
     scaledRect.scale(m_scale);
     IntRect coverageRectInTileCoords(enclosingIntRect(scaledRect));
 
-    IntSize oldTileSize = m_tileSize;
-    m_tileSize = computeTileSize();
-    bool tileSizeChanged = m_tileSize != oldTileSize;
+    TileCohort currCohort = nextTileCohort();
+    unsigned tilesInCohort = 0;
 
-    if (tileSizeChanged) {
-        removeAllTiles();
-        m_cohortList.clear();
-    } else {
-        TileCohort currCohort = nextTileCohort();
-        unsigned tilesInCohort = 0;
-        
-        // Move tiles newly outside the coverage rect into the cohort map.
-        for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
-            TileInfo& tileInfo = it->value;
-            TileIndex tileIndex = it->key;
+    // Move tiles newly outside the coverage rect into the cohort map.
+    for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
+        TileInfo& tileInfo = it->value;
+        TileIndex tileIndex = it->key;
 
-            PlatformCALayer* tileLayer = tileInfo.layer.get();
-            IntRect tileRect = rectForTileIndex(tileIndex);
-            if (tileRect.intersects(coverageRectInTileCoords)) {
-                tileInfo.cohort = VisibleTileCohort;
-                if (tileInfo.hasStaleContent) {
-                    // FIXME: store a dirty region per layer?
-                    tileLayer->setNeedsDisplay();
-                    tileInfo.hasStaleContent = false;
-                }
-            } else {
-                // Add to the currentCohort if not already in one.
-                if (tileInfo.cohort == VisibleTileCohort) {
-                    tileInfo.cohort = currCohort;
-                    ++tilesInCohort;
-                    
-                    if (m_unparentsOffscreenTiles)
-                        tileLayer->removeFromSuperlayer();
-                }
+        PlatformCALayer* tileLayer = tileInfo.layer.get();
+        IntRect tileRect = rectForTileIndex(tileIndex);
+        if (tileRect.intersects(coverageRectInTileCoords)) {
+            tileInfo.cohort = VisibleTileCohort;
+            if (tileInfo.hasStaleContent) {
+                // FIXME: store a dirty region per layer?
+                tileLayer->setNeedsDisplay();
+                tileInfo.hasStaleContent = false;
             }
-        }
-        
-        if (tilesInCohort)
-            startedNewCohort(currCohort);
+        } else {
+            // Add to the currentCohort if not already in one.
+            if (tileInfo.cohort == VisibleTileCohort) {
+                tileInfo.cohort = currCohort;
+                ++tilesInCohort;
 
-        if (!m_aggressivelyRetainsTiles)
-            scheduleCohortRemoval();
+                if (m_unparentsOffscreenTiles)
+                    tileLayer->removeFromSuperlayer();
+            }
+        }
     }
 
+    if (tilesInCohort)
+        startedNewCohort(currCohort);
+
+    if (!m_aggressivelyRetainsTiles)
+        scheduleCohortRemoval();
+
     // Ensure primary tile coverage tiles.
     m_primaryTileCoverageRect = ensureTilesForRect(tileCoverageRect, CoverageType::PrimaryTiles);
 
index 956b0ad..611fc68 100644 (file)
@@ -216,12 +216,6 @@ static TiledBacking::TileCoverage computeTileCoverage(RenderLayerBacking* backin
         if (frameView.verticalScrollbarMode() != ScrollbarAlwaysOff || clipsToExposedRect)
             tileCoverage |= TiledBacking::CoverageForVerticalScrolling;
     }
-    if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(backing->owningLayer())) {
-        // Ask our TiledBacking for large tiles unless the only reason we're main-thread-scrolling
-        // is a page overlay (find-in-page, the Web Inspector highlight mechanism, etc.).
-        if (scrollingCoordinator->synchronousScrollingReasons() & ~ScrollingCoordinator::ForcedOnMainThread)
-            tileCoverage |= TiledBacking::CoverageForSlowScrolling;
-    }
     return tileCoverage;
 }
 
index b8b6a22..b26fbce 100644 (file)
@@ -1304,6 +1304,35 @@ void RenderObject::repaintRectangle(const LayoutRect& r, bool immediate, bool sh
     repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(dirtyRect), immediate, shouldClipToLayer);
 }
 
+void RenderObject::repaintSlowRepaintObject() const
+{
+    // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
+    RenderView* view;
+    if (!isRooted(&view))
+        return;
+
+    // Don't repaint if we're printing.
+    if (view->printing())
+        return;
+
+    RenderLayerModelObject* repaintContainer = containerForRepaint();
+    if (!repaintContainer)
+        repaintContainer = view;
+
+    bool shouldClipToLayer = true;
+    IntRect repaintRect;
+
+    // If this is the root background, we need to check if there is an extended background rect. If
+    // there is, then we should not allow painting to clip to the layer size.
+    if (isRoot() || isBody()) {
+        shouldClipToLayer = !view->frameView().hasExtendedBackgroundRectForPainting();
+        repaintRect = pixelSnappedIntRect(view->backgroundRect(view));
+    } else
+        repaintRect = pixelSnappedIntRect(clippedOverflowRectForRepaint(repaintContainer));
+
+    repaintUsingContainer(repaintContainer, repaintRect, false, shouldClipToLayer);
+}
+
 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
 {
     return pixelSnappedIntRect(absoluteClippedOverflowRect());
index f4b0993..91872ac 100644 (file)
@@ -733,6 +733,9 @@ public:
     // Repaint a specific subrectangle within a given object.  The rect |r| is in the object's coordinate space.
     void repaintRectangle(const LayoutRect&, bool immediate = false, bool shouldClipToLayer = true) const;
 
+    // Repaint a slow repaint object, which, at this time, means we are repainting an object with background-attachment:fixed.
+    void repaintSlowRepaintObject() const;
+
     bool checkForRepaintDuringLayout() const;
 
     // Returns the rect that should be repainted whenever this object changes.  The rect is in the view's