Title: [131940] trunk/Source/WebCore
Revision
131940
Author
simon.fra...@apple.com
Date
2012-10-19 13:43:46 -0700 (Fri, 19 Oct 2012)

Log Message

Use tile caches in place of CATiledLayer
https://bugs.webkit.org/show_bug.cgi?id=99806
<rdar://problem/6474145>

Reviewed by Tim Horton.

Have GraphicsLayerCA use TileCaches instead of CATiledLayer now for
layers that exceed the 2000px size threshold.

* platform/graphics/TiledBacking.h:
(TiledBacking): Have normal getter and setter for the visible rect.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly): We need
to pass in an old visibleRect to commitLayerChangesBeforeSublayers(). Just use
our current visible rect, which result in no tile area work.
(WebCore::GraphicsLayerCA::computeVisibleRect): Make this const and have it
return the rect, for clarity.
(WebCore::GraphicsLayerCA::recursiveCommitChanges): Keep track of the old
visible rect, and use the change flags mechanism to ensure that we recompute
tile areas later.
When calling commitLayerChangesBeforeSublayers() on the mask layer, just pass
its own visible rect as the old visible rect.
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Pass in the
oldVisibleRect so that updateVisibleRect() can use this to see how the
visibleRect is changing.
(WebCore::GraphicsLayerCA::adjustTiledLayerVisibleRect): This member function
compares the old and new visible rects, and extends the tile coverage area
in directions where more content is being exposed. It takes care to avoid
"jitter" in the visible rect deltas causing edge tiles to get created then
destroyed by keeping any extra padding that already exists in a direction
where more content is being exposed.
(WebCore::GraphicsLayerCA::updateVisibleRect): Call adjustTiledLayerVisibleRect()
and use the result to update the TiledBacking's visibleRect.
(WebCore::GraphicsLayerCA::swapFromOrToTiledLayer): Create layers of type
LayerTypeTileCacheLayer instead of LayerTypeWebTiledLayer. Because tile
cache layers involve adding an extra layer to the hierarchy (the tile container),
we call updateSublayerList() when changing layer type.
* platform/graphics/ca/GraphicsLayerCA.h: New m_sizeAtLastVisibleRectUpdate member
that is used to prevent the adjustTiledLayerVisibleRect() logic being confused by
size changes.
(WebCore::GraphicsLayerCA::visibleRect):
* platform/graphics/ca/mac/TileCache.h: Have normal getter and setter for the visible rect.
* platform/graphics/ca/mac/TileCache.mm:
(WebCore::TileCache::setVisibleRect): Renamed to setVisibleRect().
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::flushPendingLayerChanges): Avoid doing work
for pages in the page cache, for which the root layer is unattached.
(WebCore::RenderLayerCompositor::frameViewDidScroll): visibleRectChanged() was renamed
to setVisibleRect().

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (131939 => 131940)


--- trunk/Source/WebCore/ChangeLog	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/ChangeLog	2012-10-19 20:43:46 UTC (rev 131940)
@@ -1,3 +1,55 @@
+2012-10-19  Simon Fraser  <simon.fra...@apple.com>
+
+        Use tile caches in place of CATiledLayer
+        https://bugs.webkit.org/show_bug.cgi?id=99806
+        <rdar://problem/6474145>
+
+        Reviewed by Tim Horton.
+
+        Have GraphicsLayerCA use TileCaches instead of CATiledLayer now for
+        layers that exceed the 2000px size threshold.
+
+        * platform/graphics/TiledBacking.h:
+        (TiledBacking): Have normal getter and setter for the visible rect.
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly): We need
+        to pass in an old visibleRect to commitLayerChangesBeforeSublayers(). Just use
+        our current visible rect, which result in no tile area work.
+        (WebCore::GraphicsLayerCA::computeVisibleRect): Make this const and have it
+        return the rect, for clarity.
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges): Keep track of the old
+        visible rect, and use the change flags mechanism to ensure that we recompute
+        tile areas later.
+        When calling commitLayerChangesBeforeSublayers() on the mask layer, just pass
+        its own visible rect as the old visible rect.
+        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Pass in the
+        oldVisibleRect so that updateVisibleRect() can use this to see how the
+        visibleRect is changing.
+        (WebCore::GraphicsLayerCA::adjustTiledLayerVisibleRect): This member function
+        compares the old and new visible rects, and extends the tile coverage area
+        in directions where more content is being exposed. It takes care to avoid
+        "jitter" in the visible rect deltas causing edge tiles to get created then
+        destroyed by keeping any extra padding that already exists in a direction
+        where more content is being exposed.
+        (WebCore::GraphicsLayerCA::updateVisibleRect): Call adjustTiledLayerVisibleRect()
+        and use the result to update the TiledBacking's visibleRect.
+        (WebCore::GraphicsLayerCA::swapFromOrToTiledLayer): Create layers of type
+        LayerTypeTileCacheLayer instead of LayerTypeWebTiledLayer. Because tile
+        cache layers involve adding an extra layer to the hierarchy (the tile container),
+        we call updateSublayerList() when changing layer type.
+        * platform/graphics/ca/GraphicsLayerCA.h: New m_sizeAtLastVisibleRectUpdate member
+        that is used to prevent the adjustTiledLayerVisibleRect() logic being confused by
+        size changes.
+        (WebCore::GraphicsLayerCA::visibleRect):
+        * platform/graphics/ca/mac/TileCache.h: Have normal getter and setter for the visible rect.
+        * platform/graphics/ca/mac/TileCache.mm:
+        (WebCore::TileCache::setVisibleRect): Renamed to setVisibleRect().
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::flushPendingLayerChanges): Avoid doing work
+        for pages in the page cache, for which the root layer is unattached.
+        (WebCore::RenderLayerCompositor::frameViewDidScroll): visibleRectChanged() was renamed
+        to setVisibleRect().
+
 2012-10-19  Beth Dakin  <bda...@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=99768

Modified: trunk/Source/WebCore/platform/graphics/TiledBacking.h (131939 => 131940)


--- trunk/Source/WebCore/platform/graphics/TiledBacking.h	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/platform/graphics/TiledBacking.h	2012-10-19 20:43:46 UTC (rev 131940)
@@ -34,7 +34,9 @@
 public:
     virtual ~TiledBacking() { }
 
-    virtual void visibleRectChanged(const IntRect&) = 0;
+    virtual void setVisibleRect(const IntRect&) = 0;
+    virtual IntRect visibleRect() const = 0;
+
     virtual void setIsInWindow(bool) = 0;
 
     enum {

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (131939 => 131940)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2012-10-19 20:43:46 UTC (rev 131940)
@@ -38,6 +38,7 @@
 #include "ScaleTransformOperation.h"
 #include "SystemTime.h"
 #include "TextStream.h"
+#include "TiledBacking.h"
 #include "TransformState.h"
 #include "TranslateTransformOperation.h"
 #include <QuartzCore/CATransform3D.h>
@@ -905,7 +906,7 @@
 {
     float pageScaleFactor;
     FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
-    commitLayerChangesBeforeSublayers(pageScaleFactor, offset);
+    commitLayerChangesBeforeSublayers(pageScaleFactor, offset, m_visibleRect);
     commitLayerChangesAfterSublayers();
 }
 
@@ -914,7 +915,7 @@
     return m_layer->tiledBacking();
 }
 
-void GraphicsLayerCA::computeVisibleRect(TransformState& state)
+FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state) const
 {
     bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
     TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
@@ -954,13 +955,19 @@
         state.setQuad(clipRectForSelf);
     }
 
-    m_visibleRect = clipRectForSelf;
+    return clipRectForSelf;
 }
 
 void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
 {
     TransformState localState = state;
-    computeVisibleRect(localState);
+    
+    FloatRect visibleRect = computeVisibleRect(localState);
+    FloatRect oldVisibleRect = m_visibleRect;
+    if (visibleRect != m_visibleRect) {
+        m_uncommittedChanges |= VisibleRectChanged;
+        m_visibleRect = visibleRect;
+    }
 
 #ifdef VISIBLE_TILE_WASH
     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
@@ -995,10 +1002,12 @@
     if (affectedByPageScale)
         baseRelativePosition += m_position;
     
-    commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition);
+    commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, oldVisibleRect);
 
-    if (m_maskLayer)
-        static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition);
+    if (m_maskLayer) {
+        GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
+        maskLayerCA->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
+    }
 
     const Vector<GraphicsLayer*>& childLayers = children();
     size_t numChildren = childLayers.size();
@@ -1055,7 +1064,7 @@
     return deviceScaleFactor();
 }
 
-void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
+void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect)
 {
     if (!m_uncommittedChanges)
         return;
@@ -1122,6 +1131,9 @@
     if (m_uncommittedChanges & ContentsScaleChanged)
         updateContentsScale(pageScaleFactor, positionRelativeToBase);
 
+    if (m_uncommittedChanges & VisibleRectChanged)
+        updateVisibleRect(oldVisibleRect);
+
     if (m_uncommittedChanges & DirtyRectsChanged)
         repaintLayerDirtyRects();
     
@@ -1535,7 +1547,78 @@
 {
     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
 }
+
+FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const
+{
+    // If the old visible rect is empty, we have no information about how the visible area is changing
+    // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
+    // if the size changed.
+    if (oldVisibleRect.isEmpty() || m_size != oldSize)
+        return m_visibleRect;
+
+    const float paddingMultiplier = 2;
+
+    float leftEdgeDelta = paddingMultiplier * (m_visibleRect.x() - oldVisibleRect.x());
+    float rightEdgeDelta = paddingMultiplier * (m_visibleRect.maxX() - oldVisibleRect.maxX());
+
+    float topEdgeDelta = paddingMultiplier * (m_visibleRect.y() - oldVisibleRect.y());
+    float bottomEdgeDelta = paddingMultiplier * (m_visibleRect.maxY() - oldVisibleRect.maxY());
     
+    FloatRect existingTileBackingRect = tiledBacking->visibleRect();
+    FloatRect expandedRect = m_visibleRect;
+
+    // More exposed on left side.
+    if (leftEdgeDelta < 0) {
+        float newLeft = expandedRect.x() + leftEdgeDelta;
+        // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
+        if (newLeft < existingTileBackingRect.x())
+            expandedRect.shiftXEdgeTo(newLeft);
+        else
+            expandedRect.shiftXEdgeTo(existingTileBackingRect.x());
+    }
+
+    // More exposed on right.
+    if (rightEdgeDelta > 0) {
+        float newRight = expandedRect.maxX() + rightEdgeDelta;
+        // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
+        if (newRight > existingTileBackingRect.maxX())
+            expandedRect.setWidth(newRight - expandedRect.x());
+        else
+            expandedRect.setWidth(existingTileBackingRect.maxX() - expandedRect.x());
+    }
+
+    // More exposed at top.
+    if (topEdgeDelta < 0) {
+        float newTop = expandedRect.y() + topEdgeDelta;
+        if (newTop < existingTileBackingRect.y())
+            expandedRect.shiftYEdgeTo(newTop);
+        else
+            expandedRect.shiftYEdgeTo(existingTileBackingRect.y());
+    }
+
+    // More exposed on bottom.
+    if (bottomEdgeDelta > 0) {
+        float newBottom = expandedRect.maxY() + bottomEdgeDelta;
+        if (newBottom > existingTileBackingRect.maxY())
+            expandedRect.setHeight(newBottom - expandedRect.y());
+        else
+            expandedRect.setHeight(existingTileBackingRect.maxY() - expandedRect.y());
+    }
+    
+    return expandedRect;
+}
+
+void GraphicsLayerCA::updateVisibleRect(const FloatRect& oldVisibleRect)
+{
+    if (m_layer->layerType() != PlatformCALayer::LayerTypeTileCacheLayer)
+        return;
+
+    FloatRect tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, m_sizeAtLastVisibleRectUpdate);
+    tiledBacking()->setVisibleRect(enclosingIntRect(tileArea));
+
+    m_sizeAtLastVisibleRectUpdate = m_size;
+}
+
 void GraphicsLayerCA::updateLayerBackgroundColor()
 {
     if (m_isPageTileCacheLayer) {
@@ -2501,7 +2584,7 @@
     ASSERT(useTiledLayer != m_usingTiledLayer);
     RefPtr<PlatformCALayer> oldLayer = m_layer;
     
-    m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this);
+    m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeTileCacheLayer : PlatformCALayer::LayerTypeWebLayer, this);
     m_usingTiledLayer = useTiledLayer;
     
     m_layer->adoptSublayers(oldLayer.get());
@@ -2520,6 +2603,7 @@
     updateGeometry(pageScaleFactor, positionRelativeToBase);
     updateTransform();
     updateChildrenTransform();
+    updateSublayerList();
     updateMasksToBounds();
 #if ENABLE(CSS_FILTERS)
     updateFilters();

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (131939 => 131940)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2012-10-19 20:43:46 UTC (rev 131940)
@@ -211,7 +211,7 @@
         return m_runningAnimations.find(animationName) != m_runningAnimations.end();
     }
 
-    void commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase);
+    void commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect);
     void commitLayerChangesAfterSublayers();
 
     FloatPoint computePositionRelativeToBase(float& pageScale) const;
@@ -233,7 +233,10 @@
 
     void computePixelAlignment(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase,
         FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const;
-    void computeVisibleRect(TransformState&);
+    FloatRect computeVisibleRect(TransformState&) const;
+    const FloatRect& visibleRect() const { return m_visibleRect; }
+    
+    FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const;
 
     // Used to track the path down the tree for replica layers.
     struct ReplicaState {
@@ -323,6 +326,7 @@
     void updateLayerAnimations();
     void updateContentsNeedsDisplay();
     void updateAcceleratesDrawing();
+    void updateVisibleRect(const FloatRect& oldVisibleRect);
     void updateContentsScale(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase);
     
     enum StructuralLayerPurpose {
@@ -372,8 +376,9 @@
         AcceleratesDrawingChanged = 1 << 22,
         ContentsScaleChanged = 1 << 23,
         ContentsVisibilityChanged = 1 << 24,
+        VisibleRectChanged = 1 << 25,
 #if ENABLE(CSS_FILTERS)
-        FiltersChanged = 1 << 25,
+        FiltersChanged = 1 << 26,
 #endif
     };
     typedef unsigned LayerChangeFlags;
@@ -396,6 +401,7 @@
     RefPtr<PlatformCALayer> m_visibleTileWashLayer;
 #endif
     FloatRect m_visibleRect;
+    FloatSize m_sizeAtLastVisibleRectUpdate;
     
     enum ContentsLayerPurpose {
         NoContentsLayer = 0,

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h (131939 => 131940)


--- trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h	2012-10-19 20:43:46 UTC (rev 131940)
@@ -73,7 +73,7 @@
     void setTileDebugBorderWidth(float);
     void setTileDebugBorderColor(CGColorRef);
 
-    IntRect visibleRect() const { return m_visibleRect; }
+    virtual IntRect visibleRect() const OVERRIDE { return m_visibleRect; }
 
     unsigned blankPixelCount() const;
     static unsigned blankPixelCountForTiles(const WebTileLayerList&, IntRect, IntPoint);
@@ -82,7 +82,7 @@
     TileCache(WebTileCacheLayer*, const IntSize& tileSize);
 
     // TiledBacking member functions.
-    virtual void visibleRectChanged(const IntRect&) OVERRIDE;
+    virtual void setVisibleRect(const IntRect&) OVERRIDE;
     virtual void setIsInWindow(bool) OVERRIDE;
     virtual void setTileCoverage(TileCoverage) OVERRIDE;
     virtual TileCoverage tileCoverage() const OVERRIDE { return m_tileCoverage; }

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm (131939 => 131940)


--- trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm	2012-10-19 20:43:46 UTC (rev 131940)
@@ -220,7 +220,7 @@
     }
 }
 
-void TileCache::visibleRectChanged(const IntRect& visibleRect)
+void TileCache::setVisibleRect(const IntRect& visibleRect)
 {
     if (m_visibleRect == visibleRect)
         return;

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (131939 => 131940)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-10-19 20:33:27 UTC (rev 131939)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-10-19 20:43:46 UTC (rev 131940)
@@ -283,6 +283,9 @@
     if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
         return;
     
+    if (rootLayerAttachment() == RootLayerUnattached)
+        return;
+
     AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation());
 
     ASSERT(!m_flushingLayers);
@@ -1097,7 +1100,7 @@
     if (TiledBacking* tiledBacking = frameView->tiledBacking()) {
         IntRect visibleContentRect = frameView->visibleContentRect(false /* exclude scrollbars */);
         visibleContentRect.move(toSize(frameView->scrollOrigin()));
-        tiledBacking->visibleRectChanged(visibleContentRect);
+        tiledBacking->setVisibleRect(visibleContentRect);
     }
 
     if (!m_scrollLayer)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to