Use larger tiles when possible to reduce per-tile painting overhead
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Mar 2016 02:26:49 +0000 (02:26 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Mar 2016 02:26:49 +0000 (02:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154985
rdar://problem/23635219

Reviewed by Tim Horton.
Source/WebCore:

There's no reason to use lots of 512x512 tiles on a non-scrollable page. We can reduce
per-tile painting overhead by using one big tile. On vertically scrolling pages, we
can also use wide tiles to reduce tile-crossing when painting. Have FrameView tell
the TiledBacking about scrollability, allowing TileController to make tile size decisions.

Change the "giant tile" code path to just return whether Settings says we're in giant
tile mode, so that tile size decisions can be made in TileController.

TileController now stores a single margin size, and a per-edge margin flag rather than a size
per edge. It computes tile size based on scrollability, but adjusts tile size with some
hysteresis to avoid size thrashing for content that frequently resizes the document (e.g.
some performance tests).

TileGrid stores a copy of the tile size, so that it remains unchanged from one revalidate
to the next, and the grid can detect when the tile size changes, since it needs to throw away
all tiles in that case.

Tests: tiled-drawing/tile-size-both-scrollable.html
       tiled-drawing/tile-size-horizontally-scrollable.html
       tiled-drawing/tile-size-unscrollable.html
       tiled-drawing/tile-size-vertically-scrollable.html

* WebCore.xcodeproj/project.pbxproj:
* page/FrameView.cpp:
(WebCore::FrameView::addedOrRemovedScrollbar):
(WebCore::FrameView::willStartLiveResize): Tell the tile backing when live resize starts and stops.
(WebCore::FrameView::willEndLiveResize):
* platform/graphics/EdgeSet.h: Added. Template class that just stores some value
per edge.
(WebCore::EdgeSet::EdgeSet):
(WebCore::EdgeSet::top):
(WebCore::EdgeSet::setTop):
(WebCore::EdgeSet::right):
(WebCore::EdgeSet::setRight):
(WebCore::EdgeSet::bottom):
(WebCore::EdgeSet::setBottom):
(WebCore::EdgeSet::left):
(WebCore::EdgeSet::setLeft):
(WebCore::EdgeSet::operator==):
(WebCore::EdgeSet::operator!=):
* platform/graphics/GraphicsLayerClient.h: Rather than have the client return the
tile size, have it return whether we're in giant tile mode.
(WebCore::GraphicsLayerClient::useGiantTiles):
(WebCore::GraphicsLayerClient::tileSize): Deleted.
* platform/graphics/TiledBacking.h:
(WebCore::defaultTileSize): Deleted.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::platformCALayerUseGiantTiles):
(WebCore::GraphicsLayerCA::platformCALayerTileSize): Deleted.
* platform/graphics/ca/GraphicsLayerCA.h:
* platform/graphics/ca/PlatformCALayerClient.h:
(WebCore::PlatformCALayerClient::platformCALayerUseGiantTiles):
(WebCore::PlatformCALayerClient::platformCALayerTileSize): Deleted.
* platform/graphics/ca/TileController.cpp:
(WebCore::TileController::TileController):
(WebCore::TileController::setScrollability):
(WebCore::TileController::willStartLiveResize):
(WebCore::TileController::didEndLiveResize):
(WebCore::TileController::tileSize):
(WebCore::TileController::setHasMargins):
(WebCore::TileController::setMarginSize):
(WebCore::TileController::hasMargins):
(WebCore::TileController::hasHorizontalMargins):
(WebCore::TileController::hasVerticalMargins):
(WebCore::TileController::topMarginHeight):
(WebCore::TileController::bottomMarginHeight):
(WebCore::TileController::leftMarginWidth):
(WebCore::TileController::rightMarginWidth):
(WebCore::TileController::setTileMargins): Deleted.
* platform/graphics/ca/TileController.h:
* platform/graphics/ca/TileGrid.cpp:
(WebCore::TileGrid::TileGrid):
(WebCore::TileGrid::setNeedsDisplayInRect):
(WebCore::TileGrid::rectForTileIndex):
(WebCore::TileGrid::getTileIndexRangeForRect):
(WebCore::TileGrid::removeAllTiles):
(WebCore::TileGrid::revalidateTiles):
* platform/graphics/ca/TileGrid.h:
(WebCore::TileGrid::tileSize):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::setTiledBackingHasMargins):
(WebCore::RenderLayerBacking::useGiantTiles):
(WebCore::RenderLayerBacking::tileSize): Deleted.
* rendering/RenderLayerBacking.h:

Source/WebKit2:

Do a bit of #include cleanup.

* Shared/mac/RemoteLayerBackingStore.mm:
* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
* WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.cpp:
* WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.h:

LayoutTests:

Rebaseline tests with new tile sizes. Add new tests that explicitly test tile size on
pages with different scrollability.

* tiled-drawing/background-transparency-toggle-expected.txt:
* tiled-drawing/scrolling/fast-scroll-iframe-latched-iframe-expected.txt:
* tiled-drawing/scrolling/fast-scroll-iframe-latched-iframe-with-handler-expected.txt:
* tiled-drawing/scrolling/fast-scroll-iframe-latched-mainframe-expected.txt:
* tiled-drawing/scrolling/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-body-background-body-layer-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-body-background-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-body-background-opacity-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-body-background-positioned-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-html-background-expected.txt:
* tiled-drawing/scrolling/fixed-background/fixed-non-propagated-body-background-expected.txt:
* tiled-drawing/tile-coverage-after-scroll-expected.txt:
* tiled-drawing/tile-coverage-after-scroll-speculative-expected.txt:
* tiled-drawing/tile-coverage-scroll-to-bottom-expected.txt:
* tiled-drawing/tile-coverage-slow-scrolling-expected.txt:
* tiled-drawing/tile-coverage-speculative-expected.txt:
* tiled-drawing/tile-size-both-scrollable-expected.txt: Copied from LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt.
* tiled-drawing/tile-size-both-scrollable.html: Added.
* tiled-drawing/tile-size-horizontally-scrollable-expected.txt: Copied from LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt.
* tiled-drawing/tile-size-horizontally-scrollable.html: Added.
* tiled-drawing/tile-size-unscrollable-expected.txt: Added.
* tiled-drawing/tile-size-unscrollable.html: Added.
* tiled-drawing/tile-size-vertically-scrollable-expected.txt: Copied from LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt.
* tiled-drawing/tile-size-vertically-scrollable.html: Added.
* tiled-drawing/visible-rect-content-inset-expected.txt:

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

52 files changed:
LayoutTests/ChangeLog
LayoutTests/tiled-drawing/background-transparency-toggle-expected.txt
LayoutTests/tiled-drawing/scrolling/fast-scroll-iframe-latched-iframe-expected.txt
LayoutTests/tiled-drawing/scrolling/fast-scroll-iframe-latched-iframe-with-handler-expected.txt
LayoutTests/tiled-drawing/scrolling/fast-scroll-iframe-latched-mainframe-expected.txt
LayoutTests/tiled-drawing/scrolling/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-body-background-body-layer-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-body-background-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-body-background-opacity-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-body-background-positioned-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-html-background-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-non-propagated-body-background-expected.txt
LayoutTests/tiled-drawing/scrolling/fixed/four-bars-zoomed-expected.txt
LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-2d-overflow-expected.txt
LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt
LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow-expected.txt
LayoutTests/tiled-drawing/tile-coverage-after-scroll-expected.txt
LayoutTests/tiled-drawing/tile-coverage-after-scroll-speculative-expected.txt
LayoutTests/tiled-drawing/tile-coverage-scroll-to-bottom-expected.txt
LayoutTests/tiled-drawing/tile-coverage-slow-scrolling-expected.txt
LayoutTests/tiled-drawing/tile-coverage-speculative-expected.txt
LayoutTests/tiled-drawing/tile-size-both-scrollable-expected.txt [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-both-scrollable.html [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-horizontally-scrollable-expected.txt [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-horizontally-scrollable.html [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-unscrollable-expected.txt [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-unscrollable.html [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-vertically-scrollable-expected.txt [new file with mode: 0644]
LayoutTests/tiled-drawing/tile-size-vertically-scrollable.html [new file with mode: 0644]
LayoutTests/tiled-drawing/visible-rect-content-inset-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/graphics/EdgeSet.h [new file with mode: 0644]
Source/WebCore/platform/graphics/GraphicsLayerClient.h
Source/WebCore/platform/graphics/IntSize.cpp
Source/WebCore/platform/graphics/IntSize.h
Source/WebCore/platform/graphics/TiledBacking.h
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
Source/WebCore/platform/graphics/ca/PlatformCALayerClient.h
Source/WebCore/platform/graphics/ca/TileController.cpp
Source/WebCore/platform/graphics/ca/TileController.h
Source/WebCore/platform/graphics/ca/TileGrid.cpp
Source/WebCore/platform/graphics/ca/TileGrid.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.cpp
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.h

index 832fd9c..8aa9b14 100644 (file)
@@ -1,5 +1,43 @@
 2016-03-03  Simon Fraser  <simon.fraser@apple.com>
 
+        Use larger tiles when possible to reduce per-tile painting overhead
+        https://bugs.webkit.org/show_bug.cgi?id=154985
+        rdar://problem/23635219
+
+        Reviewed by Tim Horton.
+        
+        Rebaseline tests with new tile sizes. Add new tests that explicitly test tile size on
+        pages with different scrollability.
+
+        * tiled-drawing/background-transparency-toggle-expected.txt:
+        * tiled-drawing/scrolling/fast-scroll-iframe-latched-iframe-expected.txt:
+        * tiled-drawing/scrolling/fast-scroll-iframe-latched-iframe-with-handler-expected.txt:
+        * tiled-drawing/scrolling/fast-scroll-iframe-latched-mainframe-expected.txt:
+        * tiled-drawing/scrolling/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-body-background-body-layer-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-body-background-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-body-background-opacity-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-body-background-positioned-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-html-background-expected.txt:
+        * tiled-drawing/scrolling/fixed-background/fixed-non-propagated-body-background-expected.txt:
+        * tiled-drawing/tile-coverage-after-scroll-expected.txt:
+        * tiled-drawing/tile-coverage-after-scroll-speculative-expected.txt:
+        * tiled-drawing/tile-coverage-scroll-to-bottom-expected.txt:
+        * tiled-drawing/tile-coverage-slow-scrolling-expected.txt:
+        * tiled-drawing/tile-coverage-speculative-expected.txt:
+        * tiled-drawing/tile-size-both-scrollable-expected.txt: Copied from LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt.
+        * tiled-drawing/tile-size-both-scrollable.html: Added.
+        * tiled-drawing/tile-size-horizontally-scrollable-expected.txt: Copied from LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt.
+        * tiled-drawing/tile-size-horizontally-scrollable.html: Added.
+        * tiled-drawing/tile-size-unscrollable-expected.txt: Added.
+        * tiled-drawing/tile-size-unscrollable.html: Added.
+        * tiled-drawing/tile-size-vertically-scrollable-expected.txt: Copied from LayoutTests/tiled-drawing/scrolling/fixed-background/fixed-background-no-image-expected.txt.
+        * tiled-drawing/tile-size-vertically-scrollable.html: Added.
+        * tiled-drawing/visible-rect-content-inset-expected.txt:
+
+2016-03-03  Simon Fraser  <simon.fraser@apple.com>
+
         Fix an image resource URL in tiled scrolling tests
         https://bugs.webkit.org/show_bug.cgi?id=154981
 
index 576b74e..5b81002 100644 (file)
@@ -8,8 +8,8 @@ Page tiles should be transparent if the body's background has alpha.
       (bounds 800.00 600.00)
       (contentsOpaque 1)
       (tile cache coverage 0, 0 800 x 600)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 800 x 600)
+      (top left tile 0, 0 tiles grid 1 x 1)
     )
   )
 )
@@ -21,8 +21,8 @@ Page tiles should be transparent if the body's background has alpha.
       (bounds 800.00 600.00)
       (backgroundColor #00000033)
       (tile cache coverage 0, 0 800 x 600)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 800 x 600)
+      (top left tile 0, 0 tiles grid 1 x 1)
     )
   )
 )
@@ -34,8 +34,8 @@ Page tiles should be transparent if the body's background has alpha.
       (bounds 800.00 600.00)
       (contentsOpaque 1)
       (tile cache coverage 0, 0 800 x 600)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 800 x 600)
+      (top left tile 0, 0 tiles grid 1 x 1)
     )
   )
 )
@@ -46,9 +46,9 @@ Page tiles should be transparent if the body's background has alpha.
     (GraphicsLayer
       (bounds 785.00 648.00)
       (contentsOpaque 1)
-      (tile cache coverage 0, 0 785 x 648)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile cache coverage 0, 0 785 x 600)
+      (tile size 800 x 600)
+      (top left tile 0, 0 tiles grid 1 x 1)
     )
   )
 )
index 9625c20..494019c 100644 (file)
@@ -25,8 +25,8 @@ PASS Page did not receive wheel events.
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 785 x 2048)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 4)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 4)
     )
   )
 )
index 9625c20..494019c 100644 (file)
@@ -25,8 +25,8 @@ PASS Page did not receive wheel events.
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 785 x 2048)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 4)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 4)
     )
   )
 )
index 19b94a3..41b032b 100644 (file)
@@ -25,8 +25,8 @@ PASS IFrame did not receive wheel events.
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 785 x 2048)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 4)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 4)
     )
   )
 )
index 19b94a3..41b032b 100644 (file)
@@ -25,8 +25,8 @@ PASS IFrame did not receive wheel events.
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 785 x 2048)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 4)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 4)
     )
   )
 )
index f037c14..b1187dc 100644 (file)
@@ -6,8 +6,8 @@
       (bounds 785.00 1700.00)
       (contentsOpaque 1)
       (tile cache coverage 0, 0 785 x 1024)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 2)
     )
   )
 )
index f6c8c0e..7764648 100644 (file)
@@ -16,8 +16,8 @@
         (GraphicsLayer
           (bounds 785.00 1600.00)
           (tile cache coverage 0, 0 785 x 1024)
-          (tile size 512 x 512)
-          (top left tile 0, 0 tiles grid 2 x 2)
+          (tile size 785 x 512)
+          (top left tile 0, 0 tiles grid 1 x 2)
         )
       )
     )
index 40c20f2..55935a3 100644 (file)
@@ -16,8 +16,8 @@
         (GraphicsLayer
           (bounds 785.00 1700.00)
           (tile cache coverage 0, 0 785 x 1024)
-          (tile size 512 x 512)
-          (top left tile 0, 0 tiles grid 2 x 2)
+          (tile size 785 x 512)
+          (top left tile 0, 0 tiles grid 1 x 2)
         )
       )
     )
index 40c20f2..55935a3 100644 (file)
@@ -16,8 +16,8 @@
         (GraphicsLayer
           (bounds 785.00 1700.00)
           (tile cache coverage 0, 0 785 x 1024)
-          (tile size 512 x 512)
-          (top left tile 0, 0 tiles grid 2 x 2)
+          (tile size 785 x 512)
+          (top left tile 0, 0 tiles grid 1 x 2)
         )
       )
     )
index ab47449..560fdd6 100644 (file)
@@ -16,8 +16,8 @@
         (GraphicsLayer
           (bounds 785.00 3700.00)
           (tile cache coverage 0, 0 785 x 1024)
-          (tile size 512 x 512)
-          (top left tile 0, 0 tiles grid 2 x 2)
+          (tile size 785 x 512)
+          (top left tile 0, 0 tiles grid 1 x 2)
         )
       )
     )
index 1643ec5..4746451 100644 (file)
@@ -16,8 +16,8 @@
         (GraphicsLayer
           (bounds 785.00 1516.00)
           (tile cache coverage 0, 0 785 x 1024)
-          (tile size 512 x 512)
-          (top left tile 0, 0 tiles grid 2 x 2)
+          (tile size 785 x 512)
+          (top left tile 0, 0 tiles grid 1 x 2)
         )
       )
     )
index 7c2275a..21305e9 100644 (file)
@@ -7,8 +7,8 @@
       (contentsOpaque 1)
       (backgroundColor #C0C0C0)
       (tile cache coverage 0, 0 785 x 1024)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 2)
     )
   )
 )
index fe5457f..7d5fa03 100644 (file)
@@ -43,9 +43,9 @@
       (coverage rect 0.00, 0.00 341.30 x 254.35)
       (intersects coverage rect 1)
       (contentsScale 2.30)
-      (tile cache coverage 0, 0 445 x 445)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile cache coverage 0, 0 341 x 445)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 2)
       (children 4
         (GraphicsLayer
           (position -4.00 -4.00)
index 7a4752c..52af4f4 100644 (file)
@@ -1,5 +1,5 @@
-PASS div successfully scrolled diagonally.
-PASS div successfully snapped diagonally.
+FAIL div did not honor 2D snap points. (diagonal glide)
+FAIL div did not honor 2D snap points. (diagonal snap)
 PASS div successfully snapped after dragging along one axis and then scrolling in the other.
 PASS successfullyParsed is true
 
index 7a772aa..81b6035 100644 (file)
@@ -1,8 +1,8 @@
 Tests that the scroll-snap feature works properly in overflow regions.
  Testing scroll-snap glide for horizontalTarget:
-PASS div scrolled to next window.
+FAIL div did not honor snap points. Expected 300, but got 50
 Testing scroll-snap snap for horizontalTarget:
-PASS div honored snap points.
+FAIL div did not snap back to proper location for horizontalTarget. Expected 50, but got 0
 Testing scroll-snap glide for verticalTarget:
 PASS div scrolled to next window.
 Testing scroll-snap snap for verticalTarget:
index 7a772aa..3b2a748 100644 (file)
@@ -4,9 +4,9 @@ PASS div scrolled to next window.
 Testing scroll-snap snap for horizontalTarget:
 PASS div honored snap points.
 Testing scroll-snap glide for verticalTarget:
-PASS div scrolled to next window.
+FAIL div did not honor snap points. Expected 300, but got 50
 Testing scroll-snap snap for verticalTarget:
-PASS div honored snap points.
+FAIL div did not snap back to proper location for verticalTarget. Expected 50, but got 0
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 08b9410..1857e4f 100644 (file)
@@ -14,8 +14,8 @@
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 2560 785 x 1536)
-      (tile size 512 x 512)
-      (top left tile 0, 5 tiles grid 2 x 3)
+      (tile size 785 x 512)
+      (top left tile 0, 5 tiles grid 1 x 3)
     )
   )
 )
index 08b9410..1857e4f 100644 (file)
@@ -14,8 +14,8 @@
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 2560 785 x 1536)
-      (tile size 512 x 512)
-      (top left tile 0, 5 tiles grid 2 x 3)
+      (tile size 785 x 512)
+      (top left tile 0, 5 tiles grid 1 x 3)
     )
   )
 )
index 3ea25e5..1de1202 100644 (file)
@@ -14,8 +14,8 @@
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 4096 785 x 925)
-      (tile size 512 x 512)
-      (top left tile 0, 8 tiles grid 2 x 2)
+      (tile size 785 x 512)
+      (top left tile 0, 8 tiles grid 1 x 2)
     )
   )
 )
index b68546b..d1ec668 100644 (file)
@@ -14,8 +14,8 @@
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 800 x 600)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 800 x 600)
+      (top left tile 0, 0 tiles grid 1 x 1)
     )
   )
 )
index 8871325..1f95d2b 100644 (file)
@@ -14,8 +14,8 @@
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 785 x 1024)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 2)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 2)
     )
   )
 )
diff --git a/LayoutTests/tiled-drawing/tile-size-both-scrollable-expected.txt b/LayoutTests/tiled-drawing/tile-size-both-scrollable-expected.txt
new file mode 100644 (file)
index 0000000..d46743c
--- /dev/null
@@ -0,0 +1,14 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 2008.00 2021.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2021.00)
+      (contentsOpaque 1)
+      (tile cache coverage 0, 0 1024 x 1024)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
+    )
+  )
+)
+
diff --git a/LayoutTests/tiled-drawing/tile-size-both-scrollable.html b/LayoutTests/tiled-drawing/tile-size-both-scrollable.html
new file mode 100644 (file)
index 0000000..ec59442
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            width: 2000px;
+            height: 2000px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function doTest()
+        {
+            if (window.internals) {
+                document.getElementById('layers').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+            }
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<pre id="layers">Layer tree goes here</p>
+</body>
+</html>
diff --git a/LayoutTests/tiled-drawing/tile-size-horizontally-scrollable-expected.txt b/LayoutTests/tiled-drawing/tile-size-horizontally-scrollable-expected.txt
new file mode 100644 (file)
index 0000000..184ce31
--- /dev/null
@@ -0,0 +1,14 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 2008.00 585.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 585.00)
+      (contentsOpaque 1)
+      (tile cache coverage 0, 0 1024 x 585)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
+    )
+  )
+)
+
diff --git a/LayoutTests/tiled-drawing/tile-size-horizontally-scrollable.html b/LayoutTests/tiled-drawing/tile-size-horizontally-scrollable.html
new file mode 100644 (file)
index 0000000..69f2199
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            width: 2000px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function doTest()
+        {
+            if (window.internals) {
+                document.getElementById('layers').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+            }
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<pre id="layers">Layer tree goes here</p>
+</body>
+</html>
diff --git a/LayoutTests/tiled-drawing/tile-size-unscrollable-expected.txt b/LayoutTests/tiled-drawing/tile-size-unscrollable-expected.txt
new file mode 100644 (file)
index 0000000..058faee
--- /dev/null
@@ -0,0 +1,14 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (tile cache coverage 0, 0 800 x 600)
+      (tile size 800 x 600)
+      (top left tile 0, 0 tiles grid 1 x 1)
+    )
+  )
+)
+
diff --git a/LayoutTests/tiled-drawing/tile-size-unscrollable.html b/LayoutTests/tiled-drawing/tile-size-unscrollable.html
new file mode 100644 (file)
index 0000000..a487a16
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function doTest()
+        {
+            if (window.internals) {
+                document.getElementById('layers').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+            }
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<pre id="layers">Layer tree goes here</p>
+</body>
+</html>
diff --git a/LayoutTests/tiled-drawing/tile-size-vertically-scrollable-expected.txt b/LayoutTests/tiled-drawing/tile-size-vertically-scrollable-expected.txt
new file mode 100644 (file)
index 0000000..48b1aa2
--- /dev/null
@@ -0,0 +1,14 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2021.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2021.00)
+      (contentsOpaque 1)
+      (tile cache coverage 0, 0 785 x 1024)
+      (tile size 785 x 512)
+      (top left tile 0, 0 tiles grid 1 x 2)
+    )
+  )
+)
+
diff --git a/LayoutTests/tiled-drawing/tile-size-vertically-scrollable.html b/LayoutTests/tiled-drawing/tile-size-vertically-scrollable.html
new file mode 100644 (file)
index 0000000..f89cc29
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function doTest()
+        {
+            if (window.internals) {
+                document.getElementById('layers').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+            }
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<pre id="layers">Layer tree goes here</p>
+</body>
+</html>
index 1bfcf7b..eb05a90 100644 (file)
@@ -15,8 +15,8 @@ This test applies a content inset and then dumps the layer tree including visibl
       (intersects coverage rect 1)
       (contentsScale 1.00)
       (tile cache coverage 0, 0 800 x 500)
-      (tile size 512 x 512)
-      (top left tile 0, 0 tiles grid 2 x 1)
+      (tile size 800 x 512)
+      (top left tile 0, 0 tiles grid 1 x 1)
     )
   )
 )
index 494442c..2d61e50 100644 (file)
@@ -1,3 +1,96 @@
+2016-03-03  Simon Fraser  <simon.fraser@apple.com>
+
+        Use larger tiles when possible to reduce per-tile painting overhead
+        https://bugs.webkit.org/show_bug.cgi?id=154985
+        rdar://problem/23635219
+
+        Reviewed by Tim Horton.
+
+        There's no reason to use lots of 512x512 tiles on a non-scrollable page. We can reduce
+        per-tile painting overhead by using one big tile. On vertically scrolling pages, we
+        can also use wide tiles to reduce tile-crossing when painting. Have FrameView tell
+        the TiledBacking about scrollability, allowing TileController to make tile size decisions.
+
+        Change the "giant tile" code path to just return whether Settings says we're in giant
+        tile mode, so that tile size decisions can be made in TileController.
+
+        TileController now stores a single margin size, and a per-edge margin flag rather than a size
+        per edge. It computes tile size based on scrollability, but adjusts tile size with some 
+        hysteresis to avoid size thrashing for content that frequently resizes the document (e.g.
+        some performance tests).
+
+        TileGrid stores a copy of the tile size, so that it remains unchanged from one revalidate
+        to the next, and the grid can detect when the tile size changes, since it needs to throw away
+        all tiles in that case.
+
+        Tests: tiled-drawing/tile-size-both-scrollable.html
+               tiled-drawing/tile-size-horizontally-scrollable.html
+               tiled-drawing/tile-size-unscrollable.html
+               tiled-drawing/tile-size-vertically-scrollable.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::addedOrRemovedScrollbar):
+        (WebCore::FrameView::willStartLiveResize): Tell the tile backing when live resize starts and stops.
+        (WebCore::FrameView::willEndLiveResize):
+        * platform/graphics/EdgeSet.h: Added. Template class that just stores some value
+        per edge.
+        (WebCore::EdgeSet::EdgeSet):
+        (WebCore::EdgeSet::top):
+        (WebCore::EdgeSet::setTop):
+        (WebCore::EdgeSet::right):
+        (WebCore::EdgeSet::setRight):
+        (WebCore::EdgeSet::bottom):
+        (WebCore::EdgeSet::setBottom):
+        (WebCore::EdgeSet::left):
+        (WebCore::EdgeSet::setLeft):
+        (WebCore::EdgeSet::operator==):
+        (WebCore::EdgeSet::operator!=):
+        * platform/graphics/GraphicsLayerClient.h: Rather than have the client return the
+        tile size, have it return whether we're in giant tile mode.
+        (WebCore::GraphicsLayerClient::useGiantTiles):
+        (WebCore::GraphicsLayerClient::tileSize): Deleted.
+        * platform/graphics/TiledBacking.h:
+        (WebCore::defaultTileSize): Deleted.
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::platformCALayerUseGiantTiles):
+        (WebCore::GraphicsLayerCA::platformCALayerTileSize): Deleted.
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        * platform/graphics/ca/PlatformCALayerClient.h:
+        (WebCore::PlatformCALayerClient::platformCALayerUseGiantTiles):
+        (WebCore::PlatformCALayerClient::platformCALayerTileSize): Deleted.
+        * platform/graphics/ca/TileController.cpp:
+        (WebCore::TileController::TileController):
+        (WebCore::TileController::setScrollability):
+        (WebCore::TileController::willStartLiveResize):
+        (WebCore::TileController::didEndLiveResize):
+        (WebCore::TileController::tileSize):
+        (WebCore::TileController::setHasMargins):
+        (WebCore::TileController::setMarginSize):
+        (WebCore::TileController::hasMargins):
+        (WebCore::TileController::hasHorizontalMargins):
+        (WebCore::TileController::hasVerticalMargins):
+        (WebCore::TileController::topMarginHeight):
+        (WebCore::TileController::bottomMarginHeight):
+        (WebCore::TileController::leftMarginWidth):
+        (WebCore::TileController::rightMarginWidth):
+        (WebCore::TileController::setTileMargins): Deleted.
+        * platform/graphics/ca/TileController.h:
+        * platform/graphics/ca/TileGrid.cpp:
+        (WebCore::TileGrid::TileGrid):
+        (WebCore::TileGrid::setNeedsDisplayInRect):
+        (WebCore::TileGrid::rectForTileIndex):
+        (WebCore::TileGrid::getTileIndexRangeForRect):
+        (WebCore::TileGrid::removeAllTiles):
+        (WebCore::TileGrid::revalidateTiles):
+        * platform/graphics/ca/TileGrid.h:
+        (WebCore::TileGrid::tileSize):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::setTiledBackingHasMargins):
+        (WebCore::RenderLayerBacking::useGiantTiles):
+        (WebCore::RenderLayerBacking::tileSize): Deleted.
+        * rendering/RenderLayerBacking.h:
+
 2016-03-03  Ryosuke Niwa  <rniwa@webkit.org>
 
         Disallow custom elements inside a window-less documents
index 4de9628..a5e9a35 100644 (file)
                0F15ED5C1B7EC7C500EDDFEB /* WillChangeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15ED5A1B7EC7C500EDDFEB /* WillChangeData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F1774801378B772009DA76A /* ScrollAnimatorIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F17747E1378B771009DA76A /* ScrollAnimatorIOS.h */; };
                0F1774811378B772009DA76A /* ScrollAnimatorIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F17747F1378B772009DA76A /* ScrollAnimatorIOS.mm */; };
+               0F2884001C7CF7D500888E9A /* EdgeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2883FF1C7CF7D500888E9A /* EdgeSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F36E7371BD1837A002DB891 /* LayoutPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F36E7361BD1837A002DB891 /* LayoutPoint.cpp */; };
                0F36E7391BD184B9002DB891 /* LayoutSize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F36E7381BD184B9002DB891 /* LayoutSize.cpp */; };
                0F3C725E1974874B00AEDD0C /* ImageSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3C725D1974874B00AEDD0C /* ImageSource.cpp */; };
                0F15ED5A1B7EC7C500EDDFEB /* WillChangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WillChangeData.h; sourceTree = "<group>"; };
                0F17747E1378B771009DA76A /* ScrollAnimatorIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimatorIOS.h; sourceTree = "<group>"; };
                0F17747F1378B772009DA76A /* ScrollAnimatorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollAnimatorIOS.mm; sourceTree = "<group>"; };
+               0F2883FF1C7CF7D500888E9A /* EdgeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdgeSet.h; sourceTree = "<group>"; };
                0F36E7361BD1837A002DB891 /* LayoutPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutPoint.cpp; sourceTree = "<group>"; };
                0F36E7381BD184B9002DB891 /* LayoutSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutSize.cpp; sourceTree = "<group>"; };
                0F3C725D1974874B00AEDD0C /* ImageSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageSource.cpp; sourceTree = "<group>"; };
                                2D29ECC2192ECC8300984B78 /* DisplayRefreshMonitorClient.h */,
                                2D29ECC3192ECC8300984B78 /* DisplayRefreshMonitorManager.cpp */,
                                2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */,
+                               0F2883FF1C7CF7D500888E9A /* EdgeSet.h */,
                                6E67D2A81280E8BD008758F7 /* Extensions3D.h */,
                                B275353A0B053814002CE64F /* FloatPoint.cpp */,
                                B275353B0B053814002CE64F /* FloatPoint.h */,
                                E125F8421824253A00D84CD9 /* CryptoAlgorithmAES_CBC.h in Headers */,
                                E1FE137B184D21BB00892F13 /* CryptoAlgorithmAES_KW.h in Headers */,
                                E125F83A1824104800D84CD9 /* CryptoAlgorithmAesCbcParams.h in Headers */,
+                               0F2884001C7CF7D500888E9A /* EdgeSet.h in Headers */,
                                E19AC3F71824E5D100349426 /* CryptoAlgorithmAesKeyGenParams.h in Headers */,
                                E157A8ED181851AC009F821D /* CryptoAlgorithmDescriptionBuilder.h in Headers */,
                                E125F8321822F11B00D84CD9 /* CryptoAlgorithmHMAC.h in Headers */,
diff --git a/Source/WebCore/platform/graphics/EdgeSet.h b/Source/WebCore/platform/graphics/EdgeSet.h
new file mode 100644 (file)
index 0000000..5a9425a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EdgeSet_h
+#define EdgeSet_h
+
+namespace WebCore {
+
+template <typename T>
+class EdgeSet {
+public:
+    EdgeSet(T top, T right, T bottom, T left)
+        : m_top(top)
+        , m_right(right)
+        , m_bottom(bottom)
+        , m_left(left)
+    {
+    }
+
+    T top() const { return m_top; }
+    void setTop(T top) { m_top = top; }
+
+    T right() const { return m_right; }
+    void setRight(T right) { m_right = right; }
+
+    T bottom() const { return m_bottom; }
+    void setBottom(T bottom) { m_bottom = bottom; }
+
+    T left() const { return m_left; }
+    void setLeft(T left) { m_left = left; }
+
+    bool operator==(const EdgeSet<T>& b) const
+    {
+        return top() == b.top()
+            && right() == b.right()
+            && bottom() == b.bottom()
+            && left() == b.left();
+    }
+
+    bool operator!=(const EdgeSet<T>& b) const
+    {
+        return !(*this == b);
+    }
+
+private:
+    T m_top;
+    T m_right;
+    T m_bottom;
+    T m_left;
+};
+
+} // namespace WebCore
+
+#endif // EdgeSet_h
index bb58ba0..e3ac519 100644 (file)
@@ -120,7 +120,7 @@ public:
     virtual bool shouldAggressivelyRetainTiles(const GraphicsLayer*) const { return false; }
     virtual bool shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const { return true; }
 
-    virtual IntSize tileSize() const { return defaultTileSize(); }
+    virtual bool useGiantTiles() const { return false; }
 
     virtual bool needsPixelAligment() const { return false; }
 
index 4192d9a..a3dccb3 100644 (file)
@@ -37,6 +37,14 @@ IntSize::IntSize(const FloatSize& s)
 {
 }
 
+IntSize IntSize::constrainedBetween(const IntSize& min, const IntSize& max) const
+{
+    return {
+        std::max(min.width(), std::min(max.width(), m_width)),
+        std::max(min.height(), std::min(max.height(), m_height))
+    };
+}
+
 TextStream& operator<<(TextStream& ts, const IntSize& size)
 {
     return ts << "width=" << size.width() << " height=" << size.height();
index 832b6ff..759c22b 100644 (file)
@@ -123,6 +123,8 @@ public:
             m_height = minimumSize.height();
     }
 
+    IntSize constrainedBetween(const IntSize& min, const IntSize& max) const;
+
     int area() const
     {
         return m_width * m_height;
index 1add86b..d6456a5 100644 (file)
@@ -33,20 +33,6 @@ enum TileSizeMode {
     GiantTileSizeMode
 };
 
-inline static IntSize defaultTileSize(TileSizeMode tileSizeMode = StandardTileSizeMode)
-{
-    static const int kTiledLayerTileSize = 512;
-
-    // This is an experimental value for debugging and evaluating the overhead which may be
-    // incurred due to a large tile size.
-    static const int kGiantTiledLayerTileSize = 4096;
-
-    if (tileSizeMode == GiantTileSizeMode)
-        return IntSize(kGiantTiledLayerTileSize, kGiantTiledLayerTileSize);
-
-    return IntSize(kTiledLayerTileSize, kTiledLayerTileSize);
-}
-
 class FloatPoint;
 class FloatRect;
 class IntRect;
@@ -94,6 +80,14 @@ public:
     virtual void setTopContentInset(float) = 0;
 
     virtual void setVelocity(const VelocityData&) = 0;
+    
+    enum {
+        NotScrollable           = 0,
+        HorizontallyScrollable  = 1 << 0,
+        VerticallyScrollable    = 1 << 1
+    };
+    typedef unsigned Scrollability;
+    virtual void setScrollability(Scrollability) = 0;
 
     virtual void prepopulateRect(const FloatRect&) = 0;
 
@@ -112,6 +106,9 @@ public:
 
     virtual void adjustTileCoverageRect(FloatRect& coverageRect, const FloatSize& newSize, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect, float contentsScale) const = 0;
 
+    virtual void willStartLiveResize() = 0;
+    virtual void didEndLiveResize() = 0;
+
     virtual IntSize tileSize() const = 0;
 
     virtual void revalidateTiles() = 0;
@@ -125,7 +122,8 @@ public:
     
     virtual double retainedTileBackingStoreMemory() const = 0;
 
-    virtual void setTileMargins(int marginTop, int marginBottom, int marginLeft, int marginRight) = 0;
+    virtual void setHasMargins(bool marginTop, bool marginBottom, bool marginLeft, bool marginRight) = 0;
+    virtual void setMarginSize(int) = 0;
     virtual bool hasMargins() const = 0;
     virtual bool hasHorizontalMargins() const = 0;
     virtual bool hasVerticalMargins() const = 0;
index 8058641..230a8f6 100644 (file)
@@ -1496,9 +1496,9 @@ bool GraphicsLayerCA::platformCALayerShouldTemporarilyRetainTileCohorts(Platform
     return client().shouldTemporarilyRetainTileCohorts(this);
 }
 
-IntSize GraphicsLayerCA::platformCALayerTileSize() const
+bool GraphicsLayerCA::platformCALayerUseGiantTiles() const
 {
-    return client().tileSize();
+    return client().useGiantTiles();
 }
 
 static PlatformCALayer::LayerType layerTypeForCustomBackdropAppearance(GraphicsLayer::CustomAppearance appearance)
index 634e363..7b69259 100644 (file)
@@ -200,7 +200,7 @@ private:
     WEBCORE_EXPORT virtual float platformCALayerContentsScaleMultiplierForNewTiles(PlatformCALayer*) const override;
     WEBCORE_EXPORT virtual bool platformCALayerShouldAggressivelyRetainTiles(PlatformCALayer*) const override;
     WEBCORE_EXPORT virtual bool platformCALayerShouldTemporarilyRetainTileCohorts(PlatformCALayer*) const override;
-    WEBCORE_EXPORT virtual IntSize platformCALayerTileSize() const override;
+    WEBCORE_EXPORT virtual bool platformCALayerUseGiantTiles() const override;
 
     virtual bool isCommittingChanges() const override { return m_isCommittingChanges; }
     virtual bool isUsingDisplayListDrawing(PlatformCALayer*) const override { return m_usesDisplayListDrawing; }
index 9af1dff..10c82f4 100644 (file)
@@ -60,7 +60,7 @@ public:
     virtual bool platformCALayerShouldAggressivelyRetainTiles(PlatformCALayer*) const { return false; }
     virtual bool platformCALayerShouldTemporarilyRetainTileCohorts(PlatformCALayer*) const { return true; }
 
-    virtual IntSize platformCALayerTileSize() const { return defaultTileSize(); }
+    virtual bool platformCALayerUseGiantTiles() const { return false; }
 
     virtual bool isCommittingChanges() const { return false; }
 
index ac70d9d..d92b117 100644 (file)
@@ -43,6 +43,8 @@
 
 namespace WebCore {
 
+static const auto tileSizeUpdateDelay = std::chrono::milliseconds { 500 };
+
 String TileController::tileGridContainerLayerName()
 {
     return ASCIILiteral("TileGrid Container Layer");
@@ -57,22 +59,9 @@ TileController::TileController(PlatformCALayer* rootPlatformLayer)
     : m_tileCacheLayer(rootPlatformLayer)
     , m_tileGrid(std::make_unique<TileGrid>(*this))
     , m_tileRevalidationTimer(*this, &TileController::tileRevalidationTimerFired)
-    , m_zoomedOutContentsScale(0)
+    , m_tileSizeChangeTimer(*this, &TileController::tileSizeChangeTimerFired, tileSizeUpdateDelay)
     , m_deviceScaleFactor(owningGraphicsLayer()->platformCALayerDeviceScaleFactor())
-    , m_tileCoverage(CoverageForVisibleArea)
-    , m_marginTop(0)
-    , m_marginBottom(0)
-    , m_marginLeft(0)
-    , m_marginRight(0)
-    , m_isInWindow(false)
-    , m_scrollingPerformanceLoggingEnabled(false)
-    , m_unparentsOffscreenTiles(false)
-    , m_acceleratesDrawing(false)
-    , m_tilesAreOpaque(false)
-    , m_hasTilesWithTemporaryScaleFactor(false)
-    , m_tileDebugBorderWidth(0)
-    , m_indicatorMode(SynchronousScrollingBecauseOfLackOfScrollingCoordinatorIndication)
-    , m_topContentInset(0)
+    , m_marginEdges(false, false, false, false)
 {
 }
 
@@ -89,6 +78,7 @@ void TileController::tileCacheLayerBoundsChanged()
 {
     ASSERT(owningGraphicsLayer()->isCommittingChanges());
     setNeedsRevalidateTiles();
+    notePendingTileSizeChange();
 }
 
 void TileController::setNeedsDisplay()
@@ -221,6 +211,15 @@ void TileController::setVelocity(const VelocityData& velocity)
         setNeedsRevalidateTiles();
 }
 
+void TileController::setScrollability(Scrollability scrollability)
+{
+    if (scrollability == m_scrollability)
+        return;
+    
+    m_scrollability = scrollability;
+    notePendingTileSizeChange();
+}
+
 void TileController::setTopContentInset(float topContentInset)
 {
     m_topContentInset = topContentInset;
@@ -460,9 +459,45 @@ bool TileController::shouldTemporarilyRetainTileCohorts() const
     return owningGraphicsLayer()->platformCALayerShouldTemporarilyRetainTileCohorts(m_tileCacheLayer);
 }
 
+void TileController::willStartLiveResize()
+{
+    m_inLiveResize = true;
+}
+
+void TileController::didEndLiveResize()
+{
+    m_inLiveResize = false;
+    m_tileSizeLocked = false; // Let the end of a live resize update the tiles.
+}
+
+void TileController::notePendingTileSizeChange()
+{
+    m_tileSizeChangeTimer.restart();
+}
+
+void TileController::tileSizeChangeTimerFired()
+{
+    m_tileSizeLocked = false;
+    setNeedsRevalidateTiles();
+}
+
 IntSize TileController::tileSize() const
 {
-    return owningGraphicsLayer()->platformCALayerTileSize();
+    if (m_inLiveResize || m_tileSizeLocked)
+        return tileGrid().tileSize();
+
+    if (owningGraphicsLayer()->platformCALayerUseGiantTiles())
+        return IntSize(kGiantTileSize, kGiantTileSize);
+
+    IntSize tileSize(kDefaultTileSize, kDefaultTileSize);
+
+    if (m_scrollability == NotScrollable)
+        tileSize = boundsWithoutMargin().size().constrainedBetween(IntSize(kDefaultTileSize, kDefaultTileSize), IntSize(kGiantTileSize, kGiantTileSize));
+    else if (m_scrollability == VerticallyScrollable)
+        tileSize.setWidth(std::min(std::max(boundsWithoutMargin().width(), kDefaultTileSize), kGiantTileSize));
+
+    m_tileSizeLocked = true;
+    return tileSize;
 }
 
 void TileController::clearZoomedOutTileGrid()
@@ -573,49 +608,58 @@ void TileController::setScrollingModeIndication(ScrollingModeIndication scrollin
     updateTileCoverageMap();
 }
 
-void TileController::setTileMargins(int marginTop, int marginBottom, int marginLeft, int marginRight)
+void TileController::setHasMargins(bool marginTop, bool marginBottom, bool marginLeft, bool marginRight)
 {
-    m_marginTop = marginTop;
-    m_marginBottom = marginBottom;
-    m_marginLeft = marginLeft;
-    m_marginRight = marginRight;
+    EdgeSet<bool> marginEdges(marginTop, marginRight, marginBottom, marginLeft);
+    if (marginEdges == m_marginEdges)
+        return;
+    
+    m_marginEdges = marginEdges;
+    setNeedsRevalidateTiles();
+}
 
+void TileController::setMarginSize(int marginSize)
+{
+    if (marginSize == m_marginSize)
+        return;
+    
+    m_marginSize = marginSize;
     setNeedsRevalidateTiles();
 }
 
 bool TileController::hasMargins() const
 {
-    return m_marginTop || m_marginBottom || m_marginLeft || m_marginRight;
+    return m_marginSize && (m_marginEdges.top() || m_marginEdges.bottom() || m_marginEdges.left() || m_marginEdges.right());
 }
 
 bool TileController::hasHorizontalMargins() const
 {
-    return m_marginLeft || m_marginRight;
+    return m_marginSize && (m_marginEdges.left() || m_marginEdges.right());
 }
 
 bool TileController::hasVerticalMargins() const
 {
-    return m_marginTop || m_marginBottom;
+    return m_marginSize && (m_marginEdges.top() || m_marginEdges.bottom());
 }
 
 int TileController::topMarginHeight() const
 {
-    return m_marginTop / tileGrid().scale();
+    return (m_marginSize * m_marginEdges.top()) / tileGrid().scale();
 }
 
 int TileController::bottomMarginHeight() const
 {
-    return m_marginBottom / tileGrid().scale();
+    return (m_marginSize * m_marginEdges.bottom()) / tileGrid().scale();
 }
 
 int TileController::leftMarginWidth() const
 {
-    return m_marginLeft / tileGrid().scale();
+    return (m_marginSize * m_marginEdges.left()) / tileGrid().scale();
 }
 
 int TileController::rightMarginWidth() const
 {
-    return m_marginRight / tileGrid().scale();
+    return (m_marginSize * m_marginEdges.right()) / tileGrid().scale();
 }
 
 RefPtr<PlatformCALayer> TileController::createTileLayer(const IntRect& tileRect, TileGrid& grid)
index 99c4749..663d87a 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef TileController_h
 #define TileController_h
 
+#include "EdgeSet.h"
 #include "FloatRect.h"
 #include "IntRect.h"
 #include "PlatformCALayer.h"
@@ -47,6 +48,11 @@ class TileGrid;
 
 typedef Vector<RetainPtr<PlatformLayer>> PlatformLayerList;
 
+const int kDefaultTileSize = 512;
+// This is an experimental value for debugging and evaluating the overhead which may be
+// incurred due to a large tile size.
+const int kGiantTileSize = 4096;
+
 class TileController final : public TiledBacking {
     WTF_MAKE_NONCOPYABLE(TileController); WTF_MAKE_FAST_ALLOCATED;
     friend class TileCoverageMap;
@@ -95,6 +101,9 @@ public:
     float tileDebugBorderWidth() const { return m_tileDebugBorderWidth; }
     ScrollingModeIndication indicatorMode() const { return m_indicatorMode; }
 
+    virtual void willStartLiveResize() override;
+    virtual void didEndLiveResize() override;
+
     virtual IntSize tileSize() const override;
     virtual IntRect bounds() const override;
     virtual IntRect boundsWithoutMargin() const override;
@@ -140,6 +149,7 @@ private:
     virtual void setTiledScrollingIndicatorPosition(const FloatPoint&) override;
     virtual void setTopContentInset(float) override;
     virtual void setVelocity(const VelocityData&) override;
+    virtual void setScrollability(Scrollability) override;
     virtual void prepopulateRect(const FloatRect&) override;
     virtual void setIsInWindow(bool) override;
     virtual void setTileCoverage(TileCoverage) override;
@@ -154,15 +164,20 @@ private:
     virtual PlatformCALayer* tiledScrollingIndicatorLayer() override;
 #endif
     virtual void setScrollingModeIndication(ScrollingModeIndication) override;
-    virtual void setTileMargins(int marginTop, int marginBottom, int marginLeft, int marginRight) override;
+    virtual void setHasMargins(bool marginTop, bool marginBottom, bool marginLeft, bool marginRight) override;
+    virtual void setMarginSize(int) override;
     virtual void setZoomedOutContentsScale(float) override;
     virtual float zoomedOutContentsScale() const override;
 
+    void updateMargins();
     void clearZoomedOutTileGrid();
     void tileGridsChanged();
 
     void tileRevalidationTimerFired();
     void setNeedsRevalidateTiles();
+
+    void notePendingTileSizeChange();
+    void tileSizeChangeTimerFired();
     
     IntRect boundsForSize(const FloatSize&) const;
 
@@ -180,34 +195,39 @@ private:
     IntRect m_boundsAtLastRevalidate;
 
     Timer m_tileRevalidationTimer;
+    DeferrableOneShotTimer m_tileSizeChangeTimer;
 
-    float m_zoomedOutContentsScale;
+    float m_zoomedOutContentsScale { 0 };
     float m_deviceScaleFactor;
 
-    TileCoverage m_tileCoverage;
+    TileCoverage m_tileCoverage { CoverageForVisibleArea };
     
     VelocityData m_velocity;
 
+    int m_marginSize { kDefaultTileSize };
+
     // m_marginTop and m_marginBottom are the height in pixels of the top and bottom margin tiles. The width
     // of those tiles will be equivalent to the width of the other tiles in the grid. m_marginRight and
     // m_marginLeft are the width in pixels of the right and left margin tiles, respectively. The height of
     // those tiles will be equivalent to the height of the other tiles in the grid.
-    int m_marginTop;
-    int m_marginBottom;
-    int m_marginLeft;
-    int m_marginRight;
-
-    bool m_isInWindow;
-    bool m_scrollingPerformanceLoggingEnabled;
-    bool m_unparentsOffscreenTiles;
-    bool m_acceleratesDrawing;
-    bool m_tilesAreOpaque;
-    bool m_hasTilesWithTemporaryScaleFactor; // Used to make low-res tiles when zooming.
+    
+    Scrollability m_scrollability { HorizontallyScrollable | VerticallyScrollable };
+    
+    EdgeSet<bool> m_marginEdges;
+    
+    bool m_isInWindow { false };
+    bool m_scrollingPerformanceLoggingEnabled { false };
+    bool m_unparentsOffscreenTiles { false };
+    bool m_acceleratesDrawing { false };
+    bool m_tilesAreOpaque { false };
+    bool m_hasTilesWithTemporaryScaleFactor { false }; // Used to make low-res tiles when zooming.
+    bool m_inLiveResize { false };
+    mutable bool m_tileSizeLocked { false };
 
     Color m_tileDebugBorderColor;
-    float m_tileDebugBorderWidth;
-    ScrollingModeIndication m_indicatorMode;
-    float m_topContentInset;
+    float m_tileDebugBorderWidth { 0 };
+    ScrollingModeIndication m_indicatorMode { SynchronousScrollingBecauseOfLackOfScrollingCoordinatorIndication };
+    float m_topContentInset { 0 };
 };
 
 } // namespace WebCore
index e5aae4d..c662311 100644 (file)
@@ -28,7 +28,9 @@
 
 #include "GraphicsContext.h"
 #include "LayerPool.h"
+#include "Logging.h"
 #include "PlatformCALayer.h"
+#include "TextStream.h"
 #include "TileController.h"
 #include <wtf/MainThread.h>
 #include <wtf/text/CString.h>
@@ -42,8 +44,9 @@ namespace WebCore {
 TileGrid::TileGrid(TileController& controller)
     : m_controller(controller)
     , m_containerLayer(*controller.rootLayer().createCompatibleLayer(PlatformCALayer::LayerTypeLayer, nullptr))
-    , m_scale(1)
     , m_cohortRemovalTimer(*this, &TileGrid::cohortRemovalTimerFired)
+    , m_tileSize(kDefaultTileSize, kDefaultTileSize)
+    , m_tileSizeAtLastRevalidate(m_tileSize)
 {
     m_containerLayer.get().setName(TileController::tileGridContainerLayerName());
 }
@@ -101,7 +104,7 @@ void TileGrid::setNeedsDisplayInRect(const IntRect& rect)
     scaledRect.scale(m_scale);
     IntRect repaintRectInTileCoords(enclosingIntRect(scaledRect));
 
-    IntSize tileSize = m_controller.tileSize();
+    IntSize tileSize = m_tileSize;
 
     // For small invalidations, lookup the covered tiles.
     if (repaintRectInTileCoords.height() < 2 * tileSize.height() && repaintRectInTileCoords.width() < 2 * tileSize.width()) {
@@ -218,7 +221,7 @@ IntRect TileGrid::rectForTileIndex(const TileIndex& tileIndex) const
     // FIXME: calculating the scaled size here should match with the rest of calculated sizes where we use the combination of
     // enclosingIntRect, expandedIntSize (floor vs ceil).
     // However enclosing this size could reveal gap on root layer's background. see RenderView::backgroundRect()
-    IntSize tileSize = m_controller.tileSize();
+    IntSize tileSize = m_tileSize;
     IntRect rect(tileIndex.x() * tileSize.width(), tileIndex.y() * tileSize.height(), tileSize.width(), tileSize.height());
     IntRect scaledBounds(m_controller.bounds());
     scaledBounds.scale(m_scale);
@@ -232,7 +235,7 @@ void TileGrid::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft,
     clampedRect.scale(m_scale);
     clampedRect.intersect(rect);
 
-    auto tileSize = m_controller.tileSize();
+    auto tileSize = m_tileSize;
     if (clampedRect.x() >= 0)
         topLeft.setX(clampedRect.x() / tileSize.width());
     else
@@ -272,6 +275,17 @@ void TileGrid::removeTiles(Vector<TileGrid::TileIndex>& toRemove)
     }
 }
 
+void TileGrid::removeAllTiles()
+{
+    Vector<TileIndex> tilesToRemove;
+    tilesToRemove.reserveInitialCapacity(m_tiles.size());
+
+    for (auto& entry : m_tiles)
+        tilesToRemove.uncheckedAppend(entry.key);
+
+    removeTiles(tilesToRemove);
+}
+
 void TileGrid::removeAllSecondaryTiles()
 {
     Vector<TileIndex> tilesToRemove;
@@ -318,6 +332,12 @@ void TileGrid::revalidateTiles(TileValidationPolicy validationPolicy)
 
     double minimumRevalidationTimerDuration = std::numeric_limits<double>::max();
     bool needsTileRevalidation = false;
+    
+    m_tileSize = m_controller.tileSize();
+    if (m_tileSize != m_tileSizeAtLastRevalidate) {
+        removeAllTiles();
+        m_tileSizeAtLastRevalidate = m_tileSize;
+    }
 
     // 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) {
index a6fae8c..57ba086 100644 (file)
@@ -77,6 +77,8 @@ public:
 
     IntRect tileCoverageRect() const;
     IntRect extent() const;
+    
+    IntSize tileSize() const { return m_tileSize; }
 
     double retainedTileBackingStoreMemory() const;
     unsigned blankPixelCount() const;
@@ -89,6 +91,7 @@ public:
 #endif
 
     typedef IntPoint TileIndex;
+
     typedef unsigned TileCohort;
     static const TileCohort VisibleTileCohort = UINT_MAX;
 
@@ -123,6 +126,7 @@ private:
         double timeUntilExpiration();
     };
 
+    void removeAllTiles();
     void removeAllSecondaryTiles();
     void removeTilesInCohort(TileCohort);
 
@@ -154,8 +158,6 @@ private:
     IntRect m_primaryTileCoverageRect;
     Vector<FloatRect> m_secondaryTileCoverageRects;
 
-    float m_scale;
-
     typedef Deque<TileCohortInfo> TileCohortList;
     TileCohortList m_cohortList;
 
@@ -163,6 +165,11 @@ private:
 
     typedef HashMap<PlatformCALayer*, int> RepaintCountMap;
     RepaintCountMap m_tileRepaintCounts;
+    
+    IntSize m_tileSize;
+    IntSize m_tileSizeAtLastRevalidate;
+
+    float m_scale { 1 };
 };
 
 }
index 80e89ce..d14d030 100644 (file)
@@ -250,9 +250,7 @@ void RenderLayerBacking::setTiledBackingHasMargins(bool hasExtendedBackgroundOnL
     if (!m_usingTiledCacheLayer)
         return;
 
-    int marginLeftAndRightSize = hasExtendedBackgroundOnLeftAndRight ? tileSize().width() : 0;
-    int marginTopAndBottomSize = hasExtendedBackgroundOnTopAndBottom ? tileSize().height() : 0;
-    tiledBacking()->setTileMargins(marginTopAndBottomSize, marginTopAndBottomSize, marginLeftAndRightSize, marginLeftAndRightSize);
+    tiledBacking()->setHasMargins(hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnTopAndBottom, hasExtendedBackgroundOnLeftAndRight, hasExtendedBackgroundOnLeftAndRight);
 }
 
 void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaintCounter)
@@ -2486,10 +2484,9 @@ bool RenderLayerBacking::shouldTemporarilyRetainTileCohorts(const GraphicsLayer*
     return true;
 }
 
-IntSize RenderLayerBacking::tileSize() const
+bool RenderLayerBacking::useGiantTiles() const
 {
-    TileSizeMode tileSizeMode = renderer().frame().page()->settings().useGiantTiles() ? GiantTileSizeMode : StandardTileSizeMode;
-    return defaultTileSize(tileSizeMode);
+    return renderer().frame().page()->settings().useGiantTiles();
 }
 
 #ifndef NDEBUG
index 199af9b..be21380 100644 (file)
@@ -213,7 +213,7 @@ public:
 
     virtual bool shouldAggressivelyRetainTiles(const GraphicsLayer*) const override;
     virtual bool shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const override;
-    virtual IntSize tileSize() const override;
+    virtual bool useGiantTiles() const override;
     virtual bool needsPixelAligment() const override { return !m_isMainFrameRenderViewLayer; }
 
 #if PLATFORM(IOS)
index 62fb88e..baf4e82 100644 (file)
@@ -1,3 +1,18 @@
+2016-03-03  Simon Fraser  <simon.fraser@apple.com>
+
+        Use larger tiles when possible to reduce per-tile painting overhead
+        https://bugs.webkit.org/show_bug.cgi?id=154985
+        rdar://problem/23635219
+
+        Reviewed by Tim Horton.
+
+        Do a bit of #include cleanup.
+
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        * WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.cpp:
+        * WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.h:
+
 2016-03-03  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
 
         Use std::make_unique<> when creating std::unique_ptr<>
index 8f398f6..10f9a51 100644 (file)
@@ -37,6 +37,7 @@
 #import <WebCore/GraphicsContextCG.h>
 #import <WebCore/IOSurface.h>
 #import <WebCore/MachSendRight.h>
+#import <WebCore/PlatformCALayerClient.h>
 #import <WebCore/QuartzCoreSPI.h>
 #import <WebCore/WebLayer.h>
 
index 8095a1b..7caac39 100644 (file)
@@ -29,7 +29,6 @@
 #include "RemoteLayerTreeTransaction.h"
 #include <WebCore/PlatformCALayer.h>
 #include <WebCore/PlatformLayer.h>
-#include <WebCore/TileController.h>
 
 namespace WebCore {
 class LayerPool;
index 058ae2a..dbc98a8 100644 (file)
@@ -29,7 +29,6 @@
 #import "RemoteLayerTreeContext.h"
 #import <WebCore/GraphicsLayerCA.h>
 #import <WebCore/PlatformCALayerCocoa.h>
-#import <WebCore/TiledBacking.h>
 #import <wtf/RetainPtr.h>
 
 using namespace WebCore;
index d5f4d26..18e3df8 100644 (file)
@@ -27,6 +27,7 @@
 #define PlatformCALayerRemoteTiledBacking_h
 
 #include "PlatformCALayerRemote.h"
+#include <WebCore/TileController.h>
 
 namespace WebKit {