Bug 1867190 - Initialise the PHC allocate delay later r=glandium
[gecko.git] / xpcom / threads / InputTaskManager.cpp
blob42b2814290ff30f563bea6f92ecbc8a9ff719033
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 #include "InputTaskManager.h"
8 #include "VsyncTaskManager.h"
9 #include "nsRefreshDriver.h"
11 namespace mozilla {
13 StaticRefPtr<InputTaskManager> InputTaskManager::gInputTaskManager;
15 void InputTaskManager::EnableInputEventPrioritization() {
16 MOZ_ASSERT(NS_IsMainThread());
17 MOZ_ASSERT(mInputQueueState == STATE_DISABLED);
18 mInputQueueState = STATE_ENABLED;
21 void InputTaskManager::FlushInputEventPrioritization() {
22 MOZ_ASSERT(NS_IsMainThread());
23 MOZ_ASSERT(mInputQueueState == STATE_ENABLED ||
24 mInputQueueState == STATE_SUSPEND);
25 mInputQueueState =
26 mInputQueueState == STATE_ENABLED ? STATE_FLUSHING : STATE_SUSPEND;
29 void InputTaskManager::SuspendInputEventPrioritization() {
30 MOZ_ASSERT(NS_IsMainThread());
31 MOZ_ASSERT(mInputQueueState == STATE_ENABLED ||
32 mInputQueueState == STATE_FLUSHING);
33 mInputQueueState = STATE_SUSPEND;
36 void InputTaskManager::ResumeInputEventPrioritization() {
37 MOZ_ASSERT(NS_IsMainThread());
38 MOZ_ASSERT(mInputQueueState == STATE_SUSPEND);
39 mInputQueueState = STATE_ENABLED;
42 int32_t InputTaskManager::GetPriorityModifierForEventLoopTurn(
43 const MutexAutoLock& aProofOfLock) {
44 // When the state is disabled, the input task that we have is
45 // very likely SuspendInputEventQueue, so here we also use
46 // normal priority as ResumeInputEventQueue, FlushInputEventQueue and
47 // SetInputEventQueueEnabled all uses normal priority, to
48 // ensure the ordering is correct.
49 if (State() == InputTaskManager::STATE_DISABLED) {
50 return static_cast<int32_t>(EventQueuePriority::Normal) -
51 static_cast<int32_t>(EventQueuePriority::InputHigh);
54 return GetPriorityModifierForEventLoopTurnForStrictVsyncAlignment();
57 void InputTaskManager::WillRunTask() {
58 TaskManager::WillRunTask();
59 mInputPriorityController.WillRunTask();
62 int32_t
63 InputTaskManager::GetPriorityModifierForEventLoopTurnForStrictVsyncAlignment() {
64 MOZ_ASSERT(!IsSuspended());
66 size_t inputCount = PendingTaskCount();
67 if (inputCount > 0 &&
68 mInputPriorityController.ShouldUseHighestPriority(this)) {
69 return static_cast<int32_t>(EventQueuePriority::InputHighest) -
70 static_cast<int32_t>(EventQueuePriority::InputHigh);
73 if (State() == STATE_FLUSHING ||
74 nsRefreshDriver::GetNextTickHint().isNothing()) {
75 return 0;
78 return static_cast<int32_t>(EventQueuePriority::InputLow) -
79 static_cast<int32_t>(EventQueuePriority::InputHigh);
82 InputTaskManager::InputPriorityController::InputPriorityController()
83 : mInputVsyncState(InputVsyncState::NoPendingVsync) {}
85 bool InputTaskManager::InputPriorityController::ShouldUseHighestPriority(
86 InputTaskManager* aInputTaskManager) {
87 if (mInputVsyncState == InputVsyncState::HasPendingVsync) {
88 return true;
91 if (mInputVsyncState == InputVsyncState::RunVsync) {
92 return false;
95 if (mInputVsyncState == InputVsyncState::NoPendingVsync &&
96 VsyncTaskManager::Get()->PendingTaskCount()) {
97 EnterPendingVsyncState(aInputTaskManager->PendingTaskCount());
98 return true;
101 return false;
104 void InputTaskManager::InputPriorityController::EnterPendingVsyncState(
105 uint32_t aNumPendingTasks) {
106 MOZ_ASSERT(mInputVsyncState == InputVsyncState::NoPendingVsync);
108 mInputVsyncState = InputVsyncState::HasPendingVsync;
109 mMaxInputTasksToRun = aNumPendingTasks;
110 mRunInputStartTime = TimeStamp::Now();
113 void InputTaskManager::InputPriorityController::WillRunVsync() {
114 if (mInputVsyncState == InputVsyncState::RunVsync ||
115 mInputVsyncState == InputVsyncState::HasPendingVsync) {
116 LeavePendingVsyncState(false);
120 void InputTaskManager::InputPriorityController::LeavePendingVsyncState(
121 bool aRunVsync) {
122 if (aRunVsync) {
123 MOZ_ASSERT(mInputVsyncState == InputVsyncState::HasPendingVsync);
124 mInputVsyncState = InputVsyncState::RunVsync;
125 } else {
126 mInputVsyncState = InputVsyncState::NoPendingVsync;
129 mMaxInputTasksToRun = 0;
132 void InputTaskManager::InputPriorityController::WillRunTask() {
133 switch (mInputVsyncState) {
134 case InputVsyncState::NoPendingVsync:
135 return;
136 case InputVsyncState::HasPendingVsync:
137 MOZ_ASSERT(mMaxInputTasksToRun > 0);
138 --mMaxInputTasksToRun;
139 if (!mMaxInputTasksToRun ||
140 TimeStamp::Now() - mRunInputStartTime >=
141 TimeDuration::FromMilliseconds(
142 StaticPrefs::dom_input_event_queue_duration_max())) {
143 LeavePendingVsyncState(true);
145 return;
146 default:
147 MOZ_DIAGNOSTIC_ASSERT(
148 false, "Shouldn't run this input task when we suppose to run vsync");
149 return;
153 // static
154 void InputTaskManager::Init() { gInputTaskManager = new InputTaskManager(); }
156 } // namespace mozilla