void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const KeyframeVector& keyframes, const TimingFunction& timingFunction) { for (size_t i = 0; i < keyframes.size(); i++) { const TimingFunction* keyframeTimingFunction = 0; if (i + 1 < keyframes.size()) { // Last keyframe has no timing function switch (timingFunction.type()) { case TimingFunction::LinearFunction: case TimingFunction::CubicBezierFunction: keyframeTimingFunction = &timingFunction; break; case TimingFunction::ChainedFunction: { const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction); // ChainedTimingFunction criteria was checked in isCandidate, // assert it is valid. ASSERT(keyframes.size() == chained.m_segments.size() + 1); keyframeTimingFunction = chained.m_segments[i].m_timingFunction.get(); break; } case TimingFunction::StepsFunction: default: ASSERT_NOT_REACHED(); } } ASSERT(!keyframes[i]->value()->dependsOnUnderlyingValue()); RefPtr<AnimatableValue> value = keyframes[i]->value()->compositeOnto(0); switch (curve.type()) { case blink::WebAnimationCurve::AnimationCurveTypeFilter: { OwnPtr<blink::WebFilterOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createFilterOperations()); bool converted = toWebFilterOperations(toAnimatableFilterOperations(value.get())->operations(), ops.get()); ASSERT_UNUSED(converted, converted); blink::WebFilterKeyframe filterKeyframe(keyframes[i]->offset(), ops.release()); blink::WebFilterAnimationCurve* filterCurve = static_cast<blink::WebFilterAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*filterCurve, filterKeyframe, keyframeTimingFunction); break; } case blink::WebAnimationCurve::AnimationCurveTypeFloat: { blink::WebFloatKeyframe floatKeyframe(keyframes[i]->offset(), toAnimatableDouble(value.get())->toDouble()); blink::WebFloatAnimationCurve* floatCurve = static_cast<blink::WebFloatAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*floatCurve, floatKeyframe, keyframeTimingFunction); break; } case blink::WebAnimationCurve::AnimationCurveTypeTransform: { OwnPtr<blink::WebTransformOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createTransformOperations()); toWebTransformOperations(toAnimatableTransform(value.get())->transformOperations(), FloatSize(), ops.get()); blink::WebTransformKeyframe transformKeyframe(keyframes[i]->offset(), ops.release()); blink::WebTransformAnimationCurve* transformCurve = static_cast<blink::WebTransformAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, keyframeTimingFunction); break; } default: ASSERT_NOT_REACHED(); } } }
TEST(AnimationTranslationUtilTest, filtersWork) { FilterOperations ops; WebFilterOperationsMock outOps; EXPECT_CALL(outOps, appendSaturateFilter(0.5)); EXPECT_CALL(outOps, appendGrayscaleFilter(0.2f)); EXPECT_CALL(outOps, appendSepiaFilter(0.8f)); EXPECT_CALL(outOps, appendOpacityFilter(0.1f)); ops.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE)); ops.operations().append(BasicColorMatrixFilterOperation::create(0.2, FilterOperation::GRAYSCALE)); ops.operations().append(BasicColorMatrixFilterOperation::create(0.8, FilterOperation::SEPIA)); ops.operations().append(BasicColorMatrixFilterOperation::create(0.1, FilterOperation::OPACITY)); toWebFilterOperations(ops, &outOps); }
void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing) { auto* lastKeyframe = keyframes.last().get(); for (const auto& keyframe : keyframes) { const TimingFunction* keyframeTimingFunction = 0; if (keyframe != lastKeyframe) { // Ignore timing function of last frame. keyframeTimingFunction = &keyframe->easing(); } // FIXME: This relies on StringKeyframes being eagerly evaluated, which will // not happen eventually. Instead we should extract the CSSValue here // and convert using another set of toAnimatableXXXOperations functions. const AnimatableValue* value = keyframe->getAnimatableValue().get(); switch (curve.type()) { case WebCompositorAnimationCurve::AnimationCurveTypeFilter: { OwnPtr<WebFilterOperations> ops = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); toWebFilterOperations(toAnimatableFilterOperations(value)->operations(), ops.get()); WebFilterKeyframe filterKeyframe(keyframe->offset(), ops.release()); WebFilterAnimationCurve* filterCurve = static_cast<WebFilterAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*filterCurve, filterKeyframe, keyframeTimingFunction); break; } case WebCompositorAnimationCurve::AnimationCurveTypeFloat: { WebFloatKeyframe floatKeyframe(keyframe->offset(), toAnimatableDouble(value)->toDouble()); WebFloatAnimationCurve* floatCurve = static_cast<WebFloatAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*floatCurve, floatKeyframe, keyframeTimingFunction); break; } case WebCompositorAnimationCurve::AnimationCurveTypeTransform: { OwnPtr<WebTransformOperations> ops = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations()); toWebTransformOperations(toAnimatableTransform(value)->transformOperations(), ops.get()); WebTransformKeyframe transformKeyframe(keyframe->offset(), ops.release()); WebTransformAnimationCurve* transformCurve = static_cast<WebTransformAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, keyframeTimingFunction); break; } default: ASSERT_NOT_REACHED(); } } }