1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_InputTaskManager_h
8 #define mozilla_InputTaskManager_h
11 #include "nsXULAppAPI.h"
12 #include "TaskController.h"
13 #include "mozilla/StaticPtr.h"
14 #include "mozilla/StaticPrefs_dom.h"
18 class InputTaskManager
: public TaskManager
{
20 int32_t GetPriorityModifierForEventLoopTurn(
21 const MutexAutoLock
& aProofOfLock
) final
;
22 void WillRunTask() final
;
24 enum InputEventQueueState
{
31 void EnableInputEventPrioritization();
32 void FlushInputEventPrioritization();
33 void SuspendInputEventPrioritization();
34 void ResumeInputEventPrioritization();
36 InputEventQueueState
State() { return mInputQueueState
; }
38 void SetState(InputEventQueueState aState
) { mInputQueueState
= aState
; }
40 static InputTaskManager
* Get() { return gInputTaskManager
.get(); }
41 static void Cleanup() { gInputTaskManager
= nullptr; }
44 bool IsSuspended(const MutexAutoLock
& aProofOfLock
) override
{
45 MOZ_ASSERT(NS_IsMainThread());
46 return mInputQueueState
== STATE_SUSPEND
|| mSuspensionLevel
> 0;
50 MOZ_ASSERT(NS_IsMainThread());
51 return mSuspensionLevel
> 0;
54 void IncSuspensionLevel() {
55 MOZ_ASSERT(NS_IsMainThread());
59 void DecSuspensionLevel() {
60 MOZ_ASSERT(NS_IsMainThread());
64 static bool CanSuspendInputEvent() {
65 // Ensure it's content process because InputTaskManager only
68 // Input tasks will have nullptr as their task manager when the
69 // event queue state is STATE_DISABLED, so we can't suspend
71 return XRE_IsContentProcess() &&
72 StaticPrefs::dom_input_events_canSuspendInBCG_enabled() &&
73 InputTaskManager::Get()->State() !=
74 InputEventQueueState::STATE_DISABLED
;
77 void NotifyVsync() { mInputPriorityController
.WillRunVsync(); }
80 InputTaskManager() : mInputQueueState(STATE_DISABLED
) {}
82 class InputPriorityController
{
84 InputPriorityController();
85 // Determines whether we should use the highest input priority for input
87 bool ShouldUseHighestPriority(InputTaskManager
*);
91 // Gets called when a input task is going to run; If the current
92 // input vsync state is `HasPendingVsync`, determines whether we
93 // should continue running input tasks or leave the `HasPendingVsync` state
95 // 1. Whether we still have time to process input tasks
96 // 2. Whether we have processed the max number of tasks that
101 // Used to represents the relationship between Input and Vsync.
103 // HasPendingVsync: There are pending vsync tasks and we are using
104 // InputHighest priority for inputs.
105 // NoPendingVsync: No pending vsync tasks and no need to use InputHighest
107 // RunVsync: Finished running input tasks and the vsync task
109 enum class InputVsyncState
{
115 void EnterPendingVsyncState(uint32_t aNumPendingTasks
);
116 void LeavePendingVsyncState(bool aRunVsync
);
118 // Stores the number of pending input tasks when we enter the
119 // InputVsyncState::HasPendingVsync state.
120 uint32_t mMaxInputTasksToRun
= 0;
122 InputVsyncState mInputVsyncState
;
124 TimeStamp mRunInputStartTime
;
127 int32_t GetPriorityModifierForEventLoopTurnForStrictVsyncAlignment();
129 Atomic
<InputEventQueueState
> mInputQueueState
;
131 static StaticRefPtr
<InputTaskManager
> gInputTaskManager
;
133 // Number of BCGs have asked InputTaskManager to suspend input events
134 uint32_t mSuspensionLevel
= 0;
136 InputPriorityController mInputPriorityController
;
139 } // namespace mozilla
141 #endif // mozilla_InputTaskManager_h