Bug 1925561 - Use a quicker radius calculation for ArcParams. r=aosmond
[gecko.git] / xpcom / threads / EventQueue.cpp
blob0decc3ce4ce2642fba3c1e810c5f843fc7e3df16
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 "mozilla/EventQueue.h"
9 #include "GeckoProfiler.h"
10 #include "InputTaskManager.h"
11 #include "VsyncTaskManager.h"
12 #include "nsIRunnable.h"
13 #include "TaskController.h"
15 using namespace mozilla;
16 using namespace mozilla::detail;
18 template <size_t ItemsPerPage>
19 void EventQueueInternal<ItemsPerPage>::PutEvent(
20 already_AddRefed<nsIRunnable>&& aEvent, EventQueuePriority aPriority,
21 const MutexAutoLock& aProofOfLock, mozilla::TimeDuration* aDelay) {
22 nsCOMPtr<nsIRunnable> event(aEvent);
24 static_assert(static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_IDLE) ==
25 static_cast<uint32_t>(EventQueuePriority::Idle));
26 static_assert(static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_NORMAL) ==
27 static_cast<uint32_t>(EventQueuePriority::Normal));
28 static_assert(
29 static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_MEDIUMHIGH) ==
30 static_cast<uint32_t>(EventQueuePriority::MediumHigh));
31 static_assert(
32 static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_INPUT_HIGH) ==
33 static_cast<uint32_t>(EventQueuePriority::InputHigh));
34 static_assert(static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_VSYNC) ==
35 static_cast<uint32_t>(EventQueuePriority::Vsync));
36 static_assert(
37 static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_RENDER_BLOCKING) ==
38 static_cast<uint32_t>(EventQueuePriority::RenderBlocking));
39 static_assert(static_cast<uint32_t>(nsIRunnablePriority::PRIORITY_CONTROL) ==
40 static_cast<uint32_t>(EventQueuePriority::Control));
42 if (mForwardToTC) {
43 TaskController* tc = TaskController::Get();
45 TaskManager* manager = nullptr;
46 if (aPriority == EventQueuePriority::InputHigh) {
47 manager = InputTaskManager::Get();
48 } else if (aPriority == EventQueuePriority::DeferredTimers ||
49 aPriority == EventQueuePriority::Idle) {
50 manager = TaskController::Get()->GetIdleTaskManager();
51 } else if (aPriority == EventQueuePriority::Vsync) {
52 manager = VsyncTaskManager::Get();
55 tc->DispatchRunnable(event.forget(), static_cast<uint32_t>(aPriority),
56 manager);
57 return;
60 if (profiler_thread_is_being_profiled(ThreadProfilingFeatures::Sampling)) {
61 // check to see if the profiler has been enabled since the last PutEvent
62 while (mDispatchTimes.Count() < mQueue.Count()) {
63 mDispatchTimes.Push(TimeStamp());
65 mDispatchTimes.Push(aDelay ? TimeStamp::Now() - *aDelay : TimeStamp::Now());
68 mQueue.Push(std::move(event));
71 template <size_t ItemsPerPage>
72 already_AddRefed<nsIRunnable> EventQueueInternal<ItemsPerPage>::GetEvent(
73 const MutexAutoLock& aProofOfLock, mozilla::TimeDuration* aLastEventDelay) {
74 if (mQueue.IsEmpty()) {
75 if (aLastEventDelay) {
76 *aLastEventDelay = TimeDuration();
78 return nullptr;
81 // We always want to clear the dispatch times, even if the profiler is turned
82 // off, because we want to empty the (previously-collected) dispatch times, if
83 // any, from when the profiler was turned on. We only want to do something
84 // interesting with the dispatch times if the profiler is turned on, though.
85 if (!mDispatchTimes.IsEmpty()) {
86 TimeStamp dispatch_time = mDispatchTimes.Pop();
87 if (profiler_is_active()) {
88 if (!dispatch_time.IsNull()) {
89 if (aLastEventDelay) {
90 *aLastEventDelay = TimeStamp::Now() - dispatch_time;
94 } else if (profiler_is_active()) {
95 if (aLastEventDelay) {
96 // if we just turned on the profiler, we don't have dispatch
97 // times for events already in the queue.
98 *aLastEventDelay = TimeDuration();
102 nsCOMPtr<nsIRunnable> result = mQueue.Pop();
103 return result.forget();
106 template <size_t ItemsPerPage>
107 bool EventQueueInternal<ItemsPerPage>::IsEmpty(
108 const MutexAutoLock& aProofOfLock) {
109 return mQueue.IsEmpty();
112 template <size_t ItemsPerPage>
113 bool EventQueueInternal<ItemsPerPage>::HasReadyEvent(
114 const MutexAutoLock& aProofOfLock) {
115 return !IsEmpty(aProofOfLock);
118 template <size_t ItemsPerPage>
119 size_t EventQueueInternal<ItemsPerPage>::Count(
120 const MutexAutoLock& aProofOfLock) const {
121 return mQueue.Count();
124 namespace mozilla {
125 template class EventQueueSized<16>; // Used by ThreadEventQueue
126 template class EventQueueSized<64>; // Used by ThrottledEventQueue
127 namespace detail {
128 template class EventQueueInternal<16>; // Used by ThreadEventQueue
129 template class EventQueueInternal<64>; // Used by ThrottledEventQueue
130 } // namespace detail
131 } // namespace mozilla