diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index 1175211106cb..f5d63162f4d6 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -70,6 +70,9 @@ LazyLogModule gRenderThreadLog("RenderThread"); static StaticRefPtr sRenderThread; static mozilla::BackgroundHangMonitor* sBackgroundHangMonitor; +#ifdef DEBUG +static bool sRenderThreadEverStarted = false; +#endif RenderThread::RenderThread(RefPtr aThread) : mThread(std::move(aThread)), @@ -92,6 +95,13 @@ void RenderThread::Start(uint32_t aNamespace) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!sRenderThread); +#ifdef DEBUG + // Check to ensure nobody will try to ever start us more than once during + // the process' lifetime (in particular after ShutDown). + MOZ_ASSERT(!sRenderThreadEverStarted); + sRenderThreadEverStarted = true; +#endif + RefPtr thread; nsresult rv = NS_NewNamedThread( "Renderer", getter_AddRefs(thread), @@ -139,28 +149,33 @@ void RenderThread::ShutDown() { sRenderThread->mHasShutdown = true; } - layers::SynchronousTask task("RenderThread"); - RefPtr runnable = - WrapRunnable(RefPtr(sRenderThread.get()), - &RenderThread::ShutDownTask, &task); + RefPtr runnable = WrapRunnable( + RefPtr(sRenderThread.get()), &RenderThread::ShutDownTask); sRenderThread->PostRunnable(runnable.forget()); - task.Wait(); + + // This will empty the thread queue and thus run the above runnable while + // spinning the MT event loop. + nsCOMPtr oldThread = sRenderThread->GetRenderThread(); + oldThread->Shutdown(); layers::SharedSurfacesParent::Shutdown(); layers::CompositableInProcessManager::Shutdown(); - sRenderThread = nullptr; #ifdef XP_WIN if (widget::WinCompositorWindowThread::Get()) { widget::WinCompositorWindowThread::ShutDown(); } #endif + + // We null this out only after we finished shutdown to give everbody the + // chance to check for sRenderThread->mHasShutdown. Hopefully everybody + // checks this before using us! + sRenderThread = nullptr; } extern void ClearAllBlobImageResources(); -void RenderThread::ShutDownTask(layers::SynchronousTask* aTask) { - layers::AutoCompleteTask complete(aTask); +void RenderThread::ShutDownTask() { MOZ_ASSERT(IsInRenderThread()); LOG("RenderThread::ShutDownTask()"); diff --git a/gfx/webrender_bindings/RenderThread.h b/gfx/webrender_bindings/RenderThread.h index f3ba69cbdd97..f6bef4549e82 100644 --- a/gfx/webrender_bindings/RenderThread.h +++ b/gfx/webrender_bindings/RenderThread.h @@ -306,7 +306,7 @@ class RenderThread final { explicit RenderThread(RefPtr aThread); void DeferredRenderTextureHostDestroy(); - void ShutDownTask(layers::SynchronousTask* aTask); + void ShutDownTask(); void InitDeviceTask(); void PostRunnable(already_AddRefed aRunnable);