Title: [110980] trunk/Source
Revision
110980
Author
[email protected]
Date
2012-03-16 03:29:34 -0700 (Fri, 16 Mar 2012)

Log Message

[chromium] Threaded opacity animation jump to opacity of 0
https://bugs.webkit.org/show_bug.cgi?id=80744

Patch by Ian Vollick <[email protected]> on 2012-03-16
Reviewed by James Robinson.

Source/WebCore:

Tested in CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity

* platform/graphics/chromium/LayerChromium.cpp:
(WebCore::LayerChromium::LayerChromium):
(WebCore::LayerChromium::opacityIsAnimating):
(WebCore):
(WebCore::LayerChromium::transformIsAnimating):
* platform/graphics/chromium/LayerChromium.h:
(LayerChromium):
(WebCore::LayerChromium::drawOpacityIsAnimating):
(WebCore::LayerChromium::setDrawOpacityIsAnimating):
* platform/graphics/chromium/RenderSurfaceChromium.cpp:
(WebCore::RenderSurfaceChromium::RenderSurfaceChromium):
* platform/graphics/chromium/RenderSurfaceChromium.h:
(WebCore::RenderSurfaceChromium::drawOpacityIsAnimating):
(WebCore::RenderSurfaceChromium::setDrawOpacityIsAnimating):
(RenderSurfaceChromium):
* platform/graphics/chromium/cc/CCLayerAnimationController.cpp:
(WebCore::CCLayerAnimationController::isAnimatingProperty):
(WebCore):
* platform/graphics/chromium/cc/CCLayerAnimationController.h:
(CCLayerAnimationController):
* platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp:
(WebCore::CCLayerAnimationControllerImpl::isAnimatingProperty):
(WebCore):
* platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h:
(CCLayerAnimationControllerImpl):
* platform/graphics/chromium/cc/CCLayerImpl.cpp:
(WebCore::CCLayerImpl::CCLayerImpl):
(WebCore::CCLayerImpl::opacityIsAnimating):
(WebCore):
(WebCore::CCLayerImpl::transformIsAnimating):
* platform/graphics/chromium/cc/CCLayerImpl.h:
(CCLayerImpl):
(WebCore::CCLayerImpl::drawOpacityIsAnimating):
(WebCore::CCLayerImpl::setDrawOpacityIsAnimating):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::paintLayerContents):
(WebCore::CCLayerTreeHost::updateCompositorResources):
* platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
(WebCore::layerShouldBeSkipped):
(WebCore::subtreeShouldBeSkipped):
(WebCore):
(WebCore::LayerChromium):
(WebCore::calculateDrawTransformsAndVisibilityInternal):
* platform/graphics/chromium/cc/CCRenderSurface.cpp:
(WebCore::CCRenderSurface::CCRenderSurface):
* platform/graphics/chromium/cc/CCRenderSurface.h:
(WebCore::CCRenderSurface::drawOpacityIsAnimating):
(WebCore::CCRenderSurface::setDrawOpacityIsAnimating):
(CCRenderSurface):

Source/WebKit/chromium:

* tests/CCLayerTreeHostTest.cpp:
(WTF):
(CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity):
(WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity):
(WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::beginTest):
(WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::animateLayers):
(WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::commitCompleteOnCCThread):
(WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::afterTest):
(WTF::TEST_F):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (110979 => 110980)


--- trunk/Source/WebCore/ChangeLog	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/ChangeLog	2012-03-16 10:29:34 UTC (rev 110980)
@@ -1,3 +1,62 @@
+2012-03-16  Ian Vollick  <[email protected]>
+
+        [chromium] Threaded opacity animation jump to opacity of 0
+        https://bugs.webkit.org/show_bug.cgi?id=80744
+
+        Reviewed by James Robinson.
+
+        Tested in CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity
+
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::LayerChromium::LayerChromium):
+        (WebCore::LayerChromium::opacityIsAnimating):
+        (WebCore):
+        (WebCore::LayerChromium::transformIsAnimating):
+        * platform/graphics/chromium/LayerChromium.h:
+        (LayerChromium):
+        (WebCore::LayerChromium::drawOpacityIsAnimating):
+        (WebCore::LayerChromium::setDrawOpacityIsAnimating):
+        * platform/graphics/chromium/RenderSurfaceChromium.cpp:
+        (WebCore::RenderSurfaceChromium::RenderSurfaceChromium):
+        * platform/graphics/chromium/RenderSurfaceChromium.h:
+        (WebCore::RenderSurfaceChromium::drawOpacityIsAnimating):
+        (WebCore::RenderSurfaceChromium::setDrawOpacityIsAnimating):
+        (RenderSurfaceChromium):
+        * platform/graphics/chromium/cc/CCLayerAnimationController.cpp:
+        (WebCore::CCLayerAnimationController::isAnimatingProperty):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCLayerAnimationController.h:
+        (CCLayerAnimationController):
+        * platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp:
+        (WebCore::CCLayerAnimationControllerImpl::isAnimatingProperty):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h:
+        (CCLayerAnimationControllerImpl):
+        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+        (WebCore::CCLayerImpl::CCLayerImpl):
+        (WebCore::CCLayerImpl::opacityIsAnimating):
+        (WebCore):
+        (WebCore::CCLayerImpl::transformIsAnimating):
+        * platform/graphics/chromium/cc/CCLayerImpl.h:
+        (CCLayerImpl):
+        (WebCore::CCLayerImpl::drawOpacityIsAnimating):
+        (WebCore::CCLayerImpl::setDrawOpacityIsAnimating):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::paintLayerContents):
+        (WebCore::CCLayerTreeHost::updateCompositorResources):
+        * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
+        (WebCore::layerShouldBeSkipped):
+        (WebCore::subtreeShouldBeSkipped):
+        (WebCore):
+        (WebCore::LayerChromium):
+        (WebCore::calculateDrawTransformsAndVisibilityInternal):
+        * platform/graphics/chromium/cc/CCRenderSurface.cpp:
+        (WebCore::CCRenderSurface::CCRenderSurface):
+        * platform/graphics/chromium/cc/CCRenderSurface.h:
+        (WebCore::CCRenderSurface::drawOpacityIsAnimating):
+        (WebCore::CCRenderSurface::setDrawOpacityIsAnimating):
+        (CCRenderSurface):
+
 2012-03-15  Jocelyn Turcotte  <[email protected]>
 
         [TexMap] Reuse textures following the same rules as they do internally.

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -80,6 +80,7 @@
     , m_alwaysReserveTextures(false)
     , m_replicaLayer(0)
     , m_drawOpacity(0)
+    , m_drawOpacityIsAnimating(false)
     , m_targetRenderSurface(0)
     , m_contentsScale(1.0)
     , m_layerAnimationDelegate(0)
@@ -389,6 +390,11 @@
     setNeedsCommit();
 }
 
+bool LayerChromium::opacityIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Opacity);
+}
+
 void LayerChromium::setOpaque(bool opaque)
 {
     if (m_opaque == opaque)
@@ -421,6 +427,11 @@
     setNeedsCommit();
 }
 
+bool LayerChromium::transformIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Transform);
+}
+
 void LayerChromium::setScrollPosition(const IntPoint& scrollPosition)
 {
     if (m_scrollPosition == scrollPosition)

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h	2012-03-16 10:29:34 UTC (rev 110980)
@@ -110,6 +110,7 @@
 
     void setOpacity(float);
     float opacity() const { return m_opacity; }
+    bool opacityIsAnimating() const;
 
     void setFilters(const FilterOperations&);
     const FilterOperations& filters() const { return m_filters; }
@@ -125,6 +126,7 @@
 
     void setTransform(const TransformationMatrix&);
     const TransformationMatrix& transform() const { return m_transform; }
+    bool transformIsAnimating() const;
 
     const IntRect& visibleLayerRect() const { return m_visibleLayerRect; }
     void setVisibleLayerRect(const IntRect& visibleLayerRect) { m_visibleLayerRect = visibleLayerRect; }
@@ -187,6 +189,10 @@
 
     float drawOpacity() const { return m_drawOpacity; }
     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
+
+    bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; }
+    void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; }
+
     const IntRect& clipRect() const { return m_clipRect; }
     void setClipRect(const IntRect& clipRect) { m_clipRect = clipRect; }
     RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; }
@@ -313,6 +319,7 @@
     // Transient properties.
     OwnPtr<RenderSurfaceChromium> m_renderSurface;
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
     IntRect m_clipRect;
     RenderSurfaceChromium* m_targetRenderSurface;
     TransformationMatrix m_drawTransform;

Modified: trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -42,6 +42,7 @@
     , m_maskLayer(0)
     , m_skipsDraw(false)
     , m_drawOpacity(1)
+    , m_drawOpacityIsAnimating(false)
     , m_nearestAncestorThatMovesPixels(0)
 {
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h	2012-03-16 10:29:34 UTC (rev 110980)
@@ -63,6 +63,9 @@
     float drawOpacity() const { return m_drawOpacity; }
     void setDrawOpacity(float drawOpacity) { m_drawOpacity = drawOpacity; }
 
+    bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; }
+    void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; }
+
     // This goes from content space with the origin in the center of the rect being transformed to the target space with the origin in the top left of the
     // rect being transformed. Position the rect so that the origin is in the center of it before applying this transform.
     const TransformationMatrix& drawTransform() const { return m_drawTransform; }
@@ -99,6 +102,7 @@
     bool m_skipsDraw;
 
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
     TransformationMatrix m_drawTransform;
     TransformationMatrix m_replicaDrawTransform;
     TransformationMatrix m_originTransform;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -228,6 +228,15 @@
     return 0;
 }
 
+bool CCLayerAnimationController::isAnimatingProperty(CCActiveAnimation::TargetProperty targetProperty) const
+{
+    for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+        if (m_activeAnimations[i]->runState() != CCActiveAnimation::Finished && m_activeAnimations[i]->runState() != CCActiveAnimation::Aborted && m_activeAnimations[i]->targetProperty() == targetProperty)
+            return true;
+    }
+    return false;
+}
+
 void CCLayerAnimationController::remove(int groupId, CCActiveAnimation::TargetProperty targetProperty)
 {
     for (size_t i = 0; i < m_activeAnimations.size(); ++i) {

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h	2012-03-16 10:29:34 UTC (rev 110980)
@@ -58,6 +58,7 @@
 
     bool hasActiveAnimation() const { return m_activeAnimations.size(); }
     CCActiveAnimation* getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty);
+    bool isAnimatingProperty(CCActiveAnimation::TargetProperty) const;
 
 protected:
     CCLayerAnimationController();

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -83,6 +83,15 @@
     return false;
 }
 
+bool CCLayerAnimationControllerImpl::isAnimatingProperty(CCActiveAnimation::TargetProperty targetProperty) const
+{
+    for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+        if (m_activeAnimations[i]->runState() != CCActiveAnimation::Finished && m_activeAnimations[i]->runState() != CCActiveAnimation::Aborted && m_activeAnimations[i]->targetProperty() == targetProperty)
+            return true;
+    }
+    return false;
+}
+
 void CCLayerAnimationControllerImpl::startAnimationsWaitingForNextTick(double monotonicTime, CCAnimationEventsVector& events)
 {
     for (size_t i = 0; i < m_activeAnimations.size(); ++i) {

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h	2012-03-16 10:29:34 UTC (rev 110980)
@@ -72,6 +72,8 @@
     // Returns true if there are any animations that are neither finished nor aborted.
     bool hasActiveAnimation() const;
 
+    bool isAnimatingProperty(CCActiveAnimation::TargetProperty) const;
+
 private:
     friend class CCLayerAnimationController;
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -65,6 +65,7 @@
     , m_targetRenderSurface(0)
     , m_drawDepth(0)
     , m_drawOpacity(0)
+    , m_drawOpacityIsAnimating(false)
     , m_debugBorderColor(0, 0, 0, 0)
     , m_debugBorderWidth(0)
     , m_layerAnimationController(CCLayerAnimationControllerImpl::create(this))
@@ -425,6 +426,11 @@
     noteLayerPropertyChangedForSubtree();
 }
 
+bool CCLayerImpl::opacityIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Opacity);
+}
+
 void CCLayerImpl::setPosition(const FloatPoint& position)
 {
     if (m_position == position)
@@ -462,6 +468,11 @@
     noteLayerPropertyChangedForSubtree();
 }
 
+bool CCLayerImpl::transformIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Transform);
+}
+
 void CCLayerImpl::setDebugBorderColor(Color debugBorderColor)
 {
     if (m_debugBorderColor == debugBorderColor)

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2012-03-16 10:29:34 UTC (rev 110980)
@@ -57,10 +57,15 @@
 
     // CCLayerAnimationControllerImplClient implementation.
     virtual int id() const { return m_layerId; }
+
     virtual void setOpacity(float);
     virtual float opacity() const { return m_opacity; }
+    bool opacityIsAnimating() const;
+
     virtual void setTransform(const TransformationMatrix&);
     virtual const TransformationMatrix& transform() const { return m_transform; }
+    bool transformIsAnimating() const;
+
     virtual const IntSize& bounds() const { return m_bounds; }
 
     virtual ~CCLayerImpl();
@@ -152,6 +157,9 @@
     float drawOpacity() const { return m_drawOpacity; }
     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
 
+    bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; }
+    void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; }
+
     const IntRect& clipRect() const { return m_clipRect; }
     void setClipRect(const IntRect& rect) { m_clipRect = rect; }
     CCRenderSurface* targetRenderSurface() const { return m_targetRenderSurface; }
@@ -311,6 +319,7 @@
     // to sort layers from back to front.
     float m_drawDepth;
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
 
     // Debug borders.
     Color m_debugBorderColor;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -544,7 +544,7 @@
     CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
     for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
         if (it.representsTargetRenderSurface()) {
-            ASSERT(it->renderSurface()->drawOpacity());
+            ASSERT(it->renderSurface()->drawOpacity() || it->drawOpacityIsAnimating());
 
             occlusionTracker.finishedTargetRenderSurface(*it, it->renderSurface());
             paintMaskAndReplicaForRenderSurface(*it, paintType);
@@ -567,7 +567,7 @@
     CCLayerIteratorType end = CCLayerIteratorType::end(&m_updateList);
     for (CCLayerIteratorType it = CCLayerIteratorType::begin(&m_updateList); it != end; ++it) {
         if (it.representsTargetRenderSurface()) {
-            ASSERT(it->renderSurface()->drawOpacity());
+            ASSERT(it->renderSurface()->drawOpacity() || it->drawOpacityIsAnimating());
             if (it->maskLayer())
                 it->maskLayer()->updateCompositorResources(context, updater);
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -83,8 +83,12 @@
     // Some additional conditions need to be computed at a later point after the recursion is finished.
     //   - the intersection of render surface content and layer clipRect is empty
     //   - the visibleLayerRect is empty
+    //
+    // Note, if the layer should not have been drawn due to being fully transparent,
+    // we would have skipped the entire subtree and never made it into this function,
+    // so it is safe to omit this check here.
 
-    if (!layer->drawsContent() || !layer->opacity() || layer->bounds().isEmpty())
+    if (!layer->drawsContent() || layer->bounds().isEmpty())
         return true;
 
     // The layer should not be drawn if (1) it is not double-sided and (2) the back of the layer is facing the screen.
@@ -104,6 +108,22 @@
     return false;
 }
 
+static bool subtreeShouldBeSkipped(CCLayerImpl* layer)
+{
+    // The opacity of a layer always applies to its children (either implicitly
+    // via a render surface or explicitly if the parent preserves 3D), so the
+    // entire subtree can be skipped if this layer is fully transparent.
+    return !layer->opacity();
+}
+
+static bool subtreeShouldBeSkipped(LayerChromium* layer)
+{
+    // If the opacity is being animated then the opacity on the main thread is unreliable
+    // (since the impl thread may be using a different opacity), so it should not be trusted.
+    // In particular, it should not cause the subtree to be skipped.
+    return !layer->opacity() && !layer->opacityIsAnimating();
+}
+
 template<typename LayerType>
 static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlignedWithRespectToParent)
 {
@@ -230,14 +250,15 @@
     //        S is the scale adjustment (to scale up to the layer size)
     //
 
+    if (subtreeShouldBeSkipped(layer))
+        return false;
+
     float drawOpacity = layer->opacity();
-    if (layer->parent() && layer->parent()->preserves3D())
+    bool drawOpacityIsAnimating = layer->opacityIsAnimating();
+    if (layer->parent() && layer->parent()->preserves3D()) {
         drawOpacity *= layer->parent()->drawOpacity();
-    // The opacity of a layer always applies to its children (either implicitly
-    // via a render surface or explicitly if the parent preserves 3D), so the
-    // entire subtree can be skipped if this layer is fully transparent.
-    if (!drawOpacity)
-        return false;
+        drawOpacityIsAnimating |= layer->parent()->drawOpacityIsAnimating();
+    }
 
     IntSize bounds = layer->bounds();
     FloatPoint anchorPoint = layer->anchorPoint();
@@ -286,7 +307,9 @@
 
         // The opacity value is moved from the layer to its surface, so that the entire subtree properly inherits opacity.
         renderSurface->setDrawOpacity(drawOpacity);
+        renderSurface->setDrawOpacityIsAnimating(drawOpacityIsAnimating);
         layer->setDrawOpacity(1);
+        layer->setDrawOpacityIsAnimating(false);
 
         TransformationMatrix layerOriginTransform = combinedTransform;
         layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
@@ -320,6 +343,7 @@
         transformedLayerRect = enclosingIntRect(layer->drawTransform().mapRect(layerRect));
 
         layer->setDrawOpacity(drawOpacity);
+        layer->setDrawOpacityIsAnimating(drawOpacityIsAnimating);
 
         if (layer != rootLayer) {
             ASSERT(layer->parent());

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -52,6 +52,7 @@
     , m_skipsDraw(false)
     , m_surfacePropertyChanged(false)
     , m_drawOpacity(1)
+    , m_drawOpacityIsAnimating(false)
     , m_nearestAncestorThatMovesPixels(0)
 {
     m_damageTracker = CCDamageTracker::create();

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h (110979 => 110980)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h	2012-03-16 10:29:34 UTC (rev 110980)
@@ -70,6 +70,9 @@
     float drawOpacity() const { return m_drawOpacity; }
     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
 
+    bool drawOpacityIsAnimating() const { return m_drawOpacityIsAnimating; }
+    void setDrawOpacityIsAnimating(bool drawOpacityIsAnimating) { m_drawOpacityIsAnimating = drawOpacityIsAnimating; }
+
     void setDrawTransform(const TransformationMatrix& drawTransform) { m_drawTransform = drawTransform; }
     const TransformationMatrix& drawTransform() const { return m_drawTransform; }
 
@@ -131,6 +134,7 @@
 
     OwnPtr<ManagedTexture> m_contentsTexture;
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
     TransformationMatrix m_drawTransform;
     TransformationMatrix m_replicaDrawTransform;
     TransformationMatrix m_originTransform;

Modified: trunk/Source/WebKit/chromium/ChangeLog (110979 => 110980)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-03-16 10:29:34 UTC (rev 110980)
@@ -1,3 +1,20 @@
+2012-03-16  Ian Vollick  <[email protected]>
+
+        [chromium] Threaded opacity animation jump to opacity of 0
+        https://bugs.webkit.org/show_bug.cgi?id=80744
+
+        Reviewed by James Robinson.
+
+        * tests/CCLayerTreeHostTest.cpp:
+        (WTF):
+        (CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity):
+        (WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity):
+        (WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::beginTest):
+        (WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::animateLayers):
+        (WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::commitCompleteOnCCThread):
+        (WTF::CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity::afterTest):
+        (WTF::TEST_F):
+
 2012-03-16  Dana Jansens  <[email protected]>
 
         [chromium] Changes to overdraw metrics to allow upload tracking

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (110979 => 110980)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2012-03-16 10:21:49 UTC (rev 110979)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2012-03-16 10:29:34 UTC (rev 110980)
@@ -357,7 +357,7 @@
         CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
         ASSERT(test);
         if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
-            addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 0, 0, 1);
+            addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 0, 0, 0.5);
     }
 
     static void dispatchAddAnimation(void* self)
@@ -366,7 +366,7 @@
         CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
         ASSERT(test);
         if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
-            addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 10, 0, 1);
+            addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 10, 0, 0.5);
     }
 
     static void dispatchSetNeedsAnimateAndCommit(void* self)
@@ -986,6 +986,40 @@
     runTestThreaded();
 }
 
+// Ensures that when opacity is being animated, this value does not cause the subtree to be skipped.
+class CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity : public CCLayerTreeHostTestThreadOnly {
+public:
+    CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity()
+    {
+    }
+
+    virtual void beginTest()
+    {
+        m_layerTreeHost->rootLayer()->setDrawOpacity(1);
+        m_layerTreeHost->setViewportSize(IntSize(10, 10));
+        m_layerTreeHost->rootLayer()->setOpacity(0);
+        postAddAnimationToMainThread();
+    }
+
+    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
+    {
+        // If the subtree was skipped when preparing to draw, the layer's draw opacity
+        // will not have been updated. It should be set to 0 due to the animation.
+        // Without the animation, the layer will be skipped since it has zero opacity.
+        EXPECT_EQ(0, m_layerTreeHost->rootLayer()->drawOpacity());
+        endTest();
+    }
+
+    virtual void afterTest()
+    {
+    }
+};
+
+TEST_F(CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, runMultiThread)
+{
+    runTestThreaded();
+}
+
 class CCLayerTreeHostTestScrollSimple : public CCLayerTreeHostTestThreadOnly {
 public:
     CCLayerTreeHostTestScrollSimple()
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to