Index: third_party/WebKit/Source/core/animation/CustomCompositorAnimations.cpp |
diff --git a/third_party/WebKit/Source/core/animation/CustomCompositorAnimations.cpp b/third_party/WebKit/Source/core/animation/CustomCompositorAnimations.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..00aac4028b4ce439a04940f39105b1c545b2c14b |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/animation/CustomCompositorAnimations.cpp |
@@ -0,0 +1,88 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "CustomCompositorAnimations.h" |
+ |
+#include "core/animation/Animation.h" |
+#include "core/animation/AnimationTimeline.h" |
+#include "core/animation/KeyframeEffect.h" |
+#include "core/animation/KeyframeEffectModel.h" |
+#include "core/animation/animatable/AnimatableDouble.h" |
+#include "core/animation/animatable/AnimatableTransform.h" |
+#include "core/animation/animatable/AnimatableValue.h" |
+#include "platform/TraceEvent.h" |
+#include "platform/graphics/CompositorMutation.h" |
+#include "platform/transforms/Matrix3DTransformOperation.h" |
+#include "platform/transforms/MatrixTransformOperation.h" |
+#include "platform/transforms/TransformOperations.h" |
+ |
+namespace blink { |
+ |
+namespace { |
+ |
+// Create keyframe effect with zero duration, fill mode forward, and two key |
+// frames with same value. This corresponding animation is always running and by |
+// updating the key frames we are able to control the applied value. |
+static KeyframeEffect* createInfiniteKeyFrameEffect(Element& element, CSSPropertyID propertyId, PassRefPtr<AnimatableValue> value) |
+{ |
+ AnimatableValueKeyframeVector keyframes(2); |
+ keyframes[0] = AnimatableValueKeyframe::create(); |
+ keyframes[0]->setOffset(0.0); |
+ keyframes[0]->setPropertyValue(propertyId, value.get()); |
+ keyframes[1] = AnimatableValueKeyframe::create(); |
+ keyframes[1]->setOffset(1.0); |
+ keyframes[1]->setPropertyValue(propertyId, value.get()); |
+ keyframes[1]->setComposite(EffectModel::CompositeReplace); |
+ |
+ Timing timing; |
+ timing.iterationDuration = 0; |
+ timing.fillMode = Timing::FillModeForwards; |
+ |
+ AnimatableValueKeyframeEffectModel* effectModel = AnimatableValueKeyframeEffectModel::create(keyframes); |
+ return KeyframeEffect::create(&element, effectModel, timing); |
+} |
+ |
+static KeyframeEffect* updateInfiniteKeyframeEffect(const KeyframeEffect& keyframeEffect, CSSPropertyID propertyId, PassRefPtr<AnimatableValue> value) |
+{ |
+ const KeyframeVector& oldFrames = toAnimatableValueKeyframeEffectModel(keyframeEffect.model())->getFrames(); |
+ AnimatableValueKeyframeVector keyframes(2); |
+ keyframes[0] = toAnimatableValueKeyframe(oldFrames[0]->clone().get()); |
+ keyframes[1] = toAnimatableValueKeyframe(oldFrames[1]->clone().get()); |
+ keyframes[0]->setPropertyValue(propertyId, value.get()); |
+ keyframes[1]->setPropertyValue(propertyId, value.get()); |
+ |
+ AnimatableValueKeyframeEffectModel* effectModel = AnimatableValueKeyframeEffectModel::create(keyframes); |
+ return KeyframeEffect::create(keyframeEffect.target(), effectModel, keyframeEffect.specifiedTiming()); |
+} |
+ |
+static Animation* createOrUpdateAnimation(Animation* animation, Element& element, CSSPropertyID propertyId, PassRefPtr<AnimatableValue> newValue) |
+{ |
+ if (!animation) { |
+ KeyframeEffect* keyframeEffect = createInfiniteKeyFrameEffect(element, propertyId, newValue); |
+ return element.document().timeline().play(keyframeEffect); |
+ } |
+ KeyframeEffect* keyframeEffect = updateInfiniteKeyframeEffect(*toKeyframeEffect(animation->effect()), propertyId, newValue); |
+ animation->setEffect(keyframeEffect); |
+ return animation; |
+} |
+ |
+} // namespace |
+ |
+void CustomCompositorAnimations::applyUpdate(Element& element, const CompositorMutation& mutation) |
+{ |
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), "CustomCompositorAnimations::applyUpdate"); |
+ |
+ if (mutation.isOpacityMutated()) { |
+ RefPtr<AnimatableValue> animatableValue = AnimatableDouble::create(mutation.opacity()); |
+ m_animation = createOrUpdateAnimation(m_animation, element, CSSPropertyOpacity, animatableValue.release()); |
+ } |
+ if (mutation.isTransformMutated()) { |
+ TransformOperations ops; |
+ ops.operations().append(Matrix3DTransformOperation::create(TransformationMatrix(mutation.transform()))); |
+ RefPtr<AnimatableValue> animatableValue = AnimatableTransform::create(ops, 1); |
+ m_animation = createOrUpdateAnimation(m_animation, element, CSSPropertyTransform, animatableValue.release()); |
+ } |
+} |
+ |
+} // namespace blink |