Bug 1313883 - Allow using multiple decoder devices on non-AMD hardware since they seem to crash less that way. r=dvander
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 04 Nov 2016 13:28:28 +1300
changeset 351672 4e6ed67480679dfe3efb631352b19208729fadd1
parent 351671 7817ed7afb84876da0325c571d4c889672b63050
child 351673 9b60e295a885d16b15bb3ae0b902182709e7a964
push id13
push userfmarier@mozilla.com
push dateFri, 11 Nov 2016 01:36:56 +0000
reviewersdvander
bugs1313883
milestone52.0a1
Bug 1313883 - Allow using multiple decoder devices on non-AMD hardware since they seem to crash less that way. r=dvander
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/gfxPrefs.h
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -495,29 +495,51 @@ DeviceManagerDx::CreateContentDevice()
     multi->SetMultithreadProtected(TRUE);
   }
   return FeatureStatus::Available;
 }
 
 RefPtr<ID3D11Device>
 DeviceManagerDx::CreateDecoderDevice()
 {
-  if (mCompositorDevice && mCompositorDeviceSupportsVideo && !mDecoderDevice) {
-    mDecoderDevice = mCompositorDevice;
-
-    RefPtr<ID3D10Multithread> multi;
-    mDecoderDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
-    if (multi) {
-      multi->SetMultithreadProtected(TRUE);
+  bool isAMD = false;
+  {
+    MutexAutoLock lock(mDeviceLock);
+    if (!mDeviceStatus) {
+      return nullptr;
     }
+    isAMD = mDeviceStatus->adapter().VendorId == 0x1002;
   }
 
-  if (mDecoderDevice) {
-    RefPtr<ID3D11Device> dev = mDecoderDevice;
-    return dev.forget();
+  bool reuseDevice = false;
+  if (gfxPrefs::Direct3D11ReuseDecoderDevice() < 0) {
+    // Use the default logic, which is to allow reuse of devices on AMD, but create
+    // separate devices everywhere else.
+    if (isAMD) {
+      reuseDevice = true;
+    }
+  } else if (gfxPrefs::Direct3D11ReuseDecoderDevice() > 0) {
+    reuseDevice = true;
+  }
+
+  if (reuseDevice) {
+    if (mCompositorDevice && mCompositorDeviceSupportsVideo && !mDecoderDevice) {
+      mDecoderDevice = mCompositorDevice;
+
+      RefPtr<ID3D10Multithread> multi;
+      mDecoderDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
+      if (multi) {
+        multi->SetMultithreadProtected(TRUE);
+      }
+    }
+
+    if (mDecoderDevice) {
+      RefPtr<ID3D11Device> dev = mDecoderDevice;
+      return dev.forget();
+    }
   }
 
    if (!sD3D11CreateDeviceFn) {
     // We should just be on Windows Vista or XP in this case.
     return nullptr;
   }
 
   RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
@@ -537,17 +559,19 @@ DeviceManagerDx::CreateDecoderDevice()
     return nullptr;
   }
 
   RefPtr<ID3D10Multithread> multi;
   device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
 
   multi->SetMultithreadProtected(TRUE);
 
-  mDecoderDevice = device;
+  if (reuseDevice) {
+    mDecoderDevice = device;
+  }
   return device;
 }
 
 void
 DeviceManagerDx::ResetDevices()
 {
   MutexAutoLock lock(mDeviceLock);
 
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -369,16 +369,17 @@ private:
 
   DECL_GFX_PREF(Live, "gfx.color_management.enablev4",         CMSEnableV4, bool, false);
   DECL_GFX_PREF(Live, "gfx.color_management.mode",             CMSMode, int32_t,-1);
   // The zero default here should match QCMS_INTENT_DEFAULT from qcms.h
   DECL_GFX_PREF(Live, "gfx.color_management.rendering_intent", CMSRenderingIntent, int32_t, 0);
 
   DECL_GFX_PREF(Once, "gfx.direct2d.disabled",                 Direct2DDisabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled",            Direct2DForceEnabled, bool, false);
+  DECL_GFX_PREF(Live, "gfx.direct3d11.reuse-decoder-device",   Direct3D11ReuseDecoderDevice, int32_t, -1);
   DECL_GFX_PREF(Live, "gfx.draw-color-bars",                   CompositorDrawColorBars, bool, false);
   DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll",      HidePluginsForScroll, bool, true);
   DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels",     GrallocFenceWithReadPixels, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.enabled",                LayerScopeEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.port",                   LayerScopePort, int32_t, 23456);
   // Note that        "gfx.logging.level" is defined in Logging.h.
   DECL_GFX_PREF(Live, "gfx.logging.level",                     GfxLoggingLevel, int32_t, mozilla::gfx::LOG_DEFAULT);
   DECL_GFX_PREF(Once, "gfx.logging.crash.length",              GfxLoggingCrashLength, uint32_t, 16);