https://bugs.webkit.org/show_bug.cgi?id=100169
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Oct 2012 00:19:35 +0000 (00:19 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Oct 2012 00:19:35 +0000 (00:19 +0000)
We should make TileCache tiles the size of the tile coverage rect
when we can't do fast scrolling
-and-
<rdar://problem/12505021>

Reviewed by Simon Fraser.

Source/WebCore:

Some websites that don't do fast scrolling still scroll slower than
they do with tiled drawing disabled.
https://bugs.webkit.org/show_bug.cgi?id=99768 addressed some of this
performance problem, but there is still more ground to make up. This
patch addresses the remaining issue by making tiles the size of the
window when we can't do fast scrolling.

The constructor and create function no longer take a size parameter.
That's all fully controlled within TileCache now. m_tileSize is no
longer const.
* platform/graphics/ca/mac/TileCache.h:

Store the current default size as constants so that we can access it
in both the constructor and adjustTileSizeForCoverageRect().
* platform/graphics/ca/mac/TileCache.mm:
(WebCore::TileCache::TileCache):

This new function will set m_tileSize to the size of the tile
coverage rect if the tile coverage is limited to the visible area.
Otherwise, the tiles are set to be the default size.
(WebCore::TileCache::adjustTileSizeForCoverageRect):

Call adjustTileSizeForCoverageRect().
(WebCore::TileCache::revalidateTiles):

No need to send in a size anymore.
* platform/graphics/ca/mac/WebTileCacheLayer.h:
(WebCore):

LayoutTests:

New test.
* platform/mac/tiled-drawing/tile-coverage-slow-scrolling-expected.txt: Added.
* platform/mac/tiled-drawing/tile-coverage-slow-scrolling.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/platform/mac/tiled-drawing/tile-coverage-slow-scrolling-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/tiled-drawing/tile-coverage-slow-scrolling.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ca/mac/TileCache.h
Source/WebCore/platform/graphics/ca/mac/TileCache.mm
Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm

index c1f02b6..234e405 100644 (file)
@@ -1,3 +1,17 @@
+2012-10-24  Beth Dakin  <bdakin@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=100169
+        We should make TileCache tiles the size of the tile coverage rect 
+        when we can't do fast scrolling
+        -and-
+        <rdar://problem/12505021>
+
+        Reviewed by Simon Fraser.
+
+        New test.
+        * platform/mac/tiled-drawing/tile-coverage-slow-scrolling-expected.txt: Added.
+        * platform/mac/tiled-drawing/tile-coverage-slow-scrolling.html: Added.
+
 2012-10-24  David Barton  <dbarton@mathscribe.com>
 
         MathML tests trigger font cache assertions in debug bots
diff --git a/LayoutTests/platform/mac/tiled-drawing/tile-coverage-slow-scrolling-expected.txt b/LayoutTests/platform/mac/tiled-drawing/tile-coverage-slow-scrolling-expected.txt
new file mode 100644 (file)
index 0000000..e7c8eae
--- /dev/null
@@ -0,0 +1,19 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (visible rect 0.00, 0.00 800.00 x 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (visible rect 0.00, 0.00 800.00 x 600.00)
+      (tile cache coverage 0, 0 800 x 600)
+      (children 1
+        (GraphicsLayer
+          (visible rect 0.00, 0.00 0.00 x 0.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac/tiled-drawing/tile-coverage-slow-scrolling.html b/LayoutTests/platform/mac/tiled-drawing/tile-coverage-slow-scrolling.html
new file mode 100644 (file)
index 0000000..3faf9cf
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            height: 100px;
+            width: 100px;
+            position: fixed; /* At this time, position:fixed forces slow mode. */
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function doTest()
+        {
+            if (window.internals) {
+                document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+                    internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+            }
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<div class="box">
+</div>
+<pre id="layers">Layer tree goes here</p>
+</body>
+</html>
index 2744e5b..3366332 100644 (file)
@@ -1,3 +1,42 @@
+2012-10-24  Beth Dakin  <bdakin@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=100169
+        We should make TileCache tiles the size of the tile coverage rect 
+        when we can't do fast scrolling
+        -and-
+        <rdar://problem/12505021>
+
+        Reviewed by Simon Fraser.
+
+        Some websites that don't do fast scrolling still scroll slower than 
+        they do with tiled drawing disabled. 
+        https://bugs.webkit.org/show_bug.cgi?id=99768 addressed some of this 
+        performance problem, but there is still more ground to make up. This 
+        patch addresses the remaining issue by making tiles the size of the 
+        window when we can't do fast scrolling. 
+
+        The constructor and create function no longer take a size parameter. 
+        That's all fully controlled within TileCache now. m_tileSize is no 
+        longer const.
+        * platform/graphics/ca/mac/TileCache.h:
+
+        Store the current default size as constants so that we can access it 
+        in both the constructor and adjustTileSizeForCoverageRect().
+        * platform/graphics/ca/mac/TileCache.mm:
+        (WebCore::TileCache::TileCache):
+
+        This new function will set m_tileSize to the size of the tile 
+        coverage rect if the tile coverage is limited to the visible area. 
+        Otherwise, the tiles are set to be the default size.
+        (WebCore::TileCache::adjustTileSizeForCoverageRect):
+        
+        Call adjustTileSizeForCoverageRect().
+        (WebCore::TileCache::revalidateTiles):
+
+        No need to send in a size anymore.
+        * platform/graphics/ca/mac/WebTileCacheLayer.h:
+        (WebCore):
+
 2012-10-24  David Barton  <dbarton@mathscribe.com>
 
         MathML tests trigger font cache assertions in debug bots
index a03d6d8..b564298 100644 (file)
@@ -51,7 +51,7 @@ class TileCache : public TiledBacking {
     WTF_MAKE_NONCOPYABLE(TileCache);
 
 public:
-    static PassOwnPtr<TileCache> create(WebTileCacheLayer*, const IntSize& tileSize);
+    static PassOwnPtr<TileCache> create(WebTileCacheLayer*);
     ~TileCache();
 
     void tileCacheLayerBoundsChanged();
@@ -79,7 +79,7 @@ public:
     static unsigned blankPixelCountForTiles(const WebTileLayerList&, IntRect, IntPoint);
 
 private:
-    TileCache(WebTileCacheLayer*, const IntSize& tileSize);
+    TileCache(WebTileCacheLayer*);
 
     // TiledBacking member functions.
     virtual void setVisibleRect(const IntRect&) OVERRIDE;
@@ -99,6 +99,7 @@ private:
     void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight);
 
     IntRect computeTileCoverageRect() const;
+    IntSize tileSizeForCoverageRect(const IntRect&) const;
 
     void scheduleTileRevalidation(double interval);
     void tileRevalidationTimerFired(Timer<TileCache>*);
@@ -112,7 +113,7 @@ private:
 
     WebTileCacheLayer* m_tileCacheLayer;
     RetainPtr<CALayer> m_tileContainerLayer;
-    const IntSize m_tileSize;
+    IntSize m_tileSize;
     IntRect m_visibleRect;
 
     typedef HashMap<TileIndex, RetainPtr<WebTileLayer> > TileMap;
index 8aaf87d..5c280f2 100644 (file)
@@ -45,15 +45,18 @@ using namespace std;
 
 namespace WebCore {
 
-PassOwnPtr<TileCache> TileCache::create(WebTileCacheLayer* tileCacheLayer, const IntSize& tileSize)
+static const int defaultTileCacheWidth = 512;
+static const int defaultTileCacheHeight = 512;
+
+PassOwnPtr<TileCache> TileCache::create(WebTileCacheLayer* tileCacheLayer)
 {
-    return adoptPtr(new TileCache(tileCacheLayer, tileSize));
+    return adoptPtr(new TileCache(tileCacheLayer));
 }
 
-TileCache::TileCache(WebTileCacheLayer* tileCacheLayer, const IntSize& tileSize)
+TileCache::TileCache(WebTileCacheLayer* tileCacheLayer)
     : m_tileCacheLayer(tileCacheLayer)
     , m_tileContainerLayer(adoptCF([[CALayer alloc] init]))
-    , m_tileSize(tileSize)
+    , m_tileSize(defaultTileCacheWidth, defaultTileCacheHeight)
     , m_tileRevalidationTimer(this, &TileCache::tileRevalidationTimerFired)
     , m_scale(1)
     , m_deviceScaleFactor(1)
@@ -300,8 +303,12 @@ void TileCache::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft
 
     topLeft.setX(max(clampedRect.x() / m_tileSize.width(), 0));
     topLeft.setY(max(clampedRect.y() / m_tileSize.height(), 0));
-    bottomRight.setX(max(clampedRect.maxX() / m_tileSize.width(), 0));
-    bottomRight.setY(max(clampedRect.maxY() / m_tileSize.height(), 0));
+
+    int bottomXRatio = ceil((float)clampedRect.maxX() / m_tileSize.width());
+    bottomRight.setX(max(bottomXRatio - 1, 0));
+
+    int bottomYRatio = ceil((float)clampedRect.maxY() / m_tileSize.height());
+    bottomRight.setY(max(bottomYRatio - 1, 0));
 }
 
 IntRect TileCache::computeTileCoverageRect() const
@@ -325,6 +332,13 @@ IntRect TileCache::computeTileCoverageRect() const
     return tileCoverageRect;
 }
 
+IntSize TileCache::tileSizeForCoverageRect(const IntRect& coverageRect) const
+{
+    if (m_tileCoverage == CoverageForVisibleArea)
+        return coverageRect.size();
+    return IntSize(defaultTileCacheWidth, defaultTileCacheHeight);
+}
+
 void TileCache::scheduleTileRevalidation(double interval)
 {
     if (m_tileRevalidationTimer.isActive() && m_tileRevalidationTimer.nextFireInterval() < interval)
@@ -379,6 +393,10 @@ void TileCache::revalidateTiles()
 
     IntRect tileCoverageRect = computeTileCoverageRect();
 
+    IntSize oldTileSize = m_tileSize;
+    m_tileSize = tileSizeForCoverageRect(tileCoverageRect);
+    bool tileSizeChanged = m_tileSize != oldTileSize;
+
     Vector<TileIndex> tilesToRemove;
 
     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
@@ -386,7 +404,7 @@ void TileCache::revalidateTiles()
 
         WebTileLayer* tileLayer = it->value.get();
 
-        if (!rectForTileIndex(tileIndex).intersects(tileCoverageRect)) {
+        if (!rectForTileIndex(tileIndex).intersects(tileCoverageRect) || tileSizeChanged) {
             // Remove this layer.
             [tileLayer removeFromSuperlayer];
             [tileLayer setTileCache:0];
index c6aab8a..d119f5b 100644 (file)
@@ -40,8 +40,7 @@ using namespace WebCore;
     if (!self)
         return nil;
 
-    // FIXME: The tile size should be configurable.
-    _tileCache = TileCache::create(self, IntSize(512, 512));
+    _tileCache = TileCache::create(self);
 #ifndef NDEBUG
     [self setName:@"WebTileCacheLayer"];
 #endif