Index: Source/core/animation/CompositorAnimations.cpp |
diff --git a/Source/core/animation/CompositorAnimations.cpp b/Source/core/animation/CompositorAnimations.cpp |
index 09c6e4f0ce606cc9f39204bf39380a8c1f7d580c..ef863e50c13ceddcac82ceff818e9029bb8f419d 100644 |
--- a/Source/core/animation/CompositorAnimations.cpp |
+++ b/Source/core/animation/CompositorAnimations.cpp |
@@ -173,15 +173,18 @@ bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim |
if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, playerPlaybackRate)) |
return false; |
- if (timing.timingFunction->type() != TimingFunction::LinearFunction) { |
- // Checks the of size of KeyframeVector instead of PropertySpecificKeyframeVector. |
+ if (timing.timingFunction->type() == TimingFunction::CubicBezierFunction) { |
+ // FIXME: Fix compositor timing functions to accept inputs outside of |
+ // [0,1]. |
+ const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(*timing.timingFunction); |
const KeyframeVector& keyframes = keyframeEffect.getFrames(); |
- if (keyframes.size() == 2 && keyframes.first()->easing().type() == TimingFunction::LinearFunction) |
- return true; |
+ double startRange = 0; |
+ double endRange = 1; |
+ cubic.range(&startRange, &endRange); |
- // FIXME: Support non-linear timing functions in the compositor for |
- // more than two keyframes. |
- return false; |
+ ASSERT(keyframes.size() >= 2); |
+ if ((startRange < 0 || endRange > 1) && (keyframes.first()->easing().type() != TimingFunction::LinearFunction || keyframes[keyframes.size() - 2]->easing().type() != TimingFunction::LinearFunction)) |
+ return false; |
} |
return true; |
@@ -281,6 +284,58 @@ bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, |
namespace { |
+void getCubicBezierTimingFunctionParameters(const TimingFunction& timingFunction, bool& outCustom, |
+ WebCompositorAnimationCurve::TimingFunctionType& outEaseSubType, |
+ double& outX1, double& outY1, double& outX2, double& outY2) |
+{ |
+ const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timingFunction); |
+ outCustom = false; |
+ |
+ switch (cubic.subType()) { |
+ case CubicBezierTimingFunction::Ease: |
+ outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEase; |
+ break; |
+ case CubicBezierTimingFunction::EaseIn: |
+ outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEaseIn; |
+ break; |
+ case CubicBezierTimingFunction::EaseOut: |
+ outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEaseOut; |
+ break; |
+ case CubicBezierTimingFunction::EaseInOut: |
+ outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut; |
+ break; |
+ case CubicBezierTimingFunction::Custom: |
+ outCustom = true; |
+ outX1 = cubic.x1(); |
+ outY1 = cubic.y1(); |
+ outX2 = cubic.x2(); |
+ outY2 = cubic.y2(); |
+ break; |
+ default: |
+ ASSERT_NOT_REACHED(); |
+ } |
+} |
+ |
+void getStepsTimingFunctionParameters(const TimingFunction& timingFunction, int& outSteps, float& outStepsStartOffset) |
+{ |
+ const StepsTimingFunction& steps = toStepsTimingFunction(timingFunction); |
+ |
+ outSteps = steps.numberOfSteps(); |
+ switch (steps.stepAtPosition()) { |
+ case StepsTimingFunction::Start: |
+ outStepsStartOffset = 1; |
+ break; |
+ case StepsTimingFunction::Middle: |
+ outStepsStartOffset = 0.5; |
+ break; |
+ case StepsTimingFunction::End: |
+ outStepsStartOffset = 0; |
+ break; |
+ default: |
+ ASSERT_NOT_REACHED(); |
+ } |
+} |
+ |
template<typename PlatformAnimationCurveType, typename PlatformAnimationKeyframeType> |
void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const PlatformAnimationKeyframeType& keyframe, const TimingFunction* timingFunction) |
{ |
@@ -292,62 +347,74 @@ void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const Plat |
switch (timingFunction->type()) { |
case TimingFunction::LinearFunction: |
curve.add(keyframe, WebCompositorAnimationCurve::TimingFunctionTypeLinear); |
- return; |
+ break; |
case TimingFunction::CubicBezierFunction: { |
- const CubicBezierTimingFunction* cubic = toCubicBezierTimingFunction(timingFunction); |
+ bool custom; |
+ WebCompositorAnimationCurve::TimingFunctionType easeSubType; |
+ double x1, y1; |
+ double x2, y2; |
+ getCubicBezierTimingFunctionParameters(*timingFunction, custom, easeSubType, x1, y1, x2, y2); |
+ |
+ if (custom) |
+ curve.add(keyframe, x1, y1, x2, y2); |
+ else |
+ curve.add(keyframe, easeSubType); |
+ break; |
+ } |
- if (cubic->subType() == CubicBezierTimingFunction::Custom) { |
- curve.add(keyframe, cubic->x1(), cubic->y1(), cubic->x2(), cubic->y2()); |
- } else { |
+ case TimingFunction::StepsFunction: { |
+ int steps; |
+ float stepsStartOffset; |
+ getStepsTimingFunctionParameters(*timingFunction, steps, stepsStartOffset); |
- WebCompositorAnimationCurve::TimingFunctionType easeType; |
- switch (cubic->subType()) { |
- case CubicBezierTimingFunction::Ease: |
- easeType = WebCompositorAnimationCurve::TimingFunctionTypeEase; |
- break; |
- case CubicBezierTimingFunction::EaseIn: |
- easeType = WebCompositorAnimationCurve::TimingFunctionTypeEaseIn; |
- break; |
- case CubicBezierTimingFunction::EaseOut: |
- easeType = WebCompositorAnimationCurve::TimingFunctionTypeEaseOut; |
- break; |
- case CubicBezierTimingFunction::EaseInOut: |
- easeType = WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut; |
- break; |
+ curve.add(keyframe, steps, stepsStartOffset); |
+ break; |
+ } |
- // Custom Bezier are handled seperately. |
- case CubicBezierTimingFunction::Custom: |
- default: |
- ASSERT_NOT_REACHED(); |
- return; |
- } |
+ default: |
+ ASSERT_NOT_REACHED(); |
+ } |
+} |
- curve.add(keyframe, easeType); |
- } |
+template <typename PlatformAnimationCurveType> |
+void setTimingFunctionOnCurve(PlatformAnimationCurveType& curve, TimingFunction* timingFunction) |
+{ |
+ if (!timingFunction) { |
+ curve.setLinearTimingFunction(); |
return; |
} |
- case TimingFunction::StepsFunction: |
- const StepsTimingFunction* steps = toStepsTimingFunction(timingFunction); |
+ switch (timingFunction->type()) { |
+ case TimingFunction::LinearFunction: |
+ curve.setLinearTimingFunction(); |
+ break; |
+ |
+ case TimingFunction::CubicBezierFunction: { |
+ bool custom; |
+ WebCompositorAnimationCurve::TimingFunctionType easeSubType; |
+ double x1, y1; |
+ double x2, y2; |
+ getCubicBezierTimingFunctionParameters(*timingFunction, custom, easeSubType, x1, y1, x2, y2); |
+ |
+ if (custom) |
+ curve.setCubicBezierTimingFunction(x1, y1, x2, y2); |
+ else |
+ curve.setCubicBezierTimingFunction(easeSubType); |
+ break; |
+ } |
+ case TimingFunction::StepsFunction: { |
+ int steps; |
float stepsStartOffset; |
- switch (steps->stepAtPosition()) { |
- case StepsTimingFunction::Start: |
- stepsStartOffset = 1; |
- break; |
- case StepsTimingFunction::Middle: |
- stepsStartOffset = 0.5; |
- break; |
- case StepsTimingFunction::End: |
- stepsStartOffset = 0; |
- break; |
- default: |
- ASSERT_NOT_REACHED(); |
- return; |
- } |
- curve.add(keyframe, steps->numberOfSteps(), stepsStartOffset); |
- return; |
+ getStepsTimingFunctionParameters(*timingFunction, steps, stepsStartOffset); |
+ |
+ curve.setStepsTimingFunction(steps, stepsStartOffset); |
+ break; |
+ } |
+ |
+ default: |
+ ASSERT_NOT_REACHED(); |
} |
} |
@@ -359,10 +426,7 @@ void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& |
for (const auto& keyframe : keyframes) { |
const TimingFunction* keyframeTimingFunction = 0; |
if (keyframe != lastKeyframe) { // Ignore timing function of last frame. |
- if (keyframes.size() == 2 && keyframes.first()->easing().type() == TimingFunction::LinearFunction) |
- keyframeTimingFunction = timing.timingFunction.get(); |
- else |
- keyframeTimingFunction = &keyframe->easing(); |
+ keyframeTimingFunction = &keyframe->easing(); |
} |
// FIXME: This relies on StringKeyframes being eagerly evaluated, which will |
@@ -422,6 +486,7 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, in |
WebFloatAnimationCurve* floatCurve = Platform::current()->compositorSupport()->createFloatAnimationCurve(); |
addKeyframesToCurve(*floatCurve, values, timing); |
+ setTimingFunctionOnCurve(*floatCurve, timing.timingFunction.get()); |
curve = adoptPtr(floatCurve); |
break; |
} |
@@ -429,6 +494,7 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, in |
targetProperty = WebCompositorAnimation::TargetPropertyFilter; |
WebFilterAnimationCurve* filterCurve = Platform::current()->compositorSupport()->createFilterAnimationCurve(); |
addKeyframesToCurve(*filterCurve, values, timing); |
+ setTimingFunctionOnCurve(*filterCurve, timing.timingFunction.get()); |
curve = adoptPtr(filterCurve); |
break; |
} |
@@ -436,6 +502,7 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, in |
targetProperty = WebCompositorAnimation::TargetPropertyTransform; |
WebTransformAnimationCurve* transformCurve = Platform::current()->compositorSupport()->createTransformAnimationCurve(); |
addKeyframesToCurve(*transformCurve, values, timing); |
+ setTimingFunctionOnCurve(*transformCurve, timing.timingFunction.get()); |
curve = adoptPtr(transformCurve); |
break; |
} |