Modified: trunk/Source/WebCore/ChangeLog (251705 => 251706)
--- trunk/Source/WebCore/ChangeLog 2019-10-29 16:09:10 UTC (rev 251705)
+++ trunk/Source/WebCore/ChangeLog 2019-10-29 16:14:58 UTC (rev 251706)
@@ -1,3 +1,29 @@
+2019-10-29 Antoine Quint <grao...@apple.com>
+
+ [Web Animations] Optimize blending for CSS Transitions
+ https://bugs.webkit.org/show_bug.cgi?id=203561
+
+ Reviewed by Simon Fraser.
+
+ The work performed in KeyframeEffect::setAnimatedPropertiesInStyle() has a level of complexity warranted by the
+ flexibility of how keyframes can be specified via the Web Animations JS API. However, in the case of CSS Transitions,
+ we already know that there are only two keyframes, one where offset=0 and one where offset=1, and that only a single
+ CSS property is specified so we can simplify the process greatly.
+
+ To ensure we only perform this quicker blending operation for keyframes computed for a CSS Transition and that no
+ modification to the keyframes have been applied via the Web Animations JS API after the fact, we now keep track
+ of whether the blending keyframes (KeyframeList) were generated for a CSS Transition or a CSS Animation and only
+ use this information to decide whether we're blending for declarative animations.
+
+ * animation/KeyframeEffect.cpp:
+ (WebCore::KeyframeEffect::processKeyframes):
+ (WebCore::KeyframeEffect::clearBlendingKeyframes):
+ (WebCore::KeyframeEffect::computeCSSAnimationBlendingKeyframes):
+ (WebCore::KeyframeEffect::computeCSSTransitionBlendingKeyframes):
+ (WebCore::KeyframeEffect::setTarget):
+ (WebCore::KeyframeEffect::setAnimatedPropertiesInStyle):
+ * animation/KeyframeEffect.h:
+
2019-10-29 Adrian Perez de Castro <ape...@igalia.com>
[GTK][WPE] Fix non-unified build after r251691
Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (251705 => 251706)
--- trunk/Source/WebCore/animation/KeyframeEffect.cpp 2019-10-29 16:09:10 UTC (rev 251705)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp 2019-10-29 16:14:58 UTC (rev 251706)
@@ -726,7 +726,7 @@
m_parsedKeyframes = WTFMove(parsedKeyframes);
- m_blendingKeyframes.clear();
+ clearBlendingKeyframes();
return { };
}
@@ -772,6 +772,13 @@
return true;
}
+
+void KeyframeEffect::clearBlendingKeyframes()
+{
+ m_blendingKeyframesSource = BlendingKeyframesSource::WebAnimation;
+ m_blendingKeyframes.clear();
+}
+
void KeyframeEffect::setBlendingKeyframes(KeyframeList& blendingKeyframes)
{
m_blendingKeyframes = WTFMove(blendingKeyframes);
@@ -909,6 +916,7 @@
Style::loadPendingResources(*style, m_target->document(), m_target.get());
}
+ m_blendingKeyframesSource = BlendingKeyframesSource::CSSAnimation;
setBlendingKeyframes(keyframeList);
}
@@ -936,6 +944,7 @@
toKeyframeValue.addProperty(property);
keyframeList.insert(WTFMove(toKeyframeValue));
+ m_blendingKeyframesSource = BlendingKeyframesSource::CSSTransition;
setBlendingKeyframes(keyframeList);
}
@@ -988,7 +997,7 @@
if (auto* effectAnimation = animation())
effectAnimation->effectTargetDidChange(previousTarget.get(), m_target.get());
- m_blendingKeyframes.clear();
+ clearBlendingKeyframes();
// We need to invalidate the effect now that the target has changed
// to ensure the effect's styles are applied to the new target right away.
@@ -1054,6 +1063,15 @@
void KeyframeEffect::setAnimatedPropertiesInStyle(RenderStyle& targetStyle, double iterationProgress)
{
+ // In the case of CSS Transitions we already know that there are only two keyframes, one where offset=0 and one where offset=1,
+ // and only a single CSS property so we can simply blend based on the style available on those keyframes with the provided iteration
+ // progress which already accounts for the transition's timing function.
+ if (m_blendingKeyframesSource == BlendingKeyframesSource::CSSTransition) {
+ ASSERT(is<CSSTransition>(animation()));
+ CSSPropertyAnimation::blendProperties(this, downcast<CSSTransition>(animation())->property(), &targetStyle, m_blendingKeyframes[0].style(), m_blendingKeyframes[1].style(), iterationProgress);
+ return;
+ }
+
// 4.4.3. The effect value of a keyframe effect
// https://drafts.csswg.org/web-animations-1/#the-effect-value-of-a-keyframe-animation-effect
//
@@ -1064,9 +1082,6 @@
if (m_blendingKeyframes.isEmpty())
return;
- bool isCSSAnimation = is<CSSAnimation>(animation());
- bool isCSSTransition = is<CSSTransition>(animation());
-
for (auto cssPropertyId : m_blendingKeyframes.properties()) {
// 1. If iteration progress is unresolved abort this procedure.
// 2. Let target property be the longhand property for which the effect value is to be calculated.
@@ -1085,7 +1100,7 @@
if (!keyframe.containsProperty(cssPropertyId)) {
// If we're dealing with a CSS animation, we consider the first and last keyframes to always have the property listed
// since the underlying style was provided and should be captured.
- if (!isCSSAnimation || (offset && offset < 1))
+ if (m_blendingKeyframesSource == BlendingKeyframesSource::WebAnimation || (offset && offset < 1))
continue;
}
if (!offset)
@@ -1184,10 +1199,8 @@
// 17. Let transformed distance be the result of evaluating the timing function associated with the first keyframe in interval endpoints
// passing interval distance as the input progress.
- // We do not need to do this for CSS Transitions since the timing function is applied to the AnimationEffect as a whole and thus
- // iterationProgress is already transformed.
auto transformedDistance = intervalDistance;
- if (!isCSSTransition && startKeyframeIndex) {
+ if (startKeyframeIndex) {
if (auto duration = iterationDuration()) {
auto rangeDuration = (endOffset - startOffset) * duration.seconds();
if (auto* timingFunction = timingFunctionForKeyframeAtIndex(startKeyframeIndex.value()))
Modified: trunk/Source/WebCore/animation/KeyframeEffect.h (251705 => 251706)
--- trunk/Source/WebCore/animation/KeyframeEffect.h 2019-10-29 16:09:10 UTC (rev 251705)
+++ trunk/Source/WebCore/animation/KeyframeEffect.h 2019-10-29 16:14:58 UTC (rev 251706)
@@ -141,6 +141,7 @@
KeyframeEffect(Element*);
enum class AcceleratedAction : uint8_t { Play, Pause, Seek, Stop };
+ enum class BlendingKeyframesSource : uint8_t { CSSAnimation, CSSTransition, WebAnimation };
void copyPropertiesFromSource(Ref<KeyframeEffect>&&);
ExceptionOr<void> processKeyframes(JSC::JSGlobalObject&, JSC::Strong<JSC::JSObject>&&);
@@ -151,6 +152,7 @@
Ref<const Animation> backingAnimationForCompositedRenderer() const;
void computedNeedsForcedLayout();
void computeStackingContextImpact();
+ void clearBlendingKeyframes();
void updateBlendingKeyframes(RenderStyle&);
void computeCSSAnimationBlendingKeyframes();
void computeCSSTransitionBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle);
@@ -170,6 +172,7 @@
RefPtr<Element> m_target;
AcceleratedAction m_lastRecordedAcceleratedAction { AcceleratedAction::Stop };
+ BlendingKeyframesSource m_blendingKeyframesSource { BlendingKeyframesSource::WebAnimation };
IterationCompositeOperation m_iterationCompositeOperation { IterationCompositeOperation::Replace };
CompositeOperation m_compositeOperation { CompositeOperation::Replace };
bool m_shouldRunAccelerated { false };