[chromium] Threaded opacity animation jump to opacity of 0
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Mar 2012 10:29:34 +0000 (10:29 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Mar 2012 10:29:34 +0000 (10:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80744

Patch by Ian Vollick <vollick@chromium.org> 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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@110980 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerChromium.h
Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationControllerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp
Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp
Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp

index 2f90e86e09ed13f4eae6f5c6937e3b1e8618c8b5..90ccc5d8587499b11ec0660a9e75941bcbb42ec4 100644 (file)
@@ -1,3 +1,62 @@
+2012-03-16  Ian Vollick  <vollick@chromium.org>
+
+        [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  <jocelyn.turcotte@nokia.com>
 
         [TexMap] Reuse textures following the same rules as they do internally.
index f973880fd175b1a4936a2eff4176f4cbf1e7c9f5..d4cad24a613b6a7954939d14559b7effb1fc6089 100644 (file)
@@ -80,6 +80,7 @@ LayerChromium::LayerChromium()
     , 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 @@ void LayerChromium::setOpacity(float opacity)
     setNeedsCommit();
 }
 
+bool LayerChromium::opacityIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Opacity);
+}
+
 void LayerChromium::setOpaque(bool opaque)
 {
     if (m_opaque == opaque)
@@ -421,6 +427,11 @@ void LayerChromium::setTransform(const TransformationMatrix& transform)
     setNeedsCommit();
 }
 
+bool LayerChromium::transformIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Transform);
+}
+
 void LayerChromium::setScrollPosition(const IntPoint& scrollPosition)
 {
     if (m_scrollPosition == scrollPosition)
index e52ec48c7d57c6cafa48faae7d0c365a5e4f9346..008150cabb8c81e35fdceecff0754d16e197b557 100644 (file)
@@ -110,6 +110,7 @@ public:
 
     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 @@ public:
 
     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 @@ public:
 
     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 @@ private:
     // Transient properties.
     OwnPtr<RenderSurfaceChromium> m_renderSurface;
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
     IntRect m_clipRect;
     RenderSurfaceChromium* m_targetRenderSurface;
     TransformationMatrix m_drawTransform;
index 69ce9526c91d7b47cf71857d56593c78a6314939..2e9998a7a114ff681ad2dc65a46fa7ffe577c143 100644 (file)
@@ -42,6 +42,7 @@ RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer)
     , m_maskLayer(0)
     , m_skipsDraw(false)
     , m_drawOpacity(1)
+    , m_drawOpacityIsAnimating(false)
     , m_nearestAncestorThatMovesPixels(0)
 {
 }
index 9045425bc3fbff23c821fffe8a4bb07395b0e28c..3a304c185d7f93252f443cc423461c99ab97cddf 100644 (file)
@@ -63,6 +63,9 @@ public:
     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 @@ private:
     bool m_skipsDraw;
 
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
     TransformationMatrix m_drawTransform;
     TransformationMatrix m_replicaDrawTransform;
     TransformationMatrix m_originTransform;
index 335d3a58e98aed297ee54054b54d0485085171b2..c3af44df56c5eb9995d5c2db39871c42d3e50e9d 100644 (file)
@@ -228,6 +228,15 @@ CCActiveAnimation* CCLayerAnimationController::getActiveAnimation(int groupId, C
     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) {
index 068213047f42ac5b2a31b0b66df73745d2c5f224..f2f66eb244ef0ab2757d29054f8c419f46e4d90f 100644 (file)
@@ -58,6 +58,7 @@ public:
 
     bool hasActiveAnimation() const { return m_activeAnimations.size(); }
     CCActiveAnimation* getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty);
+    bool isAnimatingProperty(CCActiveAnimation::TargetProperty) const;
 
 protected:
     CCLayerAnimationController();
index f09dcfae06425da83dee6fa0f9663f70230c0ae2..8a9e91b2e2a4e459de0def7f16e29d410add3050 100644 (file)
@@ -83,6 +83,15 @@ bool CCLayerAnimationControllerImpl::hasActiveAnimation() const
     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) {
index 6ac00e7ae178c57736637b22bda2c929221da6ff..89396bd9591fb74325d825b6af9aaa415aad0571 100644 (file)
@@ -72,6 +72,8 @@ public:
     // 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;
 
index 4fce76b024c35ad0964e011822bff0a372fe0f07..ad340f8f1dd3c5d16336ea8f28649e180a58cfe5 100644 (file)
@@ -65,6 +65,7 @@ CCLayerImpl::CCLayerImpl(int id)
     , 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 @@ void CCLayerImpl::setOpacity(float opacity)
     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 @@ void CCLayerImpl::setTransform(const TransformationMatrix& transform)
     noteLayerPropertyChangedForSubtree();
 }
 
+bool CCLayerImpl::transformIsAnimating() const
+{
+    return m_layerAnimationController->isAnimatingProperty(CCActiveAnimation::Transform);
+}
+
 void CCLayerImpl::setDebugBorderColor(Color debugBorderColor)
 {
     if (m_debugBorderColor == debugBorderColor)
index 8d33b642bd796f84e1632e6a5efcbcaedac0a3f6..e51a592ea75811a88d056fdecfb04095f5b86acc 100644 (file)
@@ -57,10 +57,15 @@ public:
 
     // 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 @@ public:
     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 @@ private:
     // to sort layers from back to front.
     float m_drawDepth;
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
 
     // Debug borders.
     Color m_debugBorderColor;
index 065902ce5a31323dffe91c8e5aecf031c75950e0..0831ccf7afb7f04fcf0d1b946345e278f867ea97 100644 (file)
@@ -544,7 +544,7 @@ void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList
     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 @@ void CCLayerTreeHost::updateCompositorResources(GraphicsContext3D* context, CCTe
     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);
 
index c86d74d861daf4e6e325d1c53fd47f49864f86a9..db6315c495748891ab640b9e4bf2e9a696f31899 100644 (file)
@@ -83,8 +83,12 @@ static bool layerShouldBeSkipped(LayerType* layer)
     // 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 @@ static bool layerShouldBeSkipped(LayerType* layer)
     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 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer
     //        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 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer
 
         // 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 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer
         transformedLayerRect = enclosingIntRect(layer->drawTransform().mapRect(layerRect));
 
         layer->setDrawOpacity(drawOpacity);
+        layer->setDrawOpacityIsAnimating(drawOpacityIsAnimating);
 
         if (layer != rootLayer) {
             ASSERT(layer->parent());
index 3be148b0a7b33019423cb2903051544cda333d4b..e1f5704bda3c6ebab40615f5aea05ab98ef72c9d 100644 (file)
@@ -52,6 +52,7 @@ CCRenderSurface::CCRenderSurface(CCLayerImpl* owningLayer)
     , m_skipsDraw(false)
     , m_surfacePropertyChanged(false)
     , m_drawOpacity(1)
+    , m_drawOpacityIsAnimating(false)
     , m_nearestAncestorThatMovesPixels(0)
 {
     m_damageTracker = CCDamageTracker::create();
index b5cd3a83440a7ac295e8015bf1de67be1877b587..683d166d0b784d9809841ff261c8e9a4f056beaf 100644 (file)
@@ -70,6 +70,9 @@ public:
     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 @@ private:
 
     OwnPtr<ManagedTexture> m_contentsTexture;
     float m_drawOpacity;
+    bool m_drawOpacityIsAnimating;
     TransformationMatrix m_drawTransform;
     TransformationMatrix m_replicaDrawTransform;
     TransformationMatrix m_originTransform;
index 49992ae673ef347784b587fd5e6f5398dfc75e7f..cd68b1e236b995bdcdb8a2e0c360b4d8a538edf5 100644 (file)
@@ -1,3 +1,20 @@
+2012-03-16  Ian Vollick  <vollick@chromium.org>
+
+        [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  <danakj@chromium.org>
 
         [chromium] Changes to overdraw metrics to allow upload tracking
index 706b4d0024067f9c2d7894e8804d225e1c498b31..702bbf1639b43b16aef3abb6606290498c0d6615 100644 (file)
@@ -357,7 +357,7 @@ protected:
         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 @@ protected:
         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 @@ TEST_F(CCLayerTreeHostTestTickAnimationWhileBackgrounded, runMultiThread)
     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()