Commit bbc1223b authored by timloh@chromium.org's avatar timloh@chromium.org

Web Animations: Sort Animations in the AnimationStack

This patch sorts animations in the stack so that they will be applied in the
correct order. Note that due to the way compositor integration currently is
implemented, we don't know the exact time when new animations will be started,
but expect it will be very close to the current timeline time.

http://dev.w3.org/fxtf/web-animations/#the-animation-stack

BUG=

Review URL: https://codereview.chromium.org/210703002

git-svn-id: svn://svn.chromium.org/blink/trunk@170257 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent bc3f0c91
...@@ -56,13 +56,13 @@ AnimationPlayer::AnimationPlayer(DocumentTimeline& timeline, TimedItem* content) ...@@ -56,13 +56,13 @@ AnimationPlayer::AnimationPlayer(DocumentTimeline& timeline, TimedItem* content)
, m_startTime(nullValue()) , m_startTime(nullValue())
, m_holdTime(nullValue()) , m_holdTime(nullValue())
, m_storedTimeLag(0) , m_storedTimeLag(0)
, m_sortInfo(nextSequenceNumber(), timeline.effectiveTime())
, m_content(content) , m_content(content)
, m_timeline(&timeline) , m_timeline(&timeline)
, m_paused(false) , m_paused(false)
, m_held(false) , m_held(false)
, m_isPausedForTesting(false) , m_isPausedForTesting(false)
, m_outdated(false) , m_outdated(false)
, m_sequenceNumber(nextSequenceNumber())
{ {
if (m_content) { if (m_content) {
if (m_content->player()) if (m_content->player())
...@@ -93,10 +93,7 @@ double AnimationPlayer::currentTimeWithoutLag() const ...@@ -93,10 +93,7 @@ double AnimationPlayer::currentTimeWithoutLag() const
{ {
if (isNull(m_startTime) || !m_timeline) if (isNull(m_startTime) || !m_timeline)
return 0; return 0;
double timelineTime = m_timeline->currentTime(); return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate;
if (isNull(timelineTime))
timelineTime = 0;
return (timelineTime - m_startTime) * m_playbackRate;
} }
double AnimationPlayer::currentTimeWithLag() const double AnimationPlayer::currentTimeWithLag() const
...@@ -157,6 +154,7 @@ void AnimationPlayer::setStartTime(double newStartTime) ...@@ -157,6 +154,7 @@ void AnimationPlayer::setStartTime(double newStartTime)
return; return;
updateCurrentTimingState(); // Update the value of held updateCurrentTimingState(); // Update the value of held
m_startTime = newStartTime; m_startTime = newStartTime;
m_sortInfo.m_startTime = newStartTime;
if (m_held) if (m_held)
return; return;
updateCurrentTimingState(); updateCurrentTimingState();
...@@ -314,15 +312,14 @@ void AnimationPlayer::cancel() ...@@ -314,15 +312,14 @@ void AnimationPlayer::cancel()
m_content = nullptr; m_content = nullptr;
} }
bool AnimationPlayer::hasLowerPriority(AnimationPlayer* player1, AnimationPlayer* player2) bool AnimationPlayer::SortInfo::operator<(const SortInfo& other) const
{ {
if (player1->m_startTime < player2->m_startTime) ASSERT(!std::isnan(m_startTime) && !std::isnan(other.m_startTime));
if (m_startTime < other.m_startTime)
return true; return true;
if (player1->m_startTime > player2->m_startTime) if (m_startTime > other.m_startTime)
return false; return false;
if (isNull(player1->m_startTime) != isNull(player2->m_startTime)) return m_sequenceNumber < other.m_sequenceNumber;
return isNull(player1->m_startTime);
return player1->m_sequenceNumber < player2->m_sequenceNumber;
} }
void AnimationPlayer::pauseForTesting(double pauseTime) void AnimationPlayer::pauseForTesting(double pauseTime)
......
...@@ -97,7 +97,25 @@ public: ...@@ -97,7 +97,25 @@ public:
void cancelAnimationOnCompositor(); void cancelAnimationOnCompositor();
bool hasActiveAnimationsOnCompositor(); bool hasActiveAnimationsOnCompositor();
static bool hasLowerPriority(AnimationPlayer*, AnimationPlayer*); class SortInfo {
public:
friend class AnimationPlayer;
bool operator<(const SortInfo& other) const;
private:
SortInfo(unsigned sequenceNumber, double startTime)
: m_sequenceNumber(sequenceNumber)
, m_startTime(startTime)
{ }
unsigned m_sequenceNumber;
double m_startTime;
};
const SortInfo& sortInfo() const { return m_sortInfo; }
static bool hasLowerPriority(AnimationPlayer* player1, AnimationPlayer* player2)
{
return player1->sortInfo() < player2->sortInfo();
}
private: private:
AnimationPlayer(DocumentTimeline&, TimedItem*); AnimationPlayer(DocumentTimeline&, TimedItem*);
...@@ -113,6 +131,8 @@ private: ...@@ -113,6 +131,8 @@ private:
double m_holdTime; double m_holdTime;
double m_storedTimeLag; double m_storedTimeLag;
SortInfo m_sortInfo;
RefPtr<TimedItem> m_content; RefPtr<TimedItem> m_content;
// FIXME: We should keep the timeline alive and have this as non-null // FIXME: We should keep the timeline alive and have this as non-null
// but this is tricky to do without Oilpan // but this is tricky to do without Oilpan
...@@ -125,8 +145,6 @@ private: ...@@ -125,8 +145,6 @@ private:
// This indicates timing information relevant to the player has changed by // This indicates timing information relevant to the player has changed by
// means other than the ordinary progression of time // means other than the ordinary progression of time
bool m_outdated; bool m_outdated;
unsigned m_sequenceNumber;
}; };
} // namespace } // namespace
......
...@@ -694,7 +694,8 @@ TEST_F(AnimationAnimationPlayerTest, AttachedAnimationPlayers) ...@@ -694,7 +694,8 @@ TEST_F(AnimationAnimationPlayerTest, AttachedAnimationPlayers)
TEST_F(AnimationAnimationPlayerTest, HasLowerPriority) TEST_F(AnimationAnimationPlayerTest, HasLowerPriority)
{ {
// Note that start time defaults to null // Sort time defaults to timeline current time
updateTimeline(15);
RefPtr<AnimationPlayer> player1 = timeline->createAnimationPlayer(0); RefPtr<AnimationPlayer> player1 = timeline->createAnimationPlayer(0);
RefPtr<AnimationPlayer> player2 = timeline->createAnimationPlayer(0); RefPtr<AnimationPlayer> player2 = timeline->createAnimationPlayer(0);
player2->setStartTime(10); player2->setStartTime(10);
...@@ -706,11 +707,11 @@ TEST_F(AnimationAnimationPlayerTest, HasLowerPriority) ...@@ -706,11 +707,11 @@ TEST_F(AnimationAnimationPlayerTest, HasLowerPriority)
RefPtr<AnimationPlayer> player6 = timeline->createAnimationPlayer(0); RefPtr<AnimationPlayer> player6 = timeline->createAnimationPlayer(0);
player6->setStartTime(-10); player6->setStartTime(-10);
Vector<RefPtr<AnimationPlayer> > players; Vector<RefPtr<AnimationPlayer> > players;
players.append(player1);
players.append(player3);
players.append(player6); players.append(player6);
players.append(player2); players.append(player2);
players.append(player5); players.append(player5);
players.append(player1);
players.append(player3);
players.append(player4); players.append(player4);
for (size_t i = 0; i < players.size(); i++) { for (size_t i = 0; i < players.size(); i++) {
for (size_t j = 0; j < players.size(); j++) for (size_t j = 0; j < players.size(); j++)
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include "config.h" #include "config.h"
#include "core/animation/AnimationStack.h" #include "core/animation/AnimationStack.h"
#include "core/animation/Interpolation.h"
#include "core/animation/Interpolation.h"
#include "core/animation/css/CSSAnimations.h" #include "core/animation/css/CSSAnimations.h"
namespace WebCore { namespace WebCore {
...@@ -47,6 +47,22 @@ void copyToActiveInterpolationMap(const WillBeHeapVector<RefPtrWillBeMember<WebC ...@@ -47,6 +47,22 @@ void copyToActiveInterpolationMap(const WillBeHeapVector<RefPtrWillBeMember<WebC
} }
} }
bool compareAnimations(Animation* animation1, Animation* animation2)
{
ASSERT(animation1->player() && animation2->player());
return AnimationPlayer::hasLowerPriority(animation1->player(), animation2->player());
}
void copyNewAnimationsToActiveInterpolationMap(const Vector<InertAnimation*>& newAnimations, WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& result)
{
for (size_t i = 0; i < newAnimations.size(); ++i) {
OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample = newAnimations[i]->sample();
if (sample) {
copyToActiveInterpolationMap(*sample, result);
}
}
}
} // namespace } // namespace
bool AnimationStack::affects(CSSPropertyID property) const bool AnimationStack::affects(CSSPropertyID property) const
...@@ -67,30 +83,31 @@ bool AnimationStack::hasActiveAnimationsOnCompositor(CSSPropertyID property) con ...@@ -67,30 +83,31 @@ bool AnimationStack::hasActiveAnimationsOnCompositor(CSSPropertyID property) con
return false; return false;
} }
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > AnimationStack::activeInterpolations(const AnimationStack* animationStack, const Vector<InertAnimation*>* newAnimations, const HashSet<const AnimationPlayer*>* cancelledAnimationPlayers, Animation::Priority priority) WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > AnimationStack::activeInterpolations(AnimationStack* animationStack, const Vector<InertAnimation*>* newAnimations, const HashSet<const AnimationPlayer*>* cancelledAnimationPlayers, Animation::Priority priority, double timelineCurrentTime)
{ {
// We don't exactly know when new animations will start, but timelineCurrentTime is a good estimate.
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result; WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result;
if (animationStack) { if (animationStack) {
const Vector<Animation*>& animations = animationStack->m_activeAnimations; Vector<Animation*>& animations = animationStack->m_activeAnimations;
std::sort(animations.begin(), animations.end(), compareAnimations);
for (size_t i = 0; i < animations.size(); ++i) { for (size_t i = 0; i < animations.size(); ++i) {
Animation* animation = animations[i]; Animation* animation = animations[i];
if (animation->priority() != priority) if (animation->priority() != priority)
continue; continue;
if (cancelledAnimationPlayers && cancelledAnimationPlayers->contains(animation->player())) if (cancelledAnimationPlayers && cancelledAnimationPlayers->contains(animation->player()))
continue; continue;
if (animation->player()->startTime() > timelineCurrentTime && newAnimations) {
copyNewAnimationsToActiveInterpolationMap(*newAnimations, result);
newAnimations = 0;
}
copyToActiveInterpolationMap(animation->activeInterpolations(), result); copyToActiveInterpolationMap(animation->activeInterpolations(), result);
} }
} }
if (newAnimations) { if (newAnimations)
for (size_t i = 0; i < newAnimations->size(); ++i) { copyNewAnimationsToActiveInterpolationMap(*newAnimations, result);
OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample = newAnimations->at(i)->sample();
if (sample) {
copyToActiveInterpolationMap(*sample, result);
}
}
}
return result; return result;
} }
......
...@@ -53,7 +53,7 @@ public: ...@@ -53,7 +53,7 @@ public:
bool isEmpty() const { return m_activeAnimations.isEmpty(); } bool isEmpty() const { return m_activeAnimations.isEmpty(); }
bool affects(CSSPropertyID) const; bool affects(CSSPropertyID) const;
bool hasActiveAnimationsOnCompositor(CSSPropertyID) const; bool hasActiveAnimationsOnCompositor(CSSPropertyID) const;
static WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolations(const AnimationStack*, const Vector<InertAnimation*>* newAnimations, const HashSet<const AnimationPlayer*>* cancelledAnimationPlayers, Animation::Priority); static WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolations(AnimationStack*, const Vector<InertAnimation*>* newAnimations, const HashSet<const AnimationPlayer*>* cancelledAnimationPlayers, Animation::Priority, double timelineCurrentTime);
private: private:
Vector<Animation*> m_activeAnimations; Vector<Animation*> m_activeAnimations;
......
// Copyright 2014 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 "config.h"
#include "core/animation/AnimationStack.h"
#include "core/animation/ActiveAnimations.h"
#include "core/animation/AnimatableDouble.h"
#include "core/animation/AnimationClock.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/KeyframeEffectModel.h"
#include <gtest/gtest.h>
using namespace WebCore;
namespace {
class AnimationAnimationStackTest : public ::testing::Test {
protected:
virtual void SetUp()
{
document = Document::create();
document->animationClock().resetTimeForTesting();
timeline = DocumentTimeline::create(document.get());
timeline->setZeroTime(0);
element = document->createElement("foo", ASSERT_NO_EXCEPTION);
}
AnimationPlayer* play(Animation* animation, double startTime)
{
AnimationPlayer* player = timeline->createAnimationPlayer(animation);
player->setStartTime(startTime);
player->update();
return player;
}
PassRefPtrWillBeRawPtr<AnimationEffect> makeAnimationEffect(CSSPropertyID id, PassRefPtrWillBeRawPtr<AnimatableValue> value)
{
KeyframeEffectModel::KeyframeVector keyframes(2);
keyframes[0] = Keyframe::create();
keyframes[0]->setOffset(0.0);
keyframes[0]->setPropertyValue(id, value.get());
keyframes[1] = Keyframe::create();
keyframes[1]->setOffset(1.0);
keyframes[1]->setPropertyValue(id, value.get());
return KeyframeEffectModel::create(keyframes);
}
PassRefPtr<InertAnimation> makeInertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect)
{
Timing timing;
timing.fillMode = Timing::FillModeBoth;
return InertAnimation::create(effect, timing, false);
}
PassRefPtr<Animation> makeAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect)
{
Timing timing;
timing.fillMode = Timing::FillModeBoth;
return Animation::create(element, effect, timing);
}
AnimatableValue* interpolationValue(Interpolation* interpolation)
{
return toLegacyStyleInterpolation(interpolation)->currentValue();
}
RefPtr<Document> document;
RefPtr<DocumentTimeline> timeline;
RefPtr<Element> element;
};
TEST_F(AnimationAnimationStackTest, ActiveAnimationsSorted)
{
play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 10);
play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(2))).get(), 15);
play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3))).get(), 5);
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0);
EXPECT_EQ(1u, result.size());
EXPECT_TRUE(interpolationValue(result.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(2).get()));
}
TEST_F(AnimationAnimationStackTest, NewAnimations)
{
play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 15);
play(makeAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(2))).get(), 10);
Vector<InertAnimation*> newAnimations;
RefPtr<InertAnimation> inert1 = makeInertAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3)));
RefPtr<InertAnimation> inert2 = makeInertAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(4)));
newAnimations.append(inert1.get());
newAnimations.append(inert2.get());
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), &newAnimations, 0, Animation::DefaultPriority, 10);
EXPECT_EQ(2u, result.size());
EXPECT_TRUE(interpolationValue(result.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(1).get()));
EXPECT_TRUE(interpolationValue(result.get(CSSPropertyZIndex))->equals(AnimatableDouble::create(4).get()));
}
TEST_F(AnimationAnimationStackTest, CancelledAnimationPlayers)
{
HashSet<const AnimationPlayer*> cancelledAnimationPlayers;
cancelledAnimationPlayers.add(play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 0));
play(makeAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(2))).get(), 0);
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, &cancelledAnimationPlayers, Animation::DefaultPriority, 0);
EXPECT_EQ(1u, result.size());
EXPECT_TRUE(interpolationValue(result.get(CSSPropertyZIndex))->equals(AnimatableDouble::create(2).get()));
}
}
...@@ -80,7 +80,7 @@ AnimationPlayer* DocumentTimeline::createAnimationPlayer(TimedItem* child) ...@@ -80,7 +80,7 @@ AnimationPlayer* DocumentTimeline::createAnimationPlayer(TimedItem* child)
AnimationPlayer* DocumentTimeline::play(TimedItem* child) AnimationPlayer* DocumentTimeline::play(TimedItem* child)
{ {
AnimationPlayer* player = createAnimationPlayer(child); AnimationPlayer* player = createAnimationPlayer(child);
player->setStartTime(currentTime()); player->setStartTime(effectiveTime());
return player; return player;
} }
...@@ -151,6 +151,12 @@ double DocumentTimeline::currentTime() ...@@ -151,6 +151,12 @@ double DocumentTimeline::currentTime()
return m_document->animationClock().currentTime() - m_zeroTime; return m_document->animationClock().currentTime() - m_zeroTime;
} }
double DocumentTimeline::effectiveTime()
{
double time = currentTime();
return std::isnan(time) ? 0 : time;
}
void DocumentTimeline::pauseAnimationsForTesting(double pauseTime) void DocumentTimeline::pauseAnimationsForTesting(double pauseTime)
{ {
for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it) for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
......
...@@ -81,6 +81,7 @@ public: ...@@ -81,6 +81,7 @@ public:
bool hasPendingUpdates() const { return !m_playersNeedingUpdate.isEmpty(); } bool hasPendingUpdates() const { return !m_playersNeedingUpdate.isEmpty(); }
double zeroTime() const { return m_zeroTime; } double zeroTime() const { return m_zeroTime; }
double currentTime(); double currentTime();
double effectiveTime();
void pauseAnimationsForTesting(double); void pauseAnimationsForTesting(double);
size_t numberOfActiveAnimationsForTesting() const; size_t numberOfActiveAnimationsForTesting() const;
......
...@@ -323,9 +323,9 @@ PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Elemen ...@@ -323,9 +323,9 @@ PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Elemen
{ {
OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = adoptPtrWillBeNoop(new CSSAnimationUpdate()); OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = adoptPtrWillBeNoop(new CSSAnimationUpdate());
calculateAnimationUpdate(update.get(), element, parentElement, style, parentStyle, resolver); calculateAnimationUpdate(update.get(), element, parentElement, style, parentStyle, resolver);
calculateAnimationActiveInterpolations(update.get(), element); calculateAnimationActiveInterpolations(update.get(), element, parentElement.document().timeline().currentTime());
calculateTransitionUpdate(update.get(), element, style); calculateTransitionUpdate(update.get(), element, style);
calculateTransitionActiveInterpolations(update.get(), element); calculateTransitionActiveInterpolations(update.get(), element, parentElement.document().transitionTimeline().currentTime());
return update->isEmpty() ? nullptr : update.release(); return update->isEmpty() ? nullptr : update.release();
} }
...@@ -652,13 +652,13 @@ void CSSAnimations::cancel() ...@@ -652,13 +652,13 @@ void CSSAnimations::cancel()
m_pendingUpdate = nullptr; m_pendingUpdate = nullptr;
} }
void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* update, const Element* element) void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* update, const Element* element, double timelineCurrentTime)
{ {
ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0; ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0; AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimationPlayers().isEmpty()) { if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimationPlayers().isEmpty()) {
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::DefaultPriority)); WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::DefaultPriority, timelineCurrentTime));
update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations); update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
return; return;
} }
...@@ -669,18 +669,18 @@ void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u ...@@ -669,18 +669,18 @@ void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u
for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = animations.begin(); animationsIter != animations.end(); ++animationsIter) for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = animations.begin(); animationsIter != animations.end(); ++animationsIter)
newAnimations.append(animationsIter->get()); newAnimations.append(animationsIter->get());
} }
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority)); WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority, timelineCurrentTime));
update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations); update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
} }
void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* update, const Element* element) void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* update, const Element* element, double timelineCurrentTime)
{ {
ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0; ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0; AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForTransitions; WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForTransitions;
if (update->newTransitions().isEmpty() && update->cancelledTransitions().isEmpty()) { if (update->newTransitions().isEmpty() && update->cancelledTransitions().isEmpty()) {
activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::TransitionPriority); activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::TransitionPriority, timelineCurrentTime);
} else { } else {
Vector<InertAnimation*> newTransitions; Vector<InertAnimation*> newTransitions;
for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter) for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter)
...@@ -696,7 +696,7 @@ void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* ...@@ -696,7 +696,7 @@ void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate*
} }
} }
activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, &newTransitions, &cancelledAnimationPlayers, Animation::TransitionPriority); activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, &newTransitions, &cancelledAnimationPlayers, Animation::TransitionPriority, timelineCurrentTime);
} }
// Properties being animated by animations don't get values from transitions applied. // Properties being animated by animations don't get values from transitions applied.
......
...@@ -200,8 +200,8 @@ private: ...@@ -200,8 +200,8 @@ private:
static void calculateTransitionUpdate(CSSAnimationUpdate*, const Element*, const RenderStyle&); static void calculateTransitionUpdate(CSSAnimationUpdate*, const Element*, const RenderStyle&);
static void calculateTransitionUpdateForProperty(CSSPropertyID, const CSSAnimationData*, const RenderStyle& oldStyle, const RenderStyle&, const TransitionMap* activeTransitions, CSSAnimationUpdate*, const Element*); static void calculateTransitionUpdateForProperty(CSSPropertyID, const CSSAnimationData*, const RenderStyle& oldStyle, const RenderStyle&, const TransitionMap* activeTransitions, CSSAnimationUpdate*, const Element*);
static void calculateAnimationActiveInterpolations(CSSAnimationUpdate*, const Element*); static void calculateAnimationActiveInterpolations(CSSAnimationUpdate*, const Element*, double timelineCurrentTime);
static void calculateTransitionActiveInterpolations(CSSAnimationUpdate*, const Element*); static void calculateTransitionActiveInterpolations(CSSAnimationUpdate*, const Element*, double timelineCurrentTime);
class AnimationEventDelegate FINAL : public TimedItem::EventDelegate { class AnimationEventDelegate FINAL : public TimedItem::EventDelegate {
public: public:
......
...@@ -3268,6 +3268,7 @@ ...@@ -3268,6 +3268,7 @@
'animation/AnimatableValueTestHelperTest.cpp', 'animation/AnimatableValueTestHelperTest.cpp',
'animation/AnimationClockTest.cpp', 'animation/AnimationClockTest.cpp',
'animation/AnimationHelpersTest.cpp', 'animation/AnimationHelpersTest.cpp',
'animation/AnimationStackTest.cpp',
'animation/AnimationTest.cpp', 'animation/AnimationTest.cpp',
'animation/AnimationTestHelper.cpp', 'animation/AnimationTestHelper.cpp',
'animation/AnimationTestHelper.h', 'animation/AnimationTestHelper.h',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment