Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(988)

Unified Diff: Source/core/frame/animation/KeyframeAnimation.cpp

Issue 139273007: Web Animations: Remove legacy animations engine. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix TestExpectations. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/frame/animation/KeyframeAnimation.h ('k') | Source/core/rendering/CompositedLayerMapping.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/frame/animation/KeyframeAnimation.cpp
diff --git a/Source/core/frame/animation/KeyframeAnimation.cpp b/Source/core/frame/animation/KeyframeAnimation.cpp
deleted file mode 100644
index 948ca03ce42a6223c549d875860d56af61678db6..0000000000000000000000000000000000000000
--- a/Source/core/frame/animation/KeyframeAnimation.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2007, 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/animation/KeyframeAnimation.h"
-
-#include "CSSPropertyNames.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/UseCounter.h"
-#include "core/frame/animation/AnimationControllerPrivate.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-#include "core/frame/animation/CompositeAnimation.h"
-#include "core/rendering/RenderBoxModelObject.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "public/platform/Platform.h"
-
-using namespace std;
-
-namespace WebCore {
-
-KeyframeAnimation::KeyframeAnimation(const CSSAnimationData* animation, RenderObject& renderer, int index, CompositeAnimation* compAnim, RenderStyle& unanimatedStyle)
- : AnimationBase(animation, renderer, compAnim)
- , m_keyframes(renderer, animation->name())
- , m_index(index)
- , m_startEventDispatched(false)
- , m_unanimatedStyle(unanimatedStyle)
-{
- // Get the keyframe RenderStyles
- if (m_object && m_object->node() && m_object->node()->isElementNode())
- m_object->document().ensureStyleResolver().keyframeStylesForAnimation(toElement(m_object->node()), unanimatedStyle, m_keyframes);
-
- // Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
- validateTransformFunctionList();
- checkForMatchingFilterFunctionLists();
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it)
- blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(*it));
-}
-
-KeyframeAnimation::~KeyframeAnimation()
-{
- // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
- if (!postActive())
- endAnimation();
-}
-
-void KeyframeAnimation::fetchIntervalEndpointsForProperty(CSSPropertyID property, const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
-{
- // Find the first key
- double elapsedTime = getElapsedTime();
- if (m_animation->duration() && m_animation->iterationCount() != CSSAnimationData::IterationCountInfinite)
- elapsedTime = min(elapsedTime, m_animation->duration() * m_animation->iterationCount());
-
- const double fractionalTime = this->fractionalTime(1, elapsedTime, 0);
-
- size_t numKeyframes = m_keyframes.size();
- if (!numKeyframes)
- return;
-
- ASSERT(!m_keyframes[0].key());
- ASSERT(m_keyframes[m_keyframes.size() - 1].key() == 1);
-
- size_t currentIndex = 0;
- size_t firstIndex = 0;
- size_t lastIndex = numKeyframes - 1;
- size_t distance = numKeyframes;
-
- // Find keyframe that is closest to elapsed time.
- while (distance > 1) {
- currentIndex = (lastIndex + firstIndex) >> 1;
- double key = m_keyframes[currentIndex].key();
- distance = lastIndex - currentIndex;
-
- if (key < fractionalTime) {
- if (distance < 2)
- currentIndex++;
- firstIndex = currentIndex;
- } else {
- lastIndex = currentIndex;
- }
- }
-
- int prevIndex = -1;
- int nextIndex = -1;
-
- // Iterate forward to find next keyframe that is used to animate CSS property.
- for (size_t i = currentIndex; i < numKeyframes; ++i) {
- const KeyframeValue& keyFrame = m_keyframes[i];
- if (keyFrame.key() > fractionalTime && keyFrame.containsProperty(property)) {
- nextIndex = i;
- break;
- }
- }
-
- // Iterate backward to find previous keyframe.
- for (int i = currentIndex; i >= 0; --i) {
- const KeyframeValue& keyFrame = m_keyframes[i];
- if (keyFrame.key() <= fractionalTime && keyFrame.containsProperty(property)) {
- prevIndex = i;
- break;
- }
- }
-
- double scale = 1;
- double offset = 0;
-
- if (prevIndex == -1)
- prevIndex = 0;
-
- if (nextIndex == -1)
- nextIndex = numKeyframes - 1;
-
- const KeyframeValue& prevKeyframe = m_keyframes[prevIndex];
- const KeyframeValue& nextKeyframe = m_keyframes[nextIndex];
-
- fromStyle = prevKeyframe.style();
- toStyle = nextKeyframe.style();
-
- offset = prevKeyframe.key();
- scale = 1.0 / (nextKeyframe.key() - prevKeyframe.key());
- // A scale of infinity is handled in AnimationBase::fractionalTime().
- ASSERT(scale >= 0 && (!std::isinf(scale) || prevIndex == nextIndex));
-
- prog = progress(scale, offset, KeyframeValue::timingFunction(*prevKeyframe.style()));
-}
-
-void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
-{
- // Fire the start timeout if needed
- fireAnimationEventsIfNeeded();
-
- // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
- if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
- updateStateMachine(AnimationStateInputStartAnimation, -1);
-
- // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
- // If so, we need to send back the targetStyle.
- if (postActive()) {
- if (!animatedStyle)
- animatedStyle = const_cast<RenderStyle*>(targetStyle);
- return;
- }
-
- // If we are waiting for the start timer, we don't want to change the style yet.
- // Special case 1 - if the delay time is 0, then we do want to set the first frame of the
- // animation right away. This avoids a flash when the animation starts.
- // Special case 2 - if there is a backwards fill mode, then we want to continue
- // through to the style blend so that we get the fromStyle.
- if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
- return;
-
- // If we have no keyframes, don't animate.
- if (!m_keyframes.size()) {
- updateStateMachine(AnimationStateInputEndAnimation, -1);
- return;
- }
-
- // Run a cycle of animation.
- // We know we will need a new render style, so make one if needed.
- if (!animatedStyle)
- animatedStyle = RenderStyle::clone(targetStyle);
-
- // FIXME: we need to be more efficient about determining which keyframes we are animating between.
- // We should cache the last pair or something.
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- // Get the from/to styles and progress between
- const RenderStyle* fromStyle = 0;
- const RenderStyle* toStyle = 0;
- double progress = 0.0;
- fetchIntervalEndpointsForProperty(*it, fromStyle, toStyle, progress);
-
- bool needsAnim = CSSPropertyAnimation::blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
- if (!needsAnim)
- // If we are running an accelerated animation, set a flag in the style
- // to indicate it. This can be used to make sure we get an updated
- // style for hit testing, etc.
- animatedStyle->setIsRunningAcceleratedAnimation();
- }
-}
-
-void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
-{
- // If we're in the delay phase and we're not backwards filling, tell the caller
- // to use the current style.
- if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
- return;
-
- if (!m_keyframes.size())
- return;
-
- if (!animatedStyle)
- animatedStyle = RenderStyle::clone(m_object->style());
-
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- // Get the from/to styles and progress between
- const RenderStyle* fromStyle = 0;
- const RenderStyle* toStyle = 0;
- double progress = 0.0;
- fetchIntervalEndpointsForProperty(*it, fromStyle, toStyle, progress);
-
- CSSPropertyAnimation::blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
- }
-}
-
-bool KeyframeAnimation::hasAnimationForProperty(CSSPropertyID property) const
-{
- return m_keyframes.containsProperty(property);
-}
-
-void KeyframeAnimation::startAnimation(double timeOffset)
-{
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking)
- m_isAccelerated = toRenderBoxModelObject(m_object)->startAnimation(timeOffset, m_animation.get(), m_keyframes);
-}
-
-void KeyframeAnimation::pauseAnimation(double timeOffset)
-{
- if (!m_object)
- return;
-
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- toRenderBoxModelObject(m_object)->animationPaused(timeOffset, m_keyframes.animationName());
-
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
-}
-
-void KeyframeAnimation::endAnimation()
-{
- if (!m_object)
- return;
-
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- toRenderBoxModelObject(m_object)->animationFinished(m_keyframes.animationName());
- m_isAccelerated = false;
-
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
-}
-
-bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const
-{
- return m_object->document().hasListenerType(listenerType);
-}
-
-void KeyframeAnimation::onAnimationStart(double elapsedTime)
-{
- sendAnimationEvent(EventTypeNames::animationstart, elapsedTime);
-}
-
-void KeyframeAnimation::onAnimationIteration(double elapsedTime)
-{
- sendAnimationEvent(EventTypeNames::animationiteration, elapsedTime);
-}
-
-void KeyframeAnimation::onAnimationEnd(double elapsedTime)
-{
- sendAnimationEvent(EventTypeNames::animationend, elapsedTime);
- // End the animation if we don't fill forwards. Forward filling
- // animations are ended properly in the class destructor.
- if (!m_animation->fillsForwards())
- endAnimation();
-}
-
-bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
-{
- Document::ListenerType listenerType;
- if (eventType == EventTypeNames::animationiteration)
- listenerType = Document::ANIMATIONITERATION_LISTENER;
- else if (eventType == EventTypeNames::animationend)
- listenerType = Document::ANIMATIONEND_LISTENER;
- else {
- ASSERT(eventType == EventTypeNames::animationstart);
- if (m_startEventDispatched)
- return false;
- m_startEventDispatched = true;
- listenerType = Document::ANIMATIONSTART_LISTENER;
- }
-
- if (shouldSendEventForListener(listenerType)) {
- // Dispatch the event
- RefPtr<Element> element;
- if (m_object->node() && m_object->node()->isElementNode())
- element = toElement(m_object->node());
-
- if (!element)
- return false;
-
- // Schedule event handling
- m_compAnim->animationController()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
-
- // Restore the original (unanimated) style
- if (eventType == EventTypeNames::animationend && element->renderer())
- setNeedsStyleRecalc(element.get());
-
- return true; // Did dispatch an event
- }
-
- return false; // Did not dispatch an event
-}
-
-void KeyframeAnimation::overrideAnimations()
-{
- // This will override implicit animations that match the properties in the keyframe animation
- HashSet<CSSPropertyID>::const_iterator end = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
- compositeAnimation()->overrideImplicitAnimations(*it);
-}
-
-void KeyframeAnimation::resumeOverriddenAnimations()
-{
- // This will resume overridden implicit animations
- HashSet<CSSPropertyID>::const_iterator end = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
- compositeAnimation()->resumeOverriddenImplicitAnimations(*it);
-}
-
-bool KeyframeAnimation::affectsProperty(CSSPropertyID property) const
-{
- return m_keyframes.containsProperty(property);
-}
-
-void KeyframeAnimation::validateTransformFunctionList()
-{
- m_transformFunctionListValid = false;
-
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitTransform))
- return;
-
- // Empty transforms match anything, so find the first non-empty entry as the reference
- size_t numKeyframes = m_keyframes.size();
- size_t firstNonEmptyTransformKeyframeIndex = numKeyframes;
-
- for (size_t i = 0; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- if (currentKeyframe.style()->transform().operations().size()) {
- firstNonEmptyTransformKeyframeIndex = i;
- break;
- }
- }
-
- if (firstNonEmptyTransformKeyframeIndex == numKeyframes)
- return;
-
- const TransformOperations* firstVal = &m_keyframes[firstNonEmptyTransformKeyframeIndex].style()->transform();
-
- // See if the keyframes are valid
- for (size_t i = firstNonEmptyTransformKeyframeIndex + 1; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- const TransformOperations* val = &currentKeyframe.style()->transform();
-
- // An emtpy transform list matches anything.
- if (val->operations().isEmpty())
- continue;
-
- if (!firstVal->operationsMatch(*val))
- return;
- }
-
- // Keyframes are valid
- m_transformFunctionListValid = true;
-}
-
-void KeyframeAnimation::checkForMatchingFilterFunctionLists()
-{
- m_filterFunctionListsMatch = false;
-
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitFilter))
- return;
-
- // Empty filters match anything, so find the first non-empty entry as the reference
- size_t numKeyframes = m_keyframes.size();
- size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
-
- for (size_t i = 0; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- if (currentKeyframe.style()->filter().operations().size()) {
- firstNonEmptyFilterKeyframeIndex = i;
- break;
- }
- }
-
- if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
- return;
-
- const FilterOperations* firstVal = &m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->filter();
-
- for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- const FilterOperations* val = &currentKeyframe.style()->filter();
-
- if (!firstVal->canInterpolateWith(*val))
- return;
- }
-
- m_filterFunctionListsMatch = true;
-}
-
-double KeyframeAnimation::timeToNextService()
-{
- double t = AnimationBase::timeToNextService();
- if (t != 0 || preActive())
- return t;
-
- // A return value of 0 means we need service. But if we only have accelerated animations we
- // only need service at the end of the transition
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- bool acceleratedPropertiesOnly = true;
-
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(*it) || !isAccelerated()) {
- acceleratedPropertiesOnly = false;
- break;
- }
- }
-
- if (acceleratedPropertiesOnly) {
- bool isLooping;
- getTimeToNextEvent(t, isLooping);
- }
-
- return t;
-}
-
-} // namespace WebCore
« no previous file with comments | « Source/core/frame/animation/KeyframeAnimation.h ('k') | Source/core/rendering/CompositedLayerMapping.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698