- Revision
- 147058
- Author
- simon.fra...@apple.com
- Date
- 2013-03-27 22:18:42 -0700 (Wed, 27 Mar 2013)
Log Message
Add a way to update GraphicsLayerCA visibleRects without having to do a flush
https://bugs.webkit.org/show_bug.cgi?id=113459
Reviewed by Tim Horton.
Some platforms need to update TiledBacking visible rects from
outside of WebKit, for example if they use delegated scrolling.
They want to avoid forcing layout to be up-to-date when doing this.
Currently, updating the visibleRect happens when the GraphicsLayerCA
layer are being flushed, but that makes some assumptions about
layout being up-to-date.
To fix this, add a light-weight pass over the layer tree that
uses TransformState to compute the visibleRect for each
layer, and only if the visibleRect would cause a change in the
tiles in a TiledBacking trigger a layer flush.
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::recomputeVisibleRects):
* platform/graphics/TiledBacking.h:
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::recursiveComputeVisibleRect):
(WebCore::GraphicsLayerCA::recomputeVisibleRects):
(WebCore::GraphicsLayerCA::computeVisibleRect):
* platform/graphics/ca/GraphicsLayerCA.h:
* platform/graphics/ca/mac/TileController.h:
* platform/graphics/ca/mac/TileController.mm:
(WebCore::TileController::tilesWouldChangeForVisibleRect):
(WebCore::TileController::computeTileCoverageRect):
(WebCore::TileController::revalidateTiles):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (147057 => 147058)
--- trunk/Source/WebCore/ChangeLog 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/ChangeLog 2013-03-28 05:18:42 UTC (rev 147058)
@@ -1,3 +1,37 @@
+2013-03-27 Simon Fraser <simon.fra...@apple.com>
+
+ Add a way to update GraphicsLayerCA visibleRects without having to do a flush
+ https://bugs.webkit.org/show_bug.cgi?id=113459
+
+ Reviewed by Tim Horton.
+
+ Some platforms need to update TiledBacking visible rects from
+ outside of WebKit, for example if they use delegated scrolling.
+ They want to avoid forcing layout to be up-to-date when doing this.
+
+ Currently, updating the visibleRect happens when the GraphicsLayerCA
+ layer are being flushed, but that makes some assumptions about
+ layout being up-to-date.
+
+ To fix this, add a light-weight pass over the layer tree that
+ uses TransformState to compute the visibleRect for each
+ layer, and only if the visibleRect would cause a change in the
+ tiles in a TiledBacking trigger a layer flush.
+
+ * platform/graphics/GraphicsLayer.h:
+ (WebCore::GraphicsLayer::recomputeVisibleRects):
+ * platform/graphics/TiledBacking.h:
+ * platform/graphics/ca/GraphicsLayerCA.cpp:
+ (WebCore::GraphicsLayerCA::recursiveComputeVisibleRect):
+ (WebCore::GraphicsLayerCA::recomputeVisibleRects):
+ (WebCore::GraphicsLayerCA::computeVisibleRect):
+ * platform/graphics/ca/GraphicsLayerCA.h:
+ * platform/graphics/ca/mac/TileController.h:
+ * platform/graphics/ca/mac/TileController.mm:
+ (WebCore::TileController::tilesWouldChangeForVisibleRect):
+ (WebCore::TileController::computeTileCoverageRect):
+ (WebCore::TileController::revalidateTiles):
+
2013-03-27 Philip Rogers <p...@google.com>
Rename toScriptElement -> toScriptElementIfPossible
Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (147057 => 147058)
--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h 2013-03-28 05:18:42 UTC (rev 147058)
@@ -408,8 +408,11 @@
// and descendant layers, and this layer only.
virtual void flushCompositingState(const FloatRect& /* clipRect */) { }
virtual void flushCompositingStateForThisLayerOnly() { }
-
- // Return a string with a human readable form of the layer tree, If debug is true
+
+ // Walk the layer tree, recomputing the visible rects of layer with TiledBacking, on platforms that use it.
+ virtual void recomputeVisibleRects(const FloatRect& /* clipRect */) { }
+
+ // Return a string with a human readable form of the layer tree, If debug is true
// pointers for the layers and timing data will be included in the returned string.
String layerTreeAsText(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const;
Modified: trunk/Source/WebCore/platform/graphics/TiledBacking.h (147057 => 147058)
--- trunk/Source/WebCore/platform/graphics/TiledBacking.h 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/platform/graphics/TiledBacking.h 2013-03-28 05:18:42 UTC (rev 147058)
@@ -46,6 +46,7 @@
virtual void setVisibleRect(const FloatRect&) = 0;
virtual FloatRect visibleRect() const = 0;
+ virtual bool tilesWouldChangeForVisibleRect(const FloatRect&) const = 0;
virtual void setExposedRect(const FloatRect&) = 0;
virtual void setClipsToExposedRect(bool) = 0;
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (147057 => 147058)
--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp 2013-03-28 05:18:42 UTC (rev 147058)
@@ -907,25 +907,66 @@
client()->didCommitChangesForLayer(this);
}
+void GraphicsLayerCA::recursiveComputeVisibleRect(const TransformState& state)
+{
+ TransformState localState = state;
+
+ // This may be called at times when layout has not been updated, so we want to avoid calling out to the client
+ // for animating transforms.
+ FloatRect visibleRect = computeVisibleRect(localState, 0);
+ if (visibleRect != m_visibleRect) {
+ m_visibleRect = visibleRect;
+ if (TiledBacking* tiledBacking = this->tiledBacking()) {
+ if (tiledBacking->tilesWouldChangeForVisibleRect(m_visibleRect))
+ noteLayerPropertyChanged(VisibleRectChanged);
+ }
+ }
+
+ if (m_maskLayer) {
+ GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
+ maskLayerCA->recursiveComputeVisibleRect(localState);
+ }
+
+ const Vector<GraphicsLayer*>& childLayers = children();
+ size_t numChildren = childLayers.size();
+
+ for (size_t i = 0; i < numChildren; ++i) {
+ GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+ curChild->recursiveComputeVisibleRect(localState);
+ }
+
+ if (m_replicaLayer)
+ static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveComputeVisibleRect(localState);
+}
+
+void GraphicsLayerCA::recomputeVisibleRects(const FloatRect& clipRect)
+{
+ TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
+ recursiveComputeVisibleRect(state);
+}
+
TiledBacking* GraphicsLayerCA::tiledBacking() const
{
return m_layer->tiledBacking();
}
-FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state) const
+FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state, ComputeVisibleRectFlags flags) const
{
bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
TransformationMatrix layerTransform;
FloatPoint position = m_position;
- if (m_client)
- m_client->customPositionForVisibleRectComputation(this, position);
+ if (client())
+ client()->customPositionForVisibleRectComputation(this, position);
layerTransform.translate(position.x(), position.y());
TransformationMatrix currentTransform;
- if (client() && client()->getCurrentTransform(this, currentTransform) && !currentTransform.isIdentity()) {
+ if (!(flags & RespectAnimatingTransforms) || !client() || !client()->getCurrentTransform(this, currentTransform))
+ currentTransform = m_transform;
+
+ if (!currentTransform.isIdentity()) {
FloatPoint3D absoluteAnchorPoint(anchorPoint());
absoluteAnchorPoint.scale(size().width(), size().height(), 1);
layerTransform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (147057 => 147058)
--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h 2013-03-28 05:18:42 UTC (rev 147058)
@@ -142,6 +142,9 @@
virtual void flushCompositingState(const FloatRect&);
virtual void flushCompositingStateForThisLayerOnly();
+ void recursiveComputeVisibleRect(const TransformState&);
+ virtual void recomputeVisibleRects(const FloatRect& clipRect);
+
virtual TiledBacking* tiledBacking() const OVERRIDE;
bool allowTiledLayer() const { return m_allowTiledLayer; }
@@ -243,7 +246,9 @@
void computePixelAlignment(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase,
FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const;
- FloatRect computeVisibleRect(TransformState&) const;
+ enum ComputeVisibleRectFlag { RespectAnimatingTransforms = 1 << 0 };
+ typedef unsigned ComputeVisibleRectFlags;
+ FloatRect computeVisibleRect(TransformState&, ComputeVisibleRectFlags = RespectAnimatingTransforms) const;
const FloatRect& visibleRect() const { return m_visibleRect; }
FloatRect adjustTiledLayerVisibleRect(TiledBacking*, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const;
Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileController.h (147057 => 147058)
--- trunk/Source/WebCore/platform/graphics/ca/mac/TileController.h 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileController.h 2013-03-28 05:18:42 UTC (rev 147058)
@@ -107,6 +107,7 @@
// TiledBacking member functions.
virtual void setVisibleRect(const FloatRect&) OVERRIDE;
+ virtual bool tilesWouldChangeForVisibleRect(const FloatRect&) const OVERRIDE;
virtual void setExposedRect(const FloatRect&) OVERRIDE;
virtual bool clipsToExposedRect() OVERRIDE { return m_clipsToExposedRect; }
virtual void setClipsToExposedRect(bool) OVERRIDE;
@@ -133,7 +134,7 @@
IntRect rectForTileIndex(const TileIndex&) const;
void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight) const;
- FloatRect computeTileCoverageRect(const FloatRect& previousVisibleRect) const;
+ FloatRect computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const;
IntSize tileSizeForCoverageRect(const FloatRect&) const;
void scheduleTileRevalidation(double interval);
Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm (147057 => 147058)
--- trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm 2013-03-28 05:04:38 UTC (rev 147057)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm 2013-03-28 05:18:42 UTC (rev 147058)
@@ -306,6 +306,35 @@
revalidateTiles();
}
+bool TileController::tilesWouldChangeForVisibleRect(const FloatRect& newVisibleRect) const
+{
+ FloatRect visibleRect = newVisibleRect;
+
+ if (m_clipsToExposedRect)
+ visibleRect.intersect(m_exposedRect);
+
+ if (visibleRect.isEmpty() || bounds().isEmpty())
+ return false;
+
+ FloatRect currentTileCoverageRect = computeTileCoverageRect(m_visibleRect, newVisibleRect);
+ FloatRect scaledRect(currentTileCoverageRect);
+ scaledRect.scale(m_scale);
+ IntRect currentCoverageRectInTileCoords(enclosingIntRect(scaledRect));
+
+ IntSize newTileSize = tileSizeForCoverageRect(currentTileCoverageRect);
+ bool tileSizeChanged = newTileSize != m_tileSize;
+ if (tileSizeChanged)
+ return true;
+
+ TileIndex topLeft;
+ TileIndex bottomRight;
+ getTileIndexRangeForRect(currentCoverageRectInTileCoords, topLeft, bottomRight);
+
+ IntRect coverageRect = rectForTileIndex(topLeft);
+ coverageRect.unite(rectForTileIndex(bottomRight));
+ return coverageRect != m_primaryTileCoverageRect;
+}
+
void TileController::setExposedRect(const FloatRect& exposedRect)
{
if (m_exposedRect == exposedRect)
@@ -417,9 +446,9 @@
bottomRight.setY(max(bottomYRatio - 1, 0));
}
-FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisibleRect) const
+FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const
{
- FloatRect visibleRect = m_visibleRect;
+ FloatRect visibleRect = currentVisibleRect;
if (m_clipsToExposedRect)
visibleRect.intersect(m_exposedRect);
@@ -591,7 +620,7 @@
TileValidationPolicyFlags validationPolicy = m_isInWindow ? foregroundValidationPolicy : backgroundValidationPolicy;
- FloatRect tileCoverageRect = computeTileCoverageRect(m_visibleRectAtLastRevalidate);
+ FloatRect tileCoverageRect = computeTileCoverageRect(m_visibleRectAtLastRevalidate, m_visibleRect);
FloatRect scaledRect(tileCoverageRect);
scaledRect.scale(m_scale);
IntRect coverageRectInTileCoords(enclosingIntRect(scaledRect));