Commit 9d32d07a authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Make ScriptedAnimationController a ContextLifecycleStateObserver

This removes the need for special-case pausing/unpausing in Document, as well
as custom Document::Shutdown() logic.

Bug: 1029822
Change-Id: I2c9cda5bb3720626cdc1f3fcadb7876422ca375e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1949275
Commit-Queue: Nate Chapin <japhet@chromium.org>
Auto-Submit: Nate Chapin <japhet@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#721599}
parent 4fa4076a
...@@ -3368,9 +3368,6 @@ void Document::Shutdown() { ...@@ -3368,9 +3368,6 @@ void Document::Shutdown() {
probe::DocumentDetached(this); probe::DocumentDetached(this);
// FIXME: consider using ContextLifecycleStateObserver.
if (scripted_animation_controller_)
scripted_animation_controller_->ClearDocumentPointer();
scripted_animation_controller_.Clear(); scripted_animation_controller_.Clear();
scripted_idle_task_controller_.Clear(); scripted_idle_task_controller_.Clear();
...@@ -7311,17 +7308,11 @@ void Document::AddConsoleMessageImpl(ConsoleMessage* console_message, ...@@ -7311,17 +7308,11 @@ void Document::AddConsoleMessageImpl(ConsoleMessage* console_message,
void Document::TasksWerePaused() { void Document::TasksWerePaused() {
GetScriptRunner()->Suspend(); GetScriptRunner()->Suspend();
if (scripted_animation_controller_)
scripted_animation_controller_->Pause();
} }
void Document::TasksWereUnpaused() { void Document::TasksWereUnpaused() {
GetScriptRunner()->Resume(); GetScriptRunner()->Resume();
if (scripted_animation_controller_)
scripted_animation_controller_->Unpause();
MutationObserver::ResumeSuspendedObservers(); MutationObserver::ResumeSuspendedObservers();
if (dom_window_) if (dom_window_)
DOMWindowPerformance::performance(*dom_window_)->ResumeSuspendedObservers(); DOMWindowPerformance::performance(*dom_window_)->ResumeSuspendedObservers();
...@@ -7440,9 +7431,9 @@ ScriptedAnimationController& Document::EnsureScriptedAnimationController() { ...@@ -7440,9 +7431,9 @@ ScriptedAnimationController& Document::EnsureScriptedAnimationController() {
scripted_animation_controller_ = scripted_animation_controller_ =
MakeGarbageCollected<ScriptedAnimationController>(this); MakeGarbageCollected<ScriptedAnimationController>(this);
// We need to make sure that we don't start up the animation controller on a // We need to make sure that we don't start up the animation controller on a
// background tab, for example. // detached document.
if (!GetPage()) if (!GetPage())
scripted_animation_controller_->Pause(); scripted_animation_controller_->Disable();
} }
return *scripted_animation_controller_; return *scripted_animation_controller_;
} }
......
...@@ -43,26 +43,21 @@ std::pair<EventTarget*, StringImpl*> EventTargetKey(const Event* event) { ...@@ -43,26 +43,21 @@ std::pair<EventTarget*, StringImpl*> EventTargetKey(const Event* event) {
} }
ScriptedAnimationController::ScriptedAnimationController(Document* document) ScriptedAnimationController::ScriptedAnimationController(Document* document)
: document_(document), callback_collection_(document), suspend_count_(0) {} : ContextLifecycleStateObserver(document), callback_collection_(document) {
UpdateStateIfNeeded();
}
void ScriptedAnimationController::Trace(Visitor* visitor) { void ScriptedAnimationController::Trace(Visitor* visitor) {
visitor->Trace(document_); ContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(callback_collection_); visitor->Trace(callback_collection_);
visitor->Trace(event_queue_); visitor->Trace(event_queue_);
visitor->Trace(media_query_list_listeners_); visitor->Trace(media_query_list_listeners_);
visitor->Trace(per_frame_events_); visitor->Trace(per_frame_events_);
} }
void ScriptedAnimationController::Pause() { void ScriptedAnimationController::ContextLifecycleStateChanged(
++suspend_count_; mojom::FrameLifecycleState state) {
} if (state == mojom::FrameLifecycleState::kRunning)
void ScriptedAnimationController::Unpause() {
// It would be nice to put an DCHECK_GT(suspend_count_, 0) here, but in WK1
// resume() can be called even when suspend hasn't (if a tab was created in
// the background).
if (suspend_count_ > 0)
--suspend_count_;
ScheduleAnimationIfNeeded(); ScheduleAnimationIfNeeded();
} }
...@@ -142,7 +137,7 @@ void ScriptedAnimationController::DispatchEvents( ...@@ -142,7 +137,7 @@ void ScriptedAnimationController::DispatchEvents(
void ScriptedAnimationController::ExecuteFrameCallbacks() { void ScriptedAnimationController::ExecuteFrameCallbacks() {
// dispatchEvents() runs script which can cause the document to be destroyed. // dispatchEvents() runs script which can cause the document to be destroyed.
if (!document_) if (!GetDocument())
return; return;
callback_collection_.ExecuteFrameCallbacks(current_frame_time_ms_, callback_collection_.ExecuteFrameCallbacks(current_frame_time_ms_,
...@@ -159,24 +154,26 @@ void ScriptedAnimationController::CallMediaQueryListListeners() { ...@@ -159,24 +154,26 @@ void ScriptedAnimationController::CallMediaQueryListListeners() {
} }
bool ScriptedAnimationController::HasScheduledFrameTasks() const { bool ScriptedAnimationController::HasScheduledFrameTasks() const {
if (suspend_count_) if (disabled_ || !GetDocument() || GetDocument()->IsContextPaused())
return false; return false;
return callback_collection_.HasFrameCallback() || !task_queue_.IsEmpty() || return callback_collection_.HasFrameCallback() || !task_queue_.IsEmpty() ||
!event_queue_.IsEmpty() || !media_query_list_listeners_.IsEmpty() || !event_queue_.IsEmpty() || !media_query_list_listeners_.IsEmpty() ||
(document_ && document_->HasAutofocusCandidates()); GetDocument()->HasAutofocusCandidates();
} }
void ScriptedAnimationController::ServiceScriptedAnimations( void ScriptedAnimationController::ServiceScriptedAnimations(
base::TimeTicks monotonic_time_now) { base::TimeTicks monotonic_time_now) {
if (document_ && document_->Loader()) { if (GetDocument() && GetDocument()->Loader()) {
current_frame_time_ms_ = current_frame_time_ms_ =
document_->Loader() GetDocument()
->Loader()
->GetTiming() ->GetTiming()
.MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now) .MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now)
.InMillisecondsF(); .InMillisecondsF();
current_frame_legacy_time_ms_ = current_frame_legacy_time_ms_ =
document_->Loader() GetDocument()
->Loader()
->GetTiming() ->GetTiming()
.MonotonicTimeToPseudoWallTime(monotonic_time_now) .MonotonicTimeToPseudoWallTime(monotonic_time_now)
.InMillisecondsF(); .InMillisecondsF();
...@@ -191,8 +188,8 @@ void ScriptedAnimationController::ServiceScriptedAnimations( ...@@ -191,8 +188,8 @@ void ScriptedAnimationController::ServiceScriptedAnimations(
// 10.5. For each fully active Document in docs, flush autofocus // 10.5. For each fully active Document in docs, flush autofocus
// candidates for that Document if its browsing context is a top-level // candidates for that Document if its browsing context is a top-level
// browsing context. // browsing context.
if (document_) if (GetDocument())
document_->FlushAutofocusCandidates(); GetDocument()->FlushAutofocusCandidates();
// 10.8. For each fully active Document in docs, evaluate media // 10.8. For each fully active Document in docs, evaluate media
// queries and report changes for that Document, passing in now as the // queries and report changes for that Document, passing in now as the
...@@ -259,9 +256,9 @@ void ScriptedAnimationController::EnqueueMediaQueryChangeListeners( ...@@ -259,9 +256,9 @@ void ScriptedAnimationController::EnqueueMediaQueryChangeListeners(
} }
void ScriptedAnimationController::ScheduleAnimationIfNeeded() { void ScriptedAnimationController::ScheduleAnimationIfNeeded() {
if (suspend_count_ || !document_) if (disabled_ || !GetDocument() || GetDocument()->IsContextPaused())
return; return;
LocalFrameView* frame_view = document_->View(); LocalFrameView* frame_view = GetDocument()->View();
if (!frame_view) if (!frame_view)
return; return;
...@@ -278,7 +275,7 @@ void ScriptedAnimationController::ScheduleAnimationIfNeeded() { ...@@ -278,7 +275,7 @@ void ScriptedAnimationController::ScheduleAnimationIfNeeded() {
// no need to schedule another one. // no need to schedule another one.
if (!callback_collection_.HasPostFrameCallback()) if (!callback_collection_.HasPostFrameCallback())
return; return;
if (Page* page = document_->GetPage()) { if (Page* page = GetDocument()->GetPage()) {
if (!page->Animator().IsServicingAnimations()) if (!page->Animator().IsServicingAnimations())
frame_view->ScheduleAnimation(); frame_view->ScheduleAnimation();
} }
......
...@@ -28,8 +28,10 @@ ...@@ -28,8 +28,10 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h" #include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h" #include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
...@@ -43,16 +45,18 @@ class MediaQueryListListener; ...@@ -43,16 +45,18 @@ class MediaQueryListListener;
class CORE_EXPORT ScriptedAnimationController class CORE_EXPORT ScriptedAnimationController
: public GarbageCollected<ScriptedAnimationController>, : public GarbageCollected<ScriptedAnimationController>,
public ContextLifecycleStateObserver,
public NameClient { public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(ScriptedAnimationController);
public: public:
explicit ScriptedAnimationController(Document*); explicit ScriptedAnimationController(Document*);
virtual ~ScriptedAnimationController() = default; ~ScriptedAnimationController() override = default;
void Trace(Visitor*); void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { const char* NameInHeapSnapshot() const override {
return "ScriptedAnimationController"; return "ScriptedAnimationController";
} }
void ClearDocumentPointer() { document_ = nullptr; }
// Animation frame callbacks are used for requestAnimationFrame(). // Animation frame callbacks are used for requestAnimationFrame().
typedef int CallbackId; typedef int CallbackId;
...@@ -82,8 +86,8 @@ class CORE_EXPORT ScriptedAnimationController ...@@ -82,8 +86,8 @@ class CORE_EXPORT ScriptedAnimationController
void ServiceScriptedAnimations(base::TimeTicks monotonic_time_now); void ServiceScriptedAnimations(base::TimeTicks monotonic_time_now);
void RunPostFrameCallbacks(); void RunPostFrameCallbacks();
void Pause(); void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
void Unpause(); void Disable() { disabled_ = true; }
void DispatchEventsAndCallbacksForPrinting(); void DispatchEventsAndCallbacksForPrinting();
...@@ -101,9 +105,10 @@ class CORE_EXPORT ScriptedAnimationController ...@@ -101,9 +105,10 @@ class CORE_EXPORT ScriptedAnimationController
bool HasScheduledFrameTasks() const; bool HasScheduledFrameTasks() const;
Member<Document> document_; Document* GetDocument() const { return To<Document>(GetExecutionContext()); }
FrameRequestCallbackCollection callback_collection_; FrameRequestCallbackCollection callback_collection_;
int suspend_count_; bool disabled_ = false;
Vector<base::OnceClosure> task_queue_; Vector<base::OnceClosure> task_queue_;
HeapVector<Member<Event>> event_queue_; HeapVector<Member<Event>> event_queue_;
HeapListHashSet<std::pair<Member<const EventTarget>, const StringImpl*>> HeapListHashSet<std::pair<Member<const EventTarget>, const StringImpl*>>
......
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