Add a crash guard for DXVA2D3D9. (bug 1190281 part 8, r=mattwoodrow)
☠☠ backed out by 70c553b37c19 ☠ ☠
authorDavid Anderson <dvander@alliedmods.net>
Tue, 11 Aug 2015 00:29:08 -0700
changeset 291483 6ddbdbd66174b8f70e1280e03367c683ea726370
parent 291482 c85c1d11bd72f43a69133b2076c6dd3c256d8716
child 291484 aab36e44ccf4e90cff2885db20034a17c7fcb6f9
child 291485 70c553b37c199bbca5bf9c389d687273ea4c3b16
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1190281
milestone43.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
Add a crash guard for DXVA2D3D9. (bug 1190281 part 8, r=mattwoodrow)
dom/ipc/ContentParent.cpp
dom/media/platforms/wmf/DXVA2Manager.cpp
gfx/src/DriverCrashGuard.cpp
gfx/src/DriverCrashGuard.h
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5188,16 +5188,19 @@ ContentParent::RecvBeginDriverCrashGuard
   // Only one driver crash guard should be active at a time, per-process.
   MOZ_ASSERT(!mDriverCrashGuard);
 
   UniquePtr<gfx::DriverCrashGuard> guard;
   switch (gfx::CrashGuardType(aGuardType)) {
     case gfx::CrashGuardType::D3D11Layers:
       guard = MakeUnique<gfx::D3D11LayersCrashGuard>(this);
       break;
+    case gfx::CrashGuardType::D3D9Video:
+      guard = MakeUnique<gfx::D3D9VideoCrashGuard>(this);
+      break;
     default:
       MOZ_ASSERT_UNREACHABLE("unknown crash guard type");
       return false;
   }
 
   if (guard->Crashed()) {
     *aOutCrashed = true;
     return true;
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -9,16 +9,17 @@
 #include "nsThreadUtils.h"
 #include "ImageContainer.h"
 #include "gfxWindowsPlatform.h"
 #include "D3D9SurfaceImage.h"
 #include "mozilla/layers/D3D11ShareHandleImage.h"
 #include "mozilla/Preferences.h"
 #include "mfapi.h"
 #include "MFTDecoder.h"
+#include "DriverCrashGuard.h"
 
 const CLSID CLSID_VideoProcessorMFT =
 {
   0x88753b26,
   0x5b24,
   0x49bd,
   { 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82 }
 };
@@ -85,16 +86,22 @@ D3D9DXVA2Manager::GetDXVADeviceManager()
   return mDeviceManager;
 }
 
 HRESULT
 D3D9DXVA2Manager::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  gfx::D3D9VideoCrashGuard crashGuard;
+  if (crashGuard.Crashed()) {
+    NS_WARNING("DXVA2D3D9 crash detected");
+    return E_FAIL;
+  }
+
   // Create D3D9Ex.
   HMODULE d3d9lib = LoadLibraryW(L"d3d9.dll");
   NS_ENSURE_TRUE(d3d9lib, E_FAIL);
   decltype(Direct3DCreate9Ex)* d3d9Create =
     (decltype(Direct3DCreate9Ex)*) GetProcAddress(d3d9lib, "Direct3DCreate9Ex");
   nsRefPtr<IDirect3D9Ex> d3d9Ex;
   HRESULT hr = d3d9Create(D3D_SDK_VERSION, getter_AddRefs(d3d9Ex));
   if (!d3d9Ex) {
--- a/gfx/src/DriverCrashGuard.cpp
+++ b/gfx/src/DriverCrashGuard.cpp
@@ -19,16 +19,17 @@
 #include "mozilla/dom/ContentChild.h"
 
 namespace mozilla {
 namespace gfx {
 
 static const size_t NUM_CRASH_GUARD_TYPES = size_t(CrashGuardType::NUM_TYPES);
 static const char* sCrashGuardNames[NUM_CRASH_GUARD_TYPES] = {
   "d3d11layers",
+  "d3d9video",
 };
 
 DriverCrashGuard::DriverCrashGuard(CrashGuardType aType, dom::ContentParent* aContentParent)
  : mType(aType)
  , mMode(aContentParent ? Mode::Proxy : Mode::Normal)
  , mInitialized(false)
  , mGuardActivated(false)
  , mCrashDetected(false)
@@ -417,10 +418,34 @@ D3D11LayersCrashGuard::RecordTelemetry(T
   if (sTelemetryStateRecorded) {
     return;
   }
 
   Telemetry::Accumulate(Telemetry::GRAPHICS_DRIVER_STARTUP_TEST, int32_t(aState));
   sTelemetryStateRecorded = true;
 }
 
+D3D9VideoCrashGuard::D3D9VideoCrashGuard(dom::ContentParent* aContentParent)
+ : DriverCrashGuard(CrashGuardType::D3D9Video, aContentParent)
+{
+}
+
+bool
+D3D9VideoCrashGuard::UpdateEnvironment()
+{
+  // We don't care about any extra preferences here.
+  return false;
+}
+
+void
+D3D9VideoCrashGuard::LogCrashRecovery()
+{
+  gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DXVA2D3D9 just crashed; hardware video will be disabled.";
+}
+
+void
+D3D9VideoCrashGuard::LogFeatureDisabled()
+{
+  gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DXVA2D3D9 video decoding is disabled due to a previous crash.";
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/src/DriverCrashGuard.h
+++ b/gfx/src/DriverCrashGuard.h
@@ -33,16 +33,17 @@ enum class DriverInitStatus
 
   // We crashed during driver initialization, and have restarted.
   Crashed
 };
 
 enum class CrashGuardType : uint32_t
 {
   D3D11Layers,
+  D3D9Video,
   NUM_TYPES
 };
 
 // DriverCrashGuard is used to detect crashes at graphics driver callsites.
 // 
 // If the graphics environment is unrecognized or has changed since the last
 // session, the crash guard will activate and will detect any crashes within
 // the scope of the guard object.
@@ -125,13 +126,24 @@ class D3D11LayersCrashGuard final : publ
   bool UpdateEnvironment() override;
   void LogCrashRecovery() override;
   void LogFeatureDisabled() override;
 
  private:
   void RecordTelemetry(TelemetryState aState);
 };
 
+class D3D9VideoCrashGuard final : public DriverCrashGuard
+{
+ public:
+  explicit D3D9VideoCrashGuard(dom::ContentParent* aContentParent = nullptr);
+
+ protected:
+  bool UpdateEnvironment() override;
+  void LogCrashRecovery() override;
+  void LogFeatureDisabled() override;
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif // gfx_src_DriverCrashGuard_h__