Title: [141036] trunk/Source/WebCore
Revision
141036
Author
simon.fra...@apple.com
Date
2013-01-28 19:42:59 -0800 (Mon, 28 Jan 2013)

Log Message

Avoid doing work at 60fps for tiled layers when not necessary
https://bugs.webkit.org/show_bug.cgi?id=108135

Reviewed by Dean Jackson.

When there were any tiled layers on the page, we would run a CVDisplayLink
to cause GraphicsLayerCA to flush, in order to update tiled layer visible rects.
This is overkill; we should only do this if the tiled layer is affected by
an accelerated animation.

Fix by tracking whether an ancestor has a running animation when committing
GraphicsLayerCAs.

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::flushCompositingState): Start with an empty CommitState.
(WebCore::GraphicsLayerCA::recursiveCommitChanges): Push CommitState for
each layer, which tracks whether an ancestor has a running transform animation.
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): updateLayerAnimations() renamed.
(WebCore::GraphicsLayerCA::updateAnimations): Renamed from updateLayerAnimations().
(WebCore::GraphicsLayerCA::isRunningTransformAnimation): Look in the map of running
animations for one affecting transform. This list is normally small (one item).
* platform/graphics/ca/GraphicsLayerCA.h:
(WebCore::GraphicsLayerCA::CommitState::CommitState):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (141035 => 141036)


--- trunk/Source/WebCore/ChangeLog	2013-01-29 03:42:34 UTC (rev 141035)
+++ trunk/Source/WebCore/ChangeLog	2013-01-29 03:42:59 UTC (rev 141036)
@@ -1,5 +1,31 @@
 2013-01-28  Simon Fraser  <simon.fra...@apple.com>
 
+        Avoid doing work at 60fps for tiled layers when not necessary
+        https://bugs.webkit.org/show_bug.cgi?id=108135
+
+        Reviewed by Dean Jackson.
+
+        When there were any tiled layers on the page, we would run a CVDisplayLink
+        to cause GraphicsLayerCA to flush, in order to update tiled layer visible rects.
+        This is overkill; we should only do this if the tiled layer is affected by
+        an accelerated animation.
+        
+        Fix by tracking whether an ancestor has a running animation when committing
+        GraphicsLayerCAs.
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::flushCompositingState): Start with an empty CommitState.
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges): Push CommitState for
+        each layer, which tracks whether an ancestor has a running transform animation.
+        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): updateLayerAnimations() renamed.
+        (WebCore::GraphicsLayerCA::updateAnimations): Renamed from updateLayerAnimations().
+        (WebCore::GraphicsLayerCA::isRunningTransformAnimation): Look in the map of running
+        animations for one affecting transform. This list is normally small (one item).
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        (WebCore::GraphicsLayerCA::CommitState::CommitState):
+
+2013-01-28  Simon Fraser  <simon.fra...@apple.com>
+
         compositing/reflections/become-simple-composited-reflection.html pixel result shows bug
         https://bugs.webkit.org/show_bug.cgi?id=107174
 

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


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2013-01-29 03:42:34 UTC (rev 141035)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2013-01-29 03:42:59 UTC (rev 141036)
@@ -890,7 +890,7 @@
 void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect)
 {
     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
-    recursiveCommitChanges(state);
+    recursiveCommitChanges(CommitState(), state);
 }
 
 void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
@@ -952,9 +952,11 @@
     return clipRectForSelf;
 }
 
-void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
+void GraphicsLayerCA::recursiveCommitChanges(const CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
 {
     TransformState localState = state;
+    CommitState childCommitState = commitState;
+    bool affectedByTransformAnimation = commitState.ancestorHasTransformAnimation;
     
     FloatRect visibleRect = computeVisibleRect(localState);
     FloatRect oldVisibleRect = m_visibleRect;
@@ -998,6 +1000,11 @@
     
     commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, oldVisibleRect);
 
+    if (isRunningTransformAnimation()) {
+        childCommitState.ancestorHasTransformAnimation = true;
+        affectedByTransformAnimation = true;
+    }
+
     if (m_maskLayer) {
         GraphicsLayerCA* maskLayerCA = static_cast<GraphicsLayerCA*>(m_maskLayer);
         maskLayerCA->commitLayerChangesBeforeSublayers(pageScaleFactor, baseRelativePosition, maskLayerCA->visibleRect());
@@ -1008,18 +1015,18 @@
     
     for (size_t i = 0; i < numChildren; ++i) {
         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
-        curChild->recursiveCommitChanges(localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
+        curChild->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
     }
 
     if (m_replicaLayer)
-        static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
+        static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
 
     if (m_maskLayer)
         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
 
     commitLayerChangesAfterSublayers();
 
-    if (client() && m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer)
+    if (affectedByTransformAnimation && client() && m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer)
         client()->notifyFlushBeforeDisplayRefresh(this);
 
     if (hadChanges && client())
@@ -1118,7 +1125,7 @@
 #endif
     
     if (m_uncommittedChanges & AnimationChanged)
-        updateLayerAnimations();
+        updateAnimations();
 
     // Updating the contents scale can cause parts of the layer to be invalidated,
     // so make sure to update the contents scale before updating the dirty rects.
@@ -1773,7 +1780,7 @@
     return clonedLayerRoot;
 }
 
-void GraphicsLayerCA::updateLayerAnimations()
+void GraphicsLayerCA::updateAnimations()
 {
     if (m_animationsToProcess.size()) {
         AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
@@ -1825,6 +1832,21 @@
     }
 }
 
+bool GraphicsLayerCA::isRunningTransformAnimation() const
+{
+    AnimationsMap::const_iterator end = m_runningAnimations.end();
+    for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
+        const Vector<LayerPropertyAnimation>& propertyAnimations = it->value;
+        size_t numAnimations = propertyAnimations.size();
+        for (size_t i = 0; i < numAnimations; ++i) {
+            const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
+            if (currAnimation.m_property == AnimatedPropertyWebkitTransform)
+                return true;
+        }
+    }
+    return false;
+}
+
 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
 {
     PlatformCALayer* layer = animatedLayer(property);

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


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2013-01-29 03:42:34 UTC (rev 141035)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2013-01-29 03:42:59 UTC (rev 141036)
@@ -131,7 +131,13 @@
     virtual void setMaintainsPixelAlignment(bool);
     virtual void deviceOrPageScaleFactorChanged();
 
-    void recursiveCommitChanges(const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
+    struct CommitState {
+        bool ancestorHasTransformAnimation;
+        CommitState()
+            : ancestorHasTransformAnimation(false)
+        { }
+    };
+    void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
 
     virtual void flushCompositingState(const FloatRect&);
     virtual void flushCompositingStateForThisLayerOnly();
@@ -208,6 +214,8 @@
     bool setFilterAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType);
 #endif
 
+    bool isRunningTransformAnimation() const;
+
     bool animationIsRunning(const String& animationName) const
     {
         return m_runningAnimations.find(animationName) != m_runningAnimations.end();
@@ -326,7 +334,7 @@
     void updateMaskLayer();
     void updateReplicatedLayers();
 
-    void updateLayerAnimations();
+    void updateAnimations();
     void updateContentsNeedsDisplay();
     void updateAcceleratesDrawing();
     void updateDebugBorder();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to