diff options
Diffstat (limited to 'Source/WebCore/page/animation/ImplicitAnimation.cpp')
-rw-r--r-- | Source/WebCore/page/animation/ImplicitAnimation.cpp | 165 |
1 files changed, 98 insertions, 67 deletions
diff --git a/Source/WebCore/page/animation/ImplicitAnimation.cpp b/Source/WebCore/page/animation/ImplicitAnimation.cpp index af1d78819..924eb4b35 100644 --- a/Source/WebCore/page/animation/ImplicitAnimation.cpp +++ b/Source/WebCore/page/animation/ImplicitAnimation.cpp @@ -10,7 +10,7 @@ * 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 + * 3. Neither the name of Apple 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. * @@ -27,24 +27,24 @@ */ #include "config.h" +#include "ImplicitAnimation.h" -#include "AnimationControllerPrivate.h" +#include "CSSAnimationControllerPrivate.h" #include "CSSPropertyAnimation.h" #include "CompositeAnimation.h" #include "EventNames.h" -#include "ImplicitAnimation.h" +#include "GeometryUtilities.h" #include "KeyframeAnimation.h" -#include "RenderBoxModelObject.h" +#include "RenderBox.h" +#include "StylePendingResources.h" namespace WebCore { -ImplicitAnimation::ImplicitAnimation(const Animation& transition, CSSPropertyID animatingProperty, RenderElement* renderer, CompositeAnimation* compAnim, RenderStyle* fromStyle) +ImplicitAnimation::ImplicitAnimation(const Animation& transition, CSSPropertyID animatingProperty, RenderElement* renderer, CompositeAnimation* compAnim, const RenderStyle* fromStyle) : AnimationBase(transition, renderer, compAnim) + , m_fromStyle(RenderStyle::clonePtr(*fromStyle)) , m_transitionProperty(transition.property()) , m_animatingProperty(animatingProperty) - , m_overridden(false) - , m_active(true) - , m_fromStyle(fromStyle) { ASSERT(animatingProperty != CSSPropertyInvalid); } @@ -61,12 +61,14 @@ bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inList return m_object->document().hasListenerType(inListenerType); } -void ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) +bool ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const RenderStyle*, const RenderStyle* targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle) { // If we get this far and the animation is done, it means we are cleaning up a just finished animation. // So just return. Everything is already all cleaned up. if (postActive()) - return; + return false; + + AnimationState oldState = state(); // Reset to start the transition if we are new if (isNew()) @@ -75,40 +77,64 @@ void ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const Rende // 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); + animatedStyle = RenderStyle::clonePtr(*targetStyle); -#if USE(ACCELERATED_COMPOSITING) - bool needsAnim = CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); + CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress()); // FIXME: we also need to detect cases where we have to software animate for other reasons, // such as a child using inheriting the transform. https://bugs.webkit.org/show_bug.cgi?id=23902 - if (!needsAnim) - // If we are running an accelerated animation, set a flag in the style which causes the style - // to compare as different to any other style. This ensures that changes to the property - // that is animating are correctly detected during the animation (e.g. when a transition - // gets interrupted). - animatedStyle->setIsRunningAcceleratedAnimation(); -#endif // Fire the start timeout if needed fireAnimationEventsIfNeeded(); + + didBlendStyle = true; + return state() != oldState; } -void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) +void ImplicitAnimation::getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle) { if (!animatedStyle) - animatedStyle = RenderStyle::clone(m_toStyle.get()); + animatedStyle = RenderStyle::clonePtr(*m_toStyle); + + CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress()); +} + +bool ImplicitAnimation::computeExtentOfTransformAnimation(LayoutRect& bounds) const +{ + ASSERT(hasStyle()); + + if (!is<RenderBox>(m_object)) + return true; // Non-boxes don't get transformed; - CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); + ASSERT(m_animatingProperty == CSSPropertyTransform); + + RenderBox& box = downcast<RenderBox>(*m_object); + FloatRect rendererBox = snapRectToDevicePixels(box.borderBoxRect(), box.document().deviceScaleFactor()); + + LayoutRect startBounds = bounds; + LayoutRect endBounds = bounds; + + if (transformFunctionListsMatch()) { + if (!computeTransformedExtentViaTransformList(rendererBox, *m_fromStyle, startBounds)) + return false; + + if (!computeTransformedExtentViaTransformList(rendererBox, *m_toStyle, endBounds)) + return false; + } else { + if (!computeTransformedExtentViaMatrix(rendererBox, *m_fromStyle, startBounds)) + return false; + + if (!computeTransformedExtentViaMatrix(rendererBox, *m_toStyle, endBounds)) + return false; + } + + bounds = unionRect(startBounds, endBounds); + return true; } bool ImplicitAnimation::startAnimation(double timeOffset) { -#if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->isComposited()) - return toRenderBoxModelObject(m_object)->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get()); -#else - UNUSED_PARAM(timeOffset); -#endif + return downcast<RenderBoxModelObject>(*m_object).startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get()); return false; } @@ -117,12 +143,8 @@ void ImplicitAnimation::pauseAnimation(double timeOffset) if (!m_object) return; -#if USE(ACCELERATED_COMPOSITING) if (m_object->isComposited()) - toRenderBoxModelObject(m_object)->transitionPaused(timeOffset, m_animatingProperty); -#else - UNUSED_PARAM(timeOffset); -#endif + downcast<RenderBoxModelObject>(*m_object).transitionPaused(timeOffset, m_animatingProperty); // Restore the original (unanimated) style if (!paused()) setNeedsStyleRecalc(m_object->element()); @@ -130,10 +152,8 @@ void ImplicitAnimation::pauseAnimation(double timeOffset) void ImplicitAnimation::endAnimation() { -#if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->isComposited()) - toRenderBoxModelObject(m_object)->transitionFinished(m_animatingProperty); -#endif + downcast<RenderBoxModelObject>(*m_object).transitionFinished(m_animatingProperty); } void ImplicitAnimation::onAnimationEnd(double elapsedTime) @@ -143,10 +163,9 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime) // running. But now that the transition has completed, we need to update this style with its new // destination. If we didn't, the next time through we would think a transition had started // (comparing the old unanimated style with the new final style of the transition). - RefPtr<KeyframeAnimation> keyframeAnim = m_compAnim->getAnimationForProperty(m_animatingProperty); - if (keyframeAnim) - keyframeAnim->setUnanimatedStyle(m_toStyle); - + if (auto* animation = m_compositeAnimation->animationForProperty(m_animatingProperty)) + animation->setUnanimatedStyle(RenderStyle::clonePtr(*m_toStyle)); + sendTransitionEvent(eventNames().transitionendEvent, elapsedTime); endAnimation(); } @@ -162,12 +181,12 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl // Dispatch the event RefPtr<Element> element = m_object->element(); - ASSERT(!element || !element->document().inPageCache()); + ASSERT(!element || element->document().pageCacheState() == Document::NotInPageCache); if (!element) return false; // Schedule event handling - m_compAnim->animationController()->addEventToDispatch(element, eventType, propertyName, elapsedTime); + m_compositeAnimation->animationController().addEventToDispatch(*element, eventType, propertyName, elapsedTime); // Restore the original (unanimated) style if (eventType == eventNames().transitionendEvent && element->renderer()) @@ -180,21 +199,25 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl return false; // Didn't dispatch an event } -void ImplicitAnimation::reset(RenderStyle* to) +void ImplicitAnimation::reset(const RenderStyle* to) { ASSERT(to); ASSERT(m_fromStyle); - m_toStyle = to; + m_toStyle = RenderStyle::clonePtr(*to); + + if (m_object && m_object->element()) + Style::loadPendingResources(*m_toStyle, m_object->element()->document(), m_object->element()); // Restart the transition if (m_fromStyle && m_toStyle) - updateStateMachine(AnimationStateInputRestartAnimation, -1); + updateStateMachine(AnimationStateInput::RestartAnimation, -1); // set the transform animation list validateTransformFunctionList(); -#if ENABLE(CSS_FILTERS) checkForMatchingFilterFunctionLists(); +#if ENABLE(FILTERS_LEVEL_2) + checkForMatchingBackdropFilterFunctionLists(); #endif } @@ -204,7 +227,7 @@ void ImplicitAnimation::setOverridden(bool b) return; m_overridden = b; - updateStateMachine(m_overridden ? AnimationStateInputPauseOverride : AnimationStateInputResumeOverride, -1); + updateStateMachine(m_overridden ? AnimationStateInput::PauseOverride : AnimationStateInput::ResumeOverride, -1); } bool ImplicitAnimation::affectsProperty(CSSPropertyID property) const @@ -229,12 +252,12 @@ void ImplicitAnimation::blendPropertyValueInStyle(CSSPropertyID prop, RenderStyl if (!m_toStyle) return; - CSSPropertyAnimation::blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); + CSSPropertyAnimation::blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress()); } void ImplicitAnimation::validateTransformFunctionList() { - m_transformFunctionListValid = false; + m_transformFunctionListsMatch = false; if (!m_fromStyle || !m_toStyle) return; @@ -248,44 +271,53 @@ void ImplicitAnimation::validateTransformFunctionList() if (val->operations().isEmpty()) return; - // An emtpy transform list matches anything. + // An empty transform list matches anything. if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal)) return; // Transform lists match. - m_transformFunctionListValid = true; + m_transformFunctionListsMatch = true; +} + +static bool filterOperationsMatch(const FilterOperations* fromOperations, const FilterOperations& toOperations) +{ + if (fromOperations->operations().isEmpty()) + fromOperations = &toOperations; + + if (fromOperations->operations().isEmpty()) + return false; + + if (fromOperations != &toOperations && !toOperations.operations().isEmpty() && !fromOperations->operationsMatch(toOperations)) + return false; + + return true; } -#if ENABLE(CSS_FILTERS) void ImplicitAnimation::checkForMatchingFilterFunctionLists() { m_filterFunctionListsMatch = false; - + if (!m_fromStyle || !m_toStyle) return; - - const FilterOperations* val = &m_fromStyle->filter(); - const FilterOperations* toVal = &m_toStyle->filter(); - if (val->operations().isEmpty()) - val = toVal; + m_filterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->filter(), m_toStyle->filter()); +} - if (val->operations().isEmpty()) - return; - - // An emtpy filter list matches anything. - if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal)) +#if ENABLE(FILTERS_LEVEL_2) +void ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists() +{ + m_backdropFilterFunctionListsMatch = false; + + if (!m_fromStyle || !m_toStyle) return; - // Filter lists match. - m_filterFunctionListsMatch = true; + m_backdropFilterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->backdropFilter(), m_toStyle->backdropFilter()); } #endif double ImplicitAnimation::timeToNextService() { double t = AnimationBase::timeToNextService(); -#if USE(ACCELERATED_COMPOSITING) if (t != 0 || preActive()) return t; @@ -295,7 +327,6 @@ double ImplicitAnimation::timeToNextService() bool isLooping; getTimeToNextEvent(t, isLooping); } -#endif return t; } |