Merge gfxWindowsPlatform::mAcceleration into gfxConfig. (bug 1254899 part 6, r=milan)
☠☠ backed out by df82a3088812 ☠ ☠
authorDavid Anderson <danderson@mozilla.com>
Wed, 27 Apr 2016 22:54:25 -0700
changeset 295233 f8f3ae8c5cefa67f2ce509eac3da32dc23289ebd
parent 295232 d17f98a9918a4a5e69566abf73702d8adf59151d
child 295234 e9c311c68e4aa25901a874471778e1b8b98ed7ea
push id18983
push usercbook@mozilla.com
push dateThu, 28 Apr 2016 14:35:23 +0000
treeherderfx-team@45e67d6b5a61 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmilan
bugs1254899
milestone49.0a1
Merge gfxWindowsPlatform::mAcceleration into gfxConfig. (bug 1254899 part 6, r=milan)
gfx/config/gfxConfig.cpp
gfx/config/gfxConfig.h
gfx/config/gfxFeature.h
gfx/src/gfxTelemetry.cpp
gfx/src/gfxTelemetry.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
--- a/gfx/config/gfxConfig.cpp
+++ b/gfx/config/gfxConfig.cpp
@@ -50,32 +50,44 @@ gfxConfig::IsForcedOnByUser(Feature aFea
 gfxConfig::GetValue(Feature aFeature)
 {
   AssertStatusInitialized(aFeature);
 
   const FeatureState& state = sConfig.GetState(aFeature);
   return state.GetValue();
 }
 
-/* static */
-bool
+/* static */ bool
 gfxConfig::SetDefault(Feature aFeature,
                       bool aEnable,
                       FeatureStatus aDisableStatus,
                       const char* aDisableMessage)
 {
   FeatureState& state = sConfig.GetState(aFeature);
   if (!aEnable) {
     state.DisableByDefault(aDisableStatus, aDisableMessage);
     return false;
   }
   state.EnableByDefault();
   return true;
 }
 
+/* static */ bool
+gfxConfig::InitOrUpdate(Feature aFeature,
+                        bool aEnable,
+                        FeatureStatus aDisableStatus,
+                        const char* aDisableMessage)
+{
+  FeatureState& state = sConfig.GetState(aFeature);
+  if (!state.IsInitialized()) {
+    return SetDefault(aFeature, aEnable, aDisableStatus, aDisableMessage);
+  }
+  return UpdateIfFailed(aFeature, aEnable, aDisableStatus, aDisableMessage);
+}
+
 /* static */ void
 gfxConfig::Disable(Feature aFeature, FeatureStatus aStatus, const char* aMessage)
 {
   AssertStatusInitialized(aFeature);
 
   // We should never bother setting a runtime status to "enabled," since it would
   // override an explicit user decision to disable it.
   MOZ_ASSERT(IsFeatureStatusFailure(aStatus));
--- a/gfx/config/gfxConfig.h
+++ b/gfx/config/gfxConfig.h
@@ -54,16 +54,25 @@ public:
   {
     if (!aEnable) {
       Disable(aFeature, aDisableStatus, aDisableMessage);
       return false;
     }
     return true;
   }
 
+  // Same as SetDefault, except if the feature already has a default value
+  // set, the new value will be set as a runtime value. This is useful for
+  // when the base value can change (for example, via an update from the
+  // parent process).
+  static bool InitOrUpdate(Feature aFeature,
+                           bool aEnable,
+                           FeatureStatus aDisableStatus,
+                           const char* aDisableMessage);
+
   // Set a user status that overrides the base value (but not runtime value)
   // of a parameter.
   static void UserEnable(Feature aFeature, const char* aMessage);
   static void UserForceEnable(Feature aFeature, const char* aMessage);
   static void UserDisable(Feature aFeature, const char* aMessage);
 
   // Query whether a fallback has been toggled.
   static bool UseFallback(Fallback aFallback);
--- a/gfx/config/gfxFeature.h
+++ b/gfx/config/gfxFeature.h
@@ -31,19 +31,22 @@ class FeatureState
   FeatureStatus GetValue() const;
 
   void EnableByDefault();
   void DisableByDefault(FeatureStatus aStatus, const char* aMessage);
   void SetUser(FeatureStatus aStatus, const char* aMessage);
   void SetRuntime(FeatureStatus aStatus, const char* aMessage);
   bool IsForcedOnByUser() const;
   bool DisabledByDefault() const;
+  bool IsInitialized() const {
+    return mDefault.mStatus != FeatureStatus::Unused;
+  }
 
   void AssertInitialized() const {
-    MOZ_ASSERT(mDefault.mStatus != FeatureStatus::Unused);
+    MOZ_ASSERT(IsInitialized());
   }
 
  private:
   struct Instance {
     char mMessage[64];
     FeatureStatus mStatus;
 
     void Set(FeatureStatus aStatus, const char* aMessage = nullptr);
--- a/gfx/src/gfxTelemetry.cpp
+++ b/gfx/src/gfxTelemetry.cpp
@@ -25,16 +25,18 @@ FeatureStatusToString(FeatureStatus aSta
     case FeatureStatus::Failed:
       return "failed";
     case FeatureStatus::Disabled:
       return "disabled";
     case FeatureStatus::Available:
       return "available";
     case FeatureStatus::ForceEnabled:
       return "force_enabled";
+    case FeatureStatus::CrashedOnStartup:
+      return "crashed_on_startup";
     default:
       MOZ_ASSERT_UNREACHABLE("missing status case");
       return "unknown";
   }
 }
 
 bool
 IsFeatureStatusFailure(FeatureStatus aStatus)
--- a/gfx/src/gfxTelemetry.h
+++ b/gfx/src/gfxTelemetry.h
@@ -37,17 +37,20 @@ enum class FeatureStatus
 
   // This feature was explicitly disabled by the user.
   Disabled,
 
   // This feature is available for use.
   Available,
 
   // This feature was explicitly force-enabled by the user.
-  ForceEnabled
+  ForceEnabled,
+
+  // This feature was disabled due to the startup crash guard.
+  CrashedOnStartup
 };
 
 const char* FeatureStatusToString(FeatureStatus aStatus);
 bool IsFeatureStatusFailure(FeatureStatus aStatus);
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2463,16 +2463,23 @@ gfxPlatform::UpdateDeviceInitData()
     // The parent process figures out device initialization on its own.
     return;
   }
 
   mozilla::gfx::DeviceInitData data;
   mozilla::dom::ContentChild::GetSingleton()->SendGetGraphicsDeviceInitData(&data);
 
   sDeviceInitDataDoNotUseDirectly = data;
+
+  // Ensure that child processes have inherited the HW_COMPOSITING pref.
+  gfxConfig::InitOrUpdate(
+    Feature::HW_COMPOSITING,
+    GetParentDevicePrefs().useHwCompositing(),
+    FeatureStatus::Blocked,
+    "Hardware-accelerated compositing disabled in parent process");
 }
 
 bool
 gfxPlatform::SupportsApzDragInput() const
 {
   return gfxPrefs::APZDragEnabled();
 }
 
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -360,17 +360,16 @@ NS_IMPL_ISUPPORTS(D3D9SharedTextureRepor
 
 gfxWindowsPlatform::gfxWindowsPlatform()
   : mRenderMode(RENDER_GDI)
   , mDeviceLock("gfxWindowsPlatform.mDeviceLock")
   , mIsWARP(false)
   , mHasDeviceReset(false)
   , mHasFakeDeviceReset(false)
   , mCompositorD3D11TextureSharingWorks(false)
-  , mAcceleration(FeatureStatus::Unused)
   , mD3D11Status(FeatureStatus::Unused)
   , mD2D1Status(FeatureStatus::Unused)
   , mHasD3D9DeviceReset(false)
 {
   mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
   mUseClearTypeAlways = UNINITIALIZED_VALUE;
 
   /* 
@@ -412,17 +411,16 @@ gfxWindowsPlatform::InitAcceleration()
   if (IsWin8OrLater()) {
     mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
   }
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
 
-  UpdateDeviceInitData();
   InitializeDevices();
   UpdateRenderMode();
 }
 
 bool
 gfxWindowsPlatform::CanUseHardwareVideoDecoding()
 {
   if (!gfxPrefs::LayersPreferD3D9() && !mCompositorD3D11TextureSharingWorks) {
@@ -484,19 +482,16 @@ gfxWindowsPlatform::HandleDeviceReset()
   mHasD3D9DeviceReset = false;
   mCompositorD3D11TextureSharingWorks = false;
   mDeviceResetReason = DeviceResetReason::OK;
 
   imgLoader::Singleton()->ClearCache(true);
   imgLoader::Singleton()->ClearCache(false);
   gfxAlphaBoxBlur::ShutdownBlurCache();
 
-  // Since we got a device reset, we must ask the parent process for an updated
-  // list of which devices to create.
-  UpdateDeviceInitData();
   InitializeDevices();
   BumpDeviceCounter();
   return true;
 }
 
 static const BackendType SOFTWARE_BACKEND = BackendType::CAIRO;
 
 void
@@ -2253,30 +2248,33 @@ gfxWindowsPlatform::AttemptD3D11ImageBri
     ContentAdapterIsParentAdapter(mD3D11ImageBridgeDevice);
   }
   return FeatureStatus::Available;
 }
 
 void
 gfxWindowsPlatform::InitializeDevices()
 {
+  // Ask the parent process for an updated list of which devices to create.
+  UpdateDeviceInitData();
+
   // If acceleration is disabled, we refuse to initialize anything.
-  mAcceleration = CheckAccelerationSupport();
-  if (IsFeatureStatusFailure(mAcceleration)) {
+  FeatureStatus compositing = gfxConfig::GetValue(Feature::HW_COMPOSITING);
+  if (IsFeatureStatusFailure(compositing)) {
     return;
   }
 
   MOZ_ASSERT(!InSafeMode());
 
-  // If we previously crashed initializing devices, bail out now. This is
-  // effectively a parent-process only check, since the content process
-  // cannot create a lock file.
+  // If we previously crashed initializing devices, bail out now.
   D3D11LayersCrashGuard detectCrashes;
   if (detectCrashes.Crashed()) {
-    mAcceleration = FeatureStatus::Blocked;
+    gfxConfig::Disable(Feature::HW_COMPOSITING,
+                       FeatureStatus::CrashedOnStartup,
+                       "Crashed during startup in a previous session");
     return;
   }
 
   // If we're going to prefer D3D9, stop here. The rest of this function
   // attempts to use D3D11 features.
   if (gfxPrefs::LayersPreferD3D9()) {
     mD3D11Status = FeatureStatus::Disabled;
     return;
@@ -2295,31 +2293,16 @@ gfxWindowsPlatform::InitializeDevices()
   if (gfxPrefs::DirectWriteFontRenderingForceEnabled() &&
       IsFeatureStatusFailure(mD2D1Status) &&
       !mDWriteFactory) {
     gfxCriticalNote << "Attempting DWrite without D2D support";
     InitDWriteSupport();
   }
 }
 
-FeatureStatus
-gfxWindowsPlatform::CheckAccelerationSupport()
-{
-  // Don't retry acceleration if it failed earlier.
-  if (IsFeatureStatusFailure(mAcceleration)) {
-    return mAcceleration;
-  }
-  if (XRE_IsContentProcess()) {
-    return GetParentDevicePrefs().useHwCompositing()
-           ? FeatureStatus::Available
-           : FeatureStatus::Blocked;
-  }
-  return gfxConfig::GetValue(Feature::HW_COMPOSITING);
-}
-
 bool
 gfxWindowsPlatform::CanUseD3D11ImageBridge()
 {
   if (XRE_IsContentProcess()) {
     if (!GetParentDevicePrefs().useD3D11ImageBridge()) {
       return false;
     }
   }
@@ -2895,18 +2878,18 @@ gfxWindowsPlatform::GetAcceleratedCompos
   }
 }
 
 // Some features are dependent on other features. If this is the case, we
 // try to propagate the status of the parent feature if it wasn't available.
 FeatureStatus
 gfxWindowsPlatform::GetD3D11Status() const
 {
-  if (mAcceleration != FeatureStatus::Available) {
-    return mAcceleration;
+  if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
+    return gfxConfig::GetValue(Feature::HW_COMPOSITING);
   }
   return mD3D11Status;
 }
 
 FeatureStatus
 gfxWindowsPlatform::GetD2D1Status() const
 {
   if (GetD3D11Status() != FeatureStatus::Available) {
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -283,17 +283,16 @@ private:
 
     void InitializeDevices();
     void InitializeD3D11();
     void InitializeD2D();
     bool InitDWriteSupport();
 
     void DisableD2D();
 
-    mozilla::gfx::FeatureStatus CheckAccelerationSupport();
     mozilla::gfx::FeatureStatus CheckD3D11Support(bool* aCanUseHardware);
     mozilla::gfx::FeatureStatus CheckD2D1Support();
 
     mozilla::gfx::FeatureStatus AttemptD3D11DeviceCreation();
     bool AttemptD3D11DeviceCreationHelper(
         IDXGIAdapter1* aAdapter,
         RefPtr<ID3D11Device>& aOutDevice,
         HRESULT& aResOut);
@@ -338,16 +337,15 @@ private:
     bool mCompositorD3D11TextureSharingWorks;
     mozilla::Atomic<bool> mHasD3D9DeviceReset;
     DeviceResetReason mDeviceResetReason;
 
     RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
 
     // These should not be accessed directly. Use the Get[Feature]Status
     // accessors instead.
-    mozilla::gfx::FeatureStatus mAcceleration;
     mozilla::gfx::FeatureStatus mD3D11Status;
     mozilla::gfx::FeatureStatus mD2D1Status;
 
     nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
 };
 
 #endif /* GFX_WINDOWS_PLATFORM_H */