1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_InputTaskManager_h
#define mozilla_InputTaskManager_h
#include "nsTArray.h"
#include "nsXULAppAPI.h"
#include "TaskController.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StaticPrefs_dom.h"
namespace mozilla {
class InputTaskManager : public TaskManager {
public:
int32_t GetPriorityModifierForEventLoopTurn(
const MutexAutoLock& aProofOfLock) final;
void WillRunTask() final;
enum InputEventQueueState {
STATE_DISABLED,
STATE_FLUSHING,
STATE_SUSPEND,
STATE_ENABLED
};
void EnableInputEventPrioritization();
void FlushInputEventPrioritization();
void SuspendInputEventPrioritization();
void ResumeInputEventPrioritization();
InputEventQueueState State() { return mInputQueueState; }
void SetState(InputEventQueueState aState) { mInputQueueState = aState; }
static InputTaskManager* Get() { return gInputTaskManager.get(); }
static void Cleanup() { gInputTaskManager = nullptr; }
static void Init();
bool IsSuspended(const MutexAutoLock& aProofOfLock) override {
MOZ_ASSERT(NS_IsMainThread());
return mInputQueueState == STATE_SUSPEND || mSuspensionLevel > 0;
}
bool IsSuspended() {
MOZ_ASSERT(NS_IsMainThread());
return mSuspensionLevel > 0;
}
void IncSuspensionLevel() {
MOZ_ASSERT(NS_IsMainThread());
++mSuspensionLevel;
}
void DecSuspensionLevel() {
MOZ_ASSERT(NS_IsMainThread());
--mSuspensionLevel;
}
static bool CanSuspendInputEvent() {
// Ensure it's content process because InputTaskManager only
// works in e10s.
//
// Input tasks will have nullptr as their task manager when the
// event queue state is STATE_DISABLED, so we can't suspend
// input events.
return XRE_IsContentProcess() &&
StaticPrefs::dom_input_events_canSuspendInBCG_enabled() &&
InputTaskManager::Get()->State() !=
InputEventQueueState::STATE_DISABLED;
}
void NotifyVsync() { mInputPriorityController.WillRunVsync(); }
private:
InputTaskManager() : mInputQueueState(STATE_DISABLED) {}
class InputPriorityController {
public:
InputPriorityController();
// Determines whether we should use the highest input priority for input
// tasks
bool ShouldUseHighestPriority(InputTaskManager*);
void WillRunVsync();
// Gets called when a input task is going to run; If the current
// input vsync state is `HasPendingVsync`, determines whether we
// should continue running input tasks or leave the `HasPendingVsync` state
// based on
// 1. Whether we still have time to process input tasks
// 2. Whether we have processed the max number of tasks that
// we should process.
void WillRunTask();
private:
// Used to represents the relationship between Input and Vsync.
//
// HasPendingVsync: There are pending vsync tasks and we are using
// InputHighest priority for inputs.
// NoPendingVsync: No pending vsync tasks and no need to use InputHighest
// priority.
// RunVsync: Finished running input tasks and the vsync task
// should be run.
enum class InputVsyncState {
HasPendingVsync,
NoPendingVsync,
RunVsync,
};
void EnterPendingVsyncState(uint32_t aNumPendingTasks);
void LeavePendingVsyncState(bool aRunVsync);
// Stores the number of pending input tasks when we enter the
// InputVsyncState::HasPendingVsync state.
uint32_t mMaxInputTasksToRun = 0;
InputVsyncState mInputVsyncState;
TimeStamp mRunInputStartTime;
};
int32_t GetPriorityModifierForEventLoopTurnForStrictVsyncAlignment();
Atomic<InputEventQueueState> mInputQueueState;
static StaticRefPtr<InputTaskManager> gInputTaskManager;
// Number of BCGs have asked InputTaskManager to suspend input events
uint32_t mSuspensionLevel = 0;
InputPriorityController mInputPriorityController;
};
} // namespace mozilla
#endif // mozilla_InputTaskManager_h
|