Diff
Modified: trunk/LayoutTests/ChangeLog (115946 => 115947)
--- trunk/LayoutTests/ChangeLog 2012-05-03 08:22:58 UTC (rev 115946)
+++ trunk/LayoutTests/ChangeLog 2012-05-03 08:45:14 UTC (rev 115947)
@@ -1,3 +1,34 @@
+2012-05-03 Nikolas Zimmermann <nzimmerm...@rim.com>
+
+ Fix multiple begin values support - especially with seeking through setCurrentTime
+ https://bugs.webkit.org/show_bug.cgi?id=85372
+
+ Reviewed by Zoltan Herczeg.
+
+ * svg/animations/multiple-begin-additive-animation-expected.txt: Added.
+ * svg/animations/multiple-begin-additive-animation.html: Added.
+ * svg/animations/multiple-begin-animation-discrete-expected.svg: Added.
+ * svg/animations/multiple-begin-animation-discrete.svg: Added.
+ * svg/animations/multiple-begin-animation-expected.svg: Added.
+ * svg/animations/multiple-begin-animation.svg: Added.
+ * svg/animations/resources/multiple-begin-additive-animation.svg: Added.
+ * svg/animations/script-tests/multiple-begin-additive-animation.js: Added.
+ (checkBaseValues):
+ (sample1):
+ (sample2):
+ (sample3):
+ (sample4):
+ (sample5):
+ (sample6):
+ (sample7):
+ (sample8):
+ (sample9):
+ (sample10):
+ (sample11):
+ (sample12):
+ (sample13):
+ (executeTest):
+
2012-05-03 Dongwoo Im <dw...@samsung.com>
[EFL][DRT] Implement the LayoutTestController's methods related to the Page Visibility API.
Added: trunk/LayoutTests/svg/animations/multiple-begin-additive-animation-expected.txt (0 => 115947)
--- trunk/LayoutTests/svg/animations/multiple-begin-additive-animation-expected.txt (rev 0)
+++ trunk/LayoutTests/svg/animations/multiple-begin-additive-animation-expected.txt 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,44 @@
+SVG 1.1 dynamic animation tests
+
+
+This tests additive='sum' support on animate elements with multiple begin times
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 100
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 166.67
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 366.60
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 366.73
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 499.93
+PASS rect.x.animVal.value is 400
+PASS rect.y.animVal.value is 500.06
+PASS rect.x.animVal.value is 400
+PASS rect.y.animVal.value is 566.67
+PASS rect.x.animVal.value is 400
+PASS rect.y.animVal.value is 633.33
+PASS rect.x.animVal.value is 400
+PASS rect.y.animVal.value is 633.33
+PASS rect.x.animVal.value is 400
+PASS rect.y.animVal.value is 700
+PASS rect.x.animVal.value is 400
+PASS rect.y.animVal.value is 766.60
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 766.67
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 833.33
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 900
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 900
+PASS rect.x.animVal.value is 0
+PASS rect.y.animVal.value is 900
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/svg/animations/multiple-begin-additive-animation.html (0 => 115947)
--- trunk/LayoutTests/svg/animations/multiple-begin-additive-animation.html (rev 0)
+++ trunk/LayoutTests/svg/animations/multiple-begin-additive-animation.html 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="runSMILTest()">
+<h1>SVG 1.1 dynamic animation tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/svg/animations/multiple-begin-animation-discrete-expected.svg (0 => 115947)
--- trunk/LayoutTests/svg/animations/multiple-begin-animation-discrete-expected.svg (rev 0)
+++ trunk/LayoutTests/svg/animations/multiple-begin-animation-discrete-expected.svg 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+ <rect width="100" height="100" fill="red"/>
+ <rect width="100" height="100" fill="green"/>
+</svg>
Added: trunk/LayoutTests/svg/animations/multiple-begin-animation-discrete.svg (0 => 115947)
--- trunk/LayoutTests/svg/animations/multiple-begin-animation-discrete.svg (rev 0)
+++ trunk/LayoutTests/svg/animations/multiple-begin-animation-discrete.svg 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" _onload_="loaded()">
+<rect width="100" height="100" fill="green">
+ <animate attributeName="width" attributeType="XML" calcMode="discrete" begin="0s; 3s" from="100" to="0" dur="8s"/>
+</rect>
+<script>
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function loaded() {
+ document.documentElement.setCurrentTime(6.5);
+ document.documentElement.pauseAnimations();
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+</svg>
Added: trunk/LayoutTests/svg/animations/multiple-begin-animation-expected.svg (0 => 115947)
--- trunk/LayoutTests/svg/animations/multiple-begin-animation-expected.svg (rev 0)
+++ trunk/LayoutTests/svg/animations/multiple-begin-animation-expected.svg 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+ <rect width="100" height="100" fill="green"/>
+</svg>
Added: trunk/LayoutTests/svg/animations/multiple-begin-animation.svg (0 => 115947)
--- trunk/LayoutTests/svg/animations/multiple-begin-animation.svg (rev 0)
+++ trunk/LayoutTests/svg/animations/multiple-begin-animation.svg 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" _onload_="loaded()">
+<rect width="10" height="100" fill="green">
+ <animate attributeName="width" attributeType="XML" begin="0s; 2s" from="0" to="200" dur="4s" fill="freeze"/>
+</rect>
+<script>
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function loaded() {
+ document.documentElement.setCurrentTime(4);
+ document.documentElement.pauseAnimations();
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+</svg>
Added: trunk/LayoutTests/svg/animations/resources/multiple-begin-additive-animation.svg (0 => 115947)
--- trunk/LayoutTests/svg/animations/resources/multiple-begin-additive-animation.svg (rev 0)
+++ trunk/LayoutTests/svg/animations/resources/multiple-begin-additive-animation.svg 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
+<rect width="100" height="100" fill="green">
+ <animate id="an1" attributeName="y" attributeType="XML" begin="0s" dur="12s" from="100" to="900" fill="freeze" />
+ <animate attributeName="x" attributeType="XML" calcMode="discrete" begin="0s; 2s" from="0" to="400" dur="8s" additive="sum" />
+</rect>
+</svg>
Added: trunk/LayoutTests/svg/animations/script-tests/multiple-begin-additive-animation.js (0 => 115947)
--- trunk/LayoutTests/svg/animations/script-tests/multiple-begin-additive-animation.js (rev 0)
+++ trunk/LayoutTests/svg/animations/script-tests/multiple-begin-additive-animation.js 2012-05-03 08:45:14 UTC (rev 115947)
@@ -0,0 +1,117 @@
+description("This tests additive='sum' support on animate elements with multiple begin times");
+embedSVGTestCase("resources/multiple-begin-additive-animation.svg");
+
+// Setup animation test
+function checkBaseValues() {
+return;
+ shouldBe("rect.x.baseVal.value", "0");
+ shouldBe("rect.y.baseVal.value", "0");
+}
+
+function sample1() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "100");
+ checkBaseValues();
+}
+
+function sample2() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "166.67");
+ checkBaseValues();
+}
+
+function sample3() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "366.60");
+ checkBaseValues();
+}
+
+function sample4() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "366.73");
+ checkBaseValues();
+}
+
+function sample5() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "499.93");
+ checkBaseValues();
+}
+
+function sample6() {
+ shouldBe("rect.x.animVal.value", "400");
+ shouldBeCloseEnough("rect.y.animVal.value", "500.06");
+ checkBaseValues();
+}
+
+function sample7() {
+ shouldBe("rect.x.animVal.value", "400");
+ shouldBeCloseEnough("rect.y.animVal.value", "566.67");
+ checkBaseValues();
+}
+
+function sample8() {
+ shouldBe("rect.x.animVal.value", "400");
+ shouldBeCloseEnough("rect.y.animVal.value", "633.33");
+ checkBaseValues();
+}
+
+function sample9() {
+ shouldBe("rect.x.animVal.value", "400");
+ shouldBeCloseEnough("rect.y.animVal.value", "700");
+ checkBaseValues();
+}
+
+function sample10() {
+ shouldBe("rect.x.animVal.value", "400");
+ shouldBeCloseEnough("rect.y.animVal.value", "766.60");
+ checkBaseValues();
+}
+
+function sample11() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "766.67");
+ checkBaseValues();
+}
+
+function sample12() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "833.33");
+ checkBaseValues();
+}
+
+function sample13() {
+ shouldBe("rect.x.animVal.value", "0");
+ shouldBeCloseEnough("rect.y.animVal.value", "900");
+ checkBaseValues();
+}
+
+function executeTest() {
+ rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0];
+
+ // All animations in the test file use the same duration, so it's not needed to list all sample points individually for an5/an6/an7/an8.
+ const expectedValues = [
+ // [animationId, time, sampleCallback]
+ ["an1", 0.0, sample1],
+ ["an1", 1.0, sample2],
+ ["an1", 3.999, sample3],
+ ["an1", 4.001, sample4],
+ ["an1", 5.999, sample5],
+ ["an1", 6.001, sample6],
+ ["an1", 7.0, sample7],
+ ["an1", 7.999, sample8],
+ ["an1", 8.001, sample8],
+ ["an1", 9.0, sample9],
+ ["an1", 9.999, sample10],
+ ["an1", 10.001, sample11],
+ ["an1", 11.0, sample12],
+ ["an1", 11.999, sample13],
+ ["an1", 12.001, sample13],
+ ["an1", 60.0, sample13]
+ ];
+
+ runAnimationTest(expectedValues);
+}
+
+window.animationStartsImmediately = true;
+var successfullyParsed = true;
Modified: trunk/Source/WebCore/ChangeLog (115946 => 115947)
--- trunk/Source/WebCore/ChangeLog 2012-05-03 08:22:58 UTC (rev 115946)
+++ trunk/Source/WebCore/ChangeLog 2012-05-03 08:45:14 UTC (rev 115947)
@@ -1,3 +1,58 @@
+2012-05-03 Nikolas Zimmermann <nzimmerm...@rim.com>
+
+ Fix multiple begin values support - especially with seeking through setCurrentTime
+ https://bugs.webkit.org/show_bug.cgi?id=85372
+
+ Reviewed by Zoltan Herczeg.
+
+ Multiple begin values aka. begin="0s; 2s" aren't correctly handled - resulting in broken & unexpected behavior.
+ Supporting seeking properly on documents containing such animations is very important, otherwise we can't reliable
+ test animations using either reftests or the SVG JS animation test framework.
+
+ Testcase:
+ <rect height="100" fill="green">
+ <animate attributeName="width" begin="0s; 2s" dur="8s" from="0" to="100" fill="freeze"/>
+ </rect>
+
+ What's expected?
+ Two times should be contained in the 'begin' times list in SVGSMILElement: m_beginTimes = { 0s, 2s }.
+ The initial first resolved interval is: m_intervalBegin=0.0s, m_intervalEnd=8.0s.
+
+ During t=0s..1.9999s the m_intervalBegin/m_intervalEnd are correct.
+ At t=2s, a new interval can be started. m_intervalEnd should be set to nextBeginTime, where nextBeginTime=2s.
+ The current interval should get cropped to: m_intervalBegin=0s, m_intervalEnd=2s. The following call to
+ resolveNextInterval() sees that elapsed >= m_intervalEnd, and thus moves on to the next interval.
+ m_intervalBegin should be 2s and m_intervalEnd=10s after that.
+
+ In trunk this behavior is only partly implemented and broken. Especially broken together with seeking via SVGSVGElement.setCurrentTime.
+ That's because we don't correctly seek to the right interval in case of multiple begin values, eg. if we sample an animation with
+ begin="0s; 3s" dur="6s" we always remain in the first interval and don't move on.
+
+ Fix all of these issues, making lots more tests work in Dr. Olaf Hofmanns SVG Animation test suite.
+
+ Tests: svg/animations/multiple-begin-additive-animation.html
+ svg/animations/multiple-begin-animation-discrete-expected.svg
+ svg/animations/multiple-begin-animation-discrete.svg
+ svg/animations/multiple-begin-animation-expected.svg
+ svg/animations/multiple-begin-animation.svg
+
+ * svg/animation/SMILTimeContainer.cpp:
+ (WebCore::SMILTimeContainer::begin):
+ (WebCore::SMILTimeContainer::setElapsed):
+ (WebCore::SMILTimeContainer::updateAnimations):
+ * svg/animation/SMILTimeContainer.h:
+ (SMILTimeContainer):
+ * svg/animation/SVGSMILElement.cpp:
+ (WebCore::SVGSMILElement::findInstanceTime):
+ (WebCore::SVGSMILElement::resolveInterval):
+ (WebCore::SVGSMILElement::resolveNextInterval):
+ (WebCore):
+ (WebCore::SVGSMILElement::checkRestart):
+ (WebCore::SVGSMILElement::seekToIntervalCorrespondingToTime):
+ (WebCore::SVGSMILElement::progress):
+ * svg/animation/SVGSMILElement.h:
+ (SVGSMILElement):
+
2012-05-03 Dana Jansens <dan...@chromium.org>
[chromium] Don't add small opaque areas to the occlusion tracker's Region
Modified: trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp (115946 => 115947)
--- trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp 2012-05-03 08:22:58 UTC (rev 115946)
+++ trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp 2012-05-03 08:45:14 UTC (rev 115947)
@@ -89,8 +89,10 @@
ASSERT(!m_beginTime);
double now = currentTime();
+ // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began.
+ // In this case pass on 'seekToTime=true' to updateAnimations().
m_beginTime = now - m_presetStartTime;
- updateAnimations(SMILTime(m_presetStartTime));
+ updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
m_presetStartTime = 0;
if (m_pauseTime) {
@@ -126,6 +128,9 @@
return;
}
+ if (m_beginTime)
+ m_timer.stop();
+
m_beginTime = currentTime() - time.value();
m_accumulatedPauseTime = 0;
@@ -134,7 +139,7 @@
for (unsigned n = 0; n < toReset.size(); ++n)
toReset[n]->reset();
- updateAnimations(time);
+ updateAnimations(time, true);
}
void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay)
@@ -202,7 +207,7 @@
std::sort(smilElements.begin(), smilElements.end(), applyOrderSortFunction);
}
-void SMILTimeContainer::updateAnimations(SMILTime elapsed)
+void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
{
SMILTime earliersFireTime = SMILTime::unresolved();
@@ -247,7 +252,7 @@
}
// This will calculate the contribution from the animation and add it to the resultsElement.
- animation->progress(elapsed, resultElement);
+ animation->progress(elapsed, resultElement, seekToTime);
SMILTime nextFireTime = animation->nextProgressTime();
if (nextFireTime.isFinite())
Modified: trunk/Source/WebCore/svg/animation/SMILTimeContainer.h (115946 => 115947)
--- trunk/Source/WebCore/svg/animation/SMILTimeContainer.h 2012-05-03 08:22:58 UTC (rev 115946)
+++ trunk/Source/WebCore/svg/animation/SMILTimeContainer.h 2012-05-03 08:45:14 UTC (rev 115947)
@@ -68,7 +68,7 @@
void timerFired(Timer<SMILTimeContainer>*);
void startTimer(SMILTime fireTime, SMILTime minimumDelay = 0);
- void updateAnimations(SMILTime elapsed);
+ void updateAnimations(SMILTime elapsed, bool seekToTime = false);
void updateDocumentOrderIndexes();
void sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed);
Modified: trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp (115946 => 115947)
--- trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp 2012-05-03 08:22:58 UTC (rev 115946)
+++ trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp 2012-05-03 08:45:14 UTC (rev 115947)
@@ -696,37 +696,32 @@
const SMILTimeWithOrigin* result = binarySearch<const SMILTimeWithOrigin, SMILTime, extractTimeFromVector>(list.begin(), sizeOfList, minimumTime, WTF::KeyMustNotBePresentInArray);
int indexOfResult = result - list.begin();
- if (sizeOfList - 1 > indexOfResult && list[indexOfResult].time() < minimumTime)
- ++indexOfResult;
-
ASSERT(indexOfResult < sizeOfList);
const SMILTime& currentTime = list[indexOfResult].time();
- // "The special value "indefinite" does not yield an instance time in the begin list."
+ // The special value "indefinite" does not yield an instance time in the begin list.
if (currentTime.isIndefinite() && beginOrEnd == Begin)
return SMILTime::unresolved();
if (currentTime < minimumTime)
return beginOrEnd == Begin ? SMILTime::unresolved() : SMILTime::indefinite();
+ if (currentTime > minimumTime)
+ return currentTime;
- // If the equals is NOT accepted, we have to find a bigger one.
- if (currentTime == minimumTime && !equalsMinimumOK) {
- if (indexOfResult + 1 >= sizeOfList)
- return beginOrEnd == Begin ? SMILTime::unresolved() : SMILTime::indefinite();
- }
+ ASSERT(currentTime == minimumTime);
+ if (equalsMinimumOK)
+ return currentTime;
- while (indexOfResult < sizeOfList - 1 && currentTime == list[indexOfResult + 1].time())
+ // If the equals is not accepted, return the next bigger item in the list.
+ SMILTime nextTime = currentTime;
+ while (indexOfResult < sizeOfList - 1) {
+ nextTime = list[indexOfResult + 1].time();
+ if (nextTime > minimumTime)
+ return nextTime;
++indexOfResult;
-
- if (currentTime > minimumTime)
- return currentTime;
- if (currentTime == minimumTime) {
- if (indexOfResult + 1 < sizeOfList - 1)
- return list[indexOfResult + 1].time();
- return beginOrEnd == Begin ? SMILTime::unresolved() : SMILTime::indefinite();
}
- return currentTime;
+ return beginOrEnd == Begin ? SMILTime::unresolved() : SMILTime::indefinite();
}
SMILTime SVGSMILElement::repeatingDuration() const
@@ -767,12 +762,12 @@
void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const
{
- // See the pseudocode in
- // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LifeCycle
+ // See the pseudocode in http://www.w3.org/TR/SMIL3/smil-timing.html#q90.
SMILTime beginAfter = first ? -numeric_limits<double>::infinity() : m_intervalEnd;
SMILTime lastIntervalTempEnd = numeric_limits<double>::infinity();
while (true) {
- SMILTime tempBegin = findInstanceTime(Begin, beginAfter, true);
+ bool equalsMinimumOK = !first || m_intervalEnd > m_intervalBegin;
+ SMILTime tempBegin = findInstanceTime(Begin, beginAfter, equalsMinimumOK);
if (tempBegin.isUnresolved())
break;
SMILTime tempEnd;
@@ -788,13 +783,11 @@
}
tempEnd = resolveActiveEnd(tempBegin, tempEnd);
}
- if (tempEnd > 0 || !first) {
+ if (!first || (tempEnd > 0 || (!tempBegin.value() && !tempEnd.value()))) {
beginResult = tempBegin;
endResult = tempEnd;
return;
}
- if (restart() == RestartNever)
- break;
beginAfter = tempEnd;
lastIntervalTempEnd = tempEnd;
@@ -820,7 +813,7 @@
}
}
-void SVGSMILElement::resolveNextInterval()
+void SVGSMILElement::resolveNextInterval(bool notifyDependents)
{
SMILTime begin;
SMILTime end;
@@ -830,7 +823,8 @@
if (!begin.isUnresolved() && begin != m_intervalBegin) {
m_intervalBegin = begin;
m_intervalEnd = end;
- notifyDependentsIntervalChanged(NewInterval);
+ if (notifyDependents)
+ notifyDependentsIntervalChanged(NewInterval);
m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin);
}
}
@@ -884,16 +878,16 @@
m_nextProgressTime = elapsed;
reschedule();
}
-
+
void SVGSMILElement::checkRestart(SMILTime elapsed)
{
ASSERT(!m_isWaitingForFirstInterval);
ASSERT(elapsed >= m_intervalBegin);
-
+
Restart restart = this->restart();
if (restart == RestartNever)
return;
-
+
if (elapsed < m_intervalEnd) {
if (restart != RestartAlways)
return;
@@ -902,11 +896,45 @@
m_intervalEnd = nextBegin;
notifyDependentsIntervalChanged(ExistingInterval);
}
- }
+ }
+
if (elapsed >= m_intervalEnd)
- resolveNextInterval();
+ resolveNextInterval(true);
}
-
+
+void SVGSMILElement::seekToIntervalCorrespondingToTime(SMILTime elapsed)
+{
+ ASSERT(!m_isWaitingForFirstInterval);
+ ASSERT(elapsed >= m_intervalBegin);
+
+ // Manually seek from interval to interval, just as if the animation would run regulary.
+ while (true) {
+ // Figure out the next value in the begin time list after the current interval begin.
+ SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false);
+
+ // If the 'nextBegin' time is unresolved (eg. just one defined interval), we're done seeking.
+ if (nextBegin.isUnresolved())
+ return;
+
+ // If the 'nextBegin' time is larger than or equal to the current interval end time, we're done seeking.
+ // If the 'elapsed' time is smaller than the next begin interval time, we're done seeking.
+ if (nextBegin < m_intervalEnd && elapsed >= nextBegin) {
+ // End current interval, and start a new interval from the 'nextBegin' time.
+ m_intervalEnd = nextBegin;
+ resolveNextInterval(false);
+ continue;
+ }
+
+ // If the desired 'elapsed' time is past the current interval, advance to the next.
+ if (elapsed >= m_intervalEnd) {
+ resolveNextInterval(false);
+ continue;
+ }
+
+ return;
+ }
+}
+
float SVGSMILElement::calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const
{
SMILTime simpleDuration = this->simpleDuration();
@@ -974,7 +1002,7 @@
return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_intervalBegin + repeatingDuration())) || m_activeState == Frozen;
}
-void SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement)
+void SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, bool seekToTime)
{
ASSERT(m_timeContainer);
ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite());
@@ -1003,15 +1031,19 @@
m_activeState = Active;
startedActiveInterval();
}
-
- unsigned repeat;
+
+ // This call may obtain a new interval -- never call calculateAnimationPercentAndRepeat() before!
+ if (seekToTime) {
+ seekToIntervalCorrespondingToTime(elapsed);
+ ASSERT(elapsed >= m_intervalBegin);
+ }
+
+ unsigned repeat = 0;
float percent = calculateAnimationPercentAndRepeat(elapsed, repeat);
-
checkRestart(elapsed);
ActiveState oldActiveState = m_activeState;
m_activeState = determineActiveState(elapsed);
-
if (isContributing(elapsed)) {
if (resultElement)
updateAnimation(percent, repeat, resultElement);
Modified: trunk/Source/WebCore/svg/animation/SVGSMILElement.h (115946 => 115947)
--- trunk/Source/WebCore/svg/animation/SVGSMILElement.h 2012-05-03 08:22:58 UTC (rev 115946)
+++ trunk/Source/WebCore/svg/animation/SVGSMILElement.h 2012-05-03 08:45:14 UTC (rev 115947)
@@ -89,7 +89,8 @@
SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
SMILTime simpleDuration() const;
- void progress(SMILTime elapsed, SVGSMILElement* resultsElement);
+ void seekToIntervalCorrespondingToTime(SMILTime elapsed);
+ void progress(SMILTime elapsed, SVGSMILElement* resultsElement, bool seekToTime);
SMILTime nextProgressTime() const;
void reset();
@@ -129,7 +130,7 @@
SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
void resolveFirstInterval();
- void resolveNextInterval();
+ void resolveNextInterval(bool notifyDependents);
void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
SMILTime repeatingDuration() const;