Commit 89a55e98 authored by cmarrin@apple.com's avatar cmarrin@apple.com

Fixed https://bugs.webkit.org/show_bug.cgi?id=22870

 
        I added calls beginAnimationUpdate() and endAnimationUpdate() calls
        to AnimationController. These are called by Document at the start
        and end of the recalcStyle cycle. Right now, I'm just using the 
        beginAnimationUpdate() method to reset an animation time value.
        The first time the animation time is accessed after this reset I set
        it to the currentTime. So all animations in that cycle get the same
        start time. 

        The test cases checked in test this, but in the case of the 'left'
        test it actually doesn't make any difference in most cases. This is
        because values are clamped to whole pixels, so the start times would 
        have to be pretty far off for the test to fail using the old
        currentTime() model. Still, under really heavy load, it's possible for
        the test to fail without these changes.

        The 'transform' test is another story. It animates to the full resolution
        of a floating point number, so the test fails miserably without this
        fix.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@39667 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent ae5f161d
2009-01-06 Chris Marrin <cmarrin@apple.com>
Reviewed by David Hyatt.
* animations/animation-test-helpers.js:
(runAnimationTest.matrixStringToArray):
(runAnimationTest.checkExpectedValue):
* animations/simultaneous-start-left-expected.txt: Added.
* animations/simultaneous-start-left.html: Added.
* animations/simultaneous-start-transform-expected.txt: Added.
* animations/simultaneous-start-transform.html: Added.
2009-01-06 Dean Jackson <dino@apple.com>
Reviewed by Dave Hyatt.
......
......@@ -12,15 +12,19 @@ Function parameters:
Each sub-array must contain these items in this order:
- the name of the CSS animation (may be null) [1]
- the time in seconds at which to snapshot the CSS property
- the id of the element on which to get the CSS property value
- the name of the CSS property to get [2]
- the id of the element on which to get the CSS property value [2]
- the name of the CSS property to get [3]
- the expected value for the CSS property
- the tolerance to use when comparing the effective CSS property value with its expected value
[1] If null is passed, a regular setTimeout() will be used instead to snapshot the animated property in the future,
instead of fast forwarding using the pauseAnimationAtTimeOnElementWithId() JS API from DRT
instead of fast forwarding using the pauseAnimationAtTimeOnElementWithId() JS API from DRT
[2] If a single string is passed, it is the id of the element to test. If an array with 2 elements is passed they
are the ids of 2 elements, whose values are compared for equality. In this case the expected value is ignored
but the tolerance is used in the comparison.
[2] If the CSS property name is "webkitTransform", expected value must be an array of 1 or more numbers corresponding to the matrix elements,
[3] If the CSS property name is "webkitTransform", expected value must be an array of 1 or more numbers corresponding to the matrix elements,
or a string which will be compared directly (useful if the expected value is "none")
If the CSS property name is "webkitTransform.N", expected value must be a number corresponding to the Nth element of the matrix
......@@ -35,7 +39,14 @@ function runAnimationTest(expected, callback, event)
var diff = Math.abs(actual - desired);
return diff <= tolerance;
}
function matrixStringToArray(s)
{
var m = s.split("(");
m = m[1].split(")");
return m[0].split(",");
}
function checkExpectedValue(expected, index)
{
var animationName = expected[index][0];
......@@ -45,44 +56,90 @@ function runAnimationTest(expected, callback, event)
var expectedValue = expected[index][4];
var tolerance = expected[index][5];
// Check for a pair of element Ids
var compareElements = false;
var elementId2;
if (typeof elementId != "string") {
if (elementId.length != 2)
return;
elementId2 = elementId[1];
elementId = elementId[0];
compareElements = true;
}
if (animationName && hasPauseAnimationAPI && !layoutTestController.pauseAnimationAtTimeOnElementWithId(animationName, time, elementId)) {
result += "FAIL - animation \"" + animationName + "\" is not running" + "<br>";
return;
}
var computedValue;
var pass;
if (compareElements && animationName && hasPauseAnimationAPI && !layoutTestController.pauseAnimationAtTimeOnElementWithId(animationName, time, elementId2)) {
result += "FAIL - animation \"" + animationName + "\" is not running" + "<br>";
return;
}
var computedValue, computedValue2;
var pass = true;
if (!property.indexOf("webkitTransform")) {
computedValue = window.getComputedStyle(document.getElementById(elementId)).webkitTransform;
if (typeof expectedValue == "string")
pass = (computedValue == expectedValue);
else if (typeof expectedValue == "number") {
var m = computedValue.split("(");
var m = m[1].split(",");
pass = isCloseEnough(parseFloat(m[parseInt(property.substring(16))]), expectedValue, tolerance);
} else {
var m = computedValue.split("(");
var m = m[1].split(",");
for (i = 0; i < expectedValue.length; ++i) {
pass = isCloseEnough(parseFloat(m[i]), expectedValue[i], tolerance);
if (compareElements) {
computedValue2 = window.getComputedStyle(document.getElementById(elementId2)).webkitTransform;
var m1 = matrixStringToArray(computedValue);
var m2 = matrixStringToArray(computedValue2);
// for now we assume that both matrices are either both 2D or both 3D
var count = (computedValue.substring(0, 7) == "matrix3d") ? 16 : 6;
for (var i = 0; i < count; ++i) {
pass = isCloseEnough(parseFloat(m1[i]), m2[i], tolerance);
if (!pass)
break;
}
} else {
if (typeof expectedValue == "string")
pass = (computedValue == expectedValue);
else if (typeof expectedValue == "number") {
var m = matrixStringToArray(computedValue);
pass = isCloseEnough(parseFloat(m[parseInt(property.substring(16))]), expectedValue, tolerance);
} else {
var m = matrixStringToArray(computedValue);
for (i = 0; i < expectedValue.length; ++i) {
pass = isCloseEnough(parseFloat(m[i]), expectedValue[i], tolerance);
if (!pass)
break;
}
}
}
} else if (property == "lineHeight") {
computedValue = parseInt(window.getComputedStyle(document.getElementById(elementId)).lineHeight);
pass = isCloseEnough(computedValue, expectedValue, tolerance);
} else {
if (compareElements) {
computedValue2 = parseInt(window.getComputedStyle(document.getElementById(elementId2)).lineHeight);
pass = isCloseEnough(computedValue, computedValue2, tolerance);
}
else
pass = isCloseEnough(computedValue, expectedValue, tolerance);
} else {
var computedStyle = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property);
computedValue = computedStyle.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
pass = isCloseEnough(computedValue, expectedValue, tolerance);
if (compareElements) {
var computedStyle2 = window.getComputedStyle(document.getElementById(elementId2)).getPropertyCSSValue(property);
computedValue2 = computedStyle2.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
pass = isCloseEnough(computedValue, computedValue2, tolerance);
}
else
pass = isCloseEnough(computedValue, expectedValue, tolerance);
}
if (pass)
result += "PASS - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s saw something close to: " + expectedValue + "<br>";
else
result += "FAIL - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s expected: " + expectedValue + " but saw: " + computedValue + "<br>";
if (compareElements) {
if (pass)
result += "PASS - \"" + property + "\" property for \"" + elementId + "\" and \"" + elementId2 + "\" elements at " + time + "s are close enough to each other" + "<br>";
else
result += "FAIL - \"" + property + "\" property for \"" + elementId + "\" and \"" + elementId2 + "\" elements at " + time + "s saw: \"" + computedValue + "\" and \"" + computedValue2 + "\" which are not close enough to each other" + "<br>";
} else {
if (pass)
result += "PASS - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s saw something close to: " + expectedValue + "<br>";
else
result += "FAIL - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s expected: " + expectedValue + " but saw: " + computedValue + "<br>";
}
}
function endTest()
......
This test performs an animation of the left property. It animates over 10 seconds. It takes 3 snapshots and expects each result to be within a specified range.
PASS - "left" property for "box1" element at 2s saw something close to: 170
PASS - "left" property for "box2" element at 2s saw something close to: 170
PASS - "left" property for "box1" and "box2" elements at 2s are close enough to each other
PASS - "left" property for "box1" element at 5s saw something close to: 410
PASS - "left" property for "box2" element at 5s saw something close to: 410
PASS - "left" property for "box1" and "box2" elements at 5s are close enough to each other
PASS - "left" property for "box1" element at 8s saw something close to: 650
PASS - "left" property for "box2" element at 8s saw something close to: 650
PASS - "left" property for "box1" and "box2" elements at 8s are close enough to each other
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test simultaneous starting of two animations</title>
<style type="text/css" media="screen">
.box {
position: relative;
left: 100px;
height: 100px;
width: 100px;
background-color: blue;
-webkit-animation-duration: 10s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: "anim";
}
@-webkit-keyframes "anim" {
from { left: 10px; }
to { left: 810px; }
}
#box1 {
top: 10px;
background-color: blue;
}
#box2 {
top: 10px;
background-color: red;
}
</style>
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
["anim", 2, "box1", "left", 170, 5],
["anim", 2, "box2", "left", 170, 5],
["anim", 2, ["box1", "box2"], "left", "", 0],
["anim", 5, "box1", "left", 410, 5],
["anim", 5, "box2", "left", 410, 5],
["anim", 5, ["box1", "box2"], "left", "", 0],
["anim", 8, "box1", "left", 650, 5],
["anim", 8, "box2", "left", 650, 5],
["anim", 8, ["box1", "box2"], "left", "", 0],
];
runAnimationTest(expectedValues);
</script>
</head>
<body>
This test performs an animation of the left property. It animates over 10 seconds.
It takes 3 snapshots and expects each result to be within a specified range.
<div id="box1" class="box">
</div>
<div id="box2" class="box">
</div>
<div id="result">
</div>
</body>
</html>
This test performs an animation of the transform property. It animates over 10 seconds. It takes 3 snapshots and expects each result to be within a specified range. PASS - "webkitTransform" property for "box1" element at 2s saw something close to: 0.309017,0.951057
PASS - "webkitTransform" property for "box2" element at 2s saw something close to: 0.309017,0.951057
PASS - "webkitTransform" property for "box1" and "box2" elements at 2s are close enough to each other
PASS - "webkitTransform" property for "box1" element at 5s saw something close to: -1,0
PASS - "webkitTransform" property for "box2" element at 5s saw something close to: -1,0
PASS - "webkitTransform" property for "box1" and "box2" elements at 5s are close enough to each other
PASS - "webkitTransform" property for "box1" element at 8s saw something close to: 0.309017,-0.951057
PASS - "webkitTransform" property for "box2" element at 8s saw something close to: 0.309017,-0.951057
PASS - "webkitTransform" property for "box1" and "box2" elements at 8s are close enough to each other
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test simultaneous starting of two animations</title>
<style type="text/css" media="screen">
.box {
position: absolute;
top: 40px;
height: 100px;
width: 100px;
background-color: blue;
-webkit-animation-duration: 10s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: "anim";
}
@-webkit-keyframes "anim" {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
#box1 {
left: 40px;
background-color: blue;
}
#box2 {
left: 160px;
background-color: red;
}
</style>
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
["anim", 2, "box1", "webkitTransform", [ 0.309017, 0.951057 ], 0.05],
["anim", 2, "box2", "webkitTransform", [ 0.309017, 0.951057 ], 0.05],
["anim", 2, ["box1", "box2"], "webkitTransform", "", 0],
["anim", 5, "box1", "webkitTransform", [ -1, 0 ], 0.05],
["anim", 5, "box2", "webkitTransform", [ -1, 0 ], 0.05],
["anim", 5, ["box1", "box2"], "webkitTransform", "", 0],
["anim", 8, "box1", "webkitTransform", [ 0.309017, -0.951057 ], 0.05],
["anim", 8, "box2", "webkitTransform", [ 0.309017, -0.951057 ], 0.05],
["anim", 8, ["box1", "box2"], "webkitTransform", "", 0],
];
runAnimationTest(expectedValues);
</script>
</head>
<body>
This test performs an animation of the transform property. It animates over 10 seconds.
It takes 3 snapshots and expects each result to be within a specified range.
<div id="box1" class="box">
</div>
<div id="box2" class="box">
</div>
<div id="result" style="position:absolute; top:150px">
</div>
</body>
</html>
2009-01-06 Chris Marrin <cmarrin@apple.com>
Reviewed by David Hyatt.
Tests: animations/simultaneous-start-left.html
animations/simultaneous-start-transform.html
Fixed https://bugs.webkit.org/show_bug.cgi?id=22870
I added calls beginAnimationUpdate() and endAnimationUpdate() calls
to AnimationController. These are called by Document at the start
and end of the recalcStyle cycle. Right now, I'm just using the
beginAnimationUpdate() method to reset an animation time value.
The first time the animation time is accessed after this reset I set
it to the currentTime. So all animations in that cycle get the same
start time.
The test cases checked in test this, but in the case of the 'left'
test it actually doesn't make any difference in most cases. This is
because values are clamped to whole pixels, so the start times would
have to be pretty far off for the test to fail using the old
currentTime() model. Still, under really heavy load, it's possible for
the test to fail without these changes.
The 'transform' test is another story. It animates to the full resolution
of a floating point number, so the test fails miserably without this
fix.
* dom/Document.cpp:
(WebCore::Document::recalcStyle):
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::updateStateMachine):
(WebCore::AnimationBase::fireAnimationEventsIfNeeded):
(WebCore::AnimationBase::willNeedService):
(WebCore::AnimationBase::progress):
(WebCore::AnimationBase::goIntoEndingOrLoopingState):
(WebCore::AnimationBase::beginAnimationUpdateTime):
* page/animation/AnimationBase.h:
* page/animation/AnimationController.cpp:
(WebCore::AnimationControllerPrivate::beginAnimationUpdateTime):
(WebCore::AnimationControllerPrivate::setBeginAnimationUpdateTime):
(WebCore::AnimationControllerPrivate::AnimationControllerPrivate):
(WebCore::AnimationController::updateAnimations):
(WebCore::AnimationController::beginAnimationUpdateTime):
(WebCore::AnimationController::beginAnimationUpdate):
(WebCore::AnimationController::endAnimationUpdate):
* page/animation/AnimationController.h:
* page/animation/KeyframeAnimation.cpp:
(WebCore::KeyframeAnimation::animate):
2009-01-06 Julien Chaffraix <jchaffraix@webkit.org>
Reviewed by Nikolas Zimmermann.
......@@ -1104,7 +1104,9 @@ void Document::recalcStyle(StyleChange change)
if (m_inStyleRecalc)
return; // Guard against re-entrancy. -dwh
m_frame->animation()->beginAnimationUpdate();
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
......@@ -1169,6 +1171,8 @@ bail_out:
m_closeAfterStyleRecalc = false;
implicitClose();
}
m_frame->animation()->endAnimationUpdate();
}
void Document::updateRendering()
......
......@@ -533,7 +533,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// If we are in AnimationStateStartWaitResponse, the animation will get canceled before
// we get a response, so move to the next state.
endAnimation(false);
updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
return;
}
......@@ -552,7 +552,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
m_waitedForResponse = false;
m_requestedStartTime = currentTime();
m_requestedStartTime = beginAnimationUpdateTime();
m_animState = AnimationStateStartWaitTimer;
}
break;
......@@ -571,7 +571,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
} else {
ASSERT(!paused());
// We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
m_pauseTime = currentTime();
m_pauseTime = beginAnimationUpdateTime();
m_animState = AnimationStatePausedWaitTimer;
}
break;
......@@ -592,7 +592,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (overridden() || !startAnimation(0)) {
// We're not going to get a startTime callback, so fire the start time here
m_animState = AnimationStateStartWaitResponse;
updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
} else
m_waitedForResponse = true;
break;
......@@ -633,7 +633,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
goIntoEndingOrLoopingState();
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = currentTime();
m_pauseTime = beginAnimationUpdateTime();
endAnimation(false);
m_animState = AnimationStatePausedRun;
}
......@@ -657,7 +657,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
}
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = currentTime();
m_pauseTime = beginAnimationUpdateTime();
endAnimation(false);
m_animState = AnimationStatePausedRun;
}
......@@ -667,7 +667,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(input == AnimationStateInputPlayStateRunnning);
ASSERT(paused());
// Update the times
m_startTime += currentTime() - m_pauseTime;
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
m_pauseTime = -1;
// we were waiting for the start timer to fire, go back and wait again
......@@ -684,7 +684,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(paused());
// Update the times
if (m_animState == AnimationStatePausedRun)
m_startTime += currentTime() - m_pauseTime;
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
else
m_startTime = 0;
m_pauseTime = -1;
......@@ -695,7 +695,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// Start the animation
if (overridden() || !startAnimation(m_startTime)) {
// We're not going to get a startTime callback, so fire the start time here
updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
} else
m_waitedForResponse = true;
break;
......@@ -720,12 +720,12 @@ void AnimationBase::fireAnimationEventsIfNeeded()
// Check for start timeout
if (m_animState == AnimationStateStartWaitTimer) {
if (currentTime() - m_requestedStartTime >= m_animation->delay())
if (beginAnimationUpdateTime() - m_requestedStartTime >= m_animation->delay())
updateStateMachine(AnimationStateInputStartTimerFired, 0);
return;
}
double elapsedDuration = currentTime() - m_startTime;
double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
ASSERT(elapsedDuration >= 0);
// Check for end timeout
......@@ -767,7 +767,7 @@ double AnimationBase::willNeedService() const
return -1;
if (m_animState == AnimationStateStartWaitTimer) {
double timeFromNow = m_animation->delay() - (currentTime() - m_requestedStartTime);
double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime);
return (float) ((timeFromNow > 0) ? timeFromNow : 0);
}
......@@ -780,7 +780,7 @@ double AnimationBase::progress(double scale, double offset, const TimingFunction
if (preActive())
return 0;
double elapsedTime = running() && !paused() ? (currentTime() - m_startTime) : (m_pauseTime - m_startTime);
double elapsedTime = running() && !paused() ? (beginAnimationUpdateTime() - m_startTime) : (m_pauseTime - m_startTime);
if (running() && elapsedTime < 0)
return 0;
......@@ -826,7 +826,7 @@ void AnimationBase::goIntoEndingOrLoopingState()
if (m_animation->iterationCount() > 0)
totalDuration = m_animation->duration() * m_animation->iterationCount();
const double elapsedDuration = currentTime() - m_startTime;
const double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
ASSERT(elapsedDuration >= 0);
double durationLeft = 0;
double nextIterationTime = totalDuration;
......@@ -852,4 +852,9 @@ void AnimationBase::pauseAtTime(double t)
m_pauseTime = m_startTime + t - m_animation->delay();
}
double AnimationBase::beginAnimationUpdateTime() const
{
return m_compAnim->animationController()->beginAnimationUpdateTime();
}
} // namespace WebCore
......@@ -153,6 +153,8 @@ public:
void pauseAtTime(double t);
double beginAnimationUpdateTime() const;
protected:
virtual void overrideAnimations() { }
virtual void resumeOverriddenAnimations() { }
......
......@@ -32,11 +32,13 @@
#include "CSSParser.h"
#include "EventNames.h"
#include "Frame.h"
#include "SystemTime.h"
#include "Timer.h"
namespace WebCore {
static const double cAnimationTimerDelay = 0.025;
static const double cBeginAnimationUpdateTimeNotSet = -1;
class AnimationControllerPrivate {
public:
......@@ -65,6 +67,15 @@ public:
bool pauseAnimationAtTime(RenderObject*, const String& name, double t);
bool pauseTransitionAtTime(RenderObject*, const String& property, double t);
double beginAnimationUpdateTime()
{
if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
m_beginAnimationUpdateTime = currentTime();
return m_beginAnimationUpdateTime;
}
void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
private:
typedef HashMap<RenderObject*, RefPtr<CompositeAnimation> > RenderObjectAnimationMap;
......@@ -82,12 +93,15 @@ private:
};
Vector<EventToDispatch> m_eventsToDispatch;
double m_beginAnimationUpdateTime;
};
AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
: m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)
, m_updateRenderingDispatcher(this, &AnimationControllerPrivate::updateRenderingDispatcherFired)
, m_frame(frame)
, m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)
{
}
......@@ -316,7 +330,7 @@ void AnimationController::cancelAnimations(RenderObject* renderer)
}
PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* renderer, RenderStyle* newStyle)
{
{
// Don't do anything if we're in the cache
if (!renderer->document() || renderer->document()->inPageCache())
return newStyle;
......@@ -402,4 +416,18 @@ void AnimationController::styleAvailable()
m_data->styleAvailable();
}
double AnimationController::beginAnimationUpdateTime()
{
return m_data->beginAnimationUpdateTime();
}
void AnimationController::beginAnimationUpdate()
{
m_data->setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
}
void AnimationController::endAnimationUpdate()
{
}
} // namespace WebCore
......@@ -74,6 +74,11 @@ public:
else
m_numStyleAvailableWaiters--;
}
double beginAnimationUpdateTime();
void beginAnimationUpdate();
void endAnimationUpdate();
private:
AnimationControllerPrivate* m_data;
......
......@@ -87,7 +87,7 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
// We should cache the last pair or something.
// Find the first key
double elapsedTime = (m_startTime > 0 || m_pauseTime > 0) ? ((!paused() ? currentTime() : m_pauseTime) - m_startTime) : 0;
double elapsedTime = (m_startTime > 0 || m_pauseTime > 0) ? ((!paused() ? beginAnimationUpdateTime() : m_pauseTime) - m_startTime) : 0;