Bug 1461775 - Create paint worker threads in response to a device reset instead of preemptively. r=bas
authorRyan Hunt <rhunt@eqrion.net>
Tue, 15 May 2018 13:36:11 -0500
changeset 418623 0d06bc54d475bbe804fbb2366c46da501bba99da
parent 418622 c40a419dc1cd334fb94092f98d37926c7ee4ed08
child 418624 1191b8cd031df7f0df80999331c0abab23d7d3c6
push id34007
push usercsabou@mozilla.com
push dateThu, 17 May 2018 09:47:02 +0000
treeherdermozilla-central@8fb36531f7d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1461775
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1461775 - Create paint worker threads in response to a device reset instead of preemptively. r=bas
gfx/layers/PaintThread.cpp
gfx/layers/PaintThread.h
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/layers/PaintThread.cpp
+++ b/gfx/layers/PaintThread.cpp
@@ -162,20 +162,18 @@ PaintThread::Init()
   nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
   if (NS_FAILED(rv)) {
     return false;
   }
   sThread = thread;
 
   // Only create paint workers for tiling if we are using tiling or could
   // expect to dynamically switch to tiling in the future
-  if (gfxPlatform::GetPlatform()->UsesTiling() ||
-      gfxPrefs::LayersTilesEnabledIfSkiaPOMTP()) {
-    int32_t paintWorkerCount = PaintThread::CalculatePaintWorkerCount();
-    mPaintWorkers = SharedThreadPool::Get(NS_LITERAL_CSTRING("PaintWorker"), paintWorkerCount);
+  if (gfxPlatform::GetPlatform()->UsesTiling()) {
+    InitPaintWorkers();
   }
 
   nsCOMPtr<nsIRunnable> paintInitTask =
     NewRunnableMethod("PaintThread::InitOnPaintThread",
                       this, &PaintThread::InitOnPaintThread);
   SyncRunnable::DispatchToThread(sThread, paintInitTask);
   return true;
 }
@@ -183,16 +181,24 @@ PaintThread::Init()
 void
 PaintThread::InitOnPaintThread()
 {
   MOZ_ASSERT(!NS_IsMainThread());
   sThreadId = PlatformThread::CurrentId();
 }
 
 void
+PaintThread::InitPaintWorkers()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  int32_t count = PaintThread::CalculatePaintWorkerCount();
+  mPaintWorkers = SharedThreadPool::Get(NS_LITERAL_CSTRING("PaintWorker"), count);
+}
+
+void
 DestroyPaintThread(UniquePtr<PaintThread>&& pt)
 {
   MOZ_ASSERT(PaintThread::IsOnPaintThread());
   pt->ShutdownOnPaintThread();
 }
 
 /* static */ void
 PaintThread::Shutdown()
@@ -232,16 +238,28 @@ PaintThread::IsOnPaintThread()
 
 bool
 PaintThread::IsOnPaintWorkerThread()
 {
   return mPaintWorkers && mPaintWorkers->IsOnCurrentThread();
 }
 
 void
+PaintThread::UpdateRenderMode()
+{
+  if (!!mPaintWorkers != gfxPlatform::GetPlatform()->UsesTiling()) {
+    if (mPaintWorkers) {
+      mPaintWorkers = nullptr;
+    } else {
+      InitPaintWorkers();
+    }
+  }
+}
+
+void
 PaintThread::PrepareBuffer(CapturedBufferState* aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aState);
 
   // If painting asynchronously, we need to acquire the compositor bridge which
   // owns the underlying MessageChannel. Otherwise we leave it null and use
   // synchronous dispatch.
@@ -358,16 +376,17 @@ PaintThread::AsyncPaintContents(Composit
   }
 }
 
 void
 PaintThread::PaintTiledContents(CapturedTiledPaintState* aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aState);
+  MOZ_ASSERT(mPaintWorkers);
 
   if (gfxPrefs::LayersOMTPDumpCapture() && aState->mCapture) {
     aState->mCapture->Dump();
   }
 
   RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
   RefPtr<CapturedTiledPaintState> state(aState);
 
--- a/gfx/layers/PaintThread.h
+++ b/gfx/layers/PaintThread.h
@@ -265,16 +265,18 @@ public:
   static void Start();
   static void Shutdown();
   static PaintThread* Get();
 
   // Helper for asserts.
   static bool IsOnPaintThread();
   bool IsOnPaintWorkerThread();
 
+  void UpdateRenderMode();
+
   void PrepareBuffer(CapturedBufferState* aState);
 
   void PaintContents(CapturedPaintState* aState,
                      PrepDrawTargetForPaintingCallback aCallback);
 
   void PaintTiledContents(CapturedTiledPaintState* aState);
 
   // Must be called on the main thread. Signifies that the current
@@ -303,16 +305,17 @@ public:
   static int32_t CalculatePaintWorkerCount();
 
 private:
   PaintThread();
 
   bool Init();
   void ShutdownOnPaintThread();
   void InitOnPaintThread();
+  void InitPaintWorkers();
 
   void AsyncPrepareBuffer(CompositorBridgeChild* aBridge,
                           CapturedBufferState* aState);
   void AsyncPaintContents(CompositorBridgeChild* aBridge,
                           CapturedPaintState* aState,
                           PrepDrawTargetForPaintingCallback aCallback);
   void AsyncPaintTiledContents(CompositorBridgeChild* aBridge,
                                CapturedTiledPaintState* aState);
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -36,16 +36,17 @@
 #include "nsIGfxInfo.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "gfxGDIFontList.h"
 #include "gfxGDIFont.h"
 
 #include "mozilla/layers/CompositorThread.h"
+#include "mozilla/layers/PaintThread.h"
 #include "mozilla/layers/ReadbackManagerD3D11.h"
 
 #include "gfxDWriteFontList.h"
 #include "gfxDWriteFonts.h"
 #include "gfxDWriteCommon.h"
 #include <dwrite.h>
 
 #include "gfxTextRun.h"
@@ -488,16 +489,20 @@ gfxWindowsPlatform::IsDirect2DBackend()
 
 void
 gfxWindowsPlatform::UpdateRenderMode()
 {
   bool didReset = HandleDeviceReset();
 
   UpdateBackendPrefs();
 
+  if (PaintThread::Get()) {
+    PaintThread::Get()->UpdateRenderMode();
+  }
+
   if (didReset) {
     mScreenReferenceDrawTarget =
       CreateOffscreenContentDrawTarget(IntSize(1, 1), SurfaceFormat::B8G8R8A8);
     if (!mScreenReferenceDrawTarget) {
       gfxCriticalNote << "Failed to update reference draw target after device reset"
                       << ", D3D11 device:" << hexa(Factory::GetDirect3D11Device().get())
                       << ", D3D11 status:" << FeatureStatusToString(gfxConfig::GetValue(Feature::D3D11_COMPOSITING))
                       << ", D2D1 device:" << hexa(Factory::GetD2D1Device().get())