Bug 1281259 - Port DXVA to gfxConfig r=jrmuizel
☠☠ backed out by 9c84392108d9 ☠ ☠
authoreyim <eyim@mozilla.com>
Thu, 14 Jul 2016 10:21:06 -0400
changeset 306037 c6d147ba37b52dd368bc213580e1bec9f3f71e0d
parent 306036 3f45d79f6bc73785d1809c6ed084138fca1bb1fe
child 306038 a71e7db89da62e577f8995c886cc74272997a1bb
push id79765
push usercbook@mozilla.com
push dateThu, 21 Jul 2016 14:26:34 +0000
treeherdermozilla-inbound@ab54bfc55266 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1281259
milestone50.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 1281259 - Port DXVA to gfxConfig r=jrmuizel MozReview-Commit-ID: 7Yp3ynxZoFE
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
@@ -26,16 +26,17 @@
 #include "nsIScriptObjectPrincipal.h"
 #include "nsPIDOMWindow.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
 #include "nsServiceManagerUtils.h"
 #include "gfxPlatform.h"
 #include "mozilla/Snprintf.h"
+#include "gfxConfig.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
 struct JSContext;
 class JSObject;
 
@@ -76,17 +77,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();
 }
 
 static nsresult
 IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* aDiagnostics)
 {
   if (aType.IsEmpty()) {
     return NS_ERROR_DOM_TYPE_ERR;
--- 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
@@ -20,16 +20,17 @@
 #include "nsWindowsHelpers.h"
 #include "GfxDriverInfo.h"
 #include "gfxWindowsPlatform.h"
 #include "MediaInfo.h"
 #include "MediaPrefs.h"
 #include "prsystem.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/StaticMutex.h"
+#include "gfxConfig.h"
 
 namespace mozilla {
 
 static Atomic<bool> sDXVAEnabled(false);
 
 WMFDecoderModule::WMFDecoderModule()
   : mWMFInitialized(false)
 {
@@ -42,17 +43,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
@@ -991,16 +991,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, gfxASurface *aSurface)
@@ -2069,18 +2084,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 bool sPrefBrowserTabsRemoteAutostart = false;
 
 static mozilla::Atomic<bool> sLayersAccelerationPrefsInitialized(false);
 
 void
 gfxPlatform::InitAcceleration()
 {
@@ -2096,32 +2109,47 @@ gfxPlatform::InitAcceleration()
   // explicit.
   MOZ_ASSERT(NS_IsMainThread(), "can only initialize prefs on the main thread");
 
   gfxPrefs::GetSingleton();
   sPrefBrowserTabsRemoteAutostart = BrowserTabsRemoteAutostart();
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
   nsCString discardFailureId;
-  int32_t status;
+
+  FeatureState& hwVideoDecFeature = gfxConfig::GetFeature(Feature::HW_VIDEO_DECODING);
 
-  if (Preferences::GetBool("media.hardware-video-decoding.enabled", false) &&
+  // 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();
+  }
+  // not forced on and prefs not set
+  else {
+    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.");
+  }
+
+  gPlatform->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(),
@@ -2171,25 +2199,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
 }
@@ -2492,9 +2511,9 @@ gfxPlatform::IsGfxInfoStatusOkay(int32_t
       status != nsIGfxInfo::FEATURE_STATUS_OK)
   {
     aOutMessage->AssignLiteral("#BLOCKLIST_");
     aOutMessage->AppendASCII(aFailureId.get());
     return false;
   }
 
   return true;
-}
+}
\ No newline at end of file
--- 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
@@ -168,16 +169,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.
@@ -447,18 +450,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
@@ -397,25 +397,16 @@ gfxWindowsPlatform::InitAcceleration()
 
   InitializeConfig();
   InitializeDevices();
   UpdateANGLEConfig();
   UpdateRenderMode();
 }
 
 bool
-gfxWindowsPlatform::CanUseHardwareVideoDecoding()
-{
-  if (!gfxPrefs::LayersPreferD3D9() && !mCompositorD3D11TextureSharingWorks) {
-    return false;
-  }
-  return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
-}
-
-bool
 gfxWindowsPlatform::InitDWriteSupport()
 {
   MOZ_ASSERT(!mDWriteFactory && IsVistaOrLater());
 
   mozilla::ScopedGfxFeatureReporter reporter("DWrite");
   decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*)
       GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory");
   if (!createDWriteFactory) {
@@ -1927,16 +1918,27 @@ InitializeANGLEConfig()
   if (!gfxPlatform::IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE, &message,
                            failureId)) {
     d3d11ANGLE.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
   }
 
 }
 
 void
+gfxWindowsPlatform::InitHWVideoDecoodingConfig(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
@@ -155,29 +155,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 InitHWVideoDecoodingConfig(mozilla::gfx::FeatureState& hwVideoDecFeature);
+
     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;