Skip to content

Commit ba5ba84

Browse files
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(). git-svn-id: http://svn.webkit.org/repository/webkit/trunk@131940 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent c6cbfed commit ba5ba84

File tree

7 files changed

+164
-17
lines changed

7 files changed

+164
-17
lines changed

Source/WebCore/ChangeLog

+52
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,55 @@
1+
2012-10-19 Simon Fraser <[email protected]>
2+
3+
Use tile caches in place of CATiledLayer
4+
https://bugs.webkit.org/show_bug.cgi?id=99806
5+
<rdar://problem/6474145>
6+
7+
Reviewed by Tim Horton.
8+
9+
Have GraphicsLayerCA use TileCaches instead of CATiledLayer now for
10+
layers that exceed the 2000px size threshold.
11+
12+
* platform/graphics/TiledBacking.h:
13+
(TiledBacking): Have normal getter and setter for the visible rect.
14+
* platform/graphics/ca/GraphicsLayerCA.cpp:
15+
(WebCore::GraphicsLayerCA::flushCompositingStateForThisLayerOnly): We need
16+
to pass in an old visibleRect to commitLayerChangesBeforeSublayers(). Just use
17+
our current visible rect, which result in no tile area work.
18+
(WebCore::GraphicsLayerCA::computeVisibleRect): Make this const and have it
19+
return the rect, for clarity.
20+
(WebCore::GraphicsLayerCA::recursiveCommitChanges): Keep track of the old
21+
visible rect, and use the change flags mechanism to ensure that we recompute
22+
tile areas later.
23+
When calling commitLayerChangesBeforeSublayers() on the mask layer, just pass
24+
its own visible rect as the old visible rect.
25+
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Pass in the
26+
oldVisibleRect so that updateVisibleRect() can use this to see how the
27+
visibleRect is changing.
28+
(WebCore::GraphicsLayerCA::adjustTiledLayerVisibleRect): This member function
29+
compares the old and new visible rects, and extends the tile coverage area
30+
in directions where more content is being exposed. It takes care to avoid
31+
"jitter" in the visible rect deltas causing edge tiles to get created then
32+
destroyed by keeping any extra padding that already exists in a direction
33+
where more content is being exposed.
34+
(WebCore::GraphicsLayerCA::updateVisibleRect): Call adjustTiledLayerVisibleRect()
35+
and use the result to update the TiledBacking's visibleRect.
36+
(WebCore::GraphicsLayerCA::swapFromOrToTiledLayer): Create layers of type
37+
LayerTypeTileCacheLayer instead of LayerTypeWebTiledLayer. Because tile
38+
cache layers involve adding an extra layer to the hierarchy (the tile container),
39+
we call updateSublayerList() when changing layer type.
40+
* platform/graphics/ca/GraphicsLayerCA.h: New m_sizeAtLastVisibleRectUpdate member
41+
that is used to prevent the adjustTiledLayerVisibleRect() logic being confused by
42+
size changes.
43+
(WebCore::GraphicsLayerCA::visibleRect):
44+
* platform/graphics/ca/mac/TileCache.h: Have normal getter and setter for the visible rect.
45+
* platform/graphics/ca/mac/TileCache.mm:
46+
(WebCore::TileCache::setVisibleRect): Renamed to setVisibleRect().
47+
* rendering/RenderLayerCompositor.cpp:
48+
(WebCore::RenderLayerCompositor::flushPendingLayerChanges): Avoid doing work
49+
for pages in the page cache, for which the root layer is unattached.
50+
(WebCore::RenderLayerCompositor::frameViewDidScroll): visibleRectChanged() was renamed
51+
to setVisibleRect().
52+
153
2012-10-19 Beth Dakin <[email protected]>
254

355
https://bugs.webkit.org/show_bug.cgi?id=99768

Source/WebCore/platform/graphics/TiledBacking.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ class TiledBacking {
3434
public:
3535
virtual ~TiledBacking() { }
3636

37-
virtual void visibleRectChanged(const IntRect&) = 0;
37+
virtual void setVisibleRect(const IntRect&) = 0;
38+
virtual IntRect visibleRect() const = 0;
39+
3840
virtual void setIsInWindow(bool) = 0;
3941

4042
enum {

Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

+93-9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "ScaleTransformOperation.h"
3939
#include "SystemTime.h"
4040
#include "TextStream.h"
41+
#include "TiledBacking.h"
4142
#include "TransformState.h"
4243
#include "TranslateTransformOperation.h"
4344
#include <QuartzCore/CATransform3D.h>
@@ -905,7 +906,7 @@ void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
905906
{
906907
float pageScaleFactor;
907908
FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
908-
commitLayerChangesBeforeSublayers(pageScaleFactor, offset);
909+
commitLayerChangesBeforeSublayers(pageScaleFactor, offset, m_visibleRect);
909910
commitLayerChangesAfterSublayers();
910911
}
911912

@@ -914,7 +915,7 @@ TiledBacking* GraphicsLayerCA::tiledBacking()
914915
return m_layer->tiledBacking();
915916
}
916917

917-
void GraphicsLayerCA::computeVisibleRect(TransformState& state)
918+
FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state) const
918919
{
919920
bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
920921
TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
@@ -954,13 +955,19 @@ void GraphicsLayerCA::computeVisibleRect(TransformState& state)
954955
state.setQuad(clipRectForSelf);
955956
}
956957

957-
m_visibleRect = clipRectForSelf;
958+
return clipRectForSelf;
958959
}
959960

960961
void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
961962
{
962963
TransformState localState = state;
963-
computeVisibleRect(localState);
964+
965+
FloatRect visibleRect = computeVisibleRect(localState);
966+
FloatRect oldVisibleRect = m_visibleRect;
967+
if (visibleRect != m_visibleRect) {
968+
m_uncommittedChanges |= VisibleRectChanged;
969+
m_visibleRect = visibleRect;
970+
}
964971

965972
#ifdef VISIBLE_TILE_WASH
966973
// Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
@@ -995,10 +1002,12 @@ void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float
9951002
if (affectedByPageScale)
9961003
baseRelativePosition += m_position;
9971004

998-
commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition);
1005+
commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, oldVisibleRect);
9991006

1000-
if (m_maskLayer)
1001-
static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition);
1007+
if (m_maskLayer) {
1008+
GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
1009+
maskLayerCA->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
1010+
}
10021011

10031012
const Vector<GraphicsLayer*>& childLayers = children();
10041013
size_t numChildren = childLayers.size();
@@ -1055,7 +1064,7 @@ float GraphicsLayerCA::platformCALayerDeviceScaleFactor()
10551064
return deviceScaleFactor();
10561065
}
10571066

1058-
void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
1067+
void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect)
10591068
{
10601069
if (!m_uncommittedChanges)
10611070
return;
@@ -1122,6 +1131,9 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, c
11221131
if (m_uncommittedChanges & ContentsScaleChanged)
11231132
updateContentsScale(pageScaleFactor, positionRelativeToBase);
11241133

1134+
if (m_uncommittedChanges & VisibleRectChanged)
1135+
updateVisibleRect(oldVisibleRect);
1136+
11251137
if (m_uncommittedChanges & DirtyRectsChanged)
11261138
repaintLayerDirtyRects();
11271139

@@ -1535,7 +1547,78 @@ void GraphicsLayerCA::updateAcceleratesDrawing()
15351547
{
15361548
m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
15371549
}
1550+
1551+
FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const
1552+
{
1553+
// If the old visible rect is empty, we have no information about how the visible area is changing
1554+
// (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
1555+
// if the size changed.
1556+
if (oldVisibleRect.isEmpty() || m_size != oldSize)
1557+
return m_visibleRect;
1558+
1559+
const float paddingMultiplier = 2;
1560+
1561+
float leftEdgeDelta = paddingMultiplier * (m_visibleRect.x() - oldVisibleRect.x());
1562+
float rightEdgeDelta = paddingMultiplier * (m_visibleRect.maxX() - oldVisibleRect.maxX());
1563+
1564+
float topEdgeDelta = paddingMultiplier * (m_visibleRect.y() - oldVisibleRect.y());
1565+
float bottomEdgeDelta = paddingMultiplier * (m_visibleRect.maxY() - oldVisibleRect.maxY());
15381566

1567+
FloatRect existingTileBackingRect = tiledBacking->visibleRect();
1568+
FloatRect expandedRect = m_visibleRect;
1569+
1570+
// More exposed on left side.
1571+
if (leftEdgeDelta < 0) {
1572+
float newLeft = expandedRect.x() + leftEdgeDelta;
1573+
// Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
1574+
if (newLeft < existingTileBackingRect.x())
1575+
expandedRect.shiftXEdgeTo(newLeft);
1576+
else
1577+
expandedRect.shiftXEdgeTo(existingTileBackingRect.x());
1578+
}
1579+
1580+
// More exposed on right.
1581+
if (rightEdgeDelta > 0) {
1582+
float newRight = expandedRect.maxX() + rightEdgeDelta;
1583+
// Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
1584+
if (newRight > existingTileBackingRect.maxX())
1585+
expandedRect.setWidth(newRight - expandedRect.x());
1586+
else
1587+
expandedRect.setWidth(existingTileBackingRect.maxX() - expandedRect.x());
1588+
}
1589+
1590+
// More exposed at top.
1591+
if (topEdgeDelta < 0) {
1592+
float newTop = expandedRect.y() + topEdgeDelta;
1593+
if (newTop < existingTileBackingRect.y())
1594+
expandedRect.shiftYEdgeTo(newTop);
1595+
else
1596+
expandedRect.shiftYEdgeTo(existingTileBackingRect.y());
1597+
}
1598+
1599+
// More exposed on bottom.
1600+
if (bottomEdgeDelta > 0) {
1601+
float newBottom = expandedRect.maxY() + bottomEdgeDelta;
1602+
if (newBottom > existingTileBackingRect.maxY())
1603+
expandedRect.setHeight(newBottom - expandedRect.y());
1604+
else
1605+
expandedRect.setHeight(existingTileBackingRect.maxY() - expandedRect.y());
1606+
}
1607+
1608+
return expandedRect;
1609+
}
1610+
1611+
void GraphicsLayerCA::updateVisibleRect(const FloatRect& oldVisibleRect)
1612+
{
1613+
if (m_layer->layerType() != PlatformCALayer::LayerTypeTileCacheLayer)
1614+
return;
1615+
1616+
FloatRect tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, m_sizeAtLastVisibleRectUpdate);
1617+
tiledBacking()->setVisibleRect(enclosingIntRect(tileArea));
1618+
1619+
m_sizeAtLastVisibleRectUpdate = m_size;
1620+
}
1621+
15391622
void GraphicsLayerCA::updateLayerBackgroundColor()
15401623
{
15411624
if (m_isPageTileCacheLayer) {
@@ -2501,7 +2584,7 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer, float pageScale
25012584
ASSERT(useTiledLayer != m_usingTiledLayer);
25022585
RefPtr<PlatformCALayer> oldLayer = m_layer;
25032586

2504-
m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this);
2587+
m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeTileCacheLayer : PlatformCALayer::LayerTypeWebLayer, this);
25052588
m_usingTiledLayer = useTiledLayer;
25062589

25072590
m_layer->adoptSublayers(oldLayer.get());
@@ -2520,6 +2603,7 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer, float pageScale
25202603
updateGeometry(pageScaleFactor, positionRelativeToBase);
25212604
updateTransform();
25222605
updateChildrenTransform();
2606+
updateSublayerList();
25232607
updateMasksToBounds();
25242608
#if ENABLE(CSS_FILTERS)
25252609
updateFilters();

Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient {
211211
return m_runningAnimations.find(animationName) != m_runningAnimations.end();
212212
}
213213

214-
void commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase);
214+
void commitLayerChangesBeforeSublayers(float pageScaleFactor, const FloatPoint& positionRelativeToBase, const FloatRect& oldVisibleRect);
215215
void commitLayerChangesAfterSublayers();
216216

217217
FloatPoint computePositionRelativeToBase(float& pageScale) const;
@@ -233,7 +233,10 @@ class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient {
233233

234234
void computePixelAlignment(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase,
235235
FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const;
236-
void computeVisibleRect(TransformState&);
236+
FloatRect computeVisibleRect(TransformState&) const;
237+
const FloatRect& visibleRect() const { return m_visibleRect; }
238+
239+
FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const;
237240

238241
// Used to track the path down the tree for replica layers.
239242
struct ReplicaState {
@@ -323,6 +326,7 @@ class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient {
323326
void updateLayerAnimations();
324327
void updateContentsNeedsDisplay();
325328
void updateAcceleratesDrawing();
329+
void updateVisibleRect(const FloatRect& oldVisibleRect);
326330
void updateContentsScale(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase);
327331

328332
enum StructuralLayerPurpose {
@@ -372,8 +376,9 @@ class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient {
372376
AcceleratesDrawingChanged = 1 << 22,
373377
ContentsScaleChanged = 1 << 23,
374378
ContentsVisibilityChanged = 1 << 24,
379+
VisibleRectChanged = 1 << 25,
375380
#if ENABLE(CSS_FILTERS)
376-
FiltersChanged = 1 << 25,
381+
FiltersChanged = 1 << 26,
377382
#endif
378383
};
379384
typedef unsigned LayerChangeFlags;
@@ -396,6 +401,7 @@ class GraphicsLayerCA : public GraphicsLayer, public PlatformCALayerClient {
396401
RefPtr<PlatformCALayer> m_visibleTileWashLayer;
397402
#endif
398403
FloatRect m_visibleRect;
404+
FloatSize m_sizeAtLastVisibleRectUpdate;
399405

400406
enum ContentsLayerPurpose {
401407
NoContentsLayer = 0,

Source/WebCore/platform/graphics/ca/mac/TileCache.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class TileCache : public TiledBacking {
7373
void setTileDebugBorderWidth(float);
7474
void setTileDebugBorderColor(CGColorRef);
7575

76-
IntRect visibleRect() const { return m_visibleRect; }
76+
virtual IntRect visibleRect() const OVERRIDE { return m_visibleRect; }
7777

7878
unsigned blankPixelCount() const;
7979
static unsigned blankPixelCountForTiles(const WebTileLayerList&, IntRect, IntPoint);
@@ -82,7 +82,7 @@ class TileCache : public TiledBacking {
8282
TileCache(WebTileCacheLayer*, const IntSize& tileSize);
8383

8484
// TiledBacking member functions.
85-
virtual void visibleRectChanged(const IntRect&) OVERRIDE;
85+
virtual void setVisibleRect(const IntRect&) OVERRIDE;
8686
virtual void setIsInWindow(bool) OVERRIDE;
8787
virtual void setTileCoverage(TileCoverage) OVERRIDE;
8888
virtual TileCoverage tileCoverage() const OVERRIDE { return m_tileCoverage; }

Source/WebCore/platform/graphics/ca/mac/TileCache.mm

+1-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ - (void)setAcceleratesDrawing:(BOOL)flag;
220220
}
221221
}
222222

223-
void TileCache::visibleRectChanged(const IntRect& visibleRect)
223+
void TileCache::setVisibleRect(const IntRect& visibleRect)
224224
{
225225
if (m_visibleRect == visibleRect)
226226
return;

Source/WebCore/rendering/RenderLayerCompositor.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
283283
if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
284284
return;
285285

286+
if (rootLayerAttachment() == RootLayerUnattached)
287+
return;
288+
286289
AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame()->animation());
287290

288291
ASSERT(!m_flushingLayers);
@@ -1097,7 +1100,7 @@ void RenderLayerCompositor::frameViewDidScroll()
10971100
if (TiledBacking* tiledBacking = frameView->tiledBacking()) {
10981101
IntRect visibleContentRect = frameView->visibleContentRect(false /* exclude scrollbars */);
10991102
visibleContentRect.move(toSize(frameView->scrollOrigin()));
1100-
tiledBacking->visibleRectChanged(visibleContentRect);
1103+
tiledBacking->setVisibleRect(visibleContentRect);
11011104
}
11021105

11031106
if (!m_scrollLayer)

0 commit comments

Comments
 (0)