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

Unified Diff: Source/core/animation/AnimationPlayer.cpp

Issue 1113173003: Web Animations: Update naming to reflect spec changes (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: No, really. Created 5 years, 7 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/animation/AnimationPlayer.h ('k') | Source/core/animation/AnimationPlayer.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/animation/AnimationPlayer.cpp
diff --git a/Source/core/animation/AnimationPlayer.cpp b/Source/core/animation/AnimationPlayer.cpp
deleted file mode 100644
index 99a947be0be39fd2838bd2cb755a7331076d2671..0000000000000000000000000000000000000000
--- a/Source/core/animation/AnimationPlayer.cpp
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*
- * Copyright (C) 2013 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
- * OWNER OR 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/animation/AnimationPlayer.h"
-
-#include "core/animation/Animation.h"
-#include "core/animation/AnimationTimeline.h"
-#include "core/dom/Document.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/events/AnimationPlayerEvent.h"
-#include "core/frame/UseCounter.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/InspectorTraceEvents.h"
-#include "platform/RuntimeEnabledFeatures.h"
-#include "platform/TraceEvent.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebCompositorAnimationPlayer.h"
-#include "public/platform/WebCompositorSupport.h"
-#include "wtf/MathExtras.h"
-
-namespace blink {
-
-namespace {
-
-static unsigned nextSequenceNumber()
-{
- static unsigned next = 0;
- return ++next;
-}
-
-}
-
-PassRefPtrWillBeRawPtr<AnimationPlayer> AnimationPlayer::create(AnimationNode* source, AnimationTimeline* timeline)
-{
- if (!timeline) {
- // FIXME: Support creating players without a timeline.
- return nullptr;
- }
-
- RefPtrWillBeRawPtr<AnimationPlayer> player = adoptRefWillBeNoop(new AnimationPlayer(timeline->document()->contextDocument().get(), *timeline, source));
- player->suspendIfNeeded();
-
- if (timeline) {
- timeline->playerAttached(*player);
- player->attachCompositorTimeline();
- }
-
- return player.release();
-}
-
-AnimationPlayer::AnimationPlayer(ExecutionContext* executionContext, AnimationTimeline& timeline, AnimationNode* content)
- : ActiveDOMObject(executionContext)
- , m_playState(Idle)
- , m_playbackRate(1)
- , m_startTime(nullValue())
- , m_holdTime(0)
- , m_sequenceNumber(nextSequenceNumber())
- , m_content(content)
- , m_timeline(&timeline)
- , m_paused(false)
- , m_held(true)
- , m_isPausedForTesting(false)
- , m_outdated(false)
- , m_finished(true)
- , m_compositorState(nullptr)
- , m_compositorPending(false)
- , m_compositorGroup(0)
- , m_currentTimePending(false)
- , m_stateIsBeingUpdated(false)
-{
- if (m_content) {
- if (m_content->player()) {
- m_content->player()->cancel();
- m_content->player()->setSource(0);
- }
- m_content->attach(this);
- }
-}
-
-AnimationPlayer::~AnimationPlayer()
-{
-#if !ENABLE(OILPAN)
- if (m_content)
- m_content->detach();
- if (m_timeline)
- m_timeline->playerDestroyed(this);
-#endif
-
- destroyCompositorPlayer();
-}
-
-#if !ENABLE(OILPAN)
-void AnimationPlayer::detachFromTimeline()
-{
- dispose();
- m_timeline = nullptr;
-}
-#endif
-
-double AnimationPlayer::sourceEnd() const
-{
- return m_content ? m_content->endTimeInternal() : 0;
-}
-
-bool AnimationPlayer::limited(double currentTime) const
-{
- return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && currentTime >= sourceEnd());
-}
-
-void AnimationPlayer::setCurrentTime(double newCurrentTime)
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- m_currentTimePending = false;
- setCurrentTimeInternal(newCurrentTime / 1000, TimingUpdateOnDemand);
-
- if (calculatePlayState() == Finished)
- m_startTime = calculateStartTime(newCurrentTime);
-}
-
-void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime, TimingUpdateReason reason)
-{
- ASSERT(std::isfinite(newCurrentTime));
-
- bool oldHeld = m_held;
- bool outdated = false;
- bool isLimited = limited(newCurrentTime);
- m_held = m_paused || !m_playbackRate || isLimited || std::isnan(m_startTime);
- if (m_held) {
- if (!oldHeld || m_holdTime != newCurrentTime)
- outdated = true;
- m_holdTime = newCurrentTime;
- if (m_paused || !m_playbackRate) {
- m_startTime = nullValue();
- } else if (isLimited && std::isnan(m_startTime) && reason == TimingUpdateForAnimationFrame) {
- m_startTime = calculateStartTime(newCurrentTime);
- }
- } else {
- m_holdTime = nullValue();
- m_startTime = calculateStartTime(newCurrentTime);
- m_finished = false;
- outdated = true;
- }
-
- if (outdated) {
- setOutdated();
- }
-}
-
-// Update timing to reflect updated animation clock due to tick
-void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason)
-{
- if (m_held) {
- double newCurrentTime = m_holdTime;
- if (playStateInternal() == Finished && !isNull(m_startTime) && m_timeline) {
- // Add hystersis due to floating point error accumulation
- if (!limited(calculateCurrentTime() + 0.001 * m_playbackRate)) {
- // The current time became unlimited, eg. due to a backwards
- // seek of the timeline.
- newCurrentTime = calculateCurrentTime();
- } else if (!limited(m_holdTime)) {
- // The hold time became unlimited, eg. due to the source content
- // becoming longer.
- newCurrentTime = clampTo<double>(calculateCurrentTime(), 0, sourceEnd());
- }
- }
- setCurrentTimeInternal(newCurrentTime, reason);
- } else if (limited(calculateCurrentTime())) {
- m_held = true;
- m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd();
- }
-}
-
-double AnimationPlayer::startTime(bool& isNull) const
-{
- double result = startTime();
- isNull = std::isnan(result);
- return result;
-}
-
-double AnimationPlayer::startTime() const
-{
- return m_startTime * 1000;
-}
-
-double AnimationPlayer::currentTime(bool& isNull)
-{
- double result = currentTime();
- isNull = std::isnan(result);
- return result;
-}
-
-double AnimationPlayer::currentTime()
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- if (m_currentTimePending || playStateInternal() == Idle)
- return std::numeric_limits<double>::quiet_NaN();
-
- return currentTimeInternal() * 1000;
-}
-
-double AnimationPlayer::currentTimeInternal() const
-{
- double result = m_held ? m_holdTime : calculateCurrentTime();
-#if ENABLE(ASSERT)
- const_cast<AnimationPlayer*>(this)->updateCurrentTimingState(TimingUpdateOnDemand);
- ASSERT(result == (m_held ? m_holdTime : calculateCurrentTime()));
-#endif
- return result;
-}
-
-double AnimationPlayer::unlimitedCurrentTimeInternal() const
-{
-#if ENABLE(ASSERT)
- currentTimeInternal();
-#endif
- return playStateInternal() == Paused || isNull(m_startTime)
- ? currentTimeInternal()
- : calculateCurrentTime();
-}
-
-void AnimationPlayer::preCommit(int compositorGroup, bool startOnCompositor)
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompositorPending);
-
- bool softChange = m_compositorState && (paused() || m_compositorState->playbackRate != m_playbackRate);
- bool hardChange = m_compositorState && (m_compositorState->sourceChanged || m_compositorState->startTime != m_startTime);
-
- // FIXME: softChange && !hardChange should generate a Pause/ThenStart,
- // not a Cancel, but we can't communicate these to the compositor yet.
-
- bool changed = softChange || hardChange;
- bool shouldCancel = (!playing() && m_compositorState) || changed;
- bool shouldStart = playing() && (!m_compositorState || changed);
-
- if (shouldCancel) {
- cancelAnimationOnCompositor();
- m_compositorState = nullptr;
- }
-
- if (m_compositorState && m_compositorState->pendingAction == Start) {
- // Still waiting for a start time.
- return;
- }
-
- ASSERT(!m_compositorState || !std::isnan(m_compositorState->startTime));
-
- if (!shouldStart) {
- m_currentTimePending = false;
- }
-
- if (shouldStart) {
- m_compositorGroup = compositorGroup;
- if (startOnCompositor) {
- if (isCandidateForAnimationOnCompositor())
- createCompositorPlayer();
-
- if (maybeStartAnimationOnCompositor())
- m_compositorState = adoptPtr(new CompositorState(*this));
- else
- cancelIncompatibleAnimationsOnCompositor();
- }
- }
-}
-
-void AnimationPlayer::postCommit(double timelineTime)
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompositorPending);
-
- m_compositorPending = false;
-
- if (!m_compositorState || m_compositorState->pendingAction == None)
- return;
-
- switch (m_compositorState->pendingAction) {
- case Start:
- if (!std::isnan(m_compositorState->startTime)) {
- ASSERT(m_startTime == m_compositorState->startTime);
- m_compositorState->pendingAction = None;
- }
- break;
- case Pause:
- case PauseThenStart:
- ASSERT(std::isnan(m_startTime));
- m_compositorState->pendingAction = None;
- setCurrentTimeInternal((timelineTime - m_compositorState->startTime) * m_playbackRate, TimingUpdateForAnimationFrame);
- m_currentTimePending = false;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-void AnimationPlayer::notifyCompositorStartTime(double timelineTime)
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, DoNotSetCompositorPending);
-
- if (m_compositorState) {
- ASSERT(m_compositorState->pendingAction == Start);
- ASSERT(std::isnan(m_compositorState->startTime));
-
- double initialCompositorHoldTime = m_compositorState->holdTime;
- m_compositorState->pendingAction = None;
- m_compositorState->startTime = timelineTime + currentTimeInternal() / -m_playbackRate;
-
- if (m_startTime == timelineTime) {
- // The start time was set to the incoming compositor start time.
- // Unlikely, but possible.
- // FIXME: Depending on what changed above this might still be pending.
- // Maybe...
- m_currentTimePending = false;
- return;
- }
-
- if (!std::isnan(m_startTime) || currentTimeInternal() != initialCompositorHoldTime) {
- // A new start time or current time was set while starting.
- setCompositorPending(true);
- return;
- }
- }
-
- notifyStartTime(timelineTime);
-}
-
-void AnimationPlayer::notifyStartTime(double timelineTime)
-{
- if (playing()) {
- ASSERT(std::isnan(m_startTime));
- ASSERT(m_held);
-
- if (m_playbackRate == 0) {
- setStartTimeInternal(timelineTime);
- } else {
- setStartTimeInternal(timelineTime + currentTimeInternal() / -m_playbackRate);
- }
-
- // FIXME: This avoids marking this player as outdated needlessly when a start time
- // is notified, but we should refactor how outdating works to avoid this.
- m_outdated = false;
-
- m_currentTimePending = false;
- }
-}
-
-bool AnimationPlayer::affects(const Element& element, CSSPropertyID property) const
-{
- if (!m_content || !m_content->isAnimation())
- return false;
-
- const Animation* animation = toAnimation(m_content.get());
- return (animation->target() == &element) && animation->affects(PropertyHandle(property));
-}
-
-double AnimationPlayer::calculateStartTime(double currentTime) const
-{
- return m_timeline->effectiveTime() - currentTime / m_playbackRate;
-}
-
-double AnimationPlayer::calculateCurrentTime() const
-{
- if (isNull(m_startTime) || !m_timeline)
- return 0;
- return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate;
-}
-
-void AnimationPlayer::setStartTime(double startTime)
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- if (m_paused || playStateInternal() == Idle)
- return;
- if (startTime == m_startTime)
- return;
-
- m_currentTimePending = false;
- setStartTimeInternal(startTime / 1000);
-}
-
-void AnimationPlayer::setStartTimeInternal(double newStartTime)
-{
- ASSERT(!m_paused);
- ASSERT(std::isfinite(newStartTime));
- ASSERT(newStartTime != m_startTime);
-
- bool hadStartTime = hasStartTime();
- double previousCurrentTime = currentTimeInternal();
- m_startTime = newStartTime;
- if (m_held && m_playbackRate) {
- // If held, the start time would still be derrived from the hold time.
- // Force a new, limited, current time.
- m_held = false;
- double currentTime = calculateCurrentTime();
- if (m_playbackRate > 0 && currentTime > sourceEnd()) {
- currentTime = sourceEnd();
- } else if (m_playbackRate < 0 && currentTime < 0) {
- currentTime = 0;
- }
- setCurrentTimeInternal(currentTime, TimingUpdateOnDemand);
- }
- updateCurrentTimingState(TimingUpdateOnDemand);
- double newCurrentTime = currentTimeInternal();
-
- if (previousCurrentTime != newCurrentTime) {
- setOutdated();
- } else if (!hadStartTime && m_timeline) {
- // Even though this player is not outdated, time to effect change is
- // infinity until start time is set.
- m_timeline->wake();
- }
-}
-
-void AnimationPlayer::setSource(AnimationNode* newSource)
-{
- if (m_content == newSource)
- return;
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, SetCompositorPendingWithSourceChanged);
-
- double storedCurrentTime = currentTimeInternal();
- if (m_content)
- m_content->detach();
- m_content = newSource;
- if (newSource) {
- // FIXME: This logic needs to be updated once groups are implemented
- if (newSource->player()) {
- newSource->player()->cancel();
- newSource->player()->setSource(0);
- }
- newSource->attach(this);
- setOutdated();
- }
- setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
-}
-
-const char* AnimationPlayer::playStateString(AnimationPlayState playState)
-{
- switch (playState) {
- case Idle:
- return "idle";
- case Pending:
- return "pending";
- case Running:
- return "running";
- case Paused:
- return "paused";
- case Finished:
- return "finished";
- default:
- ASSERT_NOT_REACHED();
- return "";
- }
-}
-
-AnimationPlayer::AnimationPlayState AnimationPlayer::playStateInternal() const
-{
- return m_playState;
-}
-
-AnimationPlayer::AnimationPlayState AnimationPlayer::calculatePlayState()
-{
- if (m_playState == Idle)
- return Idle;
- if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackRate != 0))
- return Pending;
- if (m_paused)
- return Paused;
- if (limited())
- return Finished;
- return Running;
-}
-
-void AnimationPlayer::pause()
-{
- if (m_paused)
- return;
-
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- if (playing()) {
- m_currentTimePending = true;
- }
- m_paused = true;
- setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
-}
-
-void AnimationPlayer::unpause()
-{
- if (!m_paused)
- return;
-
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- m_currentTimePending = true;
- unpauseInternal();
-}
-
-void AnimationPlayer::unpauseInternal()
-{
- if (!m_paused)
- return;
- m_paused = false;
- setCurrentTimeInternal(currentTimeInternal(), TimingUpdateOnDemand);
-}
-
-void AnimationPlayer::play()
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- if (!playing())
- m_startTime = nullValue();
-
- if (playStateInternal() == Idle) {
- // We may not go into the pending state, but setting it to something other
- // than Idle here will force an update.
- ASSERT(isNull(m_startTime));
- m_playState = Pending;
- m_held = true;
- m_holdTime = 0;
- }
-
- m_finished = false;
- unpauseInternal();
- if (!m_content)
- return;
- double currentTime = this->currentTimeInternal();
- if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd())) {
- m_startTime = nullValue();
- setCurrentTimeInternal(0, TimingUpdateOnDemand);
- } else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd())) {
- m_startTime = nullValue();
- setCurrentTimeInternal(sourceEnd(), TimingUpdateOnDemand);
- }
-}
-
-void AnimationPlayer::reverse()
-{
- if (!m_playbackRate) {
- return;
- }
-
- setPlaybackRateInternal(-m_playbackRate);
- play();
-}
-
-void AnimationPlayer::finish(ExceptionState& exceptionState)
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- if (!m_playbackRate || playStateInternal() == Idle) {
- return;
- }
- if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infinity()) {
- exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity.");
- return;
- }
-
- double newCurrentTime = m_playbackRate < 0 ? 0 : sourceEnd();
- setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand);
- if (!paused()) {
- m_startTime = calculateStartTime(newCurrentTime);
- }
-
- m_currentTimePending = false;
- ASSERT(playStateInternal() != Idle);
- ASSERT(limited());
-}
-
-ScriptPromise AnimationPlayer::finished(ScriptState* scriptState)
-{
- if (!m_finishedPromise) {
- m_finishedPromise = new AnimationPlayerPromise(scriptState->executionContext(), this, AnimationPlayerPromise::Finished);
- if (playStateInternal() == Finished)
- m_finishedPromise->resolve(this);
- }
- return m_finishedPromise->promise(scriptState->world());
-}
-
-ScriptPromise AnimationPlayer::ready(ScriptState* scriptState)
-{
- if (!m_readyPromise) {
- m_readyPromise = new AnimationPlayerPromise(scriptState->executionContext(), this, AnimationPlayerPromise::Ready);
- if (playStateInternal() != Pending)
- m_readyPromise->resolve(this);
- }
- return m_readyPromise->promise(scriptState->world());
-}
-
-const AtomicString& AnimationPlayer::interfaceName() const
-{
- return EventTargetNames::AnimationPlayer;
-}
-
-ExecutionContext* AnimationPlayer::executionContext() const
-{
- return ActiveDOMObject::executionContext();
-}
-
-bool AnimationPlayer::hasPendingActivity() const
-{
- return m_pendingFinishedEvent || (!m_finished && hasEventListeners(EventTypeNames::finish));
-}
-
-void AnimationPlayer::stop()
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- m_finished = true;
- m_pendingFinishedEvent = nullptr;
-}
-
-bool AnimationPlayer::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
-{
- if (m_pendingFinishedEvent == event)
- m_pendingFinishedEvent = nullptr;
- return EventTargetWithInlineData::dispatchEvent(event);
-}
-
-double AnimationPlayer::playbackRate() const
-{
- return m_playbackRate;
-}
-
-void AnimationPlayer::setPlaybackRate(double playbackRate)
-{
- if (playbackRate == m_playbackRate)
- return;
-
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- setPlaybackRateInternal(playbackRate);
-}
-
-void AnimationPlayer::setPlaybackRateInternal(double playbackRate)
-{
- ASSERT(std::isfinite(playbackRate));
- ASSERT(playbackRate != m_playbackRate);
-
- if (!limited() && !paused() && hasStartTime())
- m_currentTimePending = true;
-
- double storedCurrentTime = currentTimeInternal();
- if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && playbackRate <= 0))
- m_finished = false;
-
- m_playbackRate = playbackRate;
- m_startTime = std::numeric_limits<double>::quiet_NaN();
- setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand);
-}
-
-void AnimationPlayer::setOutdated()
-{
- m_outdated = true;
- if (m_timeline)
- m_timeline->setOutdatedAnimationPlayer(this);
-}
-
-bool AnimationPlayer::canStartAnimationOnCompositor() const
-{
- // FIXME: Timeline playback rates should be compositable
- if (m_playbackRate == 0 || (std::isinf(sourceEnd()) && m_playbackRate < 0) || (timeline() && timeline()->playbackRate() != 1))
- return false;
-
- return m_timeline && m_content && m_content->isAnimation() && playing();
-}
-
-bool AnimationPlayer::isCandidateForAnimationOnCompositor() const
-{
- if (!canStartAnimationOnCompositor())
- return false;
-
- return toAnimation(m_content.get())->isCandidateForAnimationOnCompositor(m_playbackRate);
-}
-
-bool AnimationPlayer::maybeStartAnimationOnCompositor()
-{
- if (!canStartAnimationOnCompositor())
- return false;
-
- bool reversed = m_playbackRate < 0;
-
- double startTime = timeline()->zeroTime() + startTimeInternal();
- if (reversed) {
- startTime -= sourceEnd() / fabs(m_playbackRate);
- }
-
- double timeOffset = 0;
- if (std::isnan(startTime)) {
- timeOffset = reversed ? sourceEnd() - currentTimeInternal() : currentTimeInternal();
- timeOffset = timeOffset / fabs(m_playbackRate);
- }
- ASSERT(m_compositorGroup != 0);
- return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(m_compositorGroup, startTime, timeOffset, m_playbackRate);
-}
-
-void AnimationPlayer::setCompositorPending(bool sourceChanged)
-{
- // FIXME: Animation could notify this directly?
- if (!hasActiveAnimationsOnCompositor()) {
- destroyCompositorPlayer();
- m_compositorState.release();
- }
- if (sourceChanged && m_compositorState) {
- m_compositorState->sourceChanged = true;
- }
- if (m_compositorPending || m_isPausedForTesting) {
- return;
- }
-
- if (sourceChanged || !m_compositorState
- || !playing() || m_compositorState->playbackRate != m_playbackRate
- || m_compositorState->startTime != m_startTime) {
- m_compositorPending = true;
- ASSERT(timeline());
- ASSERT(timeline()->document());
- timeline()->document()->compositorPendingAnimations().add(this);
- }
-}
-
-void AnimationPlayer::cancelAnimationOnCompositor()
-{
- if (hasActiveAnimationsOnCompositor())
- toAnimation(m_content.get())->cancelAnimationOnCompositor();
-
- destroyCompositorPlayer();
-}
-
-void AnimationPlayer::restartAnimationOnCompositor()
-{
- if (hasActiveAnimationsOnCompositor())
- toAnimation(m_content.get())->restartAnimationOnCompositor();
-}
-
-void AnimationPlayer::cancelIncompatibleAnimationsOnCompositor()
-{
- if (m_content && m_content->isAnimation())
- toAnimation(m_content.get())->cancelIncompatibleAnimationsOnCompositor();
-}
-
-bool AnimationPlayer::hasActiveAnimationsOnCompositor()
-{
- if (!m_content || !m_content->isAnimation())
- return false;
-
- return toAnimation(m_content.get())->hasActiveAnimationsOnCompositor();
-}
-
-bool AnimationPlayer::update(TimingUpdateReason reason)
-{
- if (!m_timeline)
- return false;
-
- PlayStateUpdateScope updateScope(*this, reason, DoNotSetCompositorPending);
-
- m_outdated = false;
- bool idle = playStateInternal() == Idle;
-
- if (m_content) {
- double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal();
- // Special case for end-exclusivity when playing backwards.
- if (inheritedTime == 0 && m_playbackRate < 0)
- inheritedTime = -1;
- m_content->updateInheritedTime(inheritedTime, reason);
- }
-
- if ((idle || limited()) && !m_finished) {
- if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) {
- const AtomicString& eventType = EventTypeNames::finish;
- if (executionContext() && hasEventListeners(eventType)) {
- double eventCurrentTime = currentTimeInternal() * 1000;
- m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime());
- m_pendingFinishedEvent->setTarget(this);
- m_pendingFinishedEvent->setCurrentTarget(this);
- m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent);
- }
- m_finished = true;
- }
- }
- ASSERT(!m_outdated);
- return !m_finished;
-}
-
-double AnimationPlayer::timeToEffectChange()
-{
- ASSERT(!m_outdated);
- if (m_held || !hasStartTime())
- return std::numeric_limits<double>::infinity();
- if (!m_content)
- return -currentTimeInternal() / m_playbackRate;
- double result = m_playbackRate > 0
- ? m_content->timeToForwardsEffectChange() / m_playbackRate
- : m_content->timeToReverseEffectChange() / -m_playbackRate;
- return !hasActiveAnimationsOnCompositor() && m_content->phase() == AnimationNode::PhaseActive
- ? 0
- : result;
-}
-
-void AnimationPlayer::cancel()
-{
- PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand);
-
- if (playStateInternal() == Idle)
- return;
-
- m_holdTime = currentTimeInternal();
- m_held = true;
- // TODO
- m_playState = Idle;
- m_startTime = nullValue();
- m_currentTimePending = false;
-
- InspectorInstrumentation::didCancelAnimationPlayer(timeline()->document(), this);
-}
-
-void AnimationPlayer::beginUpdatingState()
-{
- // Nested calls are not allowed!
- ASSERT(!m_stateIsBeingUpdated);
- m_stateIsBeingUpdated = true;
-}
-
-void AnimationPlayer::endUpdatingState()
-{
- ASSERT(m_stateIsBeingUpdated);
- m_stateIsBeingUpdated = false;
-}
-
-void AnimationPlayer::createCompositorPlayer()
-{
- if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() && !m_compositorPlayer && Platform::current()->compositorSupport()) {
- m_compositorPlayer = adoptPtr(Platform::current()->compositorSupport()->createAnimationPlayer());
- ASSERT(m_compositorPlayer);
- m_compositorPlayer->setAnimationDelegate(this);
- attachCompositorTimeline();
- }
-
- attachCompositedLayers();
-}
-
-void AnimationPlayer::destroyCompositorPlayer()
-{
- detachCompositedLayers();
-
- if (m_compositorPlayer) {
- detachCompositorTimeline();
- m_compositorPlayer->setAnimationDelegate(nullptr);
- }
- m_compositorPlayer.clear();
-}
-
-void AnimationPlayer::attachCompositorTimeline()
-{
- if (m_compositorPlayer) {
- WebCompositorAnimationTimeline* timeline = m_timeline ? m_timeline->compositorTimeline() : nullptr;
- if (timeline)
- timeline->playerAttached(*this);
- }
-}
-
-void AnimationPlayer::detachCompositorTimeline()
-{
- if (m_compositorPlayer) {
- WebCompositorAnimationTimeline* timeline = m_timeline ? m_timeline->compositorTimeline() : nullptr;
- if (timeline)
- timeline->playerDestroyed(*this);
- }
-}
-
-void AnimationPlayer::attachCompositedLayers()
-{
- if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() || !m_compositorPlayer)
- return;
-
- ASSERT(m_content);
- ASSERT(m_content->isAnimation());
-
- if (toAnimation(m_content.get())->canAttachCompositedLayers())
- toAnimation(m_content.get())->attachCompositedLayers();
-}
-
-void AnimationPlayer::detachCompositedLayers()
-{
- if (m_compositorPlayer && m_compositorPlayer->isLayerAttached())
- m_compositorPlayer->detachLayer();
-}
-
-void AnimationPlayer::notifyAnimationStarted(double monotonicTime, int group)
-{
- ASSERT(RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled());
- timeline()->document()->compositorPendingAnimations().notifyCompositorAnimationStarted(monotonicTime, group);
-}
-
-AnimationPlayer::PlayStateUpdateScope::PlayStateUpdateScope(AnimationPlayer& player, TimingUpdateReason reason, CompositorPendingChange compositorPendingChange)
- : m_player(player)
- , m_initialPlayState(m_player->playStateInternal())
- , m_compositorPendingChange(compositorPendingChange)
-{
- m_player->beginUpdatingState();
- m_player->updateCurrentTimingState(reason);
-}
-
-AnimationPlayer::PlayStateUpdateScope::~PlayStateUpdateScope()
-{
- AnimationPlayState oldPlayState = m_initialPlayState;
- AnimationPlayState newPlayState = m_player->calculatePlayState();
-
- m_player->m_playState = newPlayState;
- if (oldPlayState != newPlayState) {
- bool wasActive = oldPlayState == Pending || oldPlayState == Running;
- bool isActive = newPlayState == Pending || newPlayState == Running;
- if (!wasActive && isActive)
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("blink.animations," TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Animation", m_player, "data", InspectorAnimationEvent::data(*m_player));
- else if (wasActive && !isActive)
- TRACE_EVENT_NESTABLE_ASYNC_END1("blink.animations," TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Animation", m_player, "endData", InspectorAnimationStateEvent::data(*m_player));
- else
- TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("blink.animations," TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Animation", m_player, "data", InspectorAnimationStateEvent::data(*m_player));
- }
-
- // Ordering is important, the ready promise should resolve/reject before
- // the finished promise.
- if (m_player->m_readyPromise && newPlayState != oldPlayState) {
- if (newPlayState == Idle) {
- if (m_player->m_readyPromise->state() == AnimationPlayerPromise::Pending) {
- m_player->m_readyPromise->reject(DOMException::create(AbortError));
- }
- m_player->m_readyPromise->reset();
- m_player->m_readyPromise->resolve(m_player);
- } else if (oldPlayState == Pending) {
- m_player->m_readyPromise->resolve(m_player);
- } else if (newPlayState == Pending) {
- ASSERT(m_player->m_readyPromise->state() != AnimationPlayerPromise::Pending);
- m_player->m_readyPromise->reset();
- }
- }
-
- if (m_player->m_finishedPromise && newPlayState != oldPlayState) {
- if (newPlayState == Idle) {
- if (m_player->m_finishedPromise->state() == AnimationPlayerPromise::Pending) {
- m_player->m_finishedPromise->reject(DOMException::create(AbortError));
- }
- m_player->m_finishedPromise->reset();
- } else if (newPlayState == Finished) {
- m_player->m_finishedPromise->resolve(m_player);
- } else if (oldPlayState == Finished) {
- m_player->m_finishedPromise->reset();
- }
- }
-
- if (oldPlayState != newPlayState && (oldPlayState == Idle || newPlayState == Idle)) {
- m_player->setOutdated();
- }
-
-#if ENABLE(ASSERT)
- // Verify that current time is up to date.
- m_player->currentTimeInternal();
-#endif
-
- switch (m_compositorPendingChange) {
- case SetCompositorPending:
- m_player->setCompositorPending();
- break;
- case SetCompositorPendingWithSourceChanged:
- m_player->setCompositorPending(true);
- break;
- case DoNotSetCompositorPending:
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
- m_player->endUpdatingState();
-
- if (oldPlayState != newPlayState && newPlayState == Running)
- InspectorInstrumentation::didCreateAnimationPlayer(m_player->timeline()->document(), m_player);
-}
-
-bool AnimationPlayer::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
- if (eventType == EventTypeNames::finish)
- UseCounter::count(executionContext(), UseCounter::AnimationPlayerFinishEvent);
- return EventTargetWithInlineData::addEventListener(eventType, listener, useCapture);
-}
-
-void AnimationPlayer::pauseForTesting(double pauseTime)
-{
- RELEASE_ASSERT(!paused());
- setCurrentTimeInternal(pauseTime, TimingUpdateOnDemand);
- if (hasActiveAnimationsOnCompositor())
- toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTimeInternal());
- m_isPausedForTesting = true;
- pause();
-}
-
-DEFINE_TRACE(AnimationPlayer)
-{
- visitor->trace(m_content);
- visitor->trace(m_timeline);
- visitor->trace(m_pendingFinishedEvent);
- visitor->trace(m_finishedPromise);
- visitor->trace(m_readyPromise);
- EventTargetWithInlineData::trace(visitor);
- ActiveDOMObject::trace(visitor);
-}
-
-} // namespace
« no previous file with comments | « Source/core/animation/AnimationPlayer.h ('k') | Source/core/animation/AnimationPlayer.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698