Bug 1281259 - Port DXVA configuration to gfxConfig. r? draft
authorBenoit Girard <b56girard@gmail.com>
Thu, 18 Aug 2016 13:59:39 -0400
changeset 402697 13173e111303a8e58580f5f63519e4627d287cca
parent 401500 fe895421dfbe1f1f8f1fc6a39bb20774423a6d74
child 528744 14166d92401b862d2f9750f9d994d7ac256b3840
push id26736
push userb56girard@gmail.com
push dateThu, 18 Aug 2016 17:59:22 +0000
bugs1281259
milestone51.0a1
Bug 1281259 - Port DXVA configuration to gfxConfig. r? MozReview-Commit-ID: JFpqk8KBgfD
dom/media/mediasource/MediaSource.cpp
dom/media/platforms/apple/AppleDecoderModule.cpp
dom/media/platforms/wmf/WMFDecoderModule.cpp
gfx/config/gfxFeature.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -24,16 +24,17 @@
 #include "nsError.h"
 #include "nsIRunnable.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsPIDOMWindow.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
 #include "nsServiceManagerUtils.h"
+#include "gfxConfig.h"
 #include "gfxPlatform.h"
 #include "mozilla/Sprintf.h"
 
 struct JSContext;
 class JSObject;
 
 mozilla::LogModule* GetMediaSourceLog()
 {
@@ -72,17 +73,17 @@ static const char* const gMediaSourceTyp
 // 2. If H264 hardware acceleration is not available.
 // 3. The CPU is considered to be fast enough
 static bool
 IsWebMForced(DecoderDoctorDiagnostics* aDiagnostics)
 {
   bool mp4supported =
     DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4"),
                                        aDiagnostics);
-  bool hwsupported = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
+  bool hwsupported = gfx::gfxConfig::IsEnabled(gfx::Feature::HW_VIDEO_DECODING);
   return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast();
 }
 
 namespace dom {
 
 /* static */
 nsresult
 MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* aDiagnostics)
--- a/dom/media/platforms/apple/AppleDecoderModule.cpp
+++ b/dom/media/platforms/apple/AppleDecoderModule.cpp
@@ -8,16 +8,17 @@
 #include "AppleCMLinker.h"
 #include "AppleDecoderModule.h"
 #include "AppleVTDecoder.h"
 #include "AppleVTLinker.h"
 #include "MacIOSurfaceImage.h"
 #include "MediaPrefs.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Logging.h"
+#include "gfxConfig.h"
 
 namespace mozilla {
 
 bool AppleDecoderModule::sInitialized = false;
 bool AppleDecoderModule::sIsCoreMediaAvailable = false;
 bool AppleDecoderModule::sIsVTAvailable = false;
 bool AppleDecoderModule::sIsVTHWAvailable = false;
 bool AppleDecoderModule::sCanUseHardwareVideoDecoder = true;
@@ -47,18 +48,17 @@ AppleDecoderModule::Init()
   // dlopen VideoToolbox.framework if it's available.
   // We must link both CM and VideoToolbox framework to allow for proper
   // paired Link/Unlink calls
   bool haveVideoToolbox = loaded && AppleVTLinker::Link();
   sIsVTAvailable = sIsCoreMediaAvailable && haveVideoToolbox;
 
   sIsVTHWAvailable = AppleVTLinker::skPropEnableHWAccel != nullptr;
 
-  sCanUseHardwareVideoDecoder = loaded &&
-    gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
+  sCanUseHardwareVideoDecoder = loaded && gfxConfig::IsEnabled(gfx::Feature::HW_VIDEO_DECODING);
 
   sInitialized = true;
 }
 
 nsresult
 AppleDecoderModule::Startup()
 {
   if (!sInitialized || !sIsVTAvailable) {
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -14,16 +14,17 @@
 #include "WMFMediaDataDecoder.h"
 #include "nsAutoPtr.h"
 #include "nsIWindowsRegKey.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIGfxInfo.h"
 #include "nsWindowsHelpers.h"
 #include "GfxDriverInfo.h"
+#include "gfxConfig.h"
 #include "gfxWindowsPlatform.h"
 #include "MediaInfo.h"
 #include "MediaPrefs.h"
 #include "prsystem.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/StaticMutex.h"
 #include "MP4Decoder.h"
 #include "VPXDecoder.h"
@@ -44,17 +45,17 @@ WMFDecoderModule::~WMFDecoderModule()
     NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
   }
 }
 
 /* static */
 void
 WMFDecoderModule::Init()
 {
-  sDXVAEnabled = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
+  sDXVAEnabled = gfx::gfxConfig::IsEnabled(gfx::Feature::HW_VIDEO_DECODING);
 }
 
 /* static */
 int
 WMFDecoderModule::GetNumDecoderThreads()
 {
   int32_t numCores = PR_GetNumberOfProcessors();
 
--- a/gfx/config/gfxFeature.h
+++ b/gfx/config/gfxFeature.h
@@ -17,18 +17,19 @@ namespace gfx {
 
 #define GFX_FEATURE_MAP(_)                                                        \
   /* Name,                        Type,         Description */                    \
   _(HW_COMPOSITING,               Feature,      "Compositing")                    \
   _(D3D11_COMPOSITING,            Feature,      "Direct3D11 Compositing")         \
   _(D3D9_COMPOSITING,             Feature,      "Direct3D9 Compositing")          \
   _(OPENGL_COMPOSITING,           Feature,      "OpenGL Compositing")             \
   _(DIRECT2D,                     Feature,      "Direct2D")                       \
-  _(D3D11_HW_ANGLE,               Feature,      "Direct3D11 hardware ANGLE")               \
+  _(D3D11_HW_ANGLE,               Feature,      "Direct3D11 hardware ANGLE")      \
   _(GPU_PROCESS,                  Feature,      "GPU Process")                    \
+  _(HW_VIDEO_DECODING,            Feature,      "Hardware Video Decoding")        \
   /* Add new entries above this comment */
 
 enum class Feature : uint32_t {
 #define MAKE_ENUM(name, type, desc) name,
   GFX_FEATURE_MAP(MAKE_ENUM)
 #undef MAKE_ENUM
   NumValues
 };
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -992,16 +992,31 @@ struct DependentSourceSurfaceUserData
   RefPtr<gfxASurface> mSurface;
 };
 
 void SourceSurfaceDestroyed(void *aData)
 {
   delete static_cast<DependentSourceSurfaceUserData*>(aData);
 }
 
+/**
+ * Used to update (enable or disable) hw video decode feature based on pref
+ * Dummy parameters are used to work with existing RegisterCallback func
+ */
+static void
+UpdateHWDecBasedOnPref(const char* aPref, void* aClosure)
+{
+  FeatureState& hwVideoDecFeature = gfxConfig::GetFeature(Feature::HW_VIDEO_DECODING);
+
+  if (!Preferences::GetBool("media.hardware-video-decoding.failed", false))
+  {
+    hwVideoDecFeature.UserDisable("Hardware video decoding disabled by user preference.", NS_LITERAL_CSTRING("FEATURE_FAILURE_HW_VIDEO_DEC_DISABLED_BY_PREF"));
+  }
+}
+
 void
 gfxPlatform::ClearSourceSurfaceForSurface(gfxASurface *aSurface)
 {
   aSurface->SetData(&kSourceSurface, nullptr, nullptr);
 }
 
 /* static */ already_AddRefed<SourceSurface>
 gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget,
@@ -2072,18 +2087,16 @@ gfxPlatform::OptimalFormatForContent(gfx
 
 /**
  * There are a number of layers acceleration (or layers in general) preferences
  * that should be consistent for the lifetime of the application (bug 840967).
  * As such, we will evaluate them all as soon as one of them is evaluated
  * and remember the values.  Changing these preferences during the run will
  * not have any effect until we restart.
  */
-static mozilla::Atomic<bool> sLayersSupportsHardwareVideoDecoding(false);
-static bool sLayersHardwareVideoDecodingFailed = false;
 static bool sBufferRotationCheckPref = true;
 
 static mozilla::Atomic<bool> sLayersAccelerationPrefsInitialized(false);
 
 void
 gfxPlatform::InitAcceleration()
 {
   if (sLayersAccelerationPrefsInitialized) {
@@ -2101,32 +2114,49 @@ gfxPlatform::InitAcceleration()
   gfxPrefs::GetSingleton();
 
   if (XRE_IsParentProcess()) {
     gfxVars::SetBrowserTabsRemoteAutostart(BrowserTabsRemoteAutostart());
   }
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
   nsCString discardFailureId;
+
+  FeatureState& hwVideoDecFeature = gfxConfig::GetFeature(Feature::HW_VIDEO_DECODING);
   int32_t status;
 
+  // feature prefs on
   if (Preferences::GetBool("media.hardware-video-decoding.enabled", false) &&
 #ifdef XP_WIN
-    Preferences::GetBool("media.windows-media-foundation.use-dxva", true) &&
+      Preferences::GetBool("media.windows-media-foundation.use-dxva", true) &&
 #endif
       NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING,
                                                discardFailureId, &status))) {
-      if (status == nsIGfxInfo::FEATURE_STATUS_OK || gfxPrefs::HardwareVideoDecodingForceEnabled()) {
-         sLayersSupportsHardwareVideoDecoding = true;
-    }
+    hwVideoDecFeature.EnableByDefault();
+  } else {
+    // not forced on and prefs not set
+    hwVideoDecFeature.DisableByDefault(FeatureStatus::Disabled, "HW video decode pref not set.",
+                                       NS_LITERAL_CSTRING("FEATURE_FAILURE_HW_VIDEO_DEC_DISABLED"));
   }
 
-  Preferences::AddBoolVarCache(&sLayersHardwareVideoDecodingFailed,
-                               "media.hardware-video-decoding.failed",
-                               false);
+  // force enabled feature
+  if (gfxPrefs::HardwareVideoDecodingForceEnabled()) {
+    hwVideoDecFeature.UserForceEnable("User force-enabled video decoding.");
+  }
+
+  InitHWVideoDecodingConfig(hwVideoDecFeature);
+
+  // blocklist
+  nsCString message;
+  nsCString failureId;
+  if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING, &message, failureId)) {
+    hwVideoDecFeature.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
+  }
+
+  Preferences::RegisterCallback(UpdateHWDecBasedOnPref, "media.hardware-video-decoding.failed", NULL, Preferences::ExactMatch);
 
   if (XRE_IsParentProcess()) {
     if (gfxPrefs::GPUProcessDevEnabled()) {
       // We want to hide this from about:support, so only set a default if the
       // pref is known to be true.
       gfxConfig::SetDefaultFromPref(
         Feature::GPU_PROCESS,
         gfxPrefs::GetGPUProcessDevEnabledPrefName(),
@@ -2176,25 +2206,16 @@ gfxPlatform::InitCompositorAccelerationP
   // Safe mode trumps everything.
   if (InSafeMode()) {
     feature.ForceDisable(FeatureStatus::Blocked, "Acceleration blocked by safe-mode",
                          NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_SAFEMODE"));
   }
 }
 
 bool
-gfxPlatform::CanUseHardwareVideoDecoding()
-{
-  // this function is called from the compositor thread, so it is not
-  // safe to init the prefs etc. from here.
-  MOZ_ASSERT(sLayersAccelerationPrefsInitialized);
-  return sLayersSupportsHardwareVideoDecoding && !sLayersHardwareVideoDecodingFailed;
-}
-
-bool
 gfxPlatform::AccelerateLayersByDefault()
 {
 #if defined(MOZ_GL_PROVIDER) || defined(MOZ_WIDGET_UIKIT)
   return true;
 #else
   return false;
 #endif
 }
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -47,16 +47,17 @@ class SkiaGLGlue;
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 class DataSourceSurface;
 class ScaledFont;
 class DrawEventRecorder;
 class VsyncSource;
 class DeviceInitData;
+class FeatureState;
 
 inline uint32_t
 BackendTypeBit(BackendType b)
 {
   return 1 << uint8_t(b);
 }
 
 } // namespace gfx
@@ -170,16 +171,18 @@ public:
      * Shut down Thebes.
      * Init() arranges for this to be called at an appropriate time.
      */
     static void Shutdown();
 
     static void InitLayersIPC();
     static void ShutdownLayersIPC();
 
+    virtual void InitHWVideoDecodingConfig(mozilla::gfx::FeatureState& hwVideoDecFeature){};
+
     /**
      * Initialize ScrollMetadata statics. Does not depend on gfxPlatform.
      */
     static void InitNullMetadata();
 
     /**
      * Create an offscreen surface of the given dimensions
      * and image format.
@@ -450,18 +453,16 @@ public:
         // platform-specific override, by default do nothing
     }
 
     // Are we in safe mode?
     static bool InSafeMode();
 
     static bool OffMainThreadCompositingEnabled();
 
-    virtual bool CanUseHardwareVideoDecoding();
-
     // Returns a prioritized list of all available compositor backends.
     void GetCompositorBackends(bool useAcceleration, nsTArray<mozilla::layers::LayersBackend>& aBackends);
 
     /**
      * Is it possible to use buffer rotation.  Note that these
      * check the preference, but also allow for the override to
      * disable it using DisableBufferRotation.
      */
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -392,26 +392,16 @@ gfxWindowsPlatform::InitAcceleration()
 
   // If we have Skia and we didn't init dwrite already, do it now.
   if (!mDWriteFactory && GetDefaultContentBackend() == BackendType::SKIA) {
     InitDWriteSupport();
   }
 }
 
 bool
-gfxWindowsPlatform::CanUseHardwareVideoDecoding()
-{
-  DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
-  if (!gfxPrefs::LayersPreferD3D9() && !dm->TextureSharingWorks()) {
-    return false;
-  }
-  return !dm->IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
-}
-
-bool
 gfxWindowsPlatform::InitDWriteSupport()
 {
   if (!IsVistaOrLater()) {
     return false;
   }
 
   // DWrite is only supported on Windows 7 with the platform update and higher.
   // We check this by seeing if D2D1 support is available.
@@ -1430,16 +1420,27 @@ InitializeANGLEConfig()
   if (!gfxPlatform::IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE, &message,
                            failureId)) {
     d3d11ANGLE.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
   }
 
 }
 
 void
+gfxWindowsPlatform::InitHWVideoDecodingConfig(FeatureState& hwVideoDecFeature)
+{
+    if (!gfxPrefs::LayersPreferD3D9() && !CompositorD3D11TextureSharingWorks()) {
+      hwVideoDecFeature.UserDisable("D3d9 not used, and d3d11 texture sharing not working", NS_LITERAL_CSTRING("FEATURE_FAILURE_HW_VIDEO_DEC_D3D_NOT_WORKING"));
+    }
+    else if (!IsWARP()) {
+      hwVideoDecFeature.UserDisable("WARP is disabled.", NS_LITERAL_CSTRING("FEATURE_FAILURE_HW_VIDEO_DEC_NO_WARP"));
+    }
+}
+
+void
 gfxWindowsPlatform::InitializeConfig()
 {
   if (!XRE_IsParentProcess()) {
     // Child processes init their configuration via UpdateDeviceInitData().
     return;
   }
 
   InitializeD3D9Config();
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -159,29 +159,32 @@ public:
      * Verifies a D2D device is present and working, will attempt to create one
      * it is non-functional or non-existant.
      *
      * \param aAttemptForce Attempt to force D2D cairo device creation by using
      * cairo device creation routines.
      */
     void VerifyD2DDevice(bool aAttemptForce);
 
+    /**
+     * Check to see that hw video decoding can be enabled, if not disable the feature
+     */
+    void InitHWVideoDecodingConfig(mozilla::gfx::FeatureState& hwVideoDecFeature) override;
+
     virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
                                         Script aRunScript,
                                         nsTArray<const char*>& aFontList) override;
 
     gfxFontGroup*
     CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
                     const gfxFontStyle *aStyle,
                     gfxTextPerfMetrics* aTextPerf,
                     gfxUserFontSet *aUserFontSet,
                     gfxFloat aDevToCssSize) override;
 
-    virtual bool CanUseHardwareVideoDecoding() override;
-
     /**
      * Check whether format is supported on a platform or not (if unclear, returns true)
      */
     virtual bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) override;
 
     virtual void CompositorUpdated() override;
 
     bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) override;