Diff
Modified: trunk/LayoutTests/ChangeLog (187120 => 187121)
--- trunk/LayoutTests/ChangeLog 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/ChangeLog 2015-07-21 21:19:20 UTC (rev 187121)
@@ -1,3 +1,22 @@
+2015-07-21 Simon Fraser <[email protected]>
+
+ Safari mis-applies "animation-fill-mode: forwards" when using fractional iteration count
+ https://bugs.webkit.org/show_bug.cgi?id=146996
+
+ Reviewed by Dean Jackson.
+
+ Progressions, improved tests.
+
+ * animations/animation-direction-reverse-fill-mode-expected.txt: New results; this is a progression.
+ * animations/animation-direction-reverse-fill-mode.html: Use a shorter animation. Fixed results.
+ * animations/fill-mode-iteration-count-non-integer-expected.txt:
+ * animations/fill-mode-iteration-count-non-integer.html: Use iteration counts that are not multiplies
+ of 0.5, so the test can differentiation between forward and backwards states. Add a non-linear timing
+ function to check that fill-forwards consults the timing functions. Don't print exact succeeding
+ results because they may have floating point values.
+ * animations/fill-mode-reverse-expected.txt: New results; this is a progression.
+ * animations/fill-mode-reverse.html: Fixed results, use gray.
+
2015-07-21 Said Abou-Hallawa <[email protected]>
REGRESSION (r172417, r184065): Multiple rendering issues with fixed attached background-image
Modified: trunk/LayoutTests/animations/animation-direction-reverse-fill-mode-expected.txt (187120 => 187121)
--- trunk/LayoutTests/animations/animation-direction-reverse-fill-mode-expected.txt 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/animations/animation-direction-reverse-fill-mode-expected.txt 2015-07-21 21:19:20 UTC (rev 187121)
@@ -11,7 +11,7 @@
PASS - start of animation - id: e expected: 300 actual: 300
PASS - end of animation - id: a expected: 100 actual: 100
PASS - end of animation - id: b expected: 100 actual: 100
-PASS - end of animation - id: c expected: 300 actual: 300
-PASS - end of animation - id: d expected: 300 actual: 300
+PASS - end of animation - id: c expected: 200 actual: 200
+PASS - end of animation - id: d expected: 200 actual: 200
PASS - end of animation - id: e expected: 300 actual: 300
Modified: trunk/LayoutTests/animations/animation-direction-reverse-fill-mode.html (187120 => 187121)
--- trunk/LayoutTests/animations/animation-direction-reverse-fill-mode.html 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/animations/animation-direction-reverse-fill-mode.html 2015-07-21 21:19:20 UTC (rev 187121)
@@ -10,7 +10,7 @@
height: 100px;
width: 100px;
-webkit-animation-delay: 0.1s;
- -webkit-animation-duration: 2s;
+ -webkit-animation-duration: 0.5s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: anim;
-webkit-animation-direction: reverse;
@@ -36,7 +36,7 @@
-webkit-animation-fill-mode: both;
}
#e {
- background-color: #999;
+ background-color: gray;
-webkit-animation-fill-mode: both;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate-reverse;
@@ -50,8 +50,8 @@
const expectedValues = [
{id: "a", start: 100, end: 100},
{id: "b", start: 300, end: 100},
- {id: "c", start: 100, end: 300},
- {id: "d", start: 300, end: 300},
+ {id: "c", start: 100, end: 200},
+ {id: "d", start: 300, end: 200},
{id: "e", start: 300, end: 300}
];
var result = "";
Modified: trunk/LayoutTests/animations/fill-mode-iteration-count-non-integer-expected.txt (187120 => 187121)
--- trunk/LayoutTests/animations/fill-mode-iteration-count-non-integer-expected.txt 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/animations/fill-mode-iteration-count-non-integer-expected.txt 2015-07-21 21:19:20 UTC (rev 187121)
@@ -4,14 +4,20 @@
Forwards
Both
Both iterating
+Both reverse alternate
+Ease function
PASS - start of animation - id: a expected: 100 actual: 100
PASS - start of animation - id: b expected: 200 actual: 200
PASS - start of animation - id: c expected: 100 actual: 100
PASS - start of animation - id: d expected: 200 actual: 200
PASS - start of animation - id: e expected: 200 actual: 200
-PASS - end of animation - id: a expected: 100 actual: 100
-PASS - end of animation - id: b expected: 100 actual: 100
-PASS - end of animation - id: c expected: 300 actual: 300
-PASS - end of animation - id: d expected: 300 actual: 300
-PASS - end of animation - id: e expected: 300 actual: 300
+PASS - start of animation - id: f expected: 300 actual: 300
+PASS - start of animation - id: g expected: 300 actual: 300
+PASS - end of animation - id: a close to expected: 100
+PASS - end of animation - id: b close to expected: 100
+PASS - end of animation - id: c close to expected: 225
+PASS - end of animation - id: d close to expected: 225
+PASS - end of animation - id: e close to expected: 225
+PASS - end of animation - id: f close to expected: 275
+PASS - end of animation - id: g close to expected: 291
Modified: trunk/LayoutTests/animations/fill-mode-iteration-count-non-integer.html (187120 => 187121)
--- trunk/LayoutTests/animations/fill-mode-iteration-count-non-integer.html 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/animations/fill-mode-iteration-count-non-integer.html 2015-07-21 21:19:20 UTC (rev 187121)
@@ -10,10 +10,10 @@
position: relative;
left: 100px;
top: 10px;
- height: 100px;
+ height: 25px;
width: 100px;
-webkit-animation-delay: 0.1s;
- -webkit-animation-duration: 0.2s;
+ -webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: anim;
}
@@ -34,19 +34,32 @@
#c {
background-color: green;
-webkit-animation-fill-mode: forwards;
- -webkit-animation-iteration-count: 1.5;
+ -webkit-animation-iteration-count: 1.25;
}
#d {
background-color: yellow;
-webkit-animation-fill-mode: both;
- -webkit-animation-iteration-count: 1.5;
+ -webkit-animation-iteration-count: 1.25;
}
#e {
- background-color: #999;
+ background-color: gray;
-webkit-animation-fill-mode: both;
- -webkit-animation-iteration-count: 2.5;
+ -webkit-animation-iteration-count: 2.25;
-webkit-animation-direction: alternate;
}
+ #f {
+ background-color: silver;
+ -webkit-animation-fill-mode: both;
+ -webkit-animation-iteration-count: 2.25;
+ -webkit-animation-direction: alternate-reverse;
+ }
+ #g {
+ background-color: orange;
+ -webkit-animation-fill-mode: both;
+ -webkit-animation-iteration-count: 2.25;
+ -webkit-animation-timing-function: ease-out;
+ -webkit-animation-direction: alternate-reverse;
+ }
</style>
<script type="text/_javascript_" charset="utf-8">
const numAnims = 5;
@@ -55,9 +68,11 @@
const expectedValues = [
{id: "a", start: 100, end: 100},
{id: "b", start: 200, end: 100},
- {id: "c", start: 100, end: 300},
- {id: "d", start: 200, end: 300},
- {id: "e", start: 200, end: 300}
+ {id: "c", start: 100, end: 225},
+ {id: "d", start: 200, end: 225},
+ {id: "e", start: 200, end: 225},
+ {id: "f", start: 300, end: 275},
+ {id: "g", start: 300, end: 291}
];
var result = "";
@@ -80,11 +95,10 @@
var expectedValue = expectedValues[i].end;
var realValue = window.getComputedStyle(el).getPropertyCSSValue("left").getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
if (Math.abs(expectedValue - realValue) < allowance) {
- result += "PASS";
+ result += "PASS - end of animation - id: " + expectedValues[i].id + " close to expected: " + expectedValue + "<br>";
} else {
- result += "FAIL";
+ result += "FAIL - end of animation - id: " + expectedValues[i].id + " expected: " + expectedValue + " actual: " + realValue + "<br>";
}
- result += " - end of animation - id: " + expectedValues[i].id + " expected: " + expectedValue + " actual: " + realValue + "<br>";
}
document.getElementById('result').innerHTML = result;
@@ -128,6 +142,12 @@
<div id="e" class="box">
Both iterating
</div>
+<div id="f" class="box">
+ Both reverse alternate
+</div>
+<div id="g" class="box">
+ Ease function
+</div>
<div id="result">
</div>
</body>
Modified: trunk/LayoutTests/animations/fill-mode-reverse-expected.txt (187120 => 187121)
--- trunk/LayoutTests/animations/fill-mode-reverse-expected.txt 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/animations/fill-mode-reverse-expected.txt 2015-07-21 21:19:20 UTC (rev 187121)
@@ -11,7 +11,7 @@
PASS - start of animation - id: e expected: 200 actual: 200
PASS - end of animation - id: a expected: 100 actual: 100
PASS - end of animation - id: b expected: 100 actual: 100
-PASS - end of animation - id: c expected: 300 actual: 300
-PASS - end of animation - id: d expected: 300 actual: 300
+PASS - end of animation - id: c expected: 200 actual: 200
+PASS - end of animation - id: d expected: 200 actual: 200
PASS - end of animation - id: e expected: 200 actual: 200
Modified: trunk/LayoutTests/animations/fill-mode-reverse.html (187120 => 187121)
--- trunk/LayoutTests/animations/fill-mode-reverse.html 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/LayoutTests/animations/fill-mode-reverse.html 2015-07-21 21:19:20 UTC (rev 187121)
@@ -39,7 +39,7 @@
-webkit-animation-fill-mode: both;
}
#e {
- background-color: #999;
+ background-color: gray;
-webkit-animation-fill-mode: both;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
@@ -52,8 +52,8 @@
const expectedValues = [
{id: "a", start: 100, end: 100},
{id: "b", start: 300, end: 100},
- {id: "c", start: 100, end: 300},
- {id: "d", start: 300, end: 300},
+ {id: "c", start: 100, end: 200},
+ {id: "d", start: 300, end: 200},
{id: "e", start: 200, end: 200}
];
var result = "";
Modified: trunk/Source/WebCore/ChangeLog (187120 => 187121)
--- trunk/Source/WebCore/ChangeLog 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/Source/WebCore/ChangeLog 2015-07-21 21:19:20 UTC (rev 187121)
@@ -1,3 +1,29 @@
+2015-07-21 Simon Fraser <[email protected]>
+
+ Safari mis-applies "animation-fill-mode: forwards" when using fractional iteration count
+ https://bugs.webkit.org/show_bug.cgi?id=146996
+
+ Reviewed by Dean Jackson.
+
+ animation-fill-mode: forwards with fractional iteration counts always snapped to
+ 1 or 0, depending on direction. Fix to compute the fill-forward state from the
+ correct keyframes.
+
+ If filling forwards, AnimationBase::progress() sets the elapsed time to the duration,
+ then uses fractionalTime() to handle animation direction mapping. If the fractionalTime
+ is integral, we can return early, avoiding the cost of mapping through timing functions.
+
+ Tested by existing tests.
+
+ * page/animation/AnimationBase.cpp:
+ (WebCore::AnimationBase::progress):
+ (WebCore::AnimationBase::getElapsedTime):
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::fetchIntervalEndpointsForProperty): It was possible
+ to end up with prevIndex == nextIndex with reverse animations, which resulted
+ in divide-by-zero when computing scale. Fix by picking a nextIndex that is different
+ from prevIndex.
+
2015-07-21 David Hyatt <[email protected]>
Fix failing WK1 layout tests. Make sure to reset the text zoom scale
Modified: trunk/Source/WebCore/page/animation/AnimationBase.cpp (187120 => 187121)
--- trunk/Source/WebCore/page/animation/AnimationBase.cpp 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/Source/WebCore/page/animation/AnimationBase.cpp 2015-07-21 21:19:20 UTC (rev 187121)
@@ -618,23 +618,25 @@
if (preActive())
return 0;
+ if (postActive() || !m_animation->duration())
+ return 1.0;
+
double elapsedTime = getElapsedTime();
double duration = m_animation->duration();
if (m_animation->iterationCount() > 0)
duration *= m_animation->iterationCount();
- if (postActive() || !m_animation->duration())
- return 1.0;
+ if (fillingForwards())
+ elapsedTime = duration;
+ double fractionalTime = this->fractionalTime(scale, elapsedTime, offset);
+
if (m_animation->iterationCount() > 0 && elapsedTime >= duration) {
- const int integralIterationCount = static_cast<int>(m_animation->iterationCount());
- const bool iterationCountHasFractional = m_animation->iterationCount() - integralIterationCount;
- return (integralIterationCount % 2 || iterationCountHasFractional) ? 1.0 : 0.0;
+ if (WTF::isIntegral(fractionalTime))
+ return fractionalTime;
}
- const double fractionalTime = this->fractionalTime(scale, elapsedTime, offset);
-
if (!timingFunction)
timingFunction = m_animation->timingFunction().get();
@@ -740,7 +742,7 @@
return m_pauseTime - m_startTime;
if (m_startTime <= 0)
return 0;
- if (postActive())
+ if (postActive() || fillingForwards())
return 1;
return beginAnimationUpdateTime() - m_startTime;
Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp (187120 => 187121)
--- trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp 2015-07-21 20:57:06 UTC (rev 187120)
+++ trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp 2015-07-21 21:19:20 UTC (rev 187121)
@@ -106,9 +106,16 @@
if (prevIndex == -1)
prevIndex = 0;
- if (nextIndex == -1)
- nextIndex = m_keyframes.size() - 1;
+ if (nextIndex == -1) {
+ int lastIndex = m_keyframes.size() - 1;
+ if (prevIndex == lastIndex)
+ nextIndex = 0;
+ else
+ nextIndex = lastIndex;
+ }
+ ASSERT(prevIndex != nextIndex);
+
const KeyframeValue& prevKeyframe = m_keyframes[prevIndex];
const KeyframeValue& nextKeyframe = m_keyframes[nextIndex];