[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

simon.fraser at apple.com simon.fraser at apple.com
Thu Oct 29 20:45:24 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit d8bfc22b7d090392755e286c184131116859352f
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 15 16:52:51 2009 +0000

    2009-10-15  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            Transitions fail to run sometimes
            https://bugs.webkit.org/show_bug.cgi?id=26770
    
            Fix an issue where we could attempt to start accelerated animations or transitions on
            GraphicsLayer that were not rooted (because of visibility:hidden), which would leave
            the AnimationController's m_waitingForResponse flag in a state that killed subsequent
            software transitions.
    
            * page/animation/AnimationController.cpp:
            (WebCore::AnimationControllerPrivate::AnimationControllerPrivate):
            (WebCore::AnimationControllerPrivate::endAnimationUpdate):
            (WebCore::AnimationControllerPrivate::receivedStartTimeResponse):
            (WebCore::AnimationControllerPrivate::addToStartTimeResponseWaitList):
            (WebCore::AnimationControllerPrivate::startTimeResponse):
            * page/animation/AnimationControllerPrivate.h:
            Make some methods non-inline for ease of debugging (these are not hot methods).
            Rename m_waitingForAResponse to m_waitingForResponse.
    
            * platform/graphics/GraphicsLayer.h:
            * platform/graphics/GraphicsLayer.cpp:
            (WebCore::GraphicsLayer::hasAncestor):
            New method to report whether the receiver has the given layer as an ancestor. Used for checking
            whether a layer is rooted.
    
            * rendering/RenderLayerBacking.cpp:
            (WebCore::RenderLayerBacking::startAnimation):
            (WebCore::RenderLayerBacking::startTransition):
            Don't try to start accelerated animations or transitions on non-rooted GraphicsLayers.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49633 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 574bd20..ff25135 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2009-10-15  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Transitions fail to run sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=26770
+        
+        Add a test for starting an accelerated animation on an element with a visibility:hidden ancestor,
+        to ensure that it does not block subsequent transitions.
+
+        * compositing/animation/animated-composited-inside-hidden-expected.txt: Added.
+        * compositing/animation/animated-composited-inside-hidden.html: Added.
+
 2009-10-15  Pavel Feldman  <pfeldman at chromium.org>
 
         Not reviewed: remove timer-related logs from the previously
diff --git a/LayoutTests/compositing/animation/animated-composited-inside-hidden-expected.txt b/LayoutTests/compositing/animation/animated-composited-inside-hidden-expected.txt
new file mode 100644
index 0000000..85726fd
--- /dev/null
+++ b/LayoutTests/compositing/animation/animated-composited-inside-hidden-expected.txt
@@ -0,0 +1,4 @@
+Tests that starting an animation on an element inside a visibility:hidden element does not block later transitions.
+
+PASS - "left" property for "transition-tester" element at 0.5s saw something close to: 10
+
diff --git a/LayoutTests/compositing/animation/animated-composited-inside-hidden.html b/LayoutTests/compositing/animation/animated-composited-inside-hidden.html
new file mode 100644
index 0000000..a67e543
--- /dev/null
+++ b/LayoutTests/compositing/animation/animated-composited-inside-hidden.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+  <title>Visibility nested</title>
+  <style type="text/css" media="screen">
+    .box {
+      position: relative;
+      width: 100px;
+      height: 100px;
+      border: 1px solid black;
+    }
+    
+    .middle {
+      visibility: hidden;
+    }
+
+    .inner {
+      width: 80px;
+      height: 80px;
+      -webkit-animation: spin 5s linear infinite;
+    }
+
+    @-webkit-keyframes spin {
+      0% { -webkit-transform: rotate(0); }
+      100% { -webkit-transform: rotate(360deg); }
+    }
+    
+    #transition-tester {
+      position: relative;
+      left: 0;
+      background-color: blue;
+      -webkit-transition: left 1s linear;
+    }
+    
+    #container.animating #transition-tester {
+      left: 20px;
+    }
+    
+  </style>
+  <script src="../../transitions/transition-test-helpers.js" type="text/javascript" charset="utf-8"></script>
+  <script type="text/javascript" charset="utf-8">
+    const expectedValues = [
+      // [time, element-id, property, expected-value, tolerance]
+      [0.5, 'transition-tester', 'left', 10, 2],
+    ];
+
+    function setupTest()
+    {
+      document.getElementById('container').className = 'animating';
+    }
+
+    runTransitionTest(expectedValues, setupTest, true /* use pause API */);
+  </script>
+</head>
+<body>
+
+<p>Tests that starting an animation on an element inside a visibility:hidden element does not block later transitions.</p>
+  <div id="container" class="container">
+    <div id="transition-tester" class="box"></div>
+
+    <div class="middle box">
+      <div class="inner box"></div>
+    </div>
+  </div>
+
+<div id="result"></div>
+
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index bae3829..1cf51b5 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,36 @@
+2009-10-15  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Transitions fail to run sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=26770
+
+        Fix an issue where we could attempt to start accelerated animations or transitions on
+        GraphicsLayer that were not rooted (because of visibility:hidden), which would leave
+        the AnimationController's m_waitingForResponse flag in a state that killed subsequent
+        software transitions.
+
+        * page/animation/AnimationController.cpp:
+        (WebCore::AnimationControllerPrivate::AnimationControllerPrivate):
+        (WebCore::AnimationControllerPrivate::endAnimationUpdate):
+        (WebCore::AnimationControllerPrivate::receivedStartTimeResponse):
+        (WebCore::AnimationControllerPrivate::addToStartTimeResponseWaitList):
+        (WebCore::AnimationControllerPrivate::startTimeResponse):
+        * page/animation/AnimationControllerPrivate.h:
+        Make some methods non-inline for ease of debugging (these are not hot methods).
+        Rename m_waitingForAResponse to m_waitingForResponse.
+        
+        * platform/graphics/GraphicsLayer.h:
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::hasAncestor):
+        New method to report whether the receiver has the given layer as an ancestor. Used for checking
+        whether a layer is rooted.
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::startAnimation):
+        (WebCore::RenderLayerBacking::startTransition):
+        Don't try to start accelerated animations or transitions on non-rooted GraphicsLayers.
+
 2009-10-15  Alexander Pavlov  <apavlov at chromium.org>
 
         Reviewed by Pavel Feldman.
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index 691932e..aa5de2c 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -55,7 +55,7 @@ AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
     , m_lastStyleAvailableWaiter(0)
     , m_responseWaiters(0)
     , m_lastResponseWaiter(0)
-    , m_waitingForAResponse(false)
+    , m_waitingForResponse(false)
 {
 }
 
@@ -279,6 +279,19 @@ double AnimationControllerPrivate::beginAnimationUpdateTime()
     return m_beginAnimationUpdateTime;
 }
 
+void AnimationControllerPrivate::endAnimationUpdate()
+{
+    styleAvailable();
+    if (!m_waitingForResponse)
+        startTimeResponse(beginAnimationUpdateTime());
+}
+
+void AnimationControllerPrivate::receivedStartTimeResponse(double time)
+{
+    m_waitingForResponse = false;
+    startTimeResponse(time);
+}
+
 PassRefPtr<RenderStyle> AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderObject* renderer)
 {
     if (!renderer)
@@ -378,7 +391,7 @@ void AnimationControllerPrivate::addToStartTimeResponseWaitList(AnimationBase* a
     ASSERT(!animation->next());
     
     if (willGetResponse)
-        m_waitingForAResponse = true;
+        m_waitingForResponse = true;
     
     if (m_responseWaiters)
         m_lastResponseWaiter->setNext(animation);
@@ -408,13 +421,13 @@ void AnimationControllerPrivate::removeFromStartTimeResponseWaitList(AnimationBa
     }
 }
 
-void AnimationControllerPrivate::startTimeResponse(double t)
+void AnimationControllerPrivate::startTimeResponse(double time)
 {
     // Go through list of waiters and send them on their way
     for (AnimationBase* animation = m_responseWaiters; animation; ) {
         AnimationBase* nextAnimation = animation->next();
         animation->setNext(0);
-        animation->onAnimationStartResponse(t);
+        animation->onAnimationStartResponse(time);
         animation = nextAnimation;
     }
     
diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h
index 359b9b5..7db3803 100644
--- a/WebCore/page/animation/AnimationControllerPrivate.h
+++ b/WebCore/page/animation/AnimationControllerPrivate.h
@@ -80,18 +80,8 @@ public:
 
     double beginAnimationUpdateTime();
     void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
-    void endAnimationUpdate()
-    {
-        styleAvailable();
-        if (!m_waitingForAResponse)
-            startTimeResponse(beginAnimationUpdateTime());
-    }
-    
-    void receivedStartTimeResponse(double t)
-    {
-        m_waitingForAResponse = false;
-        startTimeResponse(t);
-    }
+    void endAnimationUpdate();
+    void receivedStartTimeResponse(double);
     
     void addToStyleAvailableWaitList(AnimationBase*);
     void removeFromStyleAvailableWaitList(AnimationBase*);    
@@ -127,7 +117,7 @@ private:
     
     AnimationBase* m_responseWaiters;
     AnimationBase* m_lastResponseWaiter;
-    bool m_waitingForAResponse;
+    bool m_waitingForResponse;
 };
 
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
index b375bd3..d196a0c 100644
--- a/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -86,6 +86,16 @@ GraphicsLayer::~GraphicsLayer()
     removeFromParent();
 }
 
+bool GraphicsLayer::hasAncestor(GraphicsLayer* ancestor) const
+{
+    for (GraphicsLayer* curr = parent(); curr; curr = curr->parent()) {
+        if (curr == ancestor)
+            return true;
+    }
+    
+    return false;
+}
+
 void GraphicsLayer::addChild(GraphicsLayer* childLayer)
 {
     ASSERT(childLayer != this);
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 2924073..e5b17a6 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -172,6 +172,9 @@ public:
     GraphicsLayer* parent() const { return m_parent; };
     void setParent(GraphicsLayer* layer) { m_parent = layer; } // Internal use only.
     
+    // Returns true if the layer has the given layer as an ancestor (excluding self).
+    bool hasAncestor(GraphicsLayer*) const;
+    
     const Vector<GraphicsLayer*>& children() const { return m_children; }
 
     // Add child layers. If the child is already parented, it will be removed from its old parent.
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 50e4756..bf58a2e 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -1034,6 +1034,10 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim,
     if (!hasOpacity && !hasTransform)
         return false;
     
+    // Don't start animations if we're not rooted, because we won't get the callback that the animation started.
+    if (!m_graphicsLayer->hasAncestor(compositor()->rootPlatformLayer()))
+        return false;
+
     KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
 
@@ -1075,6 +1079,10 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R
     bool didAnimate = false;
     ASSERT(property != cAnimateAll);
 
+    // Don't start animations if we're not rooted, because we won't get the callback that the animation started.
+    if (!m_graphicsLayer->hasAncestor(compositor()->rootPlatformLayer()))
+        return false;
+
     if (property == (int)CSSPropertyOpacity) {
         const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
         if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list