Commit 3d5534bf authored by timloh@chromium.org's avatar timloh@chromium.org

Web Animations: Sort Players in DocumentTimeline::serviceAnimations

This patch makes Animations get serviced in the order specified by the
spec[1]. This means that once custom effect are implemented, they will
be queued up in the correct order. This also gets us closer to having
the animation stack in a correct order (I'm thinking of emptying the
stack after getting out the compositable values, as we traverse the
animations in the correct order).

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

BUG=334936

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

git-svn-id: svn://svn.chromium.org/blink/trunk@168597 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 0d93f811
......@@ -95,15 +95,19 @@ void DocumentTimeline::serviceAnimations()
m_timing->cancelWake();
double timeToNextEffect = std::numeric_limits<double>::infinity();
Vector<Player*> playersToRemove;
for (HashSet<RefPtr<Player> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it) {
Player* player = it->get();
if (!player->update())
playersToRemove.append(player);
timeToNextEffect = std::min(timeToNextEffect, player->timeToEffectChange());
Vector<Player*> players;
for (HashSet<RefPtr<Player> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
players.append(it->get());
std::sort(players.begin(), players.end(), Player::hasLowerPriority);
for (size_t i = 0; i < players.size(); ++i) {
Player* player = players[i];
if (player->update())
timeToNextEffect = std::min(timeToNextEffect, player->timeToEffectChange());
else
m_playersNeedingUpdate.remove(player);
}
for (size_t i = 0; i < playersToRemove.size(); ++i)
m_playersNeedingUpdate.remove(playersToRemove[i]);
ASSERT(!m_playersNeedingUpdate.isEmpty() || timeToNextEffect == std::numeric_limits<double>::infinity());
if (timeToNextEffect < s_minimumDelay)
......
......@@ -36,6 +36,16 @@
namespace WebCore {
namespace {
static unsigned nextSequenceNumber()
{
static unsigned next = 0;
return ++next;
}
}
PassRefPtr<Player> Player::create(DocumentTimeline& timeline, TimedItem* content)
{
return adoptRef(new Player(timeline, content));
......@@ -52,6 +62,7 @@ Player::Player(DocumentTimeline& timeline, TimedItem* content)
, m_held(false)
, m_isPausedForTesting(false)
, m_outdated(false)
, m_sequenceNumber(nextSequenceNumber())
{
if (m_content) {
if (m_content->player())
......@@ -299,6 +310,17 @@ void Player::cancel()
m_content = nullptr;
}
bool Player::hasLowerPriority(Player* player1, Player* player2)
{
if (player1->m_startTime < player2->m_startTime)
return true;
if (player1->m_startTime > player2->m_startTime)
return false;
if (isNull(player1->m_startTime) != isNull(player2->m_startTime))
return isNull(player1->m_startTime);
return player1->m_sequenceNumber < player2->m_sequenceNumber;
}
void Player::pauseForTesting(double pauseTime)
{
RELEASE_ASSERT(!paused());
......
......@@ -96,6 +96,8 @@ public:
void cancelAnimationOnCompositor();
bool hasActiveAnimationsOnCompositor();
static bool hasLowerPriority(Player*, Player*);
private:
Player(DocumentTimeline&, TimedItem*);
double sourceEnd() const;
......@@ -121,6 +123,8 @@ private:
// This indicates timing information relevant to the player has changed
bool m_outdated;
unsigned m_sequenceNumber;
};
} // namespace
......
......@@ -679,4 +679,30 @@ TEST_F(AnimationPlayerTest, AttachedPlayers)
EXPECT_TRUE(element->activeAnimations()->players().isEmpty());
}
TEST_F(AnimationPlayerTest, HasLowerPriority)
{
// Note that start time defaults to null
RefPtr<Player> player1 = timeline->createPlayer(0);
RefPtr<Player> player2 = timeline->createPlayer(0);
player2->setStartTime(10);
RefPtr<Player> player3 = timeline->createPlayer(0);
RefPtr<Player> player4 = timeline->createPlayer(0);
player4->setStartTime(20);
RefPtr<Player> player5 = timeline->createPlayer(0);
player5->setStartTime(10);
RefPtr<Player> player6 = timeline->createPlayer(0);
player6->setStartTime(-10);
Vector<RefPtr<Player> > players;
players.append(player1);
players.append(player3);
players.append(player6);
players.append(player2);
players.append(player5);
players.append(player4);
for (size_t i = 0; i < players.size(); i++) {
for (size_t j = 0; j < players.size(); j++)
EXPECT_EQ(i < j, Player::hasLowerPriority(players[i].get(), players[j].get()));
}
}
}
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