Add a new mode to extend the tile cache beyond the page
https://bugs.webkit.org/show_bug.cgi?id=124216

Reviewed by Simon Fraser.

This patch makes it possible to give the tile cache a margin of tiles. If there is 
a margin of tiles, this patch paints those tiles with the background color. Note 
that this patch does not actually give the tile cache a margin at this time.

You opt into a margined tiled cache by called setTileMargins() with number of 
pixels that the margin on that side should be. 
* platform/graphics/TiledBacking.h:
* platform/graphics/ca/mac/TileController.h:
* platform/graphics/ca/mac/TileController.mm:
(WebCore::TileController::TileController):
(WebCore::TileController::tilesWouldChangeForVisibleRect):

TileController::bounds() now computes the bounds INCLUDING the margin.
(WebCore::TileController::bounds):

adjustRectAtTileIndexForMargin() is a new function that is required to get the 
rect size for tiles in the margin right. rectForTileIndex() assumes all tiles 
strive to be the size of m_tileSize, but now margin tiles will be whatever the 
margin sizes were set to.
(WebCore::TileController::adjustRectAtTileIndexForMargin):
(WebCore::TileController::rectForTileIndex):

This is another instance where m_tileSize is not always the right size to use.
(WebCore::TileController::getTileIndexRangeForRect):

The tile coverage rect now might include the margin tiles. Only include them in 
slow-scrolling mode if the current position is within one tile of the edge.
(WebCore::TileController::computeTileCoverageRect):

tileSizeForCoverageRect() does not make sense in a world where the coverage rect 
will include margin. Instead, this patch implements the current strategy more 
explicitly by returning the visibleRect in the slow scrolling case, and in the 
process this patch also re-names tileSizeForCoverageRect() to computeTileSize() 
since it no longer takes a coverageRect.
(WebCore::TileController::computeTileSize):
(WebCore::TileController::revalidateTiles):

New setters and getters for the tile margins on each side.
(WebCore::TileController::setTileMargins):
(WebCore::TileController::hasMargins):
(WebCore::TileController::topMarginHeight):
(WebCore::TileController::bottomMarginHeight):
(WebCore::TileController::leftMarginWidth):
(WebCore::TileController::rightMarginWidth):

New function to add margin onto the composited bounds if there is one.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::tiledBackingHasMargin):
(WebCore::RenderLayerBacking::paintContents):
(WebCore::RenderLayerBacking::compositedBoundsIncludingMargin):
* rendering/RenderLayerBacking.h:

Do not set masks to bounds if there is a margin on the root layer.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateBacking):
(WebCore::RenderLayerCompositor::mainFrameBackingIsTiledWithMargin):
* rendering/RenderLayerCompositor.h:

Allow background color to paint into the margin tiles.
* rendering/RenderView.cpp:
(WebCore::RenderView::paintBoxDecorations):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159645 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 54fb15c..fd767cd 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -190,6 +190,11 @@
     return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
 }
 
+bool RenderLayerBacking::tiledBackingHasMargin() const
+{
+    return m_usingTiledCacheLayer && tiledBacking()->hasMargins();
+}
+
 void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
 {
     compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
@@ -2084,7 +2089,7 @@
         // The dirtyRect is in the coords of the painting root.
         IntRect dirtyRect = clip;
         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
-            dirtyRect.intersect(enclosingIntRect(compositedBounds()));
+            dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
 
         // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
         paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
@@ -2361,6 +2366,22 @@
     m_compositedBounds = bounds;
 }
 
+LayoutRect RenderLayerBacking::compositedBoundsIncludingMargin() const
+{
+    TiledBacking* tiledBacking = this->tiledBacking();
+    if (!tiledBacking || !tiledBacking->hasMargins())
+        return compositedBounds();
+
+    LayoutRect boundsIncludingMargin = compositedBounds();
+    LayoutUnit leftMarginWidth = tiledBacking->leftMarginWidth();
+    LayoutUnit topMarginHeight = tiledBacking->topMarginHeight();
+
+    boundsIncludingMargin.moveBy(IntPoint(-leftMarginWidth, -topMarginHeight));
+    boundsIncludingMargin.expand(leftMarginWidth + (LayoutUnit)tiledBacking->rightMarginWidth(), topMarginHeight + (LayoutUnit)tiledBacking->bottomMarginHeight());
+
+    return boundsIncludingMargin;
+}
+
 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
 {
     CSSPropertyID cssProperty = CSSPropertyInvalid;