Diff
Modified: trunk/Source/WebCore/ChangeLog (115518 => 115519)
--- trunk/Source/WebCore/ChangeLog 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/ChangeLog 2012-04-28 00:07:49 UTC (rev 115519)
@@ -1,3 +1,57 @@
+2012-04-27 Ian Vollick <[email protected]>
+
+ [chromium] Add pause and resume support for accelerated css animations.
+ https://bugs.webkit.org/show_bug.cgi?id=84601
+
+ Reviewed by James Robinson.
+
+ Tested in:
+ CCLayerAnimationControllerTest.syncPauseResume
+ CCActiveAnimationTest.TrimTimeTimeOffset
+ CCActiveAnimationTest.TrimTimeSuspendResume
+ CCActiveAnimationTest.IsFinishedNeedsSynchronizedStartTime
+ CCActiveAnimationTest.RunStateChangesIgnoredWhileSuspended
+
+ * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+ (WebCore::GraphicsLayerChromium::suspendAnimations):
+ (WebCore::GraphicsLayerChromium::resumeAnimations):
+ * platform/graphics/chromium/GraphicsLayerChromium.h:
+ (GraphicsLayerChromium):
+ * platform/graphics/chromium/LayerChromium.cpp:
+ (WebCore::LayerChromium::suspendAnimations):
+ (WebCore::LayerChromium::resumeAnimations):
+ * platform/graphics/chromium/LayerChromium.h:
+ (LayerChromium):
+ * platform/graphics/chromium/cc/CCActiveAnimation.cpp:
+ (WebCore::CCActiveAnimation::CCActiveAnimation):
+ (WebCore::CCActiveAnimation::setRunState):
+ (WebCore::CCActiveAnimation::suspend):
+ (WebCore::CCActiveAnimation::resume):
+ (WebCore::CCActiveAnimation::isFinishedAt):
+ (WebCore::CCActiveAnimation::trimTimeToCurrentIteration):
+ (WebCore::CCActiveAnimation::cloneForImplThread):
+ (WebCore::CCActiveAnimation::pushPropertiesTo):
+ * platform/graphics/chromium/cc/CCActiveAnimation.h:
+ (CCActiveAnimation):
+ (WebCore::CCActiveAnimation::setStartTime):
+ (WebCore::CCActiveAnimation::timeOffset):
+ (WebCore::CCActiveAnimation::setTimeOffset):
+ (WebCore::CCActiveAnimation::isFinished):
+ * platform/graphics/chromium/cc/CCLayerAnimationController.cpp:
+ (WebCore::CCLayerAnimationController::addAnimation):
+ (WebCore::CCLayerAnimationController::pauseAnimation):
+ (WebCore::CCLayerAnimationController::suspendAnimations):
+ (WebCore::CCLayerAnimationController::resumeAnimations):
+ (WebCore::CCLayerAnimationController::pushAnimationUpdatesTo):
+ (WebCore::CCLayerAnimationController::getActiveAnimation):
+ (WebCore::CCLayerAnimationController::pushNewAnimationsToImplThread):
+ (WebCore::CCLayerAnimationController::removeAnimationsCompletedOnMainThread):
+ (WebCore::CCLayerAnimationController::pushPropertiesToImplThread):
+ (WebCore):
+ (WebCore::CCLayerAnimationController::tickAnimations):
+ * platform/graphics/chromium/cc/CCLayerAnimationController.h:
+ (CCLayerAnimationController):
+
2012-04-27 Tim Horton <[email protected]>
SMIL animation causes leak of the related Document (and many elements)
Modified: trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp 2012-04-28 00:07:49 UTC (rev 115519)
@@ -420,14 +420,17 @@
primaryLayer()->removeAnimation(mapAnimationNameToId(animationName));
}
-void GraphicsLayerChromium::suspendAnimations(double time)
+void GraphicsLayerChromium::suspendAnimations(double wallClockTime)
{
- primaryLayer()->suspendAnimations(time);
+ // |wallClockTime| is in the wrong time base. Need to convert here.
+ // FIXME: find a more reliable way to do this.
+ double monotonicTime = wallClockTime + monotonicallyIncreasingTime() - currentTime();
+ primaryLayer()->suspendAnimations(monotonicTime);
}
void GraphicsLayerChromium::resumeAnimations()
{
- primaryLayer()->resumeAnimations();
+ primaryLayer()->resumeAnimations(monotonicallyIncreasingTime());
}
void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer)
Modified: trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h 2012-04-28 00:07:49 UTC (rev 115519)
@@ -102,7 +102,7 @@
virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String&, double timeOffset);
virtual void pauseAnimation(const String& animationName, double timeOffset);
virtual void removeAnimation(const String& animationName);
- virtual void suspendAnimations(double time);
+ virtual void suspendAnimations(double wallClockTime);
virtual void resumeAnimations();
virtual PlatformLayer* platformLayer() const;
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp 2012-04-28 00:07:49 UTC (rev 115519)
@@ -621,15 +621,15 @@
setNeedsCommit();
}
-void LayerChromium::suspendAnimations(double time)
+void LayerChromium::suspendAnimations(double monotonicTime)
{
- m_layerAnimationController->suspendAnimations(time);
+ m_layerAnimationController->suspendAnimations(monotonicTime);
setNeedsCommit();
}
-void LayerChromium::resumeAnimations()
+void LayerChromium::resumeAnimations(double monotonicTime)
{
- m_layerAnimationController->resumeAnimations();
+ m_layerAnimationController->resumeAnimations(monotonicTime);
setNeedsCommit();
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2012-04-28 00:07:49 UTC (rev 115519)
@@ -240,8 +240,8 @@
void pauseAnimation(int animationId, double timeOffset);
void removeAnimation(int animationId);
- void suspendAnimations(double time);
- void resumeAnimations();
+ void suspendAnimations(double monotonicTime);
+ void resumeAnimations(double monotonicTime);
CCLayerAnimationController* layerAnimationController() { return m_layerAnimationController.get(); }
void setLayerAnimationController(PassOwnPtr<CCLayerAnimationController>);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp 2012-04-28 00:07:49 UTC (rev 115519)
@@ -45,7 +45,9 @@
, m_runState(WaitingForTargetAvailability)
, m_iterations(1)
, m_startTime(0)
+ , m_timeOffset(0)
, m_needsSynchronizedStartTime(false)
+ , m_suspended(false)
, m_pauseTime(0)
, m_totalPausedTime(0)
{
@@ -55,46 +57,49 @@
{
}
-void CCActiveAnimation::setRunState(RunState runState, double now)
+void CCActiveAnimation::setRunState(RunState runState, double monotonicTime)
{
+ if (m_suspended)
+ return;
+
if (runState == Running && m_runState == Paused)
- m_totalPausedTime += now - m_pauseTime;
+ m_totalPausedTime += monotonicTime - m_pauseTime;
else if (runState == Paused)
- m_pauseTime = now;
+ m_pauseTime = monotonicTime;
m_runState = runState;
}
-bool CCActiveAnimation::isFinishedAt(double time) const
+void CCActiveAnimation::suspend(double monotonicTime)
{
- if (m_runState == Finished || m_runState == Aborted)
- return true;
-
- return m_runState == Running
- && m_iterations >= 0
- && m_iterations * m_curve->duration() <= time - startTime() - m_totalPausedTime;
+ setRunState(Paused, monotonicTime);
+ m_suspended = true;
}
-bool CCActiveAnimation::isWaiting() const
+void CCActiveAnimation::resume(double monotonicTime)
{
- return m_runState == WaitingForNextTick
- || m_runState == WaitingForTargetAvailability
- || m_runState == WaitingForStartTime;
+ m_suspended = false;
+ setRunState(Running, monotonicTime);
}
-bool CCActiveAnimation::isRunningOrHasRun() const
+bool CCActiveAnimation::isFinishedAt(double monotonicTime) const
{
+ if (m_runState == Finished || m_runState == Aborted)
+ return true;
+
+ if (m_needsSynchronizedStartTime)
+ return false;
+
return m_runState == Running
- || m_runState == Finished
- || m_runState == Aborted
- || m_runState == Paused;
+ && m_iterations >= 0
+ && m_iterations * m_curve->duration() <= monotonicTime - startTime() - m_totalPausedTime;
}
-double CCActiveAnimation::trimTimeToCurrentIteration(double now) const
+double CCActiveAnimation::trimTimeToCurrentIteration(double monotonicTime) const
{
- double trimmed = now;
+ double trimmed = monotonicTime + m_timeOffset;
// If we're paused, time is 'stuck' at the pause time.
- if (m_runState == Paused && trimmed > m_pauseTime)
+ if (m_runState == Paused)
trimmed = m_pauseTime;
// Returned time should always be relative to the start time and should subtract
@@ -129,28 +134,18 @@
toReturn->m_startTime = m_startTime;
toReturn->m_pauseTime = m_pauseTime;
toReturn->m_totalPausedTime = m_totalPausedTime;
+ toReturn->m_timeOffset = m_timeOffset;
return toReturn.release();
}
-void CCActiveAnimation::synchronizeProperties(CCActiveAnimation* other)
+void CCActiveAnimation::pushPropertiesTo(CCActiveAnimation* other) const
{
- // It is possible for the impl thread to initiate a run state change.
- // This happens when the animation was waiting for a future event to take
- // place, and the event has happened. In that case, we want 'this' to
- // assume the impl thread's run state and start time.
- if (isWaiting() && other->isRunningOrHasRun()) {
- m_runState = other->m_runState;
- m_startTime = other->m_startTime;
- } else {
+ // Currently, we only push changes due to pausing and resuming animations on the main thread.
+ if (m_runState == CCActiveAnimation::Paused || other->m_runState == CCActiveAnimation::Paused) {
other->m_runState = m_runState;
- other->m_startTime = m_startTime;
+ other->m_pauseTime = m_pauseTime;
+ other->m_totalPausedTime = m_totalPausedTime;
}
-
- // Change in state related to iterations and pause is always initiated from
- // the main thread, so it is safe to push properties in that direction.
- other->m_iterations = m_iterations;
- other->m_pauseTime = m_pauseTime;
- other->m_totalPausedTime = m_totalPausedTime;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h 2012-04-28 00:07:49 UTC (rev 115519)
@@ -72,7 +72,7 @@
TargetProperty targetProperty() const { return m_targetProperty; }
RunState runState() const { return m_runState; }
- void setRunState(RunState, double now);
+ void setRunState(RunState, double monotonicTime);
// This is the number of times that the animation will play. If this
// value is zero the animation will not play. If it is negative, then
@@ -81,15 +81,18 @@
void setIterations(int n) { m_iterations = n; }
double startTime() const { return m_startTime; }
- void setStartTime(double startTime) { m_startTime = startTime; }
+ void setStartTime(double monotonicTime) { m_startTime = monotonicTime; }
bool hasSetStartTime() const { return m_startTime; }
- bool isFinishedAt(double time) const;
+ double timeOffset() const { return m_timeOffset; }
+ void setTimeOffset(double monotonicTime) { m_timeOffset = monotonicTime; }
+
+ void suspend(double monotonicTime);
+ void resume(double monotonicTime);
+
+ bool isFinishedAt(double monotonicTime) const;
bool isFinished() const { return m_runState == Finished || m_runState == Aborted; }
- bool isWaiting() const;
- bool isRunningOrHasRun() const;
-
CCAnimationCurve* curve() { return m_curve.get(); }
const CCAnimationCurve* curve() const { return m_curve.get(); }
@@ -100,11 +103,11 @@
// Takes the given absolute time, and using the start time and the number
// of iterations, returns the relative time in the current iteration.
- double trimTimeToCurrentIteration(double now) const;
+ double trimTimeToCurrentIteration(double monotonicTime) const;
PassOwnPtr<CCActiveAnimation> cloneForImplThread() const;
- void synchronizeProperties(CCActiveAnimation*);
+ void pushPropertiesTo(CCActiveAnimation*) const;
private:
CCActiveAnimation(PassOwnPtr<CCAnimationCurve>, int animationId, int groupId, TargetProperty);
@@ -126,8 +129,17 @@
int m_iterations;
double m_startTime;
+ // The time offset effectively pushes the start of the animation back in time. This is
+ // used for resuming paused animations -- an animation is added with a non-zero time
+ // offset, causing the animation to skip ahead to the desired point in time.
+ double m_timeOffset;
+
bool m_needsSynchronizedStartTime;
+ // When an animation is suspended, it behaves as if it is paused and it also ignores
+ // all run state changes until it is resumed. This is used for testing purposes.
+ bool m_suspended;
+
// These are used in trimTimeToCurrentIteration to account for time
// spent while paused. This is not included in AnimationState since it
// there is absolutely no need for clients of this controller to know
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp 2012-04-28 00:07:49 UTC (rev 115519)
@@ -107,6 +107,9 @@
// the corresponding impl thread animation.
anim->setNeedsSynchronizedStartTime(true);
+ // If timeOffset > 0, then the animation has started in the past.
+ anim->setTimeOffset(timeOffset);
+
return anim.release();
}
@@ -138,6 +141,13 @@
toAdd = createActiveAnimation<FloatAnimationValue, CCFloatKeyframe, CCKeyframedFloatAnimationCurve>(valueList, animation, animationId, groupId, timeOffset, CCActiveAnimation::Opacity);
if (toAdd.get()) {
+ // Remove any existing animations with the same animation id and target property.
+ for (size_t i = 0; i < m_activeAnimations.size();) {
+ if (m_activeAnimations[i]->id() == animationId && m_activeAnimations[i]->targetProperty() == toAdd->targetProperty())
+ m_activeAnimations.remove(i);
+ else
+ i++;
+ }
m_activeAnimations.append(toAdd.release());
return true;
}
@@ -149,7 +159,7 @@
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
if (m_activeAnimations[i]->id() == animationId)
- m_activeAnimations[i]->setRunState(CCActiveAnimation::Paused, timeOffset);
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Paused, timeOffset + m_activeAnimations[i]->startTime());
}
}
@@ -164,13 +174,21 @@
}
// According to render layer backing, these are for testing only.
-void CCLayerAnimationController::suspendAnimations(double time)
+void CCLayerAnimationController::suspendAnimations(double monotonicTime)
{
+ 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]->setRunState(CCActiveAnimation::Paused, monotonicTime);
+ }
}
// Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimations, which is for testing.
-void CCLayerAnimationController::resumeAnimations()
+void CCLayerAnimationController::resumeAnimations(double monotonicTime)
{
+ for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+ if (m_activeAnimations[i]->runState() == CCActiveAnimation::Paused)
+ m_activeAnimations[i]->setRunState(CCActiveAnimation::Running, monotonicTime);
+ }
}
// Ensures that the list of active animations on the main thread and the impl thread
@@ -179,6 +197,7 @@
{
pushNewAnimationsToImplThread(controllerImpl);
removeAnimationsCompletedOnMainThread(controllerImpl);
+ pushPropertiesToImplThread(controllerImpl);
}
void CCLayerAnimationController::animate(double monotonicTime, CCAnimationEventsVector* events)
@@ -197,7 +216,7 @@
m_activeAnimations.append(animation);
}
-CCActiveAnimation* CCLayerAnimationController::getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty targetProperty)
+CCActiveAnimation* CCLayerAnimationController::getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty targetProperty) const
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i)
if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
@@ -235,7 +254,7 @@
}
}
-void CCLayerAnimationController::pushNewAnimationsToImplThread(CCLayerAnimationController* controllerImpl)
+void CCLayerAnimationController::pushNewAnimationsToImplThread(CCLayerAnimationController* controllerImpl) const
{
// Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
@@ -258,7 +277,7 @@
}
}
-void CCLayerAnimationController::removeAnimationsCompletedOnMainThread(CCLayerAnimationController* controllerImpl)
+void CCLayerAnimationController::removeAnimationsCompletedOnMainThread(CCLayerAnimationController* controllerImpl) const
{
// Delete all impl thread animations for which there is no corresponding main thread animation.
// Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
@@ -272,6 +291,15 @@
}
}
+void CCLayerAnimationController::pushPropertiesToImplThread(CCLayerAnimationController* controllerImpl) const
+{
+ for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
+ CCActiveAnimation* currentImpl = controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty());
+ if (currentImpl)
+ m_activeAnimations[i]->pushPropertiesTo(currentImpl);
+ }
+}
+
void CCLayerAnimationController::startAnimationsWaitingForNextTick(double monotonicTime, CCAnimationEventsVector* events)
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
@@ -404,7 +432,7 @@
void CCLayerAnimationController::tickAnimations(double monotonicTime)
{
for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
- if (m_activeAnimations[i]->runState() == CCActiveAnimation::Running) {
+ if (m_activeAnimations[i]->runState() == CCActiveAnimation::Running || m_activeAnimations[i]->runState() == CCActiveAnimation::Paused) {
double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
// Animation assumes its initial value until it gets the synchronized start time
@@ -417,7 +445,7 @@
case CCActiveAnimation::Transform: {
const CCTransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
const TransformationMatrix matrix = transformAnimationCurve->getValue(trimmed, m_client->bounds());
- if (m_activeAnimations[i]->isFinishedAt(monotonicTime) && !m_activeAnimations[i]->needsSynchronizedStartTime())
+ if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, monotonicTime);
m_client->setTransformFromAnimation(matrix);
@@ -427,7 +455,7 @@
case CCActiveAnimation::Opacity: {
const CCFloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
const float opacity = floatAnimationCurve->getValue(trimmed);
- if (m_activeAnimations[i]->isFinishedAt(monotonicTime) && !m_activeAnimations[i]->needsSynchronizedStartTime())
+ if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
m_activeAnimations[i]->setRunState(CCActiveAnimation::Finished, monotonicTime);
m_client->setOpacityFromAnimation(opacity);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h (115518 => 115519)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.h 2012-04-28 00:07:49 UTC (rev 115519)
@@ -64,8 +64,8 @@
virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, int animationId, int groupId, double timeOffset);
virtual void pauseAnimation(int animationId, double timeOffset);
virtual void removeAnimation(int animationId);
- virtual void suspendAnimations(double time);
- virtual void resumeAnimations();
+ virtual void suspendAnimations(double monotonicTime);
+ virtual void resumeAnimations(double monotonicTime);
// Ensures that the list of active animations on the main thread and the impl thread
// are kept in sync. This function does not take ownership of the impl thread controller.
@@ -77,7 +77,7 @@
// Returns the active animation in the given group, animating the given property if such an
// animation exists.
- CCActiveAnimation* getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty);
+ CCActiveAnimation* getActiveAnimation(int groupId, CCActiveAnimation::TargetProperty) const;
// Returns true if there are any animations that have neither finished nor aborted.
bool hasActiveAnimation() const;
@@ -96,8 +96,9 @@
private:
typedef HashSet<int> TargetProperties;
- void pushNewAnimationsToImplThread(CCLayerAnimationController*);
- void removeAnimationsCompletedOnMainThread(CCLayerAnimationController*);
+ void pushNewAnimationsToImplThread(CCLayerAnimationController*) const;
+ void removeAnimationsCompletedOnMainThread(CCLayerAnimationController*) const;
+ void pushPropertiesToImplThread(CCLayerAnimationController*) const;
void startAnimationsWaitingForNextTick(double monotonicTime, CCAnimationEventsVector*);
void startAnimationsWaitingForStartTime(double monotonicTime, CCAnimationEventsVector*);
Modified: trunk/Source/WebKit/chromium/ChangeLog (115518 => 115519)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-04-28 00:07:49 UTC (rev 115519)
@@ -1,3 +1,17 @@
+2012-04-27 Ian Vollick <[email protected]>
+
+ [chromium] Add pause and resume support for accelerated css animations.
+ https://bugs.webkit.org/show_bug.cgi?id=84601
+
+ Reviewed by James Robinson.
+
+ * tests/CCActiveAnimationTest.cpp:
+ (WebCore::TEST):
+ (WebCore):
+ * tests/CCLayerAnimationControllerTest.cpp:
+ (WebKitTests::TEST):
+ (WebKitTests):
+
2012-04-26 James Robinson <[email protected]>
[chromium] Separate IOSurface layer type from texture layers
Modified: trunk/Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp (115518 => 115519)
--- trunk/Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp 2012-04-28 00:07:49 UTC (rev 115519)
@@ -80,6 +80,17 @@
EXPECT_EQ(1, anim->trimTimeToCurrentIteration(6));
}
+TEST(CCActiveAnimationTest, TrimTimeTimeOffset)
+{
+ OwnPtr<CCActiveAnimation> anim(createActiveAnimation(1));
+ anim->setTimeOffset(4);
+ anim->setStartTime(4);
+ EXPECT_EQ(0, anim->trimTimeToCurrentIteration(0));
+ EXPECT_EQ(0.5, anim->trimTimeToCurrentIteration(0.5));
+ EXPECT_EQ(1, anim->trimTimeToCurrentIteration(1));
+ EXPECT_EQ(1, anim->trimTimeToCurrentIteration(1));
+}
+
TEST(CCActiveAnimationTest, TrimTimePauseResume)
{
OwnPtr<CCActiveAnimation> anim(createActiveAnimation(1));
@@ -93,6 +104,19 @@
EXPECT_EQ(1, anim->trimTimeToCurrentIteration(1024.5));
}
+TEST(CCActiveAnimationTest, TrimTimeSuspendResume)
+{
+ OwnPtr<CCActiveAnimation> anim(createActiveAnimation(1));
+ anim->setRunState(CCActiveAnimation::Running, 0);
+ EXPECT_EQ(0, anim->trimTimeToCurrentIteration(0));
+ EXPECT_EQ(0.5, anim->trimTimeToCurrentIteration(0.5));
+ anim->suspend(0.5);
+ EXPECT_EQ(0.5, anim->trimTimeToCurrentIteration(1024));
+ anim->resume(1024);
+ EXPECT_EQ(0.5, anim->trimTimeToCurrentIteration(1024));
+ EXPECT_EQ(1, anim->trimTimeToCurrentIteration(1024.5));
+}
+
TEST(CCActiveAnimationTest, IsFinishedAtZeroIterations)
{
OwnPtr<CCActiveAnimation> anim(createActiveAnimation(0));
@@ -160,4 +184,35 @@
EXPECT_TRUE(anim->isFinished());
}
+TEST(CCActiveAnimationTest, IsFinishedNeedsSynchronizedStartTime)
+{
+ OwnPtr<CCActiveAnimation> anim(createActiveAnimation(1));
+ anim->setRunState(CCActiveAnimation::Running, 2);
+ EXPECT_FALSE(anim->isFinished());
+ anim->setRunState(CCActiveAnimation::Paused, 2);
+ EXPECT_FALSE(anim->isFinished());
+ anim->setRunState(CCActiveAnimation::WaitingForNextTick, 2);
+ EXPECT_FALSE(anim->isFinished());
+ anim->setRunState(CCActiveAnimation::WaitingForTargetAvailability, 2);
+ EXPECT_FALSE(anim->isFinished());
+ anim->setRunState(CCActiveAnimation::WaitingForStartTime, 2);
+ EXPECT_FALSE(anim->isFinished());
+ anim->setRunState(CCActiveAnimation::Finished, 0);
+ EXPECT_TRUE(anim->isFinished());
+ anim->setRunState(CCActiveAnimation::Aborted, 0);
+ EXPECT_TRUE(anim->isFinished());
+}
+
+TEST(CCActiveAnimationTest, RunStateChangesIgnoredWhileSuspended)
+{
+ OwnPtr<CCActiveAnimation> anim(createActiveAnimation(1));
+ anim->suspend(0);
+ EXPECT_EQ(CCActiveAnimation::Paused, anim->runState());
+ anim->setRunState(CCActiveAnimation::Running, 0);
+ EXPECT_EQ(CCActiveAnimation::Paused, anim->runState());
+ anim->resume(0);
+ anim->setRunState(CCActiveAnimation::Running, 0);
+ EXPECT_EQ(CCActiveAnimation::Running, anim->runState());
+}
+
} // namespace
Modified: trunk/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp (115518 => 115519)
--- trunk/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp 2012-04-28 00:04:50 UTC (rev 115518)
+++ trunk/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp 2012-04-28 00:07:49 UTC (rev 115519)
@@ -199,6 +199,47 @@
EXPECT_EQ(controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->startTime(), controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->startTime());
}
+TEST(CCLayerAnimationControllerTest, syncPauseAndResume)
+{
+ FakeLayerAnimationControllerClient dummyImpl;
+ OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
+ FakeLayerAnimationControllerClient dummy;
+ OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
+
+ EXPECT_FALSE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+
+ addOpacityTransitionToController(*controller, 1, 0, 1, false);
+
+ controller->pushAnimationUpdatesTo(controllerImpl.get());
+
+ EXPECT_TRUE(controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity));
+ EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+ // Start the animations on each controller.
+ CCAnimationEventsVector events;
+ controllerImpl->animate(0, &events);
+ controller->animate(0, 0);
+ EXPECT_EQ(CCActiveAnimation::Running, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+ EXPECT_EQ(CCActiveAnimation::Running, controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+ // Pause the main-thread animation.
+ controller->suspendAnimations(1);
+ EXPECT_EQ(CCActiveAnimation::Paused, controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+ // The pause run state change should make it to the impl thread controller.
+ controller->pushAnimationUpdatesTo(controllerImpl.get());
+ EXPECT_EQ(CCActiveAnimation::Paused, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+ // Resume the main-thread animation.
+ controller->resumeAnimations(2);
+ EXPECT_EQ(CCActiveAnimation::Running, controller->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+
+ // The pause run state change should make it to the impl thread controller.
+ controller->pushAnimationUpdatesTo(controllerImpl.get());
+ EXPECT_EQ(CCActiveAnimation::Running, controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity)->runState());
+}
+
+
TEST(CCLayerAnimationControllerTest, doNotSyncFinishedAnimation)
{
FakeLayerAnimationControllerClient dummyImpl;