mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1389314
Part2: Support enabling and disabling the input priority events in runtime. r=smaug.
MozReview-Commit-ID: 3a2TNVqguVb
This commit is contained in:
parent
60d437ddc2
commit
2c638fc04f
@ -190,6 +190,7 @@ NativeInputRunnable::NativeInputRunnable(already_AddRefed<nsIRunnable>&& aEvent)
|
||||
/* static */ already_AddRefed<nsIRunnable>
|
||||
NativeInputRunnable::Create(already_AddRefed<nsIRunnable>&& aEvent)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIRunnable> event(new NativeInputRunnable(Move(aEvent)));
|
||||
return event.forget();
|
||||
}
|
||||
|
@ -1203,9 +1203,6 @@ ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
|
||||
GfxInfoBase::SetFeatureStatus(aXPCOMInit.gfxFeatureStatus());
|
||||
|
||||
DataStorage::SetCachedStorageEntries(aXPCOMInit.dataStorage());
|
||||
|
||||
// Enable input event prioritization.
|
||||
nsThreadManager::get().EnableMainThreadEventPrioritization();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
@ -3599,6 +3596,34 @@ ContentChild::RecvResetCodeCoverageCounters()
|
||||
#endif
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvSetInputEventQueueEnabled()
|
||||
{
|
||||
nsThreadManager::get().EnableMainThreadEventPrioritization();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvFlushInputEventQueue()
|
||||
{
|
||||
nsThreadManager::get().FlushInputEventPrioritization();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvSuspendInputEventQueue()
|
||||
{
|
||||
nsThreadManager::get().SuspendInputEventPrioritization();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvResumeInputEventQueue()
|
||||
{
|
||||
nsThreadManager::get().ResumeInputEventPrioritization();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIEventTarget>
|
||||
ContentChild::GetSpecificMessageEventTarget(const Message& aMsg)
|
||||
{
|
||||
|
@ -621,6 +621,18 @@ public:
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvResetCodeCoverageCounters() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvSetInputEventQueueEnabled() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvFlushInputEventQueue() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvSuspendInputEventQueue() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvResumeInputEventQueue() override;
|
||||
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
bool
|
||||
SendGetA11yContentId();
|
||||
|
@ -2094,6 +2094,8 @@ ContentParent::ContentParent(ContentParent* aOpener,
|
||||
, mCreatedPairedMinidumps(false)
|
||||
, mShutdownPending(false)
|
||||
, mIPCOpen(true)
|
||||
, mIsRemoteInputEventQueueEnabled(false)
|
||||
, mIsInputPriorityEventEnabled(false)
|
||||
, mHangMonitorActor(nullptr)
|
||||
{
|
||||
// Insert ourselves into the global linked list of ContentParent objects.
|
||||
@ -2444,6 +2446,7 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
||||
// If this isn't our first content process, just send over cached list.
|
||||
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
||||
pluginHost->SendPluginsToContent();
|
||||
MaybeEnableRemoteInputEventQueue();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2509,6 +2512,47 @@ ContentParent::OnCompositorDeviceReset()
|
||||
Unused << SendReinitRenderingForDeviceReset();
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::MaybeEnableRemoteInputEventQueue()
|
||||
{
|
||||
MOZ_ASSERT(!mIsRemoteInputEventQueueEnabled);
|
||||
if (!IsInputEventQueueSupported()) {
|
||||
return;
|
||||
}
|
||||
mIsRemoteInputEventQueueEnabled = true;
|
||||
Unused << SendSetInputEventQueueEnabled();
|
||||
SetInputPriorityEventEnabled(true);
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::SetInputPriorityEventEnabled(bool aEnabled)
|
||||
{
|
||||
if (!IsInputEventQueueSupported() ||
|
||||
!mIsRemoteInputEventQueueEnabled ||
|
||||
mIsInputPriorityEventEnabled == aEnabled) {
|
||||
return;
|
||||
}
|
||||
mIsInputPriorityEventEnabled = aEnabled;
|
||||
// Send IPC messages to flush the pending events in the input event queue and
|
||||
// the normal event queue. See PContent.ipdl for more details.
|
||||
Unused << SendSuspendInputEventQueue();
|
||||
Unused << SendFlushInputEventQueue();
|
||||
Unused << SendResumeInputEventQueue();
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
ContentParent::IsInputEventQueueSupported()
|
||||
{
|
||||
static bool sSupported = false;
|
||||
static bool sInitialized = false;
|
||||
if (!sInitialized) {
|
||||
MOZ_ASSERT(Preferences::IsServiceAvailable());
|
||||
sSupported = Preferences::GetBool("input_event_queue.supported", false);
|
||||
sInitialized = true;
|
||||
}
|
||||
return sSupported;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::OnVarChanged(const GfxVarUpdate& aVar)
|
||||
{
|
||||
|
@ -638,6 +638,15 @@ public:
|
||||
|
||||
void OnCompositorDeviceReset() override;
|
||||
|
||||
// Control the priority of the IPC messages for input events.
|
||||
void SetInputPriorityEventEnabled(bool aEnabled);
|
||||
bool IsInputPriorityEventEnabled()
|
||||
{
|
||||
return mIsInputPriorityEventEnabled;
|
||||
}
|
||||
|
||||
static bool IsInputEventQueueSupported();
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) override;
|
||||
|
||||
@ -1171,6 +1180,11 @@ private:
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvBHRThreadHang(
|
||||
const HangDetails& aHangDetails) override;
|
||||
|
||||
// Notify the ContentChild to enable the input event prioritization when
|
||||
// initializing.
|
||||
void MaybeEnableRemoteInputEventQueue();
|
||||
|
||||
public:
|
||||
void SendGetFilesResponseAndForget(const nsID& aID,
|
||||
const GetFilesResponseResult& aResult);
|
||||
@ -1233,6 +1247,14 @@ private:
|
||||
bool mShutdownPending;
|
||||
bool mIPCOpen;
|
||||
|
||||
// True if the input event queue on the main thread of the content process is
|
||||
// enabled.
|
||||
bool mIsRemoteInputEventQueueEnabled;
|
||||
|
||||
// True if we send input events with input priority. Otherwise, we send input
|
||||
// events with normal priority.
|
||||
bool mIsInputPriorityEventEnabled;
|
||||
|
||||
RefPtr<nsConsoleService> mConsoleService;
|
||||
nsConsoleService* GetConsoleService();
|
||||
nsCOMPtr<nsIContentProcessInfo> mScriptableHelper;
|
||||
|
@ -655,6 +655,11 @@ child:
|
||||
prio(input) async RealMouseMoveEvent(WidgetMouseEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId) compress;
|
||||
|
||||
async NormalPriorityRealMouseMoveEvent(WidgetMouseEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId) compress;
|
||||
|
||||
/**
|
||||
* Mouse move events with |reason == eSynthesized| are sent via a separate
|
||||
* message because they do not generate DOM 'mousemove' events, and the
|
||||
@ -665,26 +670,59 @@ child:
|
||||
prio(input) async SynthMouseMoveEvent(WidgetMouseEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
async NormalPrioritySynthMouseMoveEvent(WidgetMouseEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
|
||||
prio(input) async RealMouseButtonEvent(WidgetMouseEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
async NormalPriorityRealMouseButtonEvent(WidgetMouseEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
|
||||
prio(input) async RealKeyEvent(WidgetKeyboardEvent event);
|
||||
async NormalPriorityRealKeyEvent(WidgetKeyboardEvent event);
|
||||
|
||||
prio(input) async MouseWheelEvent(WidgetWheelEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
async NormalPriorityMouseWheelEvent(WidgetWheelEvent event,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
|
||||
prio(input) async RealTouchEvent(WidgetTouchEvent aEvent,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId,
|
||||
nsEventStatus aApzResponse);
|
||||
async NormalPriorityRealTouchEvent(WidgetTouchEvent aEvent,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId,
|
||||
nsEventStatus aApzResponse);
|
||||
|
||||
prio(input) async HandleTap(TapType aType, LayoutDevicePoint point,
|
||||
Modifiers aModifiers, ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
async NormalPriorityHandleTap(TapType aType, LayoutDevicePoint point,
|
||||
Modifiers aModifiers, ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId);
|
||||
|
||||
prio(input) async RealTouchMoveEvent(WidgetTouchEvent aEvent,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId,
|
||||
nsEventStatus aApzResponse);
|
||||
prio(input) async RealDragEvent(WidgetDragEvent aEvent,
|
||||
uint32_t aDragAction, uint32_t aDropEffect);
|
||||
async NormalPriorityRealTouchMoveEvent(WidgetTouchEvent aEvent,
|
||||
ScrollableLayerGuid aGuid,
|
||||
uint64_t aInputBlockId,
|
||||
nsEventStatus aApzResponse);
|
||||
|
||||
/*
|
||||
* We disable the input event queue when there is an active dnd session. We
|
||||
* don't need support RealDragEvent with input priority.
|
||||
*/
|
||||
async RealDragEvent(WidgetDragEvent aEvent, uint32_t aDragAction,
|
||||
uint32_t aDropEffect);
|
||||
|
||||
async PluginEvent(WidgetPluginEvent aEvent);
|
||||
|
||||
/**
|
||||
|
@ -605,6 +605,65 @@ child:
|
||||
async DumpCodeCoverageCounters();
|
||||
async ResetCodeCoverageCounters();
|
||||
|
||||
/*
|
||||
* IPC message to enable the input event queue on the main thread of the
|
||||
* content process.
|
||||
*/
|
||||
async SetInputEventQueueEnabled();
|
||||
|
||||
/*
|
||||
* IPC message to flush the input event queue on the main thread of the
|
||||
* content process.
|
||||
*
|
||||
* When the ContentParent stops sending the input event with input priority,
|
||||
* there may be some pending events in the input event queue and normal
|
||||
* event queue. Here is a possible scenario.
|
||||
* R: Runnables.
|
||||
* D: Enable the input priority event.
|
||||
* E: Disable the input priority evnet.
|
||||
*
|
||||
* D E
|
||||
* Normal Queue: R1 R2 R3
|
||||
* Input Queue: II I2 I3
|
||||
*
|
||||
* To avoid the newly added normal events (e.g. R2, which may be an input
|
||||
* event) preempt the pending input events (e.g. I1), or the newly added
|
||||
* input events (e.g. I3) preempt the pending normal events (e.g. R2), we
|
||||
* have to flush all pending events before enabling and disabling the input
|
||||
* priority event.
|
||||
*
|
||||
* To flush the normal event queue and the input event queue, we use three
|
||||
* IPC messages as the followings.
|
||||
* FI: Flush the input queue.
|
||||
* SI: Suspend the input queue.
|
||||
* RI: Resume the input queue.
|
||||
*
|
||||
* Normal Queue: R1 FI RI R2 FI RI R3
|
||||
* Input Queue: II SI I2 SI I3
|
||||
*
|
||||
* When the flush input request is processed before the other two requests,
|
||||
* we consume all input events until the suspend request. After handling the
|
||||
* suspend request, we stop consuming the input events until the resume
|
||||
* request to make sure we consume all pending normal events.
|
||||
*
|
||||
* If we process the suspend request before the other two requests, we
|
||||
* ignore the flush request and consume all pending normal events until the
|
||||
* resume request.
|
||||
*/
|
||||
async FlushInputEventQueue();
|
||||
|
||||
/*
|
||||
* IPC message to resume consuming the pending events in the input event
|
||||
* queue.
|
||||
*/
|
||||
async ResumeInputEventQueue();
|
||||
|
||||
/*
|
||||
* IPC message to suspend consuming the pending events in the input event
|
||||
* queue.
|
||||
*/
|
||||
prio(input) async SuspendInputEventQueue();
|
||||
|
||||
parent:
|
||||
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
||||
|
||||
|
@ -1416,6 +1416,17 @@ TabChild::RecvHandleTap(const GeckoContentController::TapType& aType,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityHandleTap(
|
||||
const GeckoContentController::TapType& aType,
|
||||
const LayoutDevicePoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId)
|
||||
{
|
||||
return RecvHandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::NotifyAPZStateChange(const ViewID& aViewId,
|
||||
const layers::GeckoContentController::APZStateChange& aChange,
|
||||
@ -1615,6 +1626,14 @@ TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& aEvent,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityRealMouseMoveEvent(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId)
|
||||
{
|
||||
return RecvRealMouseMoveEvent(aEvent, aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvSynthMouseMoveEvent(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
@ -1626,6 +1645,14 @@ TabChild::RecvSynthMouseMoveEvent(const WidgetMouseEvent& aEvent,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPrioritySynthMouseMoveEvent(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId)
|
||||
{
|
||||
return RecvSynthMouseMoveEvent(aEvent, aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
@ -1669,6 +1696,14 @@ TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityRealMouseButtonEvent(
|
||||
const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId)
|
||||
{
|
||||
return RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
// In case handling repeated mouse wheel takes much time, we skip firing current
|
||||
// wheel event if it may be coalesced to the next one.
|
||||
@ -1787,6 +1822,14 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityMouseWheelEvent(const WidgetWheelEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId)
|
||||
{
|
||||
return RecvMouseWheelEvent(aEvent, aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
@ -1828,6 +1871,15 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse)
|
||||
{
|
||||
return RecvRealTouchEvent(aEvent, aGuid, aInputBlockId, aApzResponse);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
@ -1840,6 +1892,16 @@ TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityRealTouchMoveEvent(
|
||||
const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse)
|
||||
{
|
||||
return RecvRealTouchMoveEvent(aEvent, aGuid, aInputBlockId, aApzResponse);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvRealDragEvent(const WidgetDragEvent& aEvent,
|
||||
const uint32_t& aDragAction,
|
||||
@ -2018,6 +2080,12 @@ TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& aEvent)
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvNormalPriorityRealKeyEvent(const WidgetKeyboardEvent& aEvent)
|
||||
{
|
||||
return RecvRealKeyEvent(aEvent);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvKeyEvent(const nsString& aType,
|
||||
const int32_t& aKeyCode,
|
||||
|
@ -387,13 +387,26 @@ public:
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityRealMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSynthMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPrioritySynthMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvRealMouseButtonEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityRealMouseButtonEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvRealDragEvent(const WidgetDragEvent& aEvent,
|
||||
const uint32_t& aDragAction,
|
||||
@ -402,21 +415,41 @@ public:
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& aEvent) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityRealKeyEvent(const mozilla::WidgetKeyboardEvent& aEvent) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvKeyEvent(const nsString& aType,
|
||||
const int32_t& aKeyCode,
|
||||
const int32_t& aCharCode,
|
||||
@ -661,6 +694,14 @@ public:
|
||||
const Modifiers& aModifiers,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvNormalPriorityHandleTap(const layers::GeckoContentController::TapType& aType,
|
||||
const LayoutDevicePoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
void SetAllowedTouchBehavior(uint64_t aInputBlockId,
|
||||
const nsTArray<TouchBehaviorFlags>& aFlags) const;
|
||||
|
||||
|
@ -179,8 +179,7 @@ TabParent::TabParent(nsIContentParent* aManager,
|
||||
MOZ_ASSERT(aManager);
|
||||
// When the input event queue is disabled, we don't need to handle the case
|
||||
// that some input events are dispatched before PBrowserConstructor.
|
||||
mIsReadyToHandleInputEvents =
|
||||
!Preferences::GetBool("input_event_queue.supported", false);
|
||||
mIsReadyToHandleInputEvents = !ContentParent::IsInputEventQueueSupported();
|
||||
}
|
||||
|
||||
TabParent::~TabParent()
|
||||
@ -1154,6 +1153,9 @@ TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent)
|
||||
uint64_t blockId;
|
||||
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
|
||||
|
||||
bool isInputPriorityEventEnabled =
|
||||
Manager()->AsContentParent()->IsInputPriorityEventEnabled();
|
||||
|
||||
if (mIsMouseEnterIntoWidgetEventSuppressed) {
|
||||
// In the case that the TabParent suppressed the eMouseEnterWidget event due
|
||||
// to its corresponding TabChild wasn't ready to handle it, we have to
|
||||
@ -1161,25 +1163,33 @@ TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent)
|
||||
mIsMouseEnterIntoWidgetEventSuppressed = false;
|
||||
WidgetMouseEvent localEvent(aEvent);
|
||||
localEvent.mMessage = eMouseEnterIntoWidget;
|
||||
DebugOnly<bool> ret = SendRealMouseButtonEvent(localEvent, guid, blockId);
|
||||
DebugOnly<bool> ret = isInputPriorityEventEnabled
|
||||
? SendRealMouseButtonEvent(localEvent, guid, blockId)
|
||||
: SendNormalPriorityRealMouseButtonEvent(localEvent, guid, blockId);
|
||||
NS_WARNING_ASSERTION(ret, "SendRealMouseButtonEvent(eMouseEnterIntoWidget) failed");
|
||||
MOZ_ASSERT(!ret || localEvent.HasBeenPostedToRemoteProcess());
|
||||
}
|
||||
|
||||
if (eMouseMove == aEvent.mMessage) {
|
||||
if (aEvent.mReason == WidgetMouseEvent::eSynthesized) {
|
||||
DebugOnly<bool> ret = SendSynthMouseMoveEvent(aEvent, guid, blockId);
|
||||
DebugOnly<bool> ret = isInputPriorityEventEnabled
|
||||
? SendSynthMouseMoveEvent(aEvent, guid, blockId)
|
||||
: SendNormalPrioritySynthMouseMoveEvent(aEvent, guid, blockId);
|
||||
NS_WARNING_ASSERTION(ret, "SendSynthMouseMoveEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
return;
|
||||
}
|
||||
DebugOnly<bool> ret = SendRealMouseMoveEvent(aEvent, guid, blockId);
|
||||
DebugOnly<bool> ret = isInputPriorityEventEnabled
|
||||
? SendRealMouseMoveEvent(aEvent, guid, blockId)
|
||||
: SendNormalPriorityRealMouseMoveEvent(aEvent, guid, blockId);
|
||||
NS_WARNING_ASSERTION(ret, "SendRealMouseMoveEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
return;
|
||||
}
|
||||
|
||||
DebugOnly<bool> ret = SendRealMouseButtonEvent(aEvent, guid, blockId);
|
||||
DebugOnly<bool> ret = isInputPriorityEventEnabled
|
||||
? SendRealMouseButtonEvent(aEvent, guid, blockId)
|
||||
: SendNormalPriorityRealMouseButtonEvent(aEvent, guid, blockId);
|
||||
NS_WARNING_ASSERTION(ret, "SendRealMouseButtonEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
}
|
||||
@ -1275,6 +1285,7 @@ TabParent::SendRealDragEvent(WidgetDragEvent& aEvent, uint32_t aDragAction,
|
||||
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!Manager()->AsContentParent()->IsInputPriorityEventEnabled());
|
||||
aEvent.mRefPoint += GetChildProcessOffset();
|
||||
if (aEvent.mMessage == eDrop) {
|
||||
if (!QueryDropLinksForVerification()) {
|
||||
@ -1305,7 +1316,10 @@ TabParent::SendMouseWheelEvent(WidgetWheelEvent& aEvent)
|
||||
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
|
||||
aEvent.mRefPoint += GetChildProcessOffset();
|
||||
DebugOnly<bool> ret =
|
||||
PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId);
|
||||
Manager()->AsContentParent()->IsInputPriorityEventEnabled()
|
||||
? PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId)
|
||||
: PBrowserParent::SendNormalPriorityMouseWheelEvent(aEvent, guid, blockId);
|
||||
|
||||
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendMouseWheelEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
}
|
||||
@ -1587,8 +1601,11 @@ TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent)
|
||||
} else {
|
||||
aEvent.PreventNativeKeyBindings();
|
||||
}
|
||||
DebugOnly<bool> ret =
|
||||
Manager()->AsContentParent()->IsInputPriorityEventEnabled()
|
||||
? PBrowserParent::SendRealKeyEvent(aEvent)
|
||||
: PBrowserParent::SendNormalPriorityRealKeyEvent(aEvent);
|
||||
|
||||
DebugOnly<bool> ret = PBrowserParent::SendRealKeyEvent(aEvent);
|
||||
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealKeyEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
}
|
||||
@ -1626,18 +1643,27 @@ TabParent::SendRealTouchEvent(WidgetTouchEvent& aEvent)
|
||||
aEvent.mTouches[i]->mRefPoint += offset;
|
||||
}
|
||||
|
||||
bool inputPriorityEventEnabled =
|
||||
Manager()->AsContentParent()->IsInputPriorityEventEnabled();
|
||||
|
||||
if (aEvent.mMessage == eTouchMove) {
|
||||
DebugOnly<bool> ret =
|
||||
PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId,
|
||||
apzResponse);
|
||||
DebugOnly<bool> ret = inputPriorityEventEnabled
|
||||
? PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId,
|
||||
apzResponse)
|
||||
: PBrowserParent::SendNormalPriorityRealTouchMoveEvent(aEvent, guid,
|
||||
blockId,
|
||||
apzResponse);
|
||||
|
||||
NS_WARNING_ASSERTION(ret,
|
||||
"PBrowserParent::SendRealTouchMoveEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
return;
|
||||
}
|
||||
DebugOnly<bool> ret = inputPriorityEventEnabled
|
||||
? PBrowserParent::SendRealTouchEvent(aEvent, guid, blockId, apzResponse)
|
||||
: PBrowserParent::SendNormalPriorityRealTouchEvent(aEvent, guid, blockId,
|
||||
apzResponse);
|
||||
|
||||
DebugOnly<bool> ret =
|
||||
PBrowserParent::SendRealTouchEvent(aEvent, guid, blockId, apzResponse);
|
||||
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealTouchEvent() failed");
|
||||
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
|
||||
}
|
||||
@ -1665,8 +1691,12 @@ TabParent::SendHandleTap(TapType aType,
|
||||
GetRenderFrame()->TakeFocusForClickFromTap();
|
||||
}
|
||||
LayoutDeviceIntPoint offset = GetChildProcessOffset();
|
||||
return PBrowserParent::SendHandleTap(aType, aPoint + offset, aModifiers,
|
||||
aGuid, aInputBlockId);
|
||||
return Manager()->AsContentParent()->IsInputPriorityEventEnabled()
|
||||
? PBrowserParent::SendHandleTap(aType, aPoint + offset, aModifiers, aGuid,
|
||||
aInputBlockId)
|
||||
: PBrowserParent::SendNormalPriorityHandleTap(aType, aPoint + offset,
|
||||
aModifiers, aGuid,
|
||||
aInputBlockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -56,6 +56,9 @@ public:
|
||||
virtual size_t Count(const MutexAutoLock& aProofOfLock) const = 0;
|
||||
|
||||
virtual void EnableInputEventPrioritization(const MutexAutoLock& aProofOfLock) = 0;
|
||||
virtual void FlushInputEventPrioritization(const MutexAutoLock& aProofOfLock) = 0;
|
||||
virtual void SuspendInputEventPrioritization(const MutexAutoLock& aProofOfLock) = 0;
|
||||
virtual void ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock) = 0;
|
||||
|
||||
virtual ~AbstractEventQueue() {}
|
||||
};
|
||||
|
@ -31,6 +31,9 @@ public:
|
||||
already_AddRefed<nsIRunnable> PeekEvent(const MutexAutoLock& aProofOfLock);
|
||||
|
||||
void EnableInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {}
|
||||
void FlushInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {}
|
||||
void SuspendInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {}
|
||||
void ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {}
|
||||
|
||||
private:
|
||||
mozilla::Queue<nsCOMPtr<nsIRunnable>> mQueue;
|
||||
|
@ -46,7 +46,7 @@ PrioritizedEventQueue<InnerQueueT>::PutEvent(already_AddRefed<nsIRunnable>&& aEv
|
||||
}
|
||||
}
|
||||
|
||||
if (priority == EventPriority::Input && !mWriteToInputQueue) {
|
||||
if (priority == EventPriority::Input && mInputQueueState == STATE_DISABLED) {
|
||||
priority = EventPriority::Normal;
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ PrioritizedEventQueue<InnerQueueT>::GetEvent(EventPriority* aPriority,
|
||||
bool normalPending = mNormalQueue->HasPendingEvent(aProofOfLock);
|
||||
size_t inputCount = mInputQueue->Count(aProofOfLock);
|
||||
|
||||
if (mReadFromInputQueue && mInputHandlingStartTime.IsNull() && inputCount > 0) {
|
||||
if (mInputQueueState == STATE_ENABLED && mInputHandlingStartTime.IsNull() && inputCount > 0) {
|
||||
mInputHandlingStartTime =
|
||||
InputEventStatistics::Get()
|
||||
.GetInputHandlingStartTime(inputCount);
|
||||
@ -161,21 +161,27 @@ PrioritizedEventQueue<InnerQueueT>::GetEvent(EventPriority* aPriority,
|
||||
|
||||
if (mProcessHighPriorityQueue) {
|
||||
queue = EventPriority::High;
|
||||
} else if (inputCount > 0 && TimeStamp::Now() > mInputHandlingStartTime
|
||||
&& mReadFromInputQueue) {
|
||||
} else if (inputCount > 0 && (mInputQueueState == STATE_FLUSHING ||
|
||||
(mInputQueueState == STATE_ENABLED &&
|
||||
TimeStamp::Now() > mInputHandlingStartTime))) {
|
||||
queue = EventPriority::Input;
|
||||
} else if (normalPending) {
|
||||
MOZ_ASSERT(mInputQueueState != STATE_FLUSHING,
|
||||
"Shouldn't consume normal event when flusing input events");
|
||||
queue = EventPriority::Normal;
|
||||
} else if (highPending) {
|
||||
queue = EventPriority::High;
|
||||
} else if (inputCount > 0 && mReadFromInputQueue) {
|
||||
} else if (inputCount > 0 && mInputQueueState != STATE_SUSPEND) {
|
||||
MOZ_ASSERT(mInputQueueState != STATE_DISABLED,
|
||||
"Shouldn't consume input events when the input queue is disabled");
|
||||
queue = EventPriority::Input;
|
||||
} else {
|
||||
// We may not actually return an idle event in this case.
|
||||
queue = EventPriority::Idle;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(queue == EventPriority::Input, mReadFromInputQueue);
|
||||
MOZ_ASSERT_IF(queue == EventPriority::Input,
|
||||
mInputQueueState != STATE_DISABLED && mInputQueueState != STATE_SUSPEND);
|
||||
|
||||
mProcessHighPriorityQueue = highPending;
|
||||
|
||||
@ -266,46 +272,41 @@ PrioritizedEventQueue<InnerQueueT>::Count(const MutexAutoLock& aProofOfLock) con
|
||||
MOZ_CRASH("unimplemented");
|
||||
}
|
||||
|
||||
// This is used to flush pending events in nsChainedEventQueue::mNormalQueue
|
||||
// before starting event prioritization.
|
||||
template<class InnerQueueT>
|
||||
class PrioritizedEventQueue<InnerQueueT>::EnablePrioritizationRunnable final
|
||||
: public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
explicit EnablePrioritizationRunnable(PrioritizedEventQueue<InnerQueueT>* aQueue)
|
||||
: Runnable("EnablePrioritizationRunnable")
|
||||
, mQueue(aQueue)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
// Do don't need to do this with the lock held because mReadFromInputQueue
|
||||
// is only read from the main thread.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mQueue->mWriteToInputQueue);
|
||||
MOZ_ASSERT(!mQueue->mReadFromInputQueue);
|
||||
mQueue->mReadFromInputQueue = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
// This is a weak pointer. It's guaranteed to stay alive until this runnable
|
||||
// runs since it functions as the event loop in which the runnable is posted.
|
||||
PrioritizedEventQueue<InnerQueueT>* mQueue;
|
||||
};
|
||||
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
PrioritizedEventQueue<InnerQueueT>::EnableInputEventPrioritization(const MutexAutoLock& aProofOfLock)
|
||||
{
|
||||
MOZ_ASSERT(!mWriteToInputQueue);
|
||||
MOZ_ASSERT(!mReadFromInputQueue);
|
||||
mWriteToInputQueue = true;
|
||||
MOZ_ASSERT(mInputQueueState == STATE_DISABLED);
|
||||
mInputQueueState = STATE_ENABLED;
|
||||
mInputHandlingStartTime = TimeStamp();
|
||||
}
|
||||
|
||||
RefPtr<EnablePrioritizationRunnable> runnable = new EnablePrioritizationRunnable(this);
|
||||
PutEvent(runnable.forget(), EventPriority::Normal, aProofOfLock);
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
PrioritizedEventQueue<InnerQueueT>::
|
||||
FlushInputEventPrioritization(const MutexAutoLock& aProofOfLock)
|
||||
{
|
||||
MOZ_ASSERT(mInputQueueState == STATE_ENABLED || mInputQueueState == STATE_SUSPEND);
|
||||
mInputQueueState =
|
||||
mInputQueueState == STATE_ENABLED ? STATE_FLUSHING : STATE_SUSPEND;
|
||||
}
|
||||
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
PrioritizedEventQueue<InnerQueueT>::
|
||||
SuspendInputEventPrioritization(const MutexAutoLock& aProofOfLock)
|
||||
{
|
||||
MOZ_ASSERT(mInputQueueState == STATE_ENABLED || mInputQueueState == STATE_FLUSHING);
|
||||
mInputQueueState = STATE_SUSPEND;
|
||||
}
|
||||
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
PrioritizedEventQueue<InnerQueueT>::
|
||||
ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock)
|
||||
{
|
||||
MOZ_ASSERT(mInputQueueState == STATE_SUSPEND);
|
||||
mInputQueueState = STATE_ENABLED;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -65,10 +65,11 @@ public:
|
||||
void SetNextIdleDeadlineRef(TimeStamp& aDeadline) { mNextIdleDeadline = &aDeadline; }
|
||||
|
||||
void EnableInputEventPrioritization(const MutexAutoLock& aProofOfLock) final;
|
||||
void FlushInputEventPrioritization(const MutexAutoLock& aProofOfLock) final;
|
||||
void SuspendInputEventPrioritization(const MutexAutoLock& aProofOfLock) final;
|
||||
void ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock) final;
|
||||
|
||||
private:
|
||||
class EnablePrioritizationRunnable;
|
||||
|
||||
// Returns a null TimeStamp if we're not in the idle period.
|
||||
mozilla::TimeStamp GetIdleDeadline();
|
||||
|
||||
@ -104,14 +105,14 @@ private:
|
||||
|
||||
TimeStamp mInputHandlingStartTime;
|
||||
|
||||
// When we enable input event prioritization, we immediately begin adding new
|
||||
// input events to the input event queue (and set
|
||||
// mWriteToInputQueue). However, we do not begin processing events from the
|
||||
// input queue until all events that were in the normal priority queue have
|
||||
// been processed. That ensures that input events will not jump ahead of
|
||||
// events that were in the queue before prioritization was enabled.
|
||||
bool mWriteToInputQueue = false;
|
||||
bool mReadFromInputQueue = false;
|
||||
enum InputEventQueueState
|
||||
{
|
||||
STATE_DISABLED,
|
||||
STATE_FLUSHING,
|
||||
STATE_SUSPEND,
|
||||
STATE_ENABLED
|
||||
};
|
||||
InputEventQueueState mInputQueueState = STATE_DISABLED;
|
||||
};
|
||||
|
||||
class EventQueue;
|
||||
|
@ -66,6 +66,9 @@ public:
|
||||
virtual void SetObserver(nsIThreadObserver* aObserver) = 0;
|
||||
|
||||
virtual void EnableInputEventPrioritization() = 0;
|
||||
virtual void FlushInputEventPrioritization() = 0;
|
||||
virtual void SuspendInputEventPrioritization() = 0;
|
||||
virtual void ResumeInputEventPrioritization() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~SynchronizedEventQueue() {}
|
||||
|
@ -175,6 +175,30 @@ ThreadEventQueue<InnerQueueT>::EnableInputEventPrioritization()
|
||||
mBaseQueue->EnableInputEventPrioritization(lock);
|
||||
}
|
||||
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
ThreadEventQueue<InnerQueueT>::FlushInputEventPrioritization()
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mBaseQueue->FlushInputEventPrioritization(lock);
|
||||
}
|
||||
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
ThreadEventQueue<InnerQueueT>::SuspendInputEventPrioritization()
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mBaseQueue->SuspendInputEventPrioritization(lock);
|
||||
}
|
||||
|
||||
template<class InnerQueueT>
|
||||
void
|
||||
ThreadEventQueue<InnerQueueT>::ResumeInputEventPrioritization()
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mBaseQueue->ResumeInputEventPrioritization(lock);
|
||||
}
|
||||
|
||||
template<class InnerQueueT>
|
||||
already_AddRefed<nsISerialEventTarget>
|
||||
ThreadEventQueue<InnerQueueT>::PushEventQueue()
|
||||
|
@ -49,6 +49,9 @@ public:
|
||||
void Disconnect(const MutexAutoLock& aProofOfLock) final {}
|
||||
|
||||
void EnableInputEventPrioritization() final;
|
||||
void FlushInputEventPrioritization() final;
|
||||
void SuspendInputEventPrioritization() final;
|
||||
void ResumeInputEventPrioritization() final;
|
||||
|
||||
/**
|
||||
* This method causes any events currently enqueued on the thread to be
|
||||
|
@ -105,6 +105,21 @@ public:
|
||||
EventQueue()->EnableInputEventPrioritization();
|
||||
}
|
||||
|
||||
void FlushInputEventPrioritization()
|
||||
{
|
||||
EventQueue()->FlushInputEventPrioritization();
|
||||
}
|
||||
|
||||
void SuspendInputEventPrioritization()
|
||||
{
|
||||
EventQueue()->SuspendInputEventPrioritization();
|
||||
}
|
||||
|
||||
void ResumeInputEventPrioritization()
|
||||
{
|
||||
EventQueue()->ResumeInputEventPrioritization();
|
||||
}
|
||||
|
||||
mozilla::TimeStamp& NextIdleDeadlineRef() { return mNextIdleDeadline; }
|
||||
|
||||
mozilla::SynchronizedEventQueue* EventQueue() { return mEvents.get(); }
|
||||
|
@ -434,21 +434,32 @@ nsThreadManager::DispatchToMainThread(nsIRunnable *aEvent, uint32_t aPriority)
|
||||
void
|
||||
nsThreadManager::EnableMainThreadEventPrioritization()
|
||||
{
|
||||
static bool sIsInitialized = false;
|
||||
if (sIsInitialized) {
|
||||
return;
|
||||
}
|
||||
sIsInitialized = true;
|
||||
MOZ_ASSERT(Preferences::IsServiceAvailable());
|
||||
bool supported = Preferences::GetBool("input_event_queue.supported", false);
|
||||
|
||||
if (!supported) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
InputEventStatistics::Get().SetEnable(true);
|
||||
mMainThread->EnableInputEventPrioritization();
|
||||
}
|
||||
|
||||
void
|
||||
nsThreadManager::FlushInputEventPrioritization()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMainThread->FlushInputEventPrioritization();
|
||||
}
|
||||
|
||||
void
|
||||
nsThreadManager::SuspendInputEventPrioritization()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMainThread->SuspendInputEventPrioritization();
|
||||
}
|
||||
|
||||
void
|
||||
nsThreadManager::ResumeInputEventPrioritization()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMainThread->ResumeInputEventPrioritization();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThreadManager::IdleDispatchToMainThread(nsIRunnable *aEvent, uint32_t aTimeout)
|
||||
{
|
||||
|
@ -55,6 +55,9 @@ public:
|
||||
}
|
||||
|
||||
void EnableMainThreadEventPrioritization();
|
||||
void FlushInputEventPrioritization();
|
||||
void SuspendInputEventPrioritization();
|
||||
void ResumeInputEventPrioritization();
|
||||
|
||||
private:
|
||||
nsThreadManager()
|
||||
|
Loading…
Reference in New Issue
Block a user