| 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;
|
| }
|
|
|