diff --git a/build/clang-plugin/ThreadAllows.txt b/build/clang-plugin/ThreadAllows.txt index cb07842ba3be..934d226d4b62 100644 --- a/build/clang-plugin/ThreadAllows.txt +++ b/build/clang-plugin/ThreadAllows.txt @@ -14,11 +14,9 @@ COM MTA Cache Deleter Cache I/O Cameras IPC -Canvas ChainedPipePump ChainedPipeRecv Checker Test -Compositor Cookie CrashRep Inject DDMediaLogs @@ -43,7 +41,6 @@ IMAP IPC Launch IPDL Background IdentityCrypto -ImageBridgeChld LS Thread LayerScope MDCDMThread diff --git a/dom/media/systemservices/MediaSystemResourceManager.cpp b/dom/media/systemservices/MediaSystemResourceManager.cpp index ff02a10ed245..8d0a797c4be2 100644 --- a/dom/media/systemservices/MediaSystemResourceManager.cpp +++ b/dom/media/systemservices/MediaSystemResourceManager.cpp @@ -71,7 +71,7 @@ void MediaSystemResourceManager::Init() { barrier.NotifyAll(); }); - imageBridge->GetThread()->Dispatch(runnable.forget()); + imageBridge->GetMessageLoop()->PostTask(runnable.forget()); // should stop the thread until done. while (!done) { @@ -178,7 +178,7 @@ void MediaSystemResourceManager::Acquire(MediaSystemResourceClient* aClient) { return; } aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING; - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableMethod("MediaSystemResourceManager::DoAcquire", this, &MediaSystemResourceManager::DoAcquire, aClient->mId)); @@ -220,7 +220,7 @@ bool MediaSystemResourceManager::AcquireSyncNoWait( aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING; } - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableMethod("MediaSystemResourceManager::DoAcquire", this, &MediaSystemResourceManager::DoAcquire, aClient->mId)); @@ -282,7 +282,7 @@ void MediaSystemResourceManager::ReleaseResource( aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END; - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableMethod( "MediaSystemResourceManager::DoRelease", this, &MediaSystemResourceManager::DoRelease, aClient->mId)); @@ -304,7 +304,7 @@ void MediaSystemResourceManager::RecvResponse(uint32_t aId, bool aSuccess) { void MediaSystemResourceManager::HandleAcquireResult(uint32_t aId, bool aSuccess) { if (!InImageBridgeChildThread()) { - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableMethod( "MediaSystemResourceManager::HandleAcquireResult", this, &MediaSystemResourceManager::HandleAcquireResult, aId, aSuccess)); diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 108c9b3a1f0a..1135dec4a44e 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -551,7 +551,7 @@ class AsyncPluginSurfaceManager : public IGPUVideoSurfaceManager { if (!InImageBridgeChildThread()) { SynchronousTask task("AsyncPluginSurfaceManager readback sync"); RefPtr result; - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableFunction("AsyncPluginSurfaceManager readback", &DoSyncReadback, &pluginSD, &result, &task)); task.Wait(); @@ -565,7 +565,7 @@ class AsyncPluginSurfaceManager : public IGPUVideoSurfaceManager { const SurfaceDescriptorGPUVideo& aSD) override { SurfaceDescriptorPlugin pluginSD = aSD; if (!InImageBridgeChildThread()) { - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableFunction("AsyncPluginSurfaceManager dealloc", &DoDealloc, &pluginSD)); return; @@ -739,7 +739,7 @@ mozilla::ipc::IPCResult PluginInstanceParent::RecvInitDXGISurface( // render to. SurfaceDescriptorPlugin sd; SynchronousTask task("SendMakeAsyncPluginSurfaces sync"); - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch( + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( NewRunnableFunction("SendingMakeAsyncPluginSurfaces", &InitDXGISurface, format, size, &sd, &task)); task.Wait(); @@ -781,8 +781,9 @@ mozilla::ipc::IPCResult PluginInstanceParent::RecvFinalizeDXGISurface( // Release the plugin surface but keep the display surface since it may // still be displayed. Also let the display surface know that it should // not receive further requests to copy from the plugin surface. - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(NewRunnableFunction( - "SendingRemoveAsyncPluginSurface", &FinalizeDXGISurface, asi.mSD)); + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( + NewRunnableFunction("SendingRemoveAsyncPluginSurface", + &FinalizeDXGISurface, asi.mSD)); mAsyncSurfaceMap.remove(asiIt); #endif @@ -896,8 +897,9 @@ mozilla::ipc::IPCResult PluginInstanceParent::RecvShowDirectDXGISurface( // Tell the ImageBridge to copy from the plugin surface to the display surface SynchronousTask task("SendUpdateAsyncPluginSurface sync"); - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(NewRunnableFunction( - "SendingUpdateAsyncPluginSurface", &CopyDXGISurface, asi.mSD, &task)); + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( + NewRunnableFunction("SendingUpdateAsyncPluginSurface", &CopyDXGISurface, + asi.mSD, &task)); task.Wait(); // Make sure we have an ImageContainer for SetCurrentImage. diff --git a/dom/workers/WorkerThread.cpp b/dom/workers/WorkerThread.cpp index b3bcba97498c..64a16f480900 100644 --- a/dom/workers/WorkerThread.cpp +++ b/dom/workers/WorkerThread.cpp @@ -322,8 +322,7 @@ uint32_t WorkerThread::RecursionDepth( return mNestedEventLoopDepth; } -PerformanceCounter* WorkerThread::GetPerformanceCounter( - nsIRunnable* aEvent) const { +PerformanceCounter* WorkerThread::GetPerformanceCounter(nsIRunnable* aEvent) { if (mWorkerPrivate) { return mWorkerPrivate->GetPerformanceCounter(); } diff --git a/dom/workers/WorkerThread.h b/dom/workers/WorkerThread.h index a643a187fc2c..8b09001e61d8 100644 --- a/dom/workers/WorkerThread.h +++ b/dom/workers/WorkerThread.h @@ -75,7 +75,7 @@ class WorkerThread final : public nsThread { uint32_t RecursionDepth(const WorkerThreadFriendKey& aKey) const; - PerformanceCounter* GetPerformanceCounter(nsIRunnable* aEvent) const override; + PerformanceCounter* GetPerformanceCounter(nsIRunnable* aEvent) override; NS_INLINE_DECL_REFCOUNTING_INHERITED(WorkerThread, nsThread) diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp index 066579329dd8..c4a3a987a9f7 100644 --- a/gfx/ipc/GPUParent.cpp +++ b/gfx/ipc/GPUParent.cpp @@ -132,7 +132,7 @@ bool GPUParent::Init(base::ProcessId aParentPid, const char* aParentBuildID, #endif CompositorThreadHolder::Start(); - APZThreadUtils::SetControllerThread(NS_GetCurrentThread()); + APZThreadUtils::SetControllerThread(MessageLoop::current()); apz::InitializeGlobalState(); LayerTreeOwnerTracker::Initialize(); CompositorBridgeParent::InitializeStatics(); diff --git a/gfx/ipc/VsyncBridgeParent.cpp b/gfx/ipc/VsyncBridgeParent.cpp index 9631d75b9883..96eac4ae4dcb 100644 --- a/gfx/ipc/VsyncBridgeParent.cpp +++ b/gfx/ipc/VsyncBridgeParent.cpp @@ -20,7 +20,7 @@ RefPtr VsyncBridgeParent::Start( RefPtr task = NewRunnableMethod&&>( "gfx::VsyncBridgeParent::Open", parent, &VsyncBridgeParent::Open, std::move(aEndpoint)); - CompositorThread()->Dispatch(task.forget()); + CompositorThreadHolder::Loop()->PostTask(task.forget()); return parent; } @@ -48,10 +48,10 @@ mozilla::ipc::IPCResult VsyncBridgeParent::RecvNotifyVsync( } void VsyncBridgeParent::Shutdown() { - if (!CompositorThreadHolder::IsInCompositorThread()) { - CompositorThread()->Dispatch( - NewRunnableMethod("gfx::VsyncBridgeParent::ShutdownImpl", this, - &VsyncBridgeParent::ShutdownImpl)); + MessageLoop* ccloop = CompositorThreadHolder::Loop(); + if (MessageLoop::current() != ccloop) { + ccloop->PostTask(NewRunnableMethod("gfx::VsyncBridgeParent::ShutdownImpl", + this, &VsyncBridgeParent::ShutdownImpl)); return; } diff --git a/gfx/layers/TextureSync.cpp b/gfx/layers/TextureSync.cpp index 7c3847b079a0..b24ac7101342 100644 --- a/gfx/layers/TextureSync.cpp +++ b/gfx/layers/TextureSync.cpp @@ -111,7 +111,7 @@ static void CheckTexturesForUnlock() { void TextureSync::DispatchCheckTexturesForUnlock() { RefPtr task = NS_NewRunnableFunction("CheckTexturesForUnlock", &CheckTexturesForUnlock); - CompositorThread()->Dispatch(task.forget()); + CompositorThreadHolder::Loop()->PostTask(task.forget()); } void TextureSync::HandleWaitForTexturesMessage(MachReceiveMessage* rmsg, diff --git a/gfx/layers/apz/public/GeckoContentController.h b/gfx/layers/apz/public/GeckoContentController.h index 82d171860bf8..3600e644d662 100644 --- a/gfx/layers/apz/public/GeckoContentController.h +++ b/gfx/layers/apz/public/GeckoContentController.h @@ -14,7 +14,6 @@ #include "mozilla/Attributes.h" // for MOZ_CAN_RUN_SCRIPT #include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM #include "mozilla/EventForwards.h" // for Modifiers -#include "mozilla/layers/APZThreadUtils.h" #include "mozilla/layers/MatrixMessage.h" // for MatrixMessage #include "mozilla/layers/RepaintRequest.h" // for RepaintRequest #include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, etc @@ -105,14 +104,12 @@ class GeckoContentController { Modifiers aModifiers) = 0; /** - * Schedules a runnable to run on the controller thread at some time + * Schedules a runnable to run on the controller/UI thread at some time * in the future. * This method must always be called on the controller thread. */ virtual void PostDelayedTask(already_AddRefed aRunnable, - int aDelayMs) { - APZThreadUtils::DelayedDispatch(std::move(aRunnable), aDelayMs); - } + int aDelayMs) = 0; /** * Returns true if we are currently on the thread that can send repaint diff --git a/gfx/layers/apz/src/APZUpdater.cpp b/gfx/layers/apz/src/APZUpdater.cpp index 91660929188c..3a5080b7c013 100644 --- a/gfx/layers/apz/src/APZUpdater.cpp +++ b/gfx/layers/apz/src/APZUpdater.cpp @@ -373,8 +373,8 @@ void APZUpdater::RunOnUpdaterThread(LayersId aLayersId, return; } - if (CompositorThread()) { - CompositorThread()->Dispatch(task.forget()); + if (MessageLoop* loop = CompositorThreadHolder::Loop()) { + loop->PostTask(task.forget()); } else { // Could happen during startup NS_WARNING("Dropping task posted to updater thread"); diff --git a/gfx/layers/apz/src/AsyncPanZoomAnimation.h b/gfx/layers/apz/src/AsyncPanZoomAnimation.h index 7b8b0e492ac2..2c602d104ad9 100644 --- a/gfx/layers/apz/src/AsyncPanZoomAnimation.h +++ b/gfx/layers/apz/src/AsyncPanZoomAnimation.h @@ -8,6 +8,7 @@ #define mozilla_layers_AsyncPanZoomAnimation_h_ #include "APZUtils.h" +#include "base/message_loop.h" #include "mozilla/RefPtr.h" #include "mozilla/TimeStamp.h" #include "nsISupportsImpl.h" diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index f4e62e8dd791..e39ed23d0938 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -33,6 +33,8 @@ #include "RecentEventsBuffer.h" // for RecentEventsBuffer #include "SampledAPZCState.h" +#include "base/message_loop.h" + namespace mozilla { namespace ipc { diff --git a/gfx/layers/apz/test/gtest/APZCBasicTester.h b/gfx/layers/apz/test/gtest/APZCBasicTester.h index ab097f460b03..75947179141c 100644 --- a/gfx/layers/apz/test/gtest/APZCBasicTester.h +++ b/gfx/layers/apz/test/gtest/APZCBasicTester.h @@ -26,7 +26,7 @@ class APZCBasicTester : public APZCTesterBase { protected: virtual void SetUp() { APZThreadUtils::SetThreadAssertionsEnabled(false); - APZThreadUtils::SetControllerThread(NS_GetCurrentThread()); + APZThreadUtils::SetControllerThread(MessageLoop::current()); tm = new TestAPZCTreeManager(mcc); updater = new APZUpdater(tm, false); diff --git a/gfx/layers/apz/test/gtest/APZCTreeManagerTester.h b/gfx/layers/apz/test/gtest/APZCTreeManagerTester.h index 7c48a2114545..f50e1545eefc 100644 --- a/gfx/layers/apz/test/gtest/APZCTreeManagerTester.h +++ b/gfx/layers/apz/test/gtest/APZCTreeManagerTester.h @@ -23,7 +23,7 @@ class APZCTreeManagerTester : public APZCTesterBase { virtual void SetUp() { gfxPlatform::GetPlatform(); APZThreadUtils::SetThreadAssertionsEnabled(false); - APZThreadUtils::SetControllerThread(NS_GetCurrentThread()); + APZThreadUtils::SetControllerThread(MessageLoop::current()); manager = new TestAPZCTreeManager(mcc); updater = new APZUpdater(manager, false); diff --git a/gfx/layers/apz/util/APZThreadUtils.cpp b/gfx/layers/apz/util/APZThreadUtils.cpp index ae05a0dea3af..03b110426253 100644 --- a/gfx/layers/apz/util/APZThreadUtils.cpp +++ b/gfx/layers/apz/util/APZThreadUtils.cpp @@ -6,100 +6,59 @@ #include "mozilla/layers/APZThreadUtils.h" -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/StaticMutex.h" - namespace mozilla { namespace layers { static bool sThreadAssertionsEnabled = true; -static StaticRefPtr sControllerThread; -static StaticMutex sControllerThreadMutex; +static MessageLoop* sControllerThread; /*static*/ void APZThreadUtils::SetThreadAssertionsEnabled(bool aEnabled) { - StaticMutexAutoLock lock(sControllerThreadMutex); sThreadAssertionsEnabled = aEnabled; } /*static*/ bool APZThreadUtils::GetThreadAssertionsEnabled() { - StaticMutexAutoLock lock(sControllerThreadMutex); return sThreadAssertionsEnabled; } /*static*/ -void APZThreadUtils::SetControllerThread(nsISerialEventTarget* aThread) { +void APZThreadUtils::SetControllerThread(MessageLoop* aLoop) { // We must either be setting the initial controller thread, or removing it, // or re-using an existing controller thread. - StaticMutexAutoLock lock(sControllerThreadMutex); - MOZ_ASSERT(!sControllerThread || !aThread || sControllerThread == aThread); - if (aThread != sControllerThread) { - // This can only happen once, on startup. - sControllerThread = aThread; - ClearOnShutdown(&sControllerThread); - } + MOZ_ASSERT(!sControllerThread || !aLoop || sControllerThread == aLoop); + sControllerThread = aLoop; } /*static*/ void APZThreadUtils::AssertOnControllerThread() { -#if DEBUG if (!GetThreadAssertionsEnabled()) { return; } - StaticMutexAutoLock lock(sControllerThreadMutex); - MOZ_ASSERT(sControllerThread && sControllerThread->IsOnCurrentThread()); -#endif + + MOZ_ASSERT(sControllerThread == MessageLoop::current()); } /*static*/ void APZThreadUtils::RunOnControllerThread(RefPtr&& aTask) { - RefPtr thread; - { - StaticMutexAutoLock lock(sControllerThreadMutex); - thread = sControllerThread; - } RefPtr task = std::move(aTask); - if (!thread) { - // Could happen on startup or if Shutdown() got called. + if (!sControllerThread) { + // Could happen on startup NS_WARNING("Dropping task posted to controller thread"); return; } - if (thread->IsOnCurrentThread()) { + if (sControllerThread == MessageLoop::current()) { task->Run(); } else { - thread->Dispatch(task.forget()); + sControllerThread->PostTask(task.forget()); } } /*static*/ bool APZThreadUtils::IsControllerThread() { - StaticMutexAutoLock lock(sControllerThreadMutex); - return sControllerThread && sControllerThread->IsOnCurrentThread(); -} - -/*static*/ -void APZThreadUtils::DelayedDispatch(already_AddRefed aRunnable, - int aDelayMs) { - MOZ_ASSERT(!XRE_IsContentProcess(), - "ContentProcessController should only be used remotely."); - RefPtr thread; - { - StaticMutexAutoLock lock(sControllerThreadMutex); - thread = sControllerThread; - } - if (!thread) { - // Could happen on startup - NS_WARNING("Dropping task posted to controller thread"); - return; - } - if (aDelayMs) { - thread->DelayedDispatch(std::move(aRunnable), aDelayMs); - } else { - thread->Dispatch(std::move(aRunnable)); - } + return sControllerThread == MessageLoop::current(); } NS_IMPL_ISUPPORTS(GenericNamedTimerCallbackBase, nsITimerCallback, nsINamed) diff --git a/gfx/layers/apz/util/APZThreadUtils.h b/gfx/layers/apz/util/APZThreadUtils.h index 7dd93c16808c..ad2091c08717 100644 --- a/gfx/layers/apz/util/APZThreadUtils.h +++ b/gfx/layers/apz/util/APZThreadUtils.h @@ -7,6 +7,7 @@ #ifndef mozilla_layers_APZThreadUtils_h #define mozilla_layers_APZThreadUtils_h +#include "base/message_loop.h" #include "nsINamed.h" #include "nsITimer.h" @@ -29,7 +30,7 @@ class APZThreadUtils { /** * Set the controller thread. */ - static void SetControllerThread(nsISerialEventTarget* aThread); + static void SetControllerThread(MessageLoop* aLoop); /** * This can be used to assert that the current thread is the @@ -49,13 +50,6 @@ class APZThreadUtils { * Returns true if currently on APZ "controller thread". */ static bool IsControllerThread(); - - /** - * Schedules a runnable to run on the controller thread at some time - * in the future. - */ - static void DelayedDispatch(already_AddRefed aRunnable, - int aDelayMs); }; // A base class for GenericNamedTimerCallback. diff --git a/gfx/layers/apz/util/ActiveElementManager.cpp b/gfx/layers/apz/util/ActiveElementManager.cpp index ed485c3a1d74..3fa4aec23ece 100644 --- a/gfx/layers/apz/util/ActiveElementManager.cpp +++ b/gfx/layers/apz/util/ActiveElementManager.cpp @@ -9,6 +9,8 @@ #include "mozilla/EventStates.h" #include "mozilla/PresShell.h" #include "mozilla/StaticPrefs_ui.h" +#include "base/message_loop.h" +#include "base/task.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/Document.h" @@ -76,7 +78,7 @@ void ActiveElementManager::TriggerElementActivation() { "layers::ActiveElementManager::SetActiveTask", this, &ActiveElementManager::SetActiveTask, mTarget); mSetActiveTask = task; - NS_GetCurrentThread()->DelayedDispatch( + MessageLoop::current()->PostDelayedTask( task.forget(), StaticPrefs::ui_touch_activation_delay_ms()); AEM_LOG("Scheduling mSetActiveTask %p\n", mSetActiveTask.get()); } diff --git a/gfx/layers/apz/util/ChromeProcessController.cpp b/gfx/layers/apz/util/ChromeProcessController.cpp index 8b2f36b7d3f3..fb71fb71494f 100644 --- a/gfx/layers/apz/util/ChromeProcessController.cpp +++ b/gfx/layers/apz/util/ChromeProcessController.cpp @@ -7,6 +7,7 @@ #include "ChromeProcessController.h" #include "MainThreadUtils.h" // for NS_IsMainThread() +#include "base/message_loop.h" // for MessageLoop #include "mozilla/PresShell.h" #include "mozilla/dom/Element.h" #include "mozilla/layers/CompositorBridgeParent.h" @@ -33,13 +34,13 @@ ChromeProcessController::ChromeProcessController( : mWidget(aWidget), mAPZEventState(aAPZEventState), mAPZCTreeManager(aAPZCTreeManager), - mUIThread(NS_GetCurrentThread()) { - // Otherwise we're initializing mUIThread incorrectly. + mUILoop(MessageLoop::current()) { + // Otherwise we're initializing mUILoop incorrectly. MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aAPZEventState); MOZ_ASSERT(aAPZCTreeManager); - mUIThread->Dispatch( + mUILoop->PostTask( NewRunnableMethod("layers::ChromeProcessController::InitializeRoot", this, &ChromeProcessController::InitializeRoot)); } @@ -52,8 +53,8 @@ void ChromeProcessController::InitializeRoot() { void ChromeProcessController::NotifyLayerTransforms( const nsTArray& aTransforms) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch(NewRunnableMethod>( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask(NewRunnableMethod>( "layers::ChromeProcessController::NotifyLayerTransforms", this, &ChromeProcessController::NotifyLayerTransforms, aTransforms)); return; @@ -73,6 +74,11 @@ void ChromeProcessController::RequestContentRepaint( } } +void ChromeProcessController::PostDelayedTask(already_AddRefed aTask, + int aDelayMs) { + MessageLoop::current()->PostDelayedTask(std::move(aTask), aDelayMs); +} + bool ChromeProcessController::IsRepaintThread() { return NS_IsMainThread(); } void ChromeProcessController::DispatchToRepaintThread( @@ -81,14 +87,14 @@ void ChromeProcessController::DispatchToRepaintThread( } void ChromeProcessController::Destroy() { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask( NewRunnableMethod("layers::ChromeProcessController::Destroy", this, &ChromeProcessController::Destroy)); return; } - MOZ_ASSERT(mUIThread->IsOnCurrentThread()); + MOZ_ASSERT(MessageLoop::current() == mUILoop); mWidget = nullptr; mAPZEventState = nullptr; } @@ -127,7 +133,7 @@ dom::Document* ChromeProcessController::GetRootContentDocument( void ChromeProcessController::HandleDoubleTap( const mozilla::CSSPoint& aPoint, Modifiers aModifiers, const ScrollableLayerGuid& aGuid) { - MOZ_ASSERT(mUIThread->IsOnCurrentThread()); + MOZ_ASSERT(MessageLoop::current() == mUILoop); RefPtr document = GetRootContentDocument(aGuid.mScrollId); if (!document.get()) { @@ -155,9 +161,9 @@ void ChromeProcessController::HandleTap( uint64_t aInputBlockId) { MOZ_LOG(sApzChromeLog, LogLevel::Debug, ("HandleTap called with %d\n", (int)aType)); - if (!mUIThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mUILoop) { MOZ_LOG(sApzChromeLog, LogLevel::Debug, ("HandleTap redispatching\n")); - mUIThread->Dispatch( + mUILoop->PostTask( NewRunnableMethod( "layers::ChromeProcessController::HandleTap", this, @@ -215,8 +221,8 @@ void ChromeProcessController::HandleTap( void ChromeProcessController::NotifyPinchGesture( PinchGestureInput::PinchGestureType aType, const ScrollableLayerGuid& aGuid, LayoutDeviceCoord aSpanChange, Modifiers aModifiers) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask( NewRunnableMethod( "layers::ChromeProcessController::NotifyPinchGesture", this, @@ -233,8 +239,8 @@ void ChromeProcessController::NotifyPinchGesture( void ChromeProcessController::NotifyAPZStateChange( const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask( NewRunnableMethod( "layers::ChromeProcessController::NotifyAPZStateChange", this, &ChromeProcessController::NotifyAPZStateChange, aGuid, aChange, @@ -251,12 +257,11 @@ void ChromeProcessController::NotifyAPZStateChange( void ChromeProcessController::NotifyMozMouseScrollEvent( const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch( - NewRunnableMethod( - "layers::ChromeProcessController::NotifyMozMouseScrollEvent", this, - &ChromeProcessController::NotifyMozMouseScrollEvent, aScrollId, - aEvent)); + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask(NewRunnableMethod( + "layers::ChromeProcessController::NotifyMozMouseScrollEvent", this, + &ChromeProcessController::NotifyMozMouseScrollEvent, aScrollId, + aEvent)); return; } @@ -272,9 +277,9 @@ void ChromeProcessController::NotifyFlushComplete() { void ChromeProcessController::NotifyAsyncScrollbarDragInitiated( uint64_t aDragBlockId, const ScrollableLayerGuid::ViewID& aScrollId, ScrollDirection aDirection) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask(NewRunnableMethod( "layers::ChromeProcessController::NotifyAsyncScrollbarDragInitiated", this, &ChromeProcessController::NotifyAsyncScrollbarDragInitiated, aDragBlockId, aScrollId, aDirection)); @@ -287,8 +292,8 @@ void ChromeProcessController::NotifyAsyncScrollbarDragInitiated( void ChromeProcessController::NotifyAsyncScrollbarDragRejected( const ScrollableLayerGuid::ViewID& aScrollId) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask(NewRunnableMethod( "layers::ChromeProcessController::NotifyAsyncScrollbarDragRejected", this, &ChromeProcessController::NotifyAsyncScrollbarDragRejected, aScrollId)); @@ -300,8 +305,8 @@ void ChromeProcessController::NotifyAsyncScrollbarDragRejected( void ChromeProcessController::NotifyAsyncAutoscrollRejected( const ScrollableLayerGuid::ViewID& aScrollId) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask(NewRunnableMethod( "layers::ChromeProcessController::NotifyAsyncAutoscrollRejected", this, &ChromeProcessController::NotifyAsyncAutoscrollRejected, aScrollId)); return; @@ -312,8 +317,8 @@ void ChromeProcessController::NotifyAsyncAutoscrollRejected( void ChromeProcessController::CancelAutoscroll( const ScrollableLayerGuid& aGuid) { - if (!mUIThread->IsOnCurrentThread()) { - mUIThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mUILoop) { + mUILoop->PostTask(NewRunnableMethod( "layers::ChromeProcessController::CancelAutoscroll", this, &ChromeProcessController::CancelAutoscroll, aGuid)); return; diff --git a/gfx/layers/apz/util/ChromeProcessController.h b/gfx/layers/apz/util/ChromeProcessController.h index a470572d240e..dc18a581a281 100644 --- a/gfx/layers/apz/util/ChromeProcessController.h +++ b/gfx/layers/apz/util/ChromeProcessController.h @@ -13,8 +13,9 @@ #include "mozilla/layers/MatrixMessage.h" class nsIDOMWindowUtils; -class nsISerialEventTarget; + class nsIWidget; +class MessageLoop; namespace mozilla { class PresShell; @@ -52,6 +53,7 @@ class ChromeProcessController : public mozilla::layers::GeckoContentController { void NotifyLayerTransforms( const nsTArray& aTransforms) override; void RequestContentRepaint(const RepaintRequest& aRequest) override; + void PostDelayedTask(already_AddRefed aTask, int aDelayMs) override; bool IsRepaintThread() override; void DispatchToRepaintThread(already_AddRefed aTask) override; MOZ_CAN_RUN_SCRIPT @@ -80,7 +82,7 @@ class ChromeProcessController : public mozilla::layers::GeckoContentController { nsCOMPtr mWidget; RefPtr mAPZEventState; RefPtr mAPZCTreeManager; - nsCOMPtr mUIThread; + MessageLoop* mUILoop; void InitializeRoot(); PresShell* GetPresShell() const; diff --git a/gfx/layers/apz/util/ContentProcessController.cpp b/gfx/layers/apz/util/ContentProcessController.cpp index df80819c244d..6fceae147506 100644 --- a/gfx/layers/apz/util/ContentProcessController.cpp +++ b/gfx/layers/apz/util/ContentProcessController.cpp @@ -96,6 +96,12 @@ void ContentProcessController::CancelAutoscroll( MOZ_ASSERT_UNREACHABLE("Unexpected message to content process"); } +void ContentProcessController::PostDelayedTask( + already_AddRefed aRunnable, int aDelayMs) { + MOZ_ASSERT_UNREACHABLE( + "ContentProcessController should only be used remotely."); +} + bool ContentProcessController::IsRepaintThread() { return NS_IsMainThread(); } void ContentProcessController::DispatchToRepaintThread( diff --git a/gfx/layers/apz/util/ContentProcessController.h b/gfx/layers/apz/util/ContentProcessController.h index d455141499e6..ff57c6f16315 100644 --- a/gfx/layers/apz/util/ContentProcessController.h +++ b/gfx/layers/apz/util/ContentProcessController.h @@ -72,6 +72,9 @@ class ContentProcessController final : public GeckoContentController { void CancelAutoscroll(const ScrollableLayerGuid& aGuid) override; + void PostDelayedTask(already_AddRefed aRunnable, + int aDelayMs) override; + bool IsRepaintThread() override; void DispatchToRepaintThread(already_AddRefed aTask) override; diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 3a15a36dc742..f9e3ab25cfc4 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -169,7 +169,8 @@ TextureClientRecycleAllocator* CompositableClient::GetTextureClientRecycler() { barrier.NotifyAll(); }); - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(runnable.forget()); + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( + runnable.forget()); // should stop the thread until done. while (!done) { diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index dbcefb088395..2d0b9df09033 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -5,61 +5,57 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/layers/TextureClient.h" - #include // for uint8_t, uint32_t, etc - -#include "BufferTexture.h" -#include "IPDLActor.h" -#include "ImageContainer.h" // for PlanarYCbCrData, etc -#include "Layers.h" // for Layer, etc -#include "LayersLogging.h" // for AppendToString -#include "MainThreadUtils.h" +#include "Layers.h" // for Layer, etc #include "gfx2DGlue.h" #include "gfxPlatform.h" // for gfxPlatform -#include "gfxUtils.h" // for gfxUtils::GetAsLZ4Base64Str +#include "MainThreadUtils.h" #include "mozilla/Atomics.h" -#include "mozilla/Mutex.h" #include "mozilla/SchedulerGroup.h" #include "mozilla/StaticPrefs_gfx.h" #include "mozilla/StaticPrefs_layers.h" -#include "mozilla/gfx/2D.h" -#include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning -#include "mozilla/gfx/Logging.h" // for gfxDebug #include "mozilla/gfx/gfxVars.h" -#include "mozilla/ipc/CrossProcessSemaphore.h" #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc #include "mozilla/layers/CompositableForwarder.h" #include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/ImageDataSerializer.h" -#include "mozilla/layers/PTextureChild.h" #include "mozilla/layers/PaintThread.h" -#include "mozilla/layers/ShadowLayers.h" -#include "mozilla/layers/TextureClientOGL.h" #include "mozilla/layers/TextureClientRecycleAllocator.h" #include "mozilla/layers/TextureRecorded.h" +#include "mozilla/Mutex.h" #include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc -#include "nsISerialEventTarget.h" #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc -#include "nsPrintfCString.h" // for nsPrintfCString +#include "ImageContainer.h" // for PlanarYCbCrData, etc +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Logging.h" // for gfxDebug +#include "mozilla/layers/TextureClientOGL.h" +#include "mozilla/layers/PTextureChild.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning +#include "nsPrintfCString.h" // for nsPrintfCString +#include "LayersLogging.h" // for AppendToString +#include "gfxUtils.h" // for gfxUtils::GetAsLZ4Base64Str +#include "IPDLActor.h" +#include "BufferTexture.h" +#include "mozilla/layers/ShadowLayers.h" +#include "mozilla/ipc/CrossProcessSemaphore.h" #ifdef XP_WIN -# include "gfx2DGlue.h" -# include "gfxWindowsPlatform.h" # include "mozilla/gfx/DeviceManagerDx.h" # include "mozilla/layers/TextureD3D11.h" # include "mozilla/layers/TextureDIB.h" +# include "gfxWindowsPlatform.h" +# include "gfx2DGlue.h" #endif #ifdef MOZ_X11 -# include "GLXLibrary.h" # include "mozilla/layers/TextureClientX11.h" +# include "GLXLibrary.h" #endif #ifdef MOZ_WAYLAND # include - -# include "gfxPlatformGtk.h" -# include "mozilla/layers/WaylandDMABUFTextureClientOGL.h" # include "mozilla/widget/nsWaylandDisplay.h" +# include "mozilla/layers/WaylandDMABUFTextureClientOGL.h" +# include "gfxPlatformGtk.h" #endif #ifdef XP_MACOSX @@ -494,12 +490,12 @@ void DeallocateTextureClient(TextureDeallocParams params) { } TextureChild* actor = params.actor; - nsCOMPtr ipdlThread; + MessageLoop* ipdlMsgLoop = nullptr; if (params.allocator) { - ipdlThread = params.allocator->GetThread(); - if (!ipdlThread) { - // An allocator with no thread means we are too late in the shutdown + ipdlMsgLoop = params.allocator->GetMessageLoop(); + if (!ipdlMsgLoop) { + // An allocator with no message loop means we are too late in the shutdown // sequence. gfxCriticalError() << "Texture deallocated too late during shutdown"; return; @@ -507,19 +503,19 @@ void DeallocateTextureClient(TextureDeallocParams params) { } // First make sure that the work is happening on the IPDL thread. - if (ipdlThread && !ipdlThread->IsOnCurrentThread()) { + if (ipdlMsgLoop && MessageLoop::current() != ipdlMsgLoop) { if (params.syncDeallocation) { bool done = false; ReentrantMonitor barrier("DeallocateTextureClient"); ReentrantMonitorAutoEnter autoMon(barrier); - ipdlThread->Dispatch(NewRunnableFunction( + ipdlMsgLoop->PostTask(NewRunnableFunction( "DeallocateTextureClientSyncProxyRunnable", DeallocateTextureClientSyncProxy, params, &barrier, &done)); while (!done) { barrier.Wait(); } } else { - ipdlThread->Dispatch(NewRunnableFunction( + ipdlMsgLoop->PostTask(NewRunnableFunction( "DeallocateTextureClientRunnable", DeallocateTextureClient, params)); } // The work has been forwarded to the IPDL thread, we are done. @@ -529,8 +525,8 @@ void DeallocateTextureClient(TextureDeallocParams params) { // Below this line, we are either in the IPDL thread or ther is no IPDL // thread anymore. - if (!ipdlThread) { - // If we don't have a thread we can't know for sure that we are in + if (!ipdlMsgLoop) { + // If we don't have a message loop we can't know for sure that we are in // the IPDL thread and use the LayersIPCChannel. // This should ideally not happen outside of gtest, but some shutdown // raciness could put us in this situation. @@ -982,14 +978,15 @@ static void CancelTextureClientNotifyNotUsed(uint64_t aTextureId, if (!aAllocator) { return; } - nsCOMPtr thread = aAllocator->GetThread(); - if (!thread) { + MessageLoop* msgLoop = nullptr; + msgLoop = aAllocator->GetMessageLoop(); + if (!msgLoop) { return; } - if (thread->IsOnCurrentThread()) { + if (MessageLoop::current() == msgLoop) { aAllocator->CancelWaitForNotifyNotUsed(aTextureId); } else { - thread->Dispatch(NewRunnableFunction( + msgLoop->PostTask(NewRunnableFunction( "CancelTextureClientNotifyNotUsedRunnable", CancelTextureClientNotifyNotUsed, aTextureId, aAllocator)); } @@ -1020,8 +1017,9 @@ void TextureClient::SetRecycleAllocator( } bool TextureClient::InitIPDLActor(CompositableForwarder* aForwarder) { - MOZ_ASSERT(aForwarder && aForwarder->GetTextureForwarder()->GetThread() == - mAllocator->GetThread()); + MOZ_ASSERT(aForwarder && + aForwarder->GetTextureForwarder()->GetMessageLoop() == + mAllocator->GetMessageLoop()); if (mActor && !mActor->IPCOpen()) { return false; @@ -1114,8 +1112,8 @@ bool TextureClient::InitIPDLActor(CompositableForwarder* aForwarder) { bool TextureClient::InitIPDLActor(KnowsCompositor* aKnowsCompositor) { MOZ_ASSERT(aKnowsCompositor && - aKnowsCompositor->GetTextureForwarder()->GetThread() == - mAllocator->GetThread()); + aKnowsCompositor->GetTextureForwarder()->GetMessageLoop() == + mAllocator->GetMessageLoop()); TextureForwarder* fwd = aKnowsCompositor->GetTextureForwarder(); if (mActor && !mActor->mDestroyed) { CompositableForwarder* currentFwd = mActor->mCompositableForwarder; diff --git a/gfx/layers/client/TextureClientRecycleAllocator.cpp b/gfx/layers/client/TextureClientRecycleAllocator.cpp index f1f1aac82233..b7c09235bbd9 100644 --- a/gfx/layers/client/TextureClientRecycleAllocator.cpp +++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp @@ -153,7 +153,7 @@ already_AddRefed TextureClientRecycleAllocator::CreateOrRecycle( new TextureClientReleaseTask(textureHolder->GetTextureClient()); textureHolder->ClearTextureClient(); textureHolder = nullptr; - mKnowsCompositor->GetTextureForwarder()->GetThread()->Dispatch( + mKnowsCompositor->GetTextureForwarder()->GetMessageLoop()->PostTask( task.forget()); } else { textureHolder->GetTextureClient()->RecycleTexture( diff --git a/gfx/layers/ipc/CanvasThread.cpp b/gfx/layers/ipc/CanvasThread.cpp index 4920ad7eef56..dd2ca8a19f65 100644 --- a/gfx/layers/ipc/CanvasThread.cpp +++ b/gfx/layers/ipc/CanvasThread.cpp @@ -21,9 +21,9 @@ StaticDataMutex> CanvasThreadHolder::sCanvasThreadHolder("sCanvasThreadHolder"); CanvasThreadHolder::CanvasThreadHolder( - already_AddRefed aCanvasThread, + UniquePtr aCanvasThread, already_AddRefed aCanvasWorkers) - : mCanvasThread(aCanvasThread), + : mCanvasThread(std::move(aCanvasThread)), mCanvasWorkers(aCanvasWorkers), mCompositorThreadKeepAlive(CompositorThreadHolder::GetSingleton()) { MOZ_ASSERT(NS_IsInCompositorThread()); @@ -34,8 +34,8 @@ CanvasThreadHolder::CanvasThreadHolder( CanvasThreadHolder::~CanvasThreadHolder() { // Note we can't just use NS_IsInCompositorThread() here because // sCompositorThreadHolder might have already gone. - MOZ_ASSERT( - mCompositorThreadKeepAlive->GetCompositorThread()->IsOnCurrentThread()); + MOZ_ASSERT(mCompositorThreadKeepAlive->GetCompositorThread()->thread_id() == + PlatformThread::CurrentId()); } /* static */ @@ -44,9 +44,10 @@ already_AddRefed CanvasThreadHolder::EnsureCanvasThread() { auto lockedCanvasThreadHolder = sCanvasThreadHolder.Lock(); if (!lockedCanvasThreadHolder.ref()) { - nsCOMPtr canvasThread; - nsresult rv = NS_NewNamedThread("Canvas", getter_AddRefs(canvasThread)); - NS_ENSURE_SUCCESS(rv, nullptr); + UniquePtr canvasThread = MakeUnique("Canvas"); + if (!canvasThread->Start()) { + return nullptr; + }; // Given that the canvas workers are receiving instructions from // content processes, it probably doesn't make sense to have more than @@ -55,14 +56,14 @@ already_AddRefed CanvasThreadHolder::EnsureCanvasThread() { // there is more than one window with canvas drawing, the OS can // manage the load between them. uint32_t threadLimit = std::max(2, PR_GetNumberOfProcessors() / 2); - nsCOMPtr canvasWorkers = + RefPtr canvasWorkers = SharedThreadPool::Get(NS_LITERAL_CSTRING("CanvasWorkers"), threadLimit); if (!canvasWorkers) { return nullptr; } lockedCanvasThreadHolder.ref() = - new CanvasThreadHolder(canvasThread.forget(), canvasWorkers.forget()); + new CanvasThreadHolder(std::move(canvasThread), canvasWorkers.forget()); } return do_AddRef(lockedCanvasThreadHolder.ref()); @@ -75,7 +76,7 @@ void CanvasThreadHolder::StaticRelease( // Note we can't just use NS_IsInCompositorThread() here because // sCompositorThreadHolder might have already gone. MOZ_ASSERT(threadHolder->mCompositorThreadKeepAlive->GetCompositorThread() - ->IsOnCurrentThread()); + ->thread_id() == PlatformThread::CurrentId()); threadHolder = nullptr; auto lockedCanvasThreadHolder = sCanvasThreadHolder.Lock(); @@ -88,18 +89,20 @@ void CanvasThreadHolder::StaticRelease( void CanvasThreadHolder::ReleaseOnCompositorThread( already_AddRefed aCanvasThreadHolder) { auto lockedCanvasThreadHolder = sCanvasThreadHolder.Lock(); - lockedCanvasThreadHolder.ref() - ->mCompositorThreadKeepAlive->GetCompositorThread() - ->Dispatch(NewRunnableFunction("CanvasThreadHolder::StaticRelease", - CanvasThreadHolder::StaticRelease, - std::move(aCanvasThreadHolder))); + base::Thread* compositorThread = + lockedCanvasThreadHolder.ref() + ->mCompositorThreadKeepAlive->GetCompositorThread(); + compositorThread->message_loop()->PostTask(NewRunnableFunction( + "CanvasThreadHolder::StaticRelease", CanvasThreadHolder::StaticRelease, + std::move(aCanvasThreadHolder))); } /* static */ bool CanvasThreadHolder::IsInCanvasThread() { auto lockedCanvasThreadHolder = sCanvasThreadHolder.Lock(); return lockedCanvasThreadHolder.ref() && - lockedCanvasThreadHolder.ref()->mCanvasThread->IsOnCurrentThread(); + lockedCanvasThreadHolder.ref()->mCanvasThread->thread_id() == + PlatformThread::CurrentId(); } /* static */ @@ -114,7 +117,8 @@ bool CanvasThreadHolder::IsInCanvasThreadOrWorker() { auto lockedCanvasThreadHolder = sCanvasThreadHolder.Lock(); return lockedCanvasThreadHolder.ref() && (lockedCanvasThreadHolder.ref()->mCanvasWorkers->IsOnCurrentThread() || - lockedCanvasThreadHolder.ref()->mCanvasThread->IsOnCurrentThread()); + lockedCanvasThreadHolder.ref()->mCanvasThread->thread_id() == + PlatformThread::CurrentId()); } /* static */ @@ -123,16 +127,17 @@ void CanvasThreadHolder::MaybeDispatchToCanvasThread( auto lockedCanvasThreadHolder = sCanvasThreadHolder.Lock(); if (!lockedCanvasThreadHolder.ref()) { // There is no canvas thread just release the runnable. - nsCOMPtr runnable = aRunnable; + RefPtr runnable = aRunnable; return; } - lockedCanvasThreadHolder.ref()->mCanvasThread->Dispatch(std::move(aRunnable)); + lockedCanvasThreadHolder.ref()->mCanvasThread->message_loop()->PostTask( + std::move(aRunnable)); } void CanvasThreadHolder::DispatchToCanvasThread( already_AddRefed aRunnable) { - mCanvasThread->Dispatch(std::move(aRunnable)); + mCanvasThread->message_loop()->PostTask(std::move(aRunnable)); } already_AddRefed CanvasThreadHolder::CreateWorkerTaskQueue() { diff --git a/gfx/layers/ipc/CanvasThread.h b/gfx/layers/ipc/CanvasThread.h index 57a17326166c..a2b68add90ba 100644 --- a/gfx/layers/ipc/CanvasThread.h +++ b/gfx/layers/ipc/CanvasThread.h @@ -7,13 +7,13 @@ #ifndef mozilla_layers_CanvasThread_h #define mozilla_layers_CanvasThread_h +#include "base/thread.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/DataMutex.h" #include "mozilla/StaticPtr.h" #include "mozilla/TaskQueue.h" #include "mozilla/UniquePtr.h" #include "nsISupports.h" -#include "nsIThread.h" #include "nsIThreadPool.h" namespace mozilla { @@ -85,12 +85,12 @@ class CanvasThreadHolder final { static StaticDataMutex> sCanvasThreadHolder; - CanvasThreadHolder(already_AddRefed aCanvasThread, + CanvasThreadHolder(UniquePtr aCanvasThread, already_AddRefed aCanvasWorkers); ~CanvasThreadHolder(); - nsCOMPtr mCanvasThread; + UniquePtr mCanvasThread; RefPtr mCanvasWorkers; // Hold a reference to prevent the compositor thread ending. diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index b972ee416506..f3ec57613d64 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -9,6 +9,7 @@ #include "mozilla/layers/CompositorThread.h" #include // for size_t #include "ClientLayerManager.h" // for ClientLayerManager +#include "base/message_loop.h" // for MessageLoop #include "base/task.h" // for NewRunnableMethod, etc #include "mozilla/StaticPrefs_layers.h" #include "mozilla/layers/CompositorManagerChild.h" @@ -35,6 +36,7 @@ #include "nsDebug.h" // for NS_WARNING #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsTArray.h" // for nsTArray, nsTArray_Impl +#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop, etc #include "FrameLayerBuilder.h" #include "mozilla/dom/BrowserChild.h" #include "mozilla/dom/BrowserParent.h" @@ -83,7 +85,7 @@ CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild* aManager) mCanSend(false), mActorDestroyed(false), mFwdTransactionId(0), - mThread(NS_GetCurrentThread()), + mMessageLoop(MessageLoop::current()), mProcessToken(0), mSectionAllocator(nullptr), mPaintLock("CompositorBridgeChild.mPaintLock"), @@ -166,7 +168,7 @@ void CompositorBridgeChild::Destroy() { // We may have already called destroy but still have lingering references // or CompositorBridgeChild::ActorDestroy was called. Ensure that we do our // post destroy clean up no matter what. It is safe to call multiple times. - NS_GetCurrentThread()->Dispatch( + MessageLoop::current()->PostTask( NewRunnableMethod("CompositorBridgeChild::PrepareFinalDestroy", selfRef, &CompositorBridgeChild::PrepareFinalDestroy)); return; @@ -223,12 +225,12 @@ void CompositorBridgeChild::Destroy() { // CompositorBridgeParent to the CompositorBridgeChild (e.g. caused by the // destruction of shared memory). We need to ensure this gets processed by the // CompositorBridgeChild before it gets destroyed. It suffices to ensure that - // events already in the thread get processed before the - // CompositorBridgeChild is destroyed, so we add a task to the thread to + // events already in the MessageLoop get processed before the + // CompositorBridgeChild is destroyed, so we add a task to the MessageLoop to // handle compositor destruction. // From now on we can't send any message message. - NS_GetCurrentThread()->Dispatch( + MessageLoop::current()->PostTask( NewRunnableMethod("CompositorBridgeChild::PrepareFinalDestroy", selfRef, &CompositorBridgeChild::PrepareFinalDestroy)); } @@ -468,8 +470,8 @@ mozilla::ipc::IPCResult CompositorBridgeChild::RecvUpdatePluginConfigurations( #if defined(XP_WIN) static void ScheduleSendAllPluginsCaptured(CompositorBridgeChild* aThis, - nsISerialEventTarget* aThread) { - aThread->Dispatch(NewNonOwningRunnableMethod( + MessageLoop* aLoop) { + aLoop->PostTask(NewNonOwningRunnableMethod( "CompositorBridgeChild::SendAllPluginsCaptured", aThis, &CompositorBridgeChild::SendAllPluginsCaptured)); } @@ -481,11 +483,12 @@ mozilla::ipc::IPCResult CompositorBridgeChild::RecvCaptureAllPlugins( MOZ_ASSERT(NS_IsMainThread()); nsIWidget::CaptureRegisteredPlugins(aParentWidget); - // Bounce the call to SendAllPluginsCaptured off the ImageBridgeChild thread, + // Bounce the call to SendAllPluginsCaptured off the ImageBridgeChild loop, // to make sure that the image updates on that thread have been processed. - ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(NewRunnableFunction( - "ScheduleSendAllPluginsCapturedRunnable", &ScheduleSendAllPluginsCaptured, - this, NS_GetCurrentThread())); + ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask( + NewRunnableFunction("ScheduleSendAllPluginsCapturedRunnable", + &ScheduleSendAllPluginsCaptured, this, + MessageLoop::current())); return IPC_OK(); #else MOZ_ASSERT_UNREACHABLE( diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index 71c9d6ec706d..c215fe70f9de 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -200,7 +200,7 @@ class CompositorBridgeChild final : public PCompositorBridgeChild, void HandleMemoryPressure(); - nsISerialEventTarget* GetThread() const override { return mThread; } + MessageLoop* GetMessageLoop() const override { return mMessageLoop; } base::ProcessId GetParentPid() const override { return OtherPid(); } @@ -373,7 +373,7 @@ class CompositorBridgeChild final : public PCompositorBridgeChild, std::unordered_map> mTexturesWaitingNotifyNotUsed; - nsCOMPtr mThread; + MessageLoop* mMessageLoop; AutoTArray, 2> mTexturePools; diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 6e5478358c5a..443fddf866c9 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -14,7 +14,10 @@ #include "apz/src/APZCTreeManager.h" // for APZCTreeManager #include "LayerTransactionParent.h" // for LayerTransactionParent #include "RenderTrace.h" // for RenderTraceLayers +#include "base/message_loop.h" // for MessageLoop #include "base/process.h" // for ProcessId +#include "base/task.h" // for CancelableTask, etc +#include "base/thread.h" // for Thread #include "gfxContext.h" // for gfxContext #include "gfxPlatform.h" // for gfxPlatform #include "TreeTraversal.h" // for ForEachNode @@ -77,6 +80,7 @@ #include "nsIWidget.h" // for nsIWidget #include "nsTArray.h" // for nsTArray #include "nsThreadUtils.h" // for NS_IsMainThread +#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop #ifdef XP_WIN # include "mozilla/layers/CompositorD3D11.h" # include "mozilla/widget/WinCompositorWidget.h" @@ -170,6 +174,10 @@ bool CompositorBridgeParentBase::DeallocShmem(ipc::Shmem& aShmem) { return PCompositorBridgeParent::DeallocShmem(aShmem); } +static inline MessageLoop* CompositorLoop() { + return CompositorThreadHolder::Loop(); +} + base::ProcessId CompositorBridgeParentBase::RemotePid() { return OtherPid(); } bool CompositorBridgeParentBase::StartSharingMetrics( @@ -177,8 +185,8 @@ bool CompositorBridgeParentBase::StartSharingMetrics( CrossProcessMutexHandle aMutexHandle, LayersId aLayersId, uint32_t aApzcId) { if (!CompositorThreadHolder::IsInCompositorThread()) { - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod( "layers::CompositorBridgeParent::StartSharingMetrics", this, @@ -198,8 +206,8 @@ bool CompositorBridgeParentBase::StartSharingMetrics( bool CompositorBridgeParentBase::StopSharingMetrics( ScrollableLayerGuid::ViewID aScrollId, uint32_t aApzcId) { if (!CompositorThreadHolder::IsInCompositorThread()) { - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod( "layers::CompositorBridgeParent::StopSharingMetrics", this, &CompositorBridgeParentBase::StopSharingMetrics, aScrollId, @@ -396,8 +404,8 @@ void CompositorBridgeParent::Initialize() { // FIXME: This holds on the the fact that right now the only thing that // can destroy this instance is initialized on the compositor thread after // this task has been processed. - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch(NewRunnableFunction( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask(NewRunnableFunction( "AddCompositorRunnable", &AddCompositor, this, &mCompositorBridgeID)); { // scope lock @@ -672,22 +680,22 @@ void CompositorBridgeParent::ActorDestroy(ActorDestroyReason why) { // on this thread. We must keep the compositor parent alive untill the code // handling message reception is finished on this thread. mSelfRef = this; - NS_GetCurrentThread()->Dispatch( + MessageLoop::current()->PostTask( NewRunnableMethod("layers::CompositorBridgeParent::DeferredDestroy", this, &CompositorBridgeParent::DeferredDestroy)); } void CompositorBridgeParent::ScheduleRenderOnCompositorThread( const wr::RenderRootSet& aRenderRoots) { - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch(NewRunnableMethod( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask(NewRunnableMethod( "layers::CompositorBridgeParent::ScheduleComposition", this, &CompositorBridgeParent::ScheduleComposition, aRenderRoots)); } void CompositorBridgeParent::InvalidateOnCompositorThread() { - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod("layers::CompositorBridgeParent::Invalidate", this, &CompositorBridgeParent::Invalidate)); } @@ -785,8 +793,8 @@ void CompositorBridgeParent::ResumeCompositionAndResize(int x, int y, int width, void CompositorBridgeParent::SchedulePauseOnCompositorThread() { MonitorAutoLock lock(mPauseCompositionMonitor); - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod("layers::CompositorBridgeParent::PauseComposition", this, &CompositorBridgeParent::PauseComposition)); @@ -797,8 +805,8 @@ void CompositorBridgeParent::SchedulePauseOnCompositorThread() { bool CompositorBridgeParent::ScheduleResumeOnCompositorThread() { MonitorAutoLock lock(mResumeCompositionMonitor); - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod("layers::CompositorBridgeParent::ResumeComposition", this, &CompositorBridgeParent::ResumeComposition)); @@ -813,8 +821,8 @@ bool CompositorBridgeParent::ScheduleResumeOnCompositorThread(int x, int y, int height) { MonitorAutoLock lock(mResumeCompositionMonitor); - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch(NewRunnableMethod( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask(NewRunnableMethod( "layers::CompositorBridgeParent::ResumeCompositionAndResize", this, &CompositorBridgeParent::ResumeCompositionAndResize, x, y, width, height)); @@ -825,6 +833,15 @@ bool CompositorBridgeParent::ScheduleResumeOnCompositorThread(int x, int y, return !mPaused; } +void CompositorBridgeParent::ScheduleTask( + already_AddRefed task, int time) { + if (time == 0) { + MessageLoop::current()->PostTask(std::move(task)); + } else { + MessageLoop::current()->PostDelayedTask(std::move(task), time); + } +} + void CompositorBridgeParent::UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) { // We get a lot of paint timings for things with empty transactions. @@ -1217,12 +1234,7 @@ void CompositorBridgeParent::ScheduleRotationOnCompositorThread( "layers::CompositorBridgeParent::ForceComposition", this, &CompositorBridgeParent::ForceComposition); mForceCompositionTask = task; - if (StaticPrefs::layers_orientation_sync_timeout() == 0) { - CompositorThread()->Dispatch(task.forget()); - } else { - CompositorThread()->DelayedDispatch( - task.forget(), StaticPrefs::layers_orientation_sync_timeout()); - } + ScheduleTask(task.forget(), StaticPrefs::layers_orientation_sync_timeout()); } } @@ -1979,13 +1991,13 @@ void CompositorBridgeParent::InitializeStatics() { /*static*/ void CompositorBridgeParent::UpdateQualitySettings() { if (!CompositorThreadHolder::IsInCompositorThread()) { - if (CompositorThread()) { - CompositorThread()->Dispatch( + if (CompositorLoop()) { + CompositorLoop()->PostTask( NewRunnableFunction("CompositorBridgeParent::UpdateQualitySettings", &CompositorBridgeParent::UpdateQualitySettings)); } - // If there is no compositor thread, e.g. due to shutdown, then we can + // If there is no compositor loop, e.g. due to shutdown, then we can // safefully just ignore this request. return; } @@ -1999,13 +2011,13 @@ void CompositorBridgeParent::UpdateQualitySettings() { /*static*/ void CompositorBridgeParent::UpdateDebugFlags() { if (!CompositorThreadHolder::IsInCompositorThread()) { - if (CompositorThread()) { - CompositorThread()->Dispatch( + if (CompositorLoop()) { + CompositorLoop()->PostTask( NewRunnableFunction("CompositorBridgeParent::UpdateDebugFlags", &CompositorBridgeParent::UpdateDebugFlags)); } - // If there is no compositor thread, e.g. due to shutdown, then we can + // If there is no compositor loop, e.g. due to shutdown, then we can // safefully just ignore this request. return; } @@ -2019,8 +2031,8 @@ void CompositorBridgeParent::UpdateDebugFlags() { /*static*/ void CompositorBridgeParent::UpdateWebRenderMultithreading() { if (!CompositorThreadHolder::IsInCompositorThread()) { - if (CompositorThread()) { - CompositorThread()->Dispatch(NewRunnableFunction( + if (CompositorLoop()) { + CompositorLoop()->PostTask(NewRunnableFunction( "CompositorBridgeParent::UpdateWebRenderMultithreading", &CompositorBridgeParent::UpdateWebRenderMultithreading)); } @@ -2037,8 +2049,8 @@ void CompositorBridgeParent::UpdateWebRenderMultithreading() { /*static*/ void CompositorBridgeParent::UpdateWebRenderBatchingParameters() { if (!CompositorThreadHolder::IsInCompositorThread()) { - if (CompositorThread()) { - CompositorThread()->Dispatch(NewRunnableFunction( + if (CompositorLoop()) { + CompositorLoop()->PostTask(NewRunnableFunction( "CompositorBridgeParent::UpdateWebRenderBatchingParameters", &CompositorBridgeParent::UpdateWebRenderBatchingParameters)); } @@ -2087,11 +2099,11 @@ void CompositorBridgeParent::DeallocateLayerTreeId(LayersId aId) { // Here main thread notifies compositor to remove an element from // sIndirectLayerTrees. This removed element might be queried soon. // Checking the elements of sIndirectLayerTrees exist or not before using. - if (!CompositorThread()) { - gfxCriticalError() << "Attempting to post to an invalid Compositor Thread"; + if (!CompositorLoop()) { + gfxCriticalError() << "Attempting to post to a invalid Compositor Loop"; return; } - CompositorThread()->Dispatch( + CompositorLoop()->PostTask( NewRunnableFunction("EraseLayerStateRunnable", &EraseLayerState, aId)); } @@ -2123,7 +2135,7 @@ void CompositorBridgeParent::SetControllerForLayerTree( LayersId aLayersId, GeckoContentController* aController) { // This ref is adopted by UpdateControllerForLayersId(). aController->AddRef(); - CompositorThread()->Dispatch(NewRunnableFunction( + CompositorLoop()->PostTask(NewRunnableFunction( "UpdateControllerForLayersIdRunnable", &UpdateControllerForLayersId, aLayersId, aController)); } @@ -2160,7 +2172,7 @@ void CompositorBridgeParent::PostInsertVsyncProfilerMarker( #if defined(MOZ_GECKO_PROFILER) // Called in the vsync thread if (profiler_is_active() && CompositorThreadHolder::IsActive()) { - CompositorThread()->Dispatch( + CompositorLoop()->PostTask( NewRunnableFunction("InsertVsyncProfilerMarkerRunnable", InsertVsyncProfilerMarker, aVsyncTimestamp)); } @@ -2383,7 +2395,7 @@ void CompositorBridgeParent::NotifyDidComposite(TransactionId aTransactionId, } void CompositorBridgeParent::InvalidateRemoteLayers() { - MOZ_ASSERT(CompositorThread()->IsOnCurrentThread()); + MOZ_ASSERT(CompositorLoop() == MessageLoop::current()); Unused << PCompositorBridgeParent::SendInvalidateLayers(LayersId{0}); @@ -2505,12 +2517,13 @@ bool CompositorBridgeParent::IsSameProcess() const { } void CompositorBridgeParent::NotifyWebRenderContextPurge() { - MOZ_ASSERT(CompositorThread()->IsOnCurrentThread()); + MOZ_ASSERT(CompositorLoop() == MessageLoop::current()); RefPtr api = mWrBridge->GetWebRenderAPI(); + api->ClearAllCaches(); } void CompositorBridgeParent::NotifyWebRenderDisableNativeCompositor() { - MOZ_ASSERT(CompositorThread()->IsOnCurrentThread()); + MOZ_ASSERT(CompositorLoop() == MessageLoop::current()); if (mWrBridge) { mWrBridge->DisableNativeCompositor(); } @@ -2642,8 +2655,8 @@ bool CompositorBridgeParent::UpdatePluginWindowState(LayersId aId) { } void CompositorBridgeParent::ScheduleShowAllPluginWindows() { - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod("layers::CompositorBridgeParent::ShowAllPluginWindows", this, &CompositorBridgeParent::ShowAllPluginWindows)); } @@ -2655,8 +2668,8 @@ void CompositorBridgeParent::ShowAllPluginWindows() { } void CompositorBridgeParent::ScheduleHideAllPluginWindows() { - MOZ_ASSERT(CompositorThread()); - CompositorThread()->Dispatch( + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask( NewRunnableMethod("layers::CompositorBridgeParent::HideAllPluginWindows", this, &CompositorBridgeParent::HideAllPluginWindows)); } @@ -2883,7 +2896,7 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvEndRecordingToDisk( aResolve(true); } else if (mWrBridge) { mWrBridge->WriteCollectedFrames()->Then( - NS_GetCurrentThread(), __func__, + MessageLoop::current()->SerialEventTarget(), __func__, [resolve{aResolve}](const bool success) { resolve(success); }, [resolve{aResolve}]() { resolve(false); }); } else { @@ -2912,7 +2925,7 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvEndRecordingToMemory( } else if (mWrBridge) { RefPtr self = this; mWrBridge->GetCollectedFrames()->Then( - NS_GetCurrentThread(), __func__, + MessageLoop::current()->SerialEventTarget(), __func__, [self, resolve{aResolve}](CollectedFrames&& frames) { resolve(self->WrapCollectedFrames(std::move(frames))); }, diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h index 3722da384fb8..44adbfa7150b 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.h +++ b/gfx/layers/ipc/CompositorBridgeParent.h @@ -47,6 +47,7 @@ #include "mozilla/layers/UiCompositorControllerParent.h" #include "mozilla/VsyncDispatcher.h" +class MessageLoop; class nsIWidget; namespace mozilla { @@ -749,6 +750,7 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase, const LayersId& aId) override; bool DeallocPLayerTransactionParent( PLayerTransactionParent* aLayers) override; + virtual void ScheduleTask(already_AddRefed, int); void SetEGLSurfaceRect(int x, int y, int width, int height); diff --git a/gfx/layers/ipc/CompositorManagerChild.cpp b/gfx/layers/ipc/CompositorManagerChild.cpp index c01b2fa5db60..cadfb1088cdf 100644 --- a/gfx/layers/ipc/CompositorManagerChild.cpp +++ b/gfx/layers/ipc/CompositorManagerChild.cpp @@ -173,8 +173,9 @@ CompositorManagerChild::CompositorManagerChild(CompositorManagerParent* aParent, MOZ_ASSERT(aParent); SetOtherProcessId(base::GetCurrentProcId()); + MessageLoop* loop = CompositorThreadHolder::Loop(); ipc::MessageChannel* channel = aParent->GetIPCChannel(); - if (NS_WARN_IF(!Open(channel, CompositorThread(), ipc::ChildSide))) { + if (NS_WARN_IF(!Open(channel, loop, ipc::ChildSide))) { return; } diff --git a/gfx/layers/ipc/CompositorManagerParent.cpp b/gfx/layers/ipc/CompositorManagerParent.cpp index 6ffaebc445f1..3c997c9f4364 100644 --- a/gfx/layers/ipc/CompositorManagerParent.cpp +++ b/gfx/layers/ipc/CompositorManagerParent.cpp @@ -68,7 +68,7 @@ bool CompositorManagerParent::Create( NewRunnableMethod&&, bool>( "CompositorManagerParent::Bind", bridge, &CompositorManagerParent::Bind, std::move(aEndpoint), aIsRoot); - CompositorThread()->Dispatch(runnable.forget()); + CompositorThreadHolder::Loop()->PostTask(runnable.forget()); return true; } @@ -201,7 +201,7 @@ void CompositorManagerParent::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); #ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN - CompositorThread()->Dispatch(NS_NewRunnableFunction( + CompositorThreadHolder::Loop()->PostTask(NS_NewRunnableFunction( "layers::CompositorManagerParent::Shutdown", []() -> void { CompositorManagerParent::ShutdownInternal(); })); #endif @@ -307,7 +307,7 @@ mozilla::ipc::IPCResult CompositorManagerParent::RecvReportMemory( // thread, so we can't just pass it over to the renderer thread. We use // an intermediate MozPromise instead. wr::RenderThread::AccumulateMemoryReport(aggregate)->Then( - CompositorThread(), __func__, + CompositorThreadHolder::Loop()->SerialEventTarget(), __func__, [resolver = std::move(aResolver)](MemoryReport aReport) { resolver(aReport); }, diff --git a/gfx/layers/ipc/CompositorThread.cpp b/gfx/layers/ipc/CompositorThread.cpp index 4dc02c6856ef..9fc9eaa1438d 100644 --- a/gfx/layers/ipc/CompositorThread.cpp +++ b/gfx/layers/ipc/CompositorThread.cpp @@ -4,31 +4,32 @@ * 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/. */ #include "CompositorThread.h" - -#include "CompositorBridgeParent.h" #include "MainThreadUtils.h" -#include "VRManagerParent.h" -#include "mozilla/BackgroundHangMonitor.h" +#include "nsThreadUtils.h" +#include "CompositorBridgeParent.h" #include "mozilla/layers/CanvasTranslator.h" #include "mozilla/layers/CompositorManagerParent.h" #include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/media/MediaSystemResourceService.h" -#include "nsThread.h" -#include "nsThreadUtils.h" +#include "VRManagerParent.h" namespace mozilla { namespace layers { static StaticRefPtr sCompositorThreadHolder; static bool sFinishedCompositorShutDown = false; -static mozilla::BackgroundHangMonitor* sBackgroundHangMonitor; -nsISerialEventTarget* CompositorThread() { +base::Thread* CompositorThread() { return sCompositorThreadHolder ? sCompositorThreadHolder->GetCompositorThread() : nullptr; } +/* static */ +MessageLoop* CompositorThreadHolder::Loop() { + return CompositorThread() ? CompositorThread()->message_loop() : nullptr; +} + CompositorThreadHolder* CompositorThreadHolder::GetSingleton() { return sCompositorThreadHolder; } @@ -40,44 +41,57 @@ CompositorThreadHolder::CompositorThreadHolder() CompositorThreadHolder::~CompositorThreadHolder() { MOZ_ASSERT(NS_IsMainThread()); + if (mCompositorThread) { + DestroyCompositorThread(mCompositorThread); + } +} + +/* static */ +void CompositorThreadHolder::DestroyCompositorThread( + base::Thread* aCompositorThread) { + MOZ_ASSERT(NS_IsMainThread()); + + MOZ_ASSERT(!sCompositorThreadHolder, + "We shouldn't be destroying the compositor thread yet."); + + delete aCompositorThread; sFinishedCompositorShutDown = true; } -/* static */ already_AddRefed -CompositorThreadHolder::CreateCompositorThread() { +/* static */ base::Thread* CompositorThreadHolder::CreateCompositorThread() { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!"); - nsCOMPtr compositorThread; - nsresult rv = NS_NewNamedThread( - "Compositor", getter_AddRefs(compositorThread), - NS_NewRunnableFunction( - "CompositorThreadHolder::CompositorThreadHolderSetup", []() { - sBackgroundHangMonitor = new mozilla::BackgroundHangMonitor( - "Compositor", - /* Timeout values are powers-of-two to enable us get better - data. 128ms is chosen for transient hangs because 8Hz should - be the minimally acceptable goal for Compositor - responsiveness (normal goal is 60Hz). */ - 128, - /* 2048ms is chosen for permanent hangs because it's longer than - * most Compositor hangs seen in the wild, but is short enough - * to not miss getting native hang stacks. */ - 2048); - nsCOMPtr thread = NS_GetCurrentThread(); - static_cast(thread.get())->SetUseHangMonitor(true); - })); + base::Thread* compositorThread = new base::Thread("Compositor"); - if (NS_FAILED(rv)) { + base::Thread::Options options; + /* Timeout values are powers-of-two to enable us get better data. + 128ms is chosen for transient hangs because 8Hz should be the minimally + acceptable goal for Compositor responsiveness (normal goal is 60Hz). */ + options.transient_hang_timeout = 128; // milliseconds + /* 2048ms is chosen for permanent hangs because it's longer than most + * Compositor hangs seen in the wild, but is short enough to not miss getting + * native hang stacks. */ + options.permanent_hang_timeout = 2048; // milliseconds +#if defined(_WIN32) + /* With d3d9 the compositor thread creates native ui, see DeviceManagerD3D9. + * As such the thread is a gui thread, and must process a windows message + * queue or + * risk deadlocks. Chromium message loop TYPE_UI does exactly what we need. */ + options.message_loop_type = MessageLoop::TYPE_UI; +#endif + + if (!compositorThread->StartWithOptions(options)) { + delete compositorThread; return nullptr; } CompositorBridgeParent::Setup(); ImageBridgeParent::Setup(); - return compositorThread.forget(); + return compositorThread; } void CompositorThreadHolder::Start() { @@ -111,19 +125,7 @@ void CompositorThreadHolder::Shutdown() { CompositorManagerParent::Shutdown(); CanvasTranslator::Shutdown(); - // Ensure there are no pending tasks that would cause an access to the - // thread's HangMonitor. APZ and Canvas can keep a reference to the compositor - // thread and may continue to dispatch tasks on it as the system shuts down. - CompositorThread()->Dispatch(NS_NewRunnableFunction( - "CompositorThreadHolder::Shutdown", - [backgroundHangMonitor = UniquePtr( - sBackgroundHangMonitor)]() { - nsCOMPtr thread = NS_GetCurrentThread(); - static_cast(thread.get())->SetUseHangMonitor(false); - })); - sCompositorThreadHolder = nullptr; - sBackgroundHangMonitor = nullptr; // No locking is needed around sFinishedCompositorShutDown because it is only // ever accessed on the main thread. @@ -134,12 +136,8 @@ void CompositorThreadHolder::Shutdown() { /* static */ bool CompositorThreadHolder::IsInCompositorThread() { - if (!CompositorThread()) { - return false; - } - bool in = false; - MOZ_ALWAYS_SUCCEEDS(CompositorThread()->IsOnCurrentThread(&in)); - return in; + return CompositorThread() && + CompositorThread()->thread_id() == PlatformThread::CurrentId(); } } // namespace layers diff --git a/gfx/layers/ipc/CompositorThread.h b/gfx/layers/ipc/CompositorThread.h index f45e31c90baf..831d42ad47b0 100644 --- a/gfx/layers/ipc/CompositorThread.h +++ b/gfx/layers/ipc/CompositorThread.h @@ -6,12 +6,13 @@ #ifndef mozilla_layers_CompositorThread_h #define mozilla_layers_CompositorThread_h +#include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS +#include "base/platform_thread.h" // for PlatformThreadId +#include "base/thread.h" // for Thread +#include "base/message_loop.h" #include "nsISupportsImpl.h" #include "ThreadSafeRefcountingWithMainThreadDestruction.h" -class nsISerialEventTarget; -class nsIThread; - namespace mozilla { namespace layers { @@ -22,9 +23,7 @@ class CompositorThreadHolder final { public: CompositorThreadHolder(); - nsISerialEventTarget* GetCompositorThread() const { - return mCompositorThread; - } + base::Thread* GetCompositorThread() const { return mCompositorThread; } static CompositorThreadHolder* GetSingleton(); @@ -41,20 +40,23 @@ class CompositorThreadHolder final { */ static void Shutdown(); + static MessageLoop* Loop(); + // Returns true if the calling thread is the compositor thread. static bool IsInCompositorThread(); private: ~CompositorThreadHolder(); - nsCOMPtr mCompositorThread; + base::Thread* const mCompositorThread; - static already_AddRefed CreateCompositorThread(); + static base::Thread* CreateCompositorThread(); + static void DestroyCompositorThread(base::Thread* aCompositorThread); friend class CompositorBridgeParent; }; -nsISerialEventTarget* CompositorThread(); +base::Thread* CompositorThread(); } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/CompositorVsyncScheduler.cpp b/gfx/layers/ipc/CompositorVsyncScheduler.cpp index d00a7fae73ea..911ac3c182d4 100644 --- a/gfx/layers/ipc/CompositorVsyncScheduler.cpp +++ b/gfx/layers/ipc/CompositorVsyncScheduler.cpp @@ -110,24 +110,24 @@ void CompositorVsyncScheduler::Destroy() { void CompositorVsyncScheduler::PostCompositeTask( VsyncId aId, TimeStamp aCompositeTimestamp) { MonitorAutoLock lock(mCurrentCompositeTaskMonitor); - if (mCurrentCompositeTask == nullptr && CompositorThread()) { + if (mCurrentCompositeTask == nullptr && CompositorThreadHolder::Loop()) { RefPtr task = NewCancelableRunnableMethod( "layers::CompositorVsyncScheduler::Composite", this, &CompositorVsyncScheduler::Composite, aId, aCompositeTimestamp); mCurrentCompositeTask = task; - CompositorThread()->Dispatch(task.forget()); + ScheduleTask(task.forget()); } } void CompositorVsyncScheduler::PostVRTask(TimeStamp aTimestamp) { MonitorAutoLock lockVR(mCurrentVRTaskMonitor); - if (mCurrentVRTask == nullptr && CompositorThread()) { + if (mCurrentVRTask == nullptr && CompositorThreadHolder::Loop()) { RefPtr task = NewCancelableRunnableMethod( "layers::CompositorVsyncScheduler::DispatchVREvents", this, &CompositorVsyncScheduler::DispatchVREvents, aTimestamp); mCurrentVRTask = task; - CompositorThread()->Dispatch(task.forget()); + CompositorThreadHolder::Loop()->PostDelayedTask(task.forget(), 0); } } @@ -329,6 +329,12 @@ void CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp) { vm->NotifyVsync(aVsyncTimestamp); } +void CompositorVsyncScheduler::ScheduleTask( + already_AddRefed aTask) { + MOZ_ASSERT(CompositorThreadHolder::Loop()); + CompositorThreadHolder::Loop()->PostDelayedTask(std::move(aTask), 0); +} + const TimeStamp& CompositorVsyncScheduler::GetLastComposeTime() const { MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); return mLastCompose; diff --git a/gfx/layers/ipc/CompositorVsyncScheduler.h b/gfx/layers/ipc/CompositorVsyncScheduler.h index bb033404aefb..c4393324ee4c 100644 --- a/gfx/layers/ipc/CompositorVsyncScheduler.h +++ b/gfx/layers/ipc/CompositorVsyncScheduler.h @@ -109,6 +109,9 @@ class CompositorVsyncScheduler { private: virtual ~CompositorVsyncScheduler(); + // Schedule a task to run on the compositor thread. + void ScheduleTask(already_AddRefed); + // Post a task to run Composite() on the compositor thread, if there isn't // such a task already queued. Can be called from any thread. void PostCompositeTask(VsyncId aId, TimeStamp aCompositeTimestamp); diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 271ec4913dd3..9a09dbd88135 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -10,6 +10,7 @@ #include "ImageContainer.h" // for ImageContainer #include "Layers.h" // for Layer, etc #include "ShadowLayers.h" // for ShadowLayerForwarder +#include "base/message_loop.h" // for MessageLoop #include "base/platform_thread.h" // for PlatformThread #include "base/process.h" // for ProcessId #include "base/task.h" // for NewRunnableFunction, etc @@ -37,8 +38,8 @@ #include "nsISupportsImpl.h" // for ImageContainer::AddRef, etc #include "nsTArray.h" // for AutoTArray, nsTArray, etc #include "nsTArrayForwardDeclare.h" // for AutoTArray -#include "nsThread.h" #include "nsThreadUtils.h" // for NS_IsMainThread +#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop #include "mozilla/StaticMutex.h" #include "mozilla/StaticPtr.h" // for StaticRefPtr #include "mozilla/layers/TextureClient.h" @@ -171,10 +172,7 @@ void ImageBridgeChild::CancelWaitForNotifyNotUsed(uint64_t aTextureId) { // Singleton static StaticMutex sImageBridgeSingletonLock; static StaticRefPtr sImageBridgeChildSingleton; -// sImageBridgeChildThread cannot be converted to use a generic -// nsISerialEventTarget (which may be backed by a threadpool) until bug 1634846 -// is addressed. Therefore we keep it as an nsIThread here. -static StaticRefPtr sImageBridgeChildThread; +static Thread* sImageBridgeChildThread = nullptr; // dispatched function void ImageBridgeChild::ShutdownStep1(SynchronousTask* aTask) { @@ -295,6 +293,8 @@ void ImageBridgeChild::ForgetImageContainer(const CompositableHandle& aHandle) { mImageContainerListeners.erase(aHandle.Value()); } +Thread* ImageBridgeChild::GetThread() const { return sImageBridgeChildThread; } + /* static */ RefPtr ImageBridgeChild::GetSingleton() { StaticMutexAutoLock lock(sImageBridgeSingletonLock); @@ -310,7 +310,7 @@ void ImageBridgeChild::UpdateImageClient(RefPtr aContainer) { RefPtr runnable = WrapRunnable(RefPtr(this), &ImageBridgeChild::UpdateImageClient, aContainer); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); return; } @@ -355,7 +355,7 @@ void ImageBridgeChild::UpdateAsyncCanvasRenderer( RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::UpdateAsyncCanvasRendererSync, &task, aWrapper); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); } @@ -409,7 +409,7 @@ void ImageBridgeChild::FlushAllImages(ImageClient* aClient, RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::FlushAllImagesSync, &task, aClient, aContainer); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); } @@ -454,11 +454,9 @@ bool ImageBridgeChild::InitForContent(Endpoint&& aEndpoint, gfxPlatform::GetPlatform(); if (!sImageBridgeChildThread) { - nsCOMPtr thread; - nsresult rv = NS_NewNamedThread("ImageBridgeChld", getter_AddRefs(thread)); - MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv), - "Failed to start ImageBridgeChild thread!"); - sImageBridgeChildThread = thread.forget(); + sImageBridgeChildThread = new Thread("ImageBridgeChild"); + bool success = sImageBridgeChildThread->Start(); + MOZ_RELEASE_ASSERT(success, "Failed to start ImageBridgeChild thread!"); } RefPtr child = new ImageBridgeChild(aNamespace); @@ -466,7 +464,7 @@ bool ImageBridgeChild::InitForContent(Endpoint&& aEndpoint, RefPtr runnable = NewRunnableMethod&&>( "layers::ImageBridgeChild::Bind", child, &ImageBridgeChild::Bind, std::move(aEndpoint)); - child->GetThread()->Dispatch(runnable.forget()); + child->GetMessageLoop()->PostTask(runnable.forget()); // Assign this after so other threads can't post messages before we connect to // IPDL. @@ -503,8 +501,9 @@ void ImageBridgeChild::Bind(Endpoint&& aEndpoint) { } void ImageBridgeChild::BindSameProcess(RefPtr aParent) { + MessageLoop* parentMsgLoop = aParent->GetMessageLoop(); ipc::MessageChannel* parentChannel = aParent->GetIPCChannel(); - Open(parentChannel, aParent->GetThread(), mozilla::ipc::ChildSide); + Open(parentChannel, parentMsgLoop, mozilla::ipc::ChildSide); // This reference is dropped in DeallocPImageBridgeChild. this->AddRef(); @@ -518,6 +517,7 @@ void ImageBridgeChild::ShutDown() { ShutdownSingleton(); + delete sImageBridgeChildThread; sImageBridgeChildThread = nullptr; } @@ -540,7 +540,7 @@ void ImageBridgeChild::WillShutdown() { RefPtr runnable = WrapRunnable(RefPtr(this), &ImageBridgeChild::ShutdownStep1, &task); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); } @@ -551,7 +551,7 @@ void ImageBridgeChild::WillShutdown() { RefPtr runnable = WrapRunnable(RefPtr(this), &ImageBridgeChild::ShutdownStep2, &task); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); } @@ -563,18 +563,17 @@ void ImageBridgeChild::InitSameProcess(uint32_t aNamespace) { MOZ_ASSERT(!sImageBridgeChildSingleton); MOZ_ASSERT(!sImageBridgeChildThread); - nsCOMPtr thread; - nsresult rv = NS_NewNamedThread("ImageBridgeChld", getter_AddRefs(thread)); - MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv), - "Failed to start ImageBridgeChild thread!"); - sImageBridgeChildThread = thread.forget(); + sImageBridgeChildThread = new Thread("ImageBridgeChild"); + if (!sImageBridgeChildThread->IsRunning()) { + sImageBridgeChildThread->Start(); + } RefPtr child = new ImageBridgeChild(aNamespace); RefPtr parent = ImageBridgeParent::CreateSameProcess(); RefPtr runnable = WrapRunnable(child, &ImageBridgeChild::BindSameProcess, parent); - child->GetThread()->Dispatch(runnable.forget()); + child->GetMessageLoop()->PostTask(runnable.forget()); // Assign this after so other threads can't post messages before we connect to // IPDL. @@ -591,15 +590,15 @@ void ImageBridgeChild::InitWithGPUProcess( MOZ_ASSERT(!sImageBridgeChildSingleton); MOZ_ASSERT(!sImageBridgeChildThread); - nsCOMPtr thread; - nsresult rv = NS_NewNamedThread("ImageBridgeChld", getter_AddRefs(thread)); - MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv), - "Failed to start ImageBridgeChild thread!"); - sImageBridgeChildThread = thread.forget(); + sImageBridgeChildThread = new Thread("ImageBridgeChild"); + if (!sImageBridgeChildThread->IsRunning()) { + sImageBridgeChildThread->Start(); + } RefPtr child = new ImageBridgeChild(aNamespace); - child->GetThread()->Dispatch(NewRunnableMethod&&>( + MessageLoop* loop = child->GetMessageLoop(); + loop->PostTask(NewRunnableMethod&&>( "layers::ImageBridgeChild::Bind", child, &ImageBridgeChild::Bind, std::move(aEndpoint))); @@ -613,11 +612,12 @@ void ImageBridgeChild::InitWithGPUProcess( bool InImageBridgeChildThread() { return sImageBridgeChildThread && - sImageBridgeChildThread->IsOnCurrentThread(); + sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId(); } -nsISerialEventTarget* ImageBridgeChild::GetThread() const { - return sImageBridgeChildThread; +MessageLoop* ImageBridgeChild::GetMessageLoop() const { + return sImageBridgeChildThread ? sImageBridgeChildThread->message_loop() + : nullptr; } /* static */ @@ -697,7 +697,7 @@ RefPtr ImageBridgeChild::CreateImageClient( RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::CreateImageClientSync, &task, &result, aType, aImageContainer); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); @@ -733,7 +733,7 @@ already_AddRefed ImageBridgeChild::CreateCanvasClient( RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::CreateCanvasClientSync, &task, aType, aFlag, &result); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); @@ -807,7 +807,7 @@ bool ImageBridgeChild::DispatchAllocShmemInternal( RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::ProxyAllocShmemNow, &task, aSize, aType, aShmem, aUnsafe, &success); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); @@ -844,7 +844,7 @@ bool ImageBridgeChild::DeallocShmem(ipc::Shmem& aShmem) { RefPtr runnable = WrapRunnable( RefPtr(this), &ImageBridgeChild::ProxyDeallocShmemNow, &task, &aShmem, &result); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); return result; @@ -999,7 +999,7 @@ void ImageBridgeChild::ReleaseCompositable(const CompositableHandle& aHandle) { RefPtr runnable = WrapRunnable(RefPtr(this), &ImageBridgeChild::ReleaseCompositable, aHandle); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); return; } diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index be0fa22a2d9d..646a2a3eccc1 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -25,6 +25,12 @@ #include "mozilla/gfx/Rect.h" #include "mozilla/ReentrantMonitor.h" // for ReentrantMonitor, etc +class MessageLoop; + +namespace base { +class Thread; +} // namespace base + namespace mozilla { namespace ipc { class Shmem; @@ -160,7 +166,14 @@ class ImageBridgeChild final : public PImageBridgeChild, * * Can be called from any thread. */ - nsISerialEventTarget* GetThread() const override; + base::Thread* GetThread() const; + + /** + * Returns the ImageBridgeChild's message loop. + * + * Can be called from any thread. + */ + MessageLoop* GetMessageLoop() const override; base::ProcessId GetParentPid() const override { return OtherPid(); } diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index b9fd0c8d0df7..2686da89f3d5 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -7,6 +7,7 @@ #include "ImageBridgeParent.h" #include // for uint64_t, uint32_t #include "CompositableHost.h" // for CompositableParent, Create +#include "base/message_loop.h" // for MessageLoop #include "base/process.h" // for ProcessId #include "base/task.h" // for CancelableTask, DeleteTask, etc #include "mozilla/ClearOnShutdown.h" @@ -61,9 +62,9 @@ void ImageBridgeParent::Setup() { } } -ImageBridgeParent::ImageBridgeParent(nsISerialEventTarget* aThread, +ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, ProcessId aChildProcessId) - : mThread(aThread), + : mMessageLoop(aLoop), mClosed(false), mCompositorThreadHolder(CompositorThreadHolder::GetSingleton()) { MOZ_ASSERT(NS_IsMainThread()); @@ -76,7 +77,7 @@ ImageBridgeParent::~ImageBridgeParent() = default; ImageBridgeParent* ImageBridgeParent::CreateSameProcess() { base::ProcessId pid = base::GetCurrentProcId(); RefPtr parent = - new ImageBridgeParent(CompositorThread(), pid); + new ImageBridgeParent(CompositorThreadHolder::Loop(), pid); parent->mSelfRef = parent; { @@ -94,15 +95,15 @@ bool ImageBridgeParent::CreateForGPUProcess( Endpoint&& aEndpoint) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU); - nsCOMPtr compositorThread = CompositorThread(); - if (!compositorThread) { + MessageLoop* loop = CompositorThreadHolder::Loop(); + if (!loop) { return false; } RefPtr parent = - new ImageBridgeParent(compositorThread, aEndpoint.OtherPid()); + new ImageBridgeParent(loop, aEndpoint.OtherPid()); - compositorThread->Dispatch(NewRunnableMethod&&>( + loop->PostTask(NewRunnableMethod&&>( "layers::ImageBridgeParent::Bind", parent, &ImageBridgeParent::Bind, std::move(aEndpoint))); @@ -132,7 +133,7 @@ void ImageBridgeParent::ShutdownInternal() { /* static */ void ImageBridgeParent::Shutdown() { - CompositorThread()->Dispatch(NS_NewRunnableFunction( + CompositorThreadHolder::Loop()->PostTask(NS_NewRunnableFunction( "ImageBridgeParent::Shutdown", []() -> void { ImageBridgeParent::ShutdownInternal(); })); } @@ -145,7 +146,7 @@ void ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy) { MonitorAutoLock lock(*sImageBridgesLock); sImageBridges.erase(OtherPid()); } - GetThread()->Dispatch( + MessageLoop::current()->PostTask( NewRunnableMethod("layers::ImageBridgeParent::DeferredDestroy", this, &ImageBridgeParent::DeferredDestroy)); @@ -218,14 +219,14 @@ mozilla::ipc::IPCResult ImageBridgeParent::RecvUpdate( /* static */ bool ImageBridgeParent::CreateForContent( Endpoint&& aEndpoint) { - nsCOMPtr compositorThread = CompositorThread(); - if (!compositorThread) { + MessageLoop* loop = CompositorThreadHolder::Loop(); + if (!loop) { return false; } RefPtr bridge = - new ImageBridgeParent(compositorThread, aEndpoint.OtherPid()); - compositorThread->Dispatch(NewRunnableMethod&&>( + new ImageBridgeParent(loop, aEndpoint.OtherPid()); + loop->PostTask(NewRunnableMethod&&>( "layers::ImageBridgeParent::Bind", bridge, &ImageBridgeParent::Bind, std::move(aEndpoint))); diff --git a/gfx/layers/ipc/ImageBridgeParent.h b/gfx/layers/ipc/ImageBridgeParent.h index 7c5e5cd2d424..1c5a30512819 100644 --- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -19,6 +19,12 @@ #include "nsISupportsImpl.h" #include "nsTArrayForwardDeclare.h" // for nsTArray +class MessageLoop; + +namespace base { +class Thread; +} // namespace base + namespace mozilla { namespace ipc { class Shmem; @@ -39,7 +45,7 @@ class ImageBridgeParent final : public PImageBridgeParent, typedef nsTArray OpDestroyArray; protected: - ImageBridgeParent(nsISerialEventTarget* aThread, ProcessId aChildProcessId); + ImageBridgeParent(MessageLoop* aLoop, ProcessId aChildProcessId); public: virtual ~ImageBridgeParent(); @@ -92,7 +98,7 @@ class ImageBridgeParent final : public PImageBridgeParent, // Shutdown step 1 mozilla::ipc::IPCResult RecvWillClose(); - nsISerialEventTarget* GetThread() const { return mThread; } + MessageLoop* GetMessageLoop() const { return mMessageLoop; } // IShmemAllocator @@ -136,7 +142,7 @@ class ImageBridgeParent final : public PImageBridgeParent, static void ShutdownInternal(); void DeferredDestroy(); - nsCOMPtr mThread; + MessageLoop* mMessageLoop; // This keeps us alive until ActorDestroy(), at which point we do a // deferred destruction of ourselves. RefPtr mSelfRef; diff --git a/gfx/layers/ipc/RemoteContentController.cpp b/gfx/layers/ipc/RemoteContentController.cpp index a007d792897c..b651b9025352 100644 --- a/gfx/layers/ipc/RemoteContentController.cpp +++ b/gfx/layers/ipc/RemoteContentController.cpp @@ -6,6 +6,8 @@ #include "mozilla/layers/RemoteContentController.h" +#include "base/message_loop.h" +#include "base/task.h" #include "MainThreadUtils.h" #include "mozilla/dom/BrowserParent.h" #include "mozilla/layers/APZCCallbackHelper.h" @@ -27,19 +29,18 @@ namespace layers { using namespace mozilla::gfx; RemoteContentController::RemoteContentController() - : mCompositorThread(NS_GetCurrentThread()), mCanSend(true) { - MOZ_ASSERT(CompositorThread()->IsOnCurrentThread()); -} + : mCompositorThread(MessageLoop::current()), mCanSend(true) {} RemoteContentController::~RemoteContentController() = default; void RemoteContentController::NotifyLayerTransforms( const nsTArray& aTransforms) { - if (!mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mCompositorThread) { // We have to send messages from the compositor thread - mCompositorThread->Dispatch(NewRunnableMethod>( - "layers::RemoteContentController::NotifyLayerTransforms", this, - &RemoteContentController::NotifyLayerTransforms, aTransforms)); + mCompositorThread->PostTask( + NewRunnableMethod>( + "layers::RemoteContentController::NotifyLayerTransforms", this, + &RemoteContentController::NotifyLayerTransforms, aTransforms)); return; } @@ -77,7 +78,7 @@ void RemoteContentController::HandleTapOnCompositorThread( TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers, ScrollableLayerGuid aGuid, uint64_t aInputBlockId) { MOZ_ASSERT(XRE_IsGPUProcess()); - MOZ_ASSERT(mCompositorThread->IsOnCurrentThread()); + MOZ_ASSERT(MessageLoop::current() == mCompositorThread); // The raw pointer to APZCTreeManagerParent is ok here because we are on the // compositor thread. @@ -98,12 +99,12 @@ void RemoteContentController::HandleTap(TapType aTapType, APZThreadUtils::AssertOnControllerThread(); if (XRE_GetProcessType() == GeckoProcessType_GPU) { - if (mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() == mCompositorThread) { HandleTapOnCompositorThread(aTapType, aPoint, aModifiers, aGuid, aInputBlockId); } else { // We have to send messages from the compositor thread - mCompositorThread->Dispatch( + mCompositorThread->PostTask( NewRunnableMethod( "layers::RemoteContentController::HandleTapOnCompositorThread", @@ -143,7 +144,7 @@ void RemoteContentController::HandleTap(TapType aTapType, void RemoteContentController::NotifyPinchGestureOnCompositorThread( PinchGestureInput::PinchGestureType aType, const ScrollableLayerGuid& aGuid, LayoutDeviceCoord aSpanChange, Modifiers aModifiers) { - MOZ_ASSERT(mCompositorThread->IsOnCurrentThread()); + MOZ_ASSERT(MessageLoop::current() == mCompositorThread); // The raw pointer to APZCTreeManagerParent is ok here because we are on the // compositor thread. @@ -166,11 +167,11 @@ void RemoteContentController::NotifyPinchGesture( // If we're in the GPU process, try to find a handle to the parent process // and send it there. if (XRE_IsGPUProcess()) { - if (mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() == mCompositorThread) { NotifyPinchGestureOnCompositorThread(aType, aGuid, aSpanChange, aModifiers); } else { - mCompositorThread->Dispatch( + mCompositorThread->PostTask( NewRunnableMethod( "layers::RemoteContentController::" @@ -196,20 +197,26 @@ void RemoteContentController::NotifyPinchGesture( } } +void RemoteContentController::PostDelayedTask(already_AddRefed aTask, + int aDelayMs) { + (MessageLoop::current() ? MessageLoop::current() : mCompositorThread) + ->PostDelayedTask(std::move(aTask), aDelayMs); +} + bool RemoteContentController::IsRepaintThread() { - return mCompositorThread->IsOnCurrentThread(); + return MessageLoop::current() == mCompositorThread; } void RemoteContentController::DispatchToRepaintThread( already_AddRefed aTask) { - mCompositorThread->Dispatch(std::move(aTask)); + mCompositorThread->PostTask(std::move(aTask)); } void RemoteContentController::NotifyAPZStateChange( const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg) { - if (!mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mCompositorThread) { // We have to send messages from the compositor thread - mCompositorThread->Dispatch( + mCompositorThread->PostTask( NewRunnableMethod( "layers::RemoteContentController::NotifyAPZStateChange", this, &RemoteContentController::NotifyAPZStateChange, aGuid, aChange, @@ -224,8 +231,8 @@ void RemoteContentController::NotifyAPZStateChange( void RemoteContentController::UpdateOverscrollVelocity(float aX, float aY, bool aIsRootContent) { - if (!mCompositorThread->IsOnCurrentThread()) { - mCompositorThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mCompositorThread) { + mCompositorThread->PostTask(NewRunnableMethod( "layers::RemoteContentController::UpdateOverscrollVelocity", this, &RemoteContentController::UpdateOverscrollVelocity, aX, aY, aIsRootContent)); @@ -238,8 +245,8 @@ void RemoteContentController::UpdateOverscrollVelocity(float aX, float aY, void RemoteContentController::UpdateOverscrollOffset(float aX, float aY, bool aIsRootContent) { - if (!mCompositorThread->IsOnCurrentThread()) { - mCompositorThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mCompositorThread) { + mCompositorThread->PostTask(NewRunnableMethod( "layers::RemoteContentController::UpdateOverscrollOffset", this, &RemoteContentController::UpdateOverscrollOffset, aX, aY, aIsRootContent)); @@ -252,9 +259,9 @@ void RemoteContentController::UpdateOverscrollOffset(float aX, float aY, void RemoteContentController::NotifyMozMouseScrollEvent( const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent) { - if (!mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mCompositorThread) { // We have to send messages from the compositor thread - mCompositorThread->Dispatch( + mCompositorThread->PostTask( NewRunnableMethod( "layers::RemoteContentController::NotifyMozMouseScrollEvent", this, &RemoteContentController::NotifyMozMouseScrollEvent, aScrollId, @@ -278,9 +285,9 @@ void RemoteContentController::NotifyFlushComplete() { void RemoteContentController::NotifyAsyncScrollbarDragInitiated( uint64_t aDragBlockId, const ScrollableLayerGuid::ViewID& aScrollId, ScrollDirection aDirection) { - if (!mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mCompositorThread) { // We have to send messages from the compositor thread - mCompositorThread->Dispatch(NewRunnableMethodPostTask(NewRunnableMethod( "layers::RemoteContentController::NotifyAsyncScrollbarDragInitiated", @@ -297,9 +304,9 @@ void RemoteContentController::NotifyAsyncScrollbarDragInitiated( void RemoteContentController::NotifyAsyncScrollbarDragRejected( const ScrollableLayerGuid::ViewID& aScrollId) { - if (!mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mCompositorThread) { // We have to send messages from the compositor thread - mCompositorThread->Dispatch(NewRunnableMethod( + mCompositorThread->PostTask(NewRunnableMethod( "layers::RemoteContentController::NotifyAsyncScrollbarDragRejected", this, &RemoteContentController::NotifyAsyncScrollbarDragRejected, aScrollId)); @@ -313,9 +320,9 @@ void RemoteContentController::NotifyAsyncScrollbarDragRejected( void RemoteContentController::NotifyAsyncAutoscrollRejected( const ScrollableLayerGuid::ViewID& aScrollId) { - if (!mCompositorThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mCompositorThread) { // We have to send messages from the compositor thread - mCompositorThread->Dispatch(NewRunnableMethod( + mCompositorThread->PostTask(NewRunnableMethod( "layers::RemoteContentController::NotifyAsyncAutoscrollRejected", this, &RemoteContentController::NotifyAsyncAutoscrollRejected, aScrollId)); return; @@ -353,8 +360,8 @@ void RemoteContentController::CancelAutoscrollCrossProcess( const ScrollableLayerGuid& aGuid) { MOZ_ASSERT(XRE_IsGPUProcess()); - if (!mCompositorThread->IsOnCurrentThread()) { - mCompositorThread->Dispatch(NewRunnableMethod( + if (MessageLoop::current() != mCompositorThread) { + mCompositorThread->PostTask(NewRunnableMethod( "layers::RemoteContentController::CancelAutoscrollCrossProcess", this, &RemoteContentController::CancelAutoscrollCrossProcess, aGuid)); return; diff --git a/gfx/layers/ipc/RemoteContentController.h b/gfx/layers/ipc/RemoteContentController.h index efd710ad8221..10448d67ff2a 100644 --- a/gfx/layers/ipc/RemoteContentController.h +++ b/gfx/layers/ipc/RemoteContentController.h @@ -52,6 +52,8 @@ class RemoteContentController : public GeckoContentController, LayoutDeviceCoord aSpanChange, Modifiers aModifiers) override; + void PostDelayedTask(already_AddRefed aTask, int aDelayMs) override; + bool IsRepaintThread() override; void DispatchToRepaintThread(already_AddRefed aTask) override; @@ -88,7 +90,7 @@ class RemoteContentController : public GeckoContentController, bool IsRemote() override; private: - nsCOMPtr mCompositorThread; + MessageLoop* mCompositorThread; bool mCanSend; void HandleTapOnMainThread(TapType aType, LayoutDevicePoint aPoint, diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 1e8dcc8d91ba..f686b1e1b681 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -189,7 +189,7 @@ RefPtr ShadowLayerForwarder::GetForMedia() { ShadowLayerForwarder::ShadowLayerForwarder( ClientLayerManager* aClientLayerManager) : mClientLayerManager(aClientLayerManager), - mThread(NS_GetCurrentThread()), + mMessageLoop(MessageLoop::current()), mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC), mIsFirstPaint(false), mNextLayerHandle(1) { @@ -500,7 +500,9 @@ void ShadowLayerForwarder::RemoveTextureFromCompositable( } bool ShadowLayerForwarder::InWorkerThread() { - return GetTextureForwarder()->GetThread()->IsOnCurrentThread(); + return MessageLoop::current() && + (GetTextureForwarder()->GetMessageLoop()->id() == + MessageLoop::current()->id()); } void ShadowLayerForwarder::StorePluginWidgetConfigurations( diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index fa7e3da201d1..f1e811dac4aa 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -418,7 +418,7 @@ class ShadowLayerForwarder final : public LayersIPCActor, private: ClientLayerManager* mClientLayerManager; Transaction* mTxn; - nsCOMPtr mThread; + MessageLoop* mMessageLoop; DiagnosticTypes mDiagnosticTypes; bool mIsFirstPaint; FocusTarget mFocusTarget; diff --git a/gfx/layers/ipc/TextureForwarder.h b/gfx/layers/ipc/TextureForwarder.h index 09ad0a12add5..49fd4a5ed013 100644 --- a/gfx/layers/ipc/TextureForwarder.h +++ b/gfx/layers/ipc/TextureForwarder.h @@ -13,7 +13,6 @@ #include "mozilla/layers/LayersTypes.h" // for LayersBackend #include "mozilla/layers/TextureClient.h" // for TextureClient #include "mozilla/layers/KnowsCompositor.h" -#include "nsISerialEventTarget.h" namespace mozilla { namespace ipc { @@ -48,7 +47,7 @@ class LayersIPCChannel : public LayersIPCActor, virtual base::ProcessId GetParentPid() const = 0; - virtual nsISerialEventTarget* GetThread() const = 0; + virtual MessageLoop* GetMessageLoop() const = 0; virtual FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator() { return nullptr; diff --git a/gfx/layers/ipc/UiCompositorControllerChild.cpp b/gfx/layers/ipc/UiCompositorControllerChild.cpp index 0225cb8b9db6..be67b4940b48 100644 --- a/gfx/layers/ipc/UiCompositorControllerChild.cpp +++ b/gfx/layers/ipc/UiCompositorControllerChild.cpp @@ -27,7 +27,9 @@ static RefPtr GetUiThread() { } #endif // defined(MOZ_WIDGET_ANDROID) -static bool IsOnUiThread() { return GetUiThread()->IsOnCurrentThread(); } +static bool IsOnUiThread() { + return GetUiThread()->SerialEventTarget()->IsOnCurrentThread(); +} namespace mozilla { namespace layers { @@ -260,7 +262,8 @@ UiCompositorControllerChild::~UiCompositorControllerChild() = default; void UiCompositorControllerChild::OpenForSameProcess() { MOZ_ASSERT(IsOnUiThread()); - mIsOpen = Open(mParent->GetIPCChannel(), mozilla::layers::CompositorThread(), + mIsOpen = Open(mParent->GetIPCChannel(), + mozilla::layers::CompositorThreadHolder::Loop(), mozilla::ipc::ChildSide); if (!mIsOpen) { diff --git a/gfx/layers/ipc/UiCompositorControllerParent.cpp b/gfx/layers/ipc/UiCompositorControllerParent.cpp index 8150e3682b84..954e2ee725b4 100644 --- a/gfx/layers/ipc/UiCompositorControllerParent.cpp +++ b/gfx/layers/ipc/UiCompositorControllerParent.cpp @@ -50,7 +50,7 @@ RefPtr UiCompositorControllerParent::Start( NewRunnableMethod&&>( "layers::UiCompositorControllerParent::Open", parent, &UiCompositorControllerParent::Open, std::move(aEndpoint)); - CompositorThread()->Dispatch(task.forget()); + CompositorThreadHolder::Loop()->PostTask(task.forget()); return parent; } @@ -181,7 +181,7 @@ void UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor( int32_t aMessage) { // This function can be call from ether compositor or controller thread. if (!CompositorThreadHolder::IsInCompositorThread()) { - CompositorThread()->Dispatch(NewRunnableMethod( + CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod( "layers::UiCompositorControllerParent::" "ToolbarAnimatorMessageFromCompositor", this, @@ -218,10 +218,11 @@ void UiCompositorControllerParent::NotifyUpdateScreenMetrics( aMetrics.GetZoom().ToScaleFactor(), PixelCastJustification::ScreenIsParentLayerForRoot); ScreenPoint scrollOffset = aMetrics.GetScrollOffset() * scale; - CompositorThread()->Dispatch(NewRunnableMethod( - "UiCompositorControllerParent::SendRootFrameMetrics", this, - &UiCompositorControllerParent::SendRootFrameMetrics, scrollOffset, - scale)); + CompositorThreadHolder::Loop()->PostTask( + NewRunnableMethod( + "UiCompositorControllerParent::SendRootFrameMetrics", this, + &UiCompositorControllerParent::SendRootFrameMetrics, scrollOffset, + scale)); #endif } @@ -248,7 +249,7 @@ void UiCompositorControllerParent::InitializeForSameProcess() { SynchronousTask task( "UiCompositorControllerParent::InitializeForSameProcess"); - CompositorThread()->Dispatch(NS_NewRunnableFunction( + CompositorThreadHolder::Loop()->PostTask(NS_NewRunnableFunction( "UiCompositorControllerParent::InitializeForSameProcess", [&]() { AutoCompleteTask complete(&task); InitializeForSameProcess(); diff --git a/gfx/layers/ipc/VideoBridgeChild.cpp b/gfx/layers/ipc/VideoBridgeChild.cpp index 7529c29318a0..a60c37de02b8 100644 --- a/gfx/layers/ipc/VideoBridgeChild.cpp +++ b/gfx/layers/ipc/VideoBridgeChild.cpp @@ -48,7 +48,9 @@ void VideoBridgeChild::Shutdown() { } VideoBridgeChild::VideoBridgeChild() - : mIPDLSelfRef(this), mThread(NS_GetCurrentThread()), mCanSend(true) {} + : mIPDLSelfRef(this), + mMessageLoop(MessageLoop::current()), + mCanSend(true) {} VideoBridgeChild::~VideoBridgeChild() = default; @@ -57,7 +59,7 @@ VideoBridgeChild* VideoBridgeChild::GetSingleton() { return sVideoBridge; } bool VideoBridgeChild::AllocUnsafeShmem( size_t aSize, ipc::SharedMemory::SharedMemoryType aType, ipc::Shmem* aShmem) { - if (!mThread->IsOnCurrentThread()) { + if (MessageLoop::current() != mMessageLoop) { return DispatchAllocShmemInternal(aSize, aType, aShmem, true); // true: unsafe } @@ -104,7 +106,7 @@ bool VideoBridgeChild::DispatchAllocShmemInternal( RefPtr runnable = WrapRunnable( RefPtr(this), &VideoBridgeChild::ProxyAllocShmemNow, &task, aSize, aType, aShmem, aUnsafe, &success); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); @@ -122,7 +124,7 @@ void VideoBridgeChild::ProxyDeallocShmemNow(SynchronousTask* aTask, } bool VideoBridgeChild::DeallocShmem(ipc::Shmem& aShmem) { - if (GetThread()->IsOnCurrentThread()) { + if (MessageLoop::current() == mMessageLoop) { if (!CanSend()) { return false; } @@ -135,7 +137,7 @@ bool VideoBridgeChild::DeallocShmem(ipc::Shmem& aShmem) { RefPtr runnable = WrapRunnable( RefPtr(this), &VideoBridgeChild::ProxyDeallocShmemNow, &task, &aShmem, &result); - GetThread()->Dispatch(runnable.forget()); + GetMessageLoop()->PostTask(runnable.forget()); task.Wait(); return result; diff --git a/gfx/layers/ipc/VideoBridgeChild.h b/gfx/layers/ipc/VideoBridgeChild.h index 69f1642d1223..1e5b3920ed2a 100644 --- a/gfx/layers/ipc/VideoBridgeChild.h +++ b/gfx/layers/ipc/VideoBridgeChild.h @@ -57,7 +57,7 @@ class VideoBridgeChild final : public PVideoBridgeChild, // ClientIPCAllocator base::ProcessId GetParentPid() const override { return OtherPid(); } - nsISerialEventTarget* GetThread() const override { return mThread; } + MessageLoop* GetMessageLoop() const override { return mMessageLoop; } void CancelWaitForNotifyNotUsed(uint64_t aTextureId) override { MOZ_ASSERT(false, "NO RECYCLING HERE"); } @@ -86,7 +86,7 @@ class VideoBridgeChild final : public PVideoBridgeChild, virtual ~VideoBridgeChild(); RefPtr mIPDLSelfRef; - nsCOMPtr mThread; + MessageLoop* mMessageLoop; bool mCanSend; }; diff --git a/gfx/layers/ipc/VideoBridgeParent.cpp b/gfx/layers/ipc/VideoBridgeParent.cpp index d8791ed9fbc0..f18585041fd0 100644 --- a/gfx/layers/ipc/VideoBridgeParent.cpp +++ b/gfx/layers/ipc/VideoBridgeParent.cpp @@ -48,7 +48,7 @@ void VideoBridgeParent::Open(Endpoint&& aEndpoint, VideoBridgeSource aSource) { RefPtr parent = new VideoBridgeParent(aSource); - CompositorThread()->Dispatch( + CompositorThreadHolder::Loop()->PostTask( NewRunnableMethod&&>( "gfx::layers::VideoBridgeParent::Bind", parent, &VideoBridgeParent::Bind, std::move(aEndpoint))); diff --git a/gfx/layers/wr/AsyncImagePipelineManager.cpp b/gfx/layers/wr/AsyncImagePipelineManager.cpp index cdc1fb1c379d..abc24a7150bb 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.cpp +++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp @@ -551,7 +551,7 @@ void AsyncImagePipelineManager::NotifyPipelinesUpdated( // Queue a runnable on the compositor thread to process the updates. // This will also call CheckForTextureHostsNotUsedByGPU. - layers::CompositorThread()->Dispatch( + layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableMethod("ProcessPipelineUpdates", this, &AsyncImagePipelineManager::ProcessPipelineUpdates)); } diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index e7643948d399..984237e5641f 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -193,7 +193,7 @@ class ScheduleObserveLayersUpdate : public wr::NotificationHandler { mIsActive(aIsActive) {} void Notify(wr::Checkpoint) override { - CompositorThread()->Dispatch( + CompositorThreadHolder::Loop()->PostTask( NewRunnableMethod( "ObserveLayersUpdate", mBridge, &CompositorBridgeParentBase::ObserveLayersUpdate, mLayersId, @@ -217,7 +217,7 @@ class SceneBuiltNotification : public wr::NotificationHandler { auto startTime = this->mTxnStartTime; RefPtr parent = mParent; wr::Epoch epoch = mEpoch; - CompositorThread()->Dispatch(NS_NewRunnableFunction( + CompositorThreadHolder::Loop()->PostTask(NS_NewRunnableFunction( "SceneBuiltNotificationRunnable", [parent, epoch, startTime]() { auto endTime = TimeStamp::Now(); #ifdef MOZ_GECKO_PROFILER @@ -287,7 +287,7 @@ class WebRenderBridgeParent::ScheduleSharedSurfaceRelease final } void Notify(wr::Checkpoint) override { - CompositorThread()->Dispatch( + CompositorThreadHolder::Loop()->PostTask( NewRunnableMethod>( "ObserveSharedSurfaceRelease", mWrBridge, &WebRenderBridgeParent::ObserveSharedSurfaceRelease, diff --git a/gfx/thebes/DeviceManagerDx.cpp b/gfx/thebes/DeviceManagerDx.cpp index 07da4f2bcc48..04be5837311e 100644 --- a/gfx/thebes/DeviceManagerDx.cpp +++ b/gfx/thebes/DeviceManagerDx.cpp @@ -1384,7 +1384,8 @@ void DeviceManagerDx::GetCompositorDevices( /* static */ void DeviceManagerDx::PreloadAttachmentsOnCompositorThread() { - if (!CompositorThread()) { + MessageLoop* loop = layers::CompositorThreadHolder::Loop(); + if (!loop) { return; } @@ -1403,7 +1404,7 @@ void DeviceManagerDx::PreloadAttachmentsOnCompositorThread() { } } }); - CompositorThread()->Dispatch(task.forget()); + loop->PostTask(task.forget()); } } // namespace gfx diff --git a/gfx/vr/VRManager.cpp b/gfx/vr/VRManager.cpp index 85416ffed497..7f4eff393831 100644 --- a/gfx/vr/VRManager.cpp +++ b/gfx/vr/VRManager.cpp @@ -309,7 +309,7 @@ void VRManager::StartTasks() { if (!mTaskTimer) { mTaskInterval = GetOptimalTaskInterval(); mTaskTimer = NS_NewTimer(); - mTaskTimer->SetTarget(CompositorThread()); + mTaskTimer->SetTarget(CompositorThreadHolder::Loop()->SerialEventTarget()); mTaskTimer->InitWithNamedFuncCallback( TaskTimerCallback, this, mTaskInterval, nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP, @@ -1380,7 +1380,7 @@ void VRManager::SubmitFrame(VRLayerParent* aLayer, mSubmitThread->Start(); mSubmitThread->PostTask(task.forget()); #else - CompositorThread()->Dispatch(task.forget()); + CompositorThreadHolder::Loop()->PostTask(task.forget()); #endif // defined(MOZ_WIDGET_ANDROID) } } @@ -1514,8 +1514,10 @@ void VRManager::SubmitFrameInternal(const layers::SurfaceDescriptor& aTexture, * frames to continue at a lower refresh rate until frame submission * succeeds again. */ - CompositorThread()->Dispatch(NewRunnableMethod("gfx::VRManager::StartFrame", - this, &VRManager::StartFrame)); + MessageLoop* loop = CompositorThreadHolder::Loop(); + + loop->PostTask(NewRunnableMethod("gfx::VRManager::StartFrame", this, + &VRManager::StartFrame)); #elif defined(MOZ_WIDGET_ANDROID) // We are already in the CompositorThreadHolder event loop on Android. StartFrame(); diff --git a/gfx/vr/VRThread.cpp b/gfx/vr/VRThread.cpp index 37748544441a..ee972226a6b5 100644 --- a/gfx/vr/VRThread.cpp +++ b/gfx/vr/VRThread.cpp @@ -7,7 +7,6 @@ #include "VRThread.h" #include "nsDebug.h" #include "nsThreadManager.h" -#include "nsThread.h" #include "nsThreadUtils.h" #include "VRManager.h" diff --git a/gfx/vr/ipc/VRGPUChild.cpp b/gfx/vr/ipc/VRGPUChild.cpp index 715c3e3c8abb..4deadbe47a1f 100644 --- a/gfx/vr/ipc/VRGPUChild.cpp +++ b/gfx/vr/ipc/VRGPUChild.cpp @@ -56,7 +56,7 @@ void VRGPUChild::Shutdown() { void VRGPUChild::ActorDestroy(ActorDestroyReason aWhy) { VRManager* vm = VRManager::Get(); - mozilla::layers::CompositorThread()->Dispatch( + mozilla::layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableMethod("VRGPUChild::ActorDestroy", vm, &VRManager::Shutdown)); mClosed = true; diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index 1dcdf6012543..fc2f62197cd7 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -40,6 +40,7 @@ void ReleaseVRManagerParentSingleton() { sVRManagerParentSingleton = nullptr; } VRManagerChild::VRManagerChild() : mRuntimeCapabilities(VRDisplayCapabilityFlags::Cap_None), + mMessageLoop(MessageLoop::current()), mFrameRequestCallbackCounter(0), mWaitingForEnumeration(false), mBackend(layers::LayersBackend::LAYERS_NONE) { @@ -111,7 +112,8 @@ void VRManagerChild::InitSameProcess() { sVRManagerChildSingleton = new VRManagerChild(); sVRManagerParentSingleton = VRManagerParent::CreateSameProcess(); sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(), - CompositorThread(), mozilla::ipc::ChildSide); + CompositorThreadHolder::Loop(), + mozilla::ipc::ChildSide); } /* static */ diff --git a/gfx/vr/ipc/VRManagerChild.h b/gfx/vr/ipc/VRManagerChild.h index 06dcae94b3ab..5ccc432b6705 100644 --- a/gfx/vr/ipc/VRManagerChild.h +++ b/gfx/vr/ipc/VRManagerChild.h @@ -158,6 +158,8 @@ class VRManagerChild : public PVRManagerChild { bool mDisplaysInitialized; nsTArray mNavigatorCallbacks; + MessageLoop* mMessageLoop; + struct XRFrameRequest { XRFrameRequest(mozilla::dom::FrameRequestCallback& aCallback, int32_t aHandle) diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp index 609e489ec305..9da0fa6f1f5a 100644 --- a/gfx/vr/ipc/VRManagerParent.cpp +++ b/gfx/vr/ipc/VRManagerParent.cpp @@ -72,12 +72,13 @@ void VRManagerParent::UnregisterFromManager() { /* static */ bool VRManagerParent::CreateForContent(Endpoint&& aEndpoint) { - if (!CompositorThread()) { + MessageLoop* loop = CompositorThreadHolder::Loop(); + if (!loop) { return false; } RefPtr vmp = new VRManagerParent(aEndpoint.OtherPid(), true); - CompositorThread()->Dispatch(NewRunnableMethod&&>( + loop->PostTask(NewRunnableMethod&&>( "gfx::VRManagerParent::Bind", vmp, &VRManagerParent::Bind, std::move(aEndpoint))); @@ -101,11 +102,12 @@ void VRManagerParent::RegisterVRManagerInCompositorThread( /*static*/ VRManagerParent* VRManagerParent::CreateSameProcess() { + MessageLoop* loop = CompositorThreadHolder::Loop(); RefPtr vmp = new VRManagerParent(base::GetCurrentProcId(), false); vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton(); vmp->mSelfRef = vmp; - CompositorThread()->Dispatch( + loop->PostTask( NewRunnableFunction("RegisterVRManagerIncompositorThreadRunnable", RegisterVRManagerInCompositorThread, vmp.get())); return vmp.get(); @@ -113,11 +115,13 @@ VRManagerParent* VRManagerParent::CreateSameProcess() { bool VRManagerParent::CreateForGPUProcess( Endpoint&& aEndpoint) { + MessageLoop* loop = CompositorThreadHolder::Loop(); + RefPtr vmp = new VRManagerParent(aEndpoint.OtherPid(), false); vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton(); vmp->mSelfRef = vmp; - CompositorThread()->Dispatch(NewRunnableMethod&&>( + loop->PostTask(NewRunnableMethod&&>( "gfx::VRManagerParent::Bind", vmp, &VRManagerParent::Bind, std::move(aEndpoint))); return true; @@ -126,7 +130,7 @@ bool VRManagerParent::CreateForGPUProcess( /*static*/ void VRManagerParent::Shutdown() { ReleaseVRManagerParentSingleton(); - CompositorThread()->Dispatch(NS_NewRunnableFunction( + CompositorThreadHolder::Loop()->PostTask(NS_NewRunnableFunction( "VRManagerParent::Shutdown", []() -> void { VRManagerParent::ShutdownInternal(); })); } diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index b5803bdeec8c..91431c0f542d 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -469,7 +469,7 @@ void RenderThread::UpdateAndRender( auto& renderer = it->second; - layers::CompositorThread()->Dispatch( + layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction("NotifyDidStartRenderRunnable", &NotifyDidStartRender, renderer->GetCompositorBridge())); @@ -487,7 +487,7 @@ void RenderThread::UpdateAndRender( TimeStamp end = TimeStamp::Now(); RefPtr info = renderer->FlushPipelineInfo(); - layers::CompositorThread()->Dispatch( + layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction("NotifyDidRenderRunnable", &NotifyDidRender, renderer->GetCompositorBridge(), info, aStartId, aStartTime, start, end, aRender, stats)); @@ -821,7 +821,7 @@ void RenderThread::HandleWebRenderError(WebRenderError aError) { return; } - layers::CompositorThread()->Dispatch(NewRunnableFunction( + layers::CompositorThreadHolder::Loop()->PostTask(NewRunnableFunction( "DoNotifyWebRenderErrorRunnable", &DoNotifyWebRenderError, aError)); { MutexAutoLock lock(mRenderTextureMapLock); @@ -1114,7 +1114,7 @@ void wr_finished_scene_build(mozilla::wr::WrWindowId aWindowId, for (size_t i = 0; i < aDocumentIdsCount; ++i) { renderRoots[i] = wr::RenderRootFromId(aDocumentIds[i]); } - layers::CompositorThread()->Dispatch( + layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction("NotifyDidSceneBuild", &NotifyDidSceneBuild, cbp, std::move(renderRoots), info)); } diff --git a/gfx/webrender_bindings/RendererOGL.cpp b/gfx/webrender_bindings/RendererOGL.cpp index fd03d91cb1b6..d6cc5f843634 100644 --- a/gfx/webrender_bindings/RendererOGL.cpp +++ b/gfx/webrender_bindings/RendererOGL.cpp @@ -200,7 +200,7 @@ bool RendererOGL::EnsureAsyncScreenshot() { return true; } if (!mDisableNativeCompositor) { - layers::CompositorThread()->Dispatch( + layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction("DoWebRenderDisableNativeCompositorRunnable", &DoWebRenderDisableNativeCompositor, mBridge)); @@ -219,7 +219,7 @@ void RendererOGL::CheckGraphicsResetStatus() { if (gl->IsSupported(gl::GLFeature::robustness)) { GLenum resetStatus = gl->fGetGraphicsResetStatus(); if (resetStatus == LOCAL_GL_PURGED_CONTEXT_RESET_NV) { - layers::CompositorThread()->Dispatch( + layers::CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction("DoNotifyWebRenderContextPurgeRunnable", &DoNotifyWebRenderContextPurge, mBridge)); } diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.h b/media/webrtc/signaling/src/media-conduit/VideoConduit.h index 7ab648f3e8a3..f372ecad5da1 100644 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h @@ -54,6 +54,7 @@ T MinIgnoreZero(const T& a, const T& b); class VideoStreamFactory; class WebrtcAudioConduit; +class nsThread; // Interface of external video encoder for WebRTC. class WebrtcVideoEncoder : public VideoEncoder, public webrtc::VideoEncoder {}; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index fe7aa459de54..c32db127ee55 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -2291,8 +2291,7 @@ bool nsWindow::NeedsPaint() { } void nsWindow::ConfigureAPZControllerThread() { - nsCOMPtr thread = mozilla::GetAndroidUiThread(); - APZThreadUtils::SetControllerThread(thread); + APZThreadUtils::SetControllerThread(mozilla::GetAndroidUiThreadMessageLoop()); } already_AddRefed diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 7c11572f2996..88e88839157a 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -908,7 +908,7 @@ void nsBaseWidget::ConfigureAPZCTreeManager() { void nsBaseWidget::ConfigureAPZControllerThread() { // By default the controller thread is the main thread. - APZThreadUtils::SetControllerThread(NS_GetCurrentThread()); + APZThreadUtils::SetControllerThread(MessageLoop::current()); } void nsBaseWidget::SetConfirmedTargetAPZC( diff --git a/widget/windows/CompositorWidgetParent.cpp b/widget/windows/CompositorWidgetParent.cpp index d59dce6905e2..1bc839f2b729 100644 --- a/widget/windows/CompositorWidgetParent.cpp +++ b/widget/windows/CompositorWidgetParent.cpp @@ -216,7 +216,7 @@ void CompositorWidgetParent::UpdateCompositorWnd(const HWND aCompositorWnd, SendUpdateCompositorWnd(reinterpret_cast(aCompositorWnd), reinterpret_cast(aParentWnd)) ->Then( - layers::CompositorThread(), __func__, + layers::CompositorThreadHolder::Loop()->SerialEventTarget(), __func__, [self](const bool& aSuccess) { if (aSuccess && self->mRootLayerTreeID.isSome()) { self->mSetParentCompleted = true; diff --git a/xpcom/threads/ThreadEventTarget.cpp b/xpcom/threads/ThreadEventTarget.cpp index 86a7dc1e5917..f2cbf093f7b0 100644 --- a/xpcom/threads/ThreadEventTarget.cpp +++ b/xpcom/threads/ThreadEventTarget.cpp @@ -167,11 +167,10 @@ ThreadEventTarget::Dispatch(already_AddRefed aEvent, NS_IMETHODIMP ThreadEventTarget::DelayedDispatch(already_AddRefed aEvent, uint32_t aDelayMs) { - nsCOMPtr event = aEvent; NS_ENSURE_TRUE(!!aDelayMs, NS_ERROR_UNEXPECTED); RefPtr r = - new DelayedRunnable(do_AddRef(this), event.forget(), aDelayMs); + new DelayedRunnable(do_AddRef(this), std::move(aEvent), aDelayMs); nsresult rv = r->Init(); NS_ENSURE_SUCCESS(rv, rv); diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 16d262893ecd..a6c42366ddf5 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -588,7 +588,6 @@ nsThread::nsThread(NotNull aQueue, mShutdownRequired(false), mPriority(PRIORITY_NORMAL), mIsMainThread(aMainThread == MAIN_THREAD), - mUseHangMonitor(aMainThread == MAIN_THREAD), mIsAPoolThreadFree(nullptr), mCanInvokeJS(false), #ifdef EARLY_BETA_OR_EARLIER @@ -607,7 +606,6 @@ nsThread::nsThread() mShutdownRequired(false), mPriority(PRIORITY_NORMAL), mIsMainThread(false), - mUseHangMonitor(false), mCanInvokeJS(false), #ifdef EARLY_BETA_OR_EARLIER mLastWakeupCheckTime(TimeStamp::Now()), @@ -1007,7 +1005,7 @@ static bool GetLabeledRunnableName(nsIRunnable* aEvent, nsACString& aName, #endif mozilla::PerformanceCounter* nsThread::GetPerformanceCounter( - nsIRunnable* aEvent) const { + nsIRunnable* aEvent) { RefPtr docRunnable = do_QueryObject(aEvent); if (docRunnable) { mozilla::dom::DocGroup* docGroup = docRunnable->DocGroup(); @@ -1079,13 +1077,8 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) { } Maybe noJSAPI; - - if (mUseHangMonitor && reallyWait) { - BackgroundHangMonitor().NotifyWait(); - } - if (mIsMainThread) { - DoMainThreadSpecificProcessing(); + DoMainThreadSpecificProcessing(reallyWait); } ++mNestedEventLoopDepth; @@ -1162,7 +1155,7 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) { mozilla::TimeStamp now = mozilla::TimeStamp::Now(); - if (mUseHangMonitor) { + if (mIsMainThread) { BackgroundHangMonitor().NotifyActivity(); } @@ -1359,11 +1352,15 @@ void nsThread::SetScriptObserver( mScriptObserver = aScriptObserver; } -void nsThread::DoMainThreadSpecificProcessing() const { +void nsThread::DoMainThreadSpecificProcessing(bool aReallyWait) { MOZ_ASSERT(mIsMainThread); ipc::CancelCPOWs(); + if (aReallyWait) { + BackgroundHangMonitor().NotifyWait(); + } + // Fire a memory pressure notification, if one is pending. if (!ShuttingDown()) { MemoryPressureState mpPending = NS_GetPendingMemoryPressure(); diff --git a/xpcom/threads/nsThread.h b/xpcom/threads/nsThread.h index ac00535323cd..37decfbad608 100644 --- a/xpcom/threads/nsThread.h +++ b/xpcom/threads/nsThread.h @@ -124,7 +124,7 @@ class PerformanceCounterState { bool mCurrentRunnableIsIdleRunnable = false; // Whether we're attached to the mainthread nsThread. - const bool mIsMainThread; + bool mIsMainThread; // The timestamp from which time to be accounted for should be measured. This // can be the start of a runnable running or the end of a nested runnable @@ -179,7 +179,7 @@ class nsThread : public nsIThreadInternal, public: // The PRThread corresponding to this thread. - PRThread* GetPRThread() const { return mThread; } + PRThread* GetPRThread() { return mThread; } const void* StackBase() const { return mStackBase; } size_t StackSize() const { return mStackSize; } @@ -225,10 +225,10 @@ class nsThread : public nsIThreadInternal, mozilla::SynchronizedEventQueue* EventQueue() { return mEvents.get(); } - bool ShuttingDown() const { return mShutdownContext != nullptr; } + bool ShuttingDown() { return mShutdownContext != nullptr; } virtual mozilla::PerformanceCounter* GetPerformanceCounter( - nsIRunnable* aEvent) const; + nsIRunnable* aEvent); size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; @@ -257,13 +257,8 @@ class nsThread : public nsIThreadInternal, // notifications, etc. nsLocalExecutionRecord EnterLocalExecution(); - void SetUseHangMonitor(bool aValue) { - MOZ_ASSERT(IsOnCurrentThread()); - mUseHangMonitor = aValue; - } - private: - void DoMainThreadSpecificProcessing() const; + void DoMainThreadSpecificProcessing(bool aReallyWait); protected: friend class nsThreadShutdownEvent; @@ -333,8 +328,7 @@ class nsThread : public nsIThreadInternal, int8_t mPriority; - const bool mIsMainThread; - bool mUseHangMonitor; + bool mIsMainThread; mozilla::Atomic* mIsAPoolThreadFree; // Set to true if this thread creates a JSRuntime. diff --git a/xpcom/threads/nsThreadUtils.cpp b/xpcom/threads/nsThreadUtils.cpp index fbb81350f87a..e1ed235d600d 100644 --- a/xpcom/threads/nsThreadUtils.cpp +++ b/xpcom/threads/nsThreadUtils.cpp @@ -133,15 +133,7 @@ already_AddRefed mozilla::CreateMediumHighRunnable( //----------------------------------------------------------------------------- nsresult NS_NewNamedThread(const nsACString& aName, nsIThread** aResult, - nsIRunnable* aInitialEvent, uint32_t aStackSize) { - nsCOMPtr event = aInitialEvent; - return NS_NewNamedThread(aName, aResult, event.forget(), aStackSize); -} - -nsresult NS_NewNamedThread(const nsACString& aName, nsIThread** aResult, - already_AddRefed aInitialEvent, - uint32_t aStackSize) { - nsCOMPtr event = std::move(aInitialEvent); + nsIRunnable* aEvent, uint32_t aStackSize) { nsCOMPtr thread; #ifdef MOZILLA_INTERNAL_API nsresult rv = nsThreadManager::get().nsThreadManager::NewNamedThread( @@ -160,8 +152,8 @@ nsresult NS_NewNamedThread(const nsACString& aName, nsIThread** aResult, return rv; } - if (event) { - rv = thread->Dispatch(event.forget(), NS_DISPATCH_NORMAL); + if (aEvent) { + rv = thread->Dispatch(aEvent, NS_DISPATCH_NORMAL); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/xpcom/threads/nsThreadUtils.h b/xpcom/threads/nsThreadUtils.h index 6ed6d54adfda..80c43b3a5bee 100644 --- a/xpcom/threads/nsThreadUtils.h +++ b/xpcom/threads/nsThreadUtils.h @@ -56,30 +56,14 @@ extern nsresult NS_NewNamedThread( nsIRunnable* aInitialEvent = nullptr, uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE); -extern nsresult NS_NewNamedThread( - const nsACString& aName, nsIThread** aResult, - already_AddRefed aInitialEvent, - uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE); - -template -inline nsresult NS_NewNamedThread( - const char (&aName)[LEN], nsIThread** aResult, - already_AddRefed aInitialEvent, - uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE) { - static_assert(LEN <= 16, "Thread name must be no more than 16 characters"); - return NS_NewNamedThread(nsDependentCString(aName, LEN - 1), aResult, - std::move(aInitialEvent), aStackSize); -} - template inline nsresult NS_NewNamedThread( const char (&aName)[LEN], nsIThread** aResult, nsIRunnable* aInitialEvent = nullptr, uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE) { - nsCOMPtr event = aInitialEvent; static_assert(LEN <= 16, "Thread name must be no more than 16 characters"); return NS_NewNamedThread(nsDependentCString(aName, LEN - 1), aResult, - event.forget(), aStackSize); + aInitialEvent, aStackSize); } /**