summaryrefslogtreecommitdiffstats
path: root/dom/animation
diff options
context:
space:
mode:
Diffstat (limited to 'dom/animation')
-rw-r--r--dom/animation/Animation.cpp29
-rw-r--r--dom/animation/Animation.h6
-rw-r--r--dom/animation/AnimationTimeline.h3
-rw-r--r--dom/animation/test/mozilla/file_restyles.html16
4 files changed, 20 insertions, 34 deletions
diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp
index 6f0fee007c..ad52495e67 100644
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -6,6 +6,7 @@
#include "Animation.h"
+#include "mozilla/Likely.h"
#include "nsIFrame.h"
#include "AnimationUtils.h"
#include "mozAutoDocUpdate.h"
@@ -926,12 +927,13 @@ void Animation::SetCurrentTimeAsDouble(const Nullable<double>& aCurrentTime,
void Animation::Tick(AnimationTimeline::TickState& aTickState) {
if (Pending()) {
- // Finish pending if we can, but make sure we've seen one existing tick, or
- // we've requested to get started via SetPendingReadyTime.
- if (!mPendingReadyTime.IsNull() || mSawTickWhilePending) {
+ if (!mPendingReadyTime.IsNull()) {
TryTriggerNow();
+ } else if (MOZ_LIKELY(mTimeline)) {
+ // Makes sure that we trigger the animation on the next tick but,
+ // importantly, with this tick's timestamp.
+ mPendingReadyTime = mTimeline->GetCurrentTimeAsTimeStamp();
}
- mSawTickWhilePending = true;
}
UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Sync);
@@ -1351,17 +1353,21 @@ void Animation::NotifyEffectTargetUpdated() {
MaybeScheduleReplacementCheck();
}
-static bool EnsurePaintIsScheduled(Document& aDoc) {
+static TimeStamp EnsurePaintIsScheduled(Document& aDoc) {
PresShell* presShell = aDoc.GetPresShell();
if (!presShell) {
- return false;
+ return {};
}
nsIFrame* rootFrame = presShell->GetRootFrame();
if (!rootFrame) {
- return false;
+ return {};
}
rootFrame->SchedulePaintWithoutInvalidatingObservers();
- return rootFrame->PresContext()->RefreshDriver()->IsInRefresh();
+ auto* rd = rootFrame->PresContext()->RefreshDriver();
+ if (!rd->IsInRefresh()) {
+ return {};
+ }
+ return rd->MostRecentRefresh(/* aEnsureTimerStarted = */ false);
}
// https://drafts.csswg.org/web-animations/#play-an-animation
@@ -1453,7 +1459,6 @@ void Animation::PlayNoUpdate(ErrorResult& aRv, LimitBehavior aLimitBehavior) {
mPendingState = PendingState::PlayPending;
mPendingReadyTime = {};
- mSawTickWhilePending = false;
if (Document* doc = GetRenderedDocument()) {
if (HasFiniteTimeline()) {
// Always schedule a task even if we would like to let this animation
@@ -1464,7 +1469,7 @@ void Animation::PlayNoUpdate(ErrorResult& aRv, LimitBehavior aLimitBehavior) {
doc->GetOrCreateScrollTimelineAnimationTracker()->AddPending(*this);
}
// Make sure to try to schedule a tick.
- mSawTickWhilePending = EnsurePaintIsScheduled(*doc);
+ mPendingReadyTime = EnsurePaintIsScheduled(*doc);
}
UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
@@ -1515,14 +1520,12 @@ void Animation::Pause(ErrorResult& aRv) {
mPendingState = PendingState::PausePending;
mPendingReadyTime = {};
- mSawTickWhilePending = false;
-
// See the relevant PlayPending code for comments.
if (Document* doc = GetRenderedDocument()) {
if (HasFiniteTimeline()) {
doc->GetOrCreateScrollTimelineAnimationTracker()->AddPending(*this);
}
- mSawTickWhilePending = EnsurePaintIsScheduled(*doc);
+ mPendingReadyTime = EnsurePaintIsScheduled(*doc);
}
UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async);
diff --git a/dom/animation/Animation.h b/dom/animation/Animation.h
index cb0859a4b6..d7edfedfc2 100644
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -114,6 +114,7 @@ class Animation : public DOMEventTargetHelper,
Nullable<TimeDuration> GetStartTime() const { return mStartTime; }
Nullable<double> GetStartTimeAsDouble() const;
void SetStartTime(const Nullable<TimeDuration>& aNewStartTime);
+ const TimeStamp& GetPendingReadyTime() const { return mPendingReadyTime; }
void SetPendingReadyTime(const TimeStamp& aReadyTime) {
mPendingReadyTime = aReadyTime;
}
@@ -550,11 +551,6 @@ class Animation : public DOMEventTargetHelper,
bool mFinishedAtLastComposeStyle = false;
bool mWasReplaceableAtLastTick = false;
- // When we create a new pending animation, this tracks whether we've seen at
- // least one refresh driver tick. This is used to guarantee that a whole tick
- // has run before triggering the animation, which guarantees (for most pages)
- // that we've actually painted.
- bool mSawTickWhilePending = false;
bool mHiddenByContentVisibility = false;
diff --git a/dom/animation/AnimationTimeline.h b/dom/animation/AnimationTimeline.h
index 96fd1650a2..bb782bfb8c 100644
--- a/dom/animation/AnimationTimeline.h
+++ b/dom/animation/AnimationTimeline.h
@@ -23,8 +23,7 @@ class ScrollTimeline;
class AnimationTimeline : public nsISupports, public nsWrapperCache {
public:
- explicit AnimationTimeline(nsIGlobalObject* aWindow,
- RTPCallerType aRTPCallerType);
+ AnimationTimeline(nsIGlobalObject* aWindow, RTPCallerType);
struct TickState {
TickState() = default;
diff --git a/dom/animation/test/mozilla/file_restyles.html b/dom/animation/test/mozilla/file_restyles.html
index 0aba35cd0e..88e6329b69 100644
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -975,13 +975,7 @@ waitForAllPaints(() => {
animation.pause();
await animation.ready;
- let restyleCount;
- restyleCount = await observeStyling(1);
- is(restyleCount, 1,
- 'Animations running on the compositor should restyle once after ' +
- 'Animation.pause() was called');
-
- restyleCount = await observeStyling(5);
+ let restyleCount = await observeStyling(5);
is(restyleCount, 0,
'Paused animations running on the compositor should never cause ' +
'restyles');
@@ -997,13 +991,7 @@ waitForAllPaints(() => {
animation.pause();
await animation.ready;
- let restyleCount;
- restyleCount = await observeStyling(1);
- is(restyleCount, 1,
- 'Animations running on the main-thread should restyle once after ' +
- 'Animation.pause() was called');
-
- restyleCount = await observeStyling(5);
+ let restyleCount = await observeStyling(5);
is(restyleCount, 0,
'Paused animations running on the main-thread should never cause ' +
'restyles');