From b9197d615fa04cefd36c813dd9dea1d9d11f2fdc Mon Sep 17 00:00:00 2001 From: Cristian Tuns Date: Fri, 24 Nov 2023 06:15:57 -0500 Subject: [PATCH] Backed out changeset 3ca9ebcd4233 (bug 1865637) for causing android mochitest failures in test_animations_effect_timing_duration.html --- dom/animation/DocumentTimeline.cpp | 94 +++++++++++++++++------------- dom/animation/DocumentTimeline.h | 3 +- dom/base/Document.cpp | 5 +- 3 files changed, 56 insertions(+), 46 deletions(-) diff --git a/dom/animation/DocumentTimeline.cpp b/dom/animation/DocumentTimeline.cpp index c426cc9f0a46..d386c502f7b4 100644 --- a/dom/animation/DocumentTimeline.cpp +++ b/dom/animation/DocumentTimeline.cpp @@ -47,11 +47,11 @@ DocumentTimeline::DocumentTimeline(Document* aDocument, mDocument(aDocument), mIsObservingRefreshDriver(false), mOriginTime(aOriginTime) { - mDocument->Timelines().insertBack(this); - // Ensure mLastRefreshDriverTime is valid. - if (nsDOMNavigationTiming* timing = mDocument->GetNavigationTiming()) { - mLastRefreshDriverTime = timing->GetNavigationStartTimeStamp(); + if (mDocument) { + mDocument->Timelines().insertBack(this); } + // Ensure mLastRefreshDriverTime is valid. + UpdateLastRefreshDriverTime(); } DocumentTimeline::~DocumentTimeline() { @@ -100,28 +100,41 @@ bool DocumentTimeline::TracksWallclockTime() const { } TimeStamp DocumentTimeline::GetCurrentTimeStamp() const { - if (nsRefreshDriver* refreshDriver = GetRefreshDriver()) { - auto ts = refreshDriver->MostRecentRefresh(); - if (ts > mLastRefreshDriverTime) { - return ts; - } - } - return mLastRefreshDriverTime; + nsRefreshDriver* refreshDriver = GetRefreshDriver(); + return refreshDriver ? refreshDriver->MostRecentRefresh() + : mLastRefreshDriverTime; } -bool DocumentTimeline::MaybeUpdateLastRefreshDriverTime(TimeStamp aTime) { - // If we don't have a refresh driver and we've never had one use the - // timeline's zero time. - // It's possible that our refresh driver's timestamp is behind from the - // navigation start time because the refresh driver timestamp is sent - // through an IPC call whereas the navigation time is set by calling - // TimeStamp::Now() directly. Make sure we only advance. - if (aTime < mLastRefreshDriverTime) { - return false; +void DocumentTimeline::UpdateLastRefreshDriverTime(TimeStamp aKnownTime) { + TimeStamp result = [&] { + if (!aKnownTime.IsNull()) { + return aKnownTime; + } + if (auto* rd = GetRefreshDriver()) { + return rd->MostRecentRefresh(); + }; + return mLastRefreshDriverTime; + }(); + + if (nsDOMNavigationTiming* timing = mDocument->GetNavigationTiming()) { + // If we don't have a refresh driver and we've never had one use the + // timeline's zero time. + // In addition, it's possible that our refresh driver's timestamp is behind + // from the navigation start time because the refresh driver timestamp is + // sent through an IPC call whereas the navigation time is set by calling + // TimeStamp::Now() directly. In such cases we also use the timeline's zero + // time. + // Also, let this time represent the current refresh time. This way we'll + // save it as the last refresh time and skip looking up navigation start + // time each time. + if (result.IsNull() || result < timing->GetNavigationStartTimeStamp()) { + result = timing->GetNavigationStartTimeStamp(); + } } - mLastRefreshDriverTime = aTime; - return true; + if (!result.IsNull()) { + mLastRefreshDriverTime = result; + } } Nullable DocumentTimeline::ToTimelineTime( @@ -156,26 +169,10 @@ void DocumentTimeline::NotifyAnimationUpdated(Animation& aAnimation) { } } -void DocumentTimeline::TriggerAllPendingAnimationsNow() { - for (Animation* animation : mAnimationOrder) { - animation->TryTriggerNow(); - } -} - -void DocumentTimeline::WillRefresh(TimeStamp aTime) { MaybeTick(aTime); } - -void DocumentTimeline::NotifyTimerAdjusted(TimeStamp aTime) { - MaybeTick(aTime); -} - -void DocumentTimeline::MaybeTick(TimeStamp aTime) { - if (!MaybeUpdateLastRefreshDriverTime(aTime)) { - return; - } - +void DocumentTimeline::MostRecentRefreshTimeUpdated() { MOZ_ASSERT(mIsObservingRefreshDriver); MOZ_ASSERT(GetRefreshDriver(), - "Should be able to reach refresh driver from within the tick"); + "Should be able to reach refresh driver from within WillRefresh"); nsAutoAnimationMutationBatch mb(mDocument); @@ -203,6 +200,21 @@ void DocumentTimeline::MaybeTick(TimeStamp aTime) { } } +void DocumentTimeline::TriggerAllPendingAnimationsNow() { + for (Animation* animation : mAnimationOrder) { + animation->TryTriggerNow(); + } +} + +void DocumentTimeline::WillRefresh(TimeStamp aTime) { + UpdateLastRefreshDriverTime(); + MostRecentRefreshTimeUpdated(); +} + +void DocumentTimeline::NotifyTimerAdjusted(TimeStamp aTime) { + MostRecentRefreshTimeUpdated(); +} + void DocumentTimeline::ObserveRefreshDriver(nsRefreshDriver* aDriver) { MOZ_ASSERT(!mIsObservingRefreshDriver); // Set the mIsObservingRefreshDriver flag before calling AddRefreshObserver @@ -229,7 +241,7 @@ void DocumentTimeline::NotifyRefreshDriverCreated(nsRefreshDriver* aDriver) { // could perform a paint before the first refresh driver tick happens. To // ensure we're in a consistent state in that case we run the first tick // manually. - MaybeTick(aDriver->MostRecentRefresh()); + MostRecentRefreshTimeUpdated(); } } diff --git a/dom/animation/DocumentTimeline.h b/dom/animation/DocumentTimeline.h index 95d0f5b9829d..d4e763ea90f8 100644 --- a/dom/animation/DocumentTimeline.h +++ b/dom/animation/DocumentTimeline.h @@ -71,8 +71,7 @@ class DocumentTimeline final : public AnimationTimeline, Document* GetDocument() const override { return mDocument; } - bool MaybeUpdateLastRefreshDriverTime(TimeStamp); - void MaybeTick(TimeStamp); + void UpdateLastRefreshDriverTime(TimeStamp aKnownTime = {}); bool IsMonotonicallyIncreasing() const override { return true; } diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index f9121ee32dbf..cd3e54a3b91e 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -13515,9 +13515,8 @@ void Document::SetNavigationTiming(nsDOMNavigationTiming* aTiming) { // If there's already the DocumentTimeline instance, tell it since the // DocumentTimeline is based on both the navigation start time stamp and the // refresh driver timestamp. - if (mDocumentTimeline && mTiming) { - mDocumentTimeline->MaybeUpdateLastRefreshDriverTime( - mTiming->GetNavigationStartTimeStamp()); + if (mDocumentTimeline) { + mDocumentTimeline->UpdateLastRefreshDriverTime(); } }