Enable Direct3D 11 in the GPU process. (bug 1294988 part 3, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Sat, 20 Aug 2016 20:59:10 -0700
changeset 403691 5fab3f36dc9d8ca584cafee7a0df63e892c33872
parent 403690 58e146b5e16411761c46b24fbcf7b531583e7c70
child 403692 ecd47b2b03d4c3698b79c45805528a5b4b352693
push id26986
push usermaglione.k@gmail.com
push dateSun, 21 Aug 2016 19:44:19 +0000
reviewersmattwoodrow
bugs1294988
milestone51.0a1
Enable Direct3D 11 in the GPU process. (bug 1294988 part 3, r=mattwoodrow)
gfx/config/gfxConfig.cpp
gfx/config/gfxConfig.h
gfx/config/gfxFeature.cpp
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUParent.cpp
gfx/ipc/GPUParent.h
gfx/ipc/GfxMessageUtils.h
gfx/ipc/GraphicsMessages.ipdlh
gfx/ipc/PGPU.ipdl
gfx/src/gfxTelemetry.h
gfx/thebes/DeviceManagerD3D11.cpp
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/config/gfxConfig.cpp
+++ b/gfx/config/gfxConfig.cpp
@@ -136,16 +136,41 @@ gfxConfig::Reenable(Feature aFeature, Fa
   FeatureState& state = sConfig->GetState(aFeature);
   MOZ_ASSERT(IsFeatureStatusFailure(state.GetValue()));
 
   const char* message = state.GetRuntimeMessage();
   EnableFallback(aFallback, message);
   state.SetRuntime(FeatureStatus::Available, nullptr);
 }
 
+/* static */ void
+gfxConfig::Inherit(Feature aFeature, FeatureStatus aStatus)
+{
+  FeatureState& state = sConfig->GetState(aFeature);
+
+  switch (aStatus) {
+  case FeatureStatus::Unused:
+    break;
+  case FeatureStatus::Available:
+    gfxConfig::EnableByDefault(aFeature);
+    break;
+  case FeatureStatus::ForceEnabled:
+    gfxConfig::EnableByDefault(aFeature);
+    gfxConfig::UserForceEnable(aFeature, "Inherited from parent process");
+    break;
+  default:
+    gfxConfig::SetDefault(
+      aFeature,
+      false,
+      aStatus,
+      "Disabled in parent process");
+    break;
+  }
+}
+
 /* static */ bool
 gfxConfig::UseFallback(Fallback aFallback)
 {
   return sConfig->UseFallbackImpl(aFallback);
 }
 
 /* static */ void
 gfxConfig::EnableFallback(Fallback aFallback, const char* aMessage)
--- a/gfx/config/gfxConfig.h
+++ b/gfx/config/gfxConfig.h
@@ -62,16 +62,19 @@ public:
                          FeatureStatus aDisableStatus,
                          const char* aDisableMessage);
   static void DisableByDefault(Feature aFeature,
                                FeatureStatus aDisableStatus,
                                const char* aDisableMessage,
                                const nsACString& aFailureId = EmptyCString());
   static void EnableByDefault(Feature aFeature);
 
+  // Inherit a computed value from another process.
+  static void Inherit(Feature aFeature, FeatureStatus aStatus);
+
   // Set a environment status that overrides both the default and user
   // statuses; this should be used to disable features based on system
   // or hardware problems that can be determined up-front. The only
   // status that can override this decision is the user force-enabling
   // the feature.
   static void Disable(Feature aFeature,
                       FeatureStatus aStatus,
                       const char* aMessage,
--- a/gfx/config/gfxFeature.cpp
+++ b/gfx/config/gfxFeature.cpp
@@ -17,17 +17,19 @@ bool
 FeatureState::IsEnabled() const
 {
   return IsInitialized() && IsFeatureStatusSuccess(GetValue());
 }
 
 FeatureStatus
 FeatureState::GetValue() const
 {
-  AssertInitialized();
+  if (!IsInitialized()) {
+    return FeatureStatus::Unused;
+  }
 
   if (mRuntime.mStatus != FeatureStatus::Unused) {
     return mRuntime.mStatus;
   }
   if (mUser.mStatus == FeatureStatus::ForceEnabled) {
     return FeatureStatus::ForceEnabled;
   }
   if (mEnvironment.mStatus != FeatureStatus::Unused) {
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "GPUChild.h"
+#include "gfxConfig.h"
 #include "gfxPrefs.h"
 #include "GPUProcessHost.h"
 #include "mozilla/gfx/gfxVars.h"
 
 namespace mozilla {
 namespace gfx {
 
 GPUChild::GPUChild(GPUProcessHost* aHost)
@@ -37,17 +38,25 @@ GPUChild::Init()
     }
 
     GfxPrefValue value;
     pref->GetCachedValue(&value);
     prefs.AppendElement(GfxPrefSetting(pref->Index(), value));
   }
 
   nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars();
-  SendInit(prefs, updates);
+
+  DevicePrefs devicePrefs;
+  devicePrefs.hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING);
+  devicePrefs.d3d11Compositing() = gfxConfig::GetValue(Feature::D3D11_COMPOSITING);
+  devicePrefs.d3d9Compositing() = gfxConfig::GetValue(Feature::D3D9_COMPOSITING);
+  devicePrefs.oglCompositing() = gfxConfig::GetValue(Feature::OPENGL_COMPOSITING);
+  devicePrefs.useD2D1() = gfxConfig::GetValue(Feature::DIRECT2D);
+
+  SendInit(prefs, updates, devicePrefs);
 
   gfxVars::AddReceiver(this);
 }
 
 void
 GPUChild::OnVarChanged(const GfxVarUpdate& aVar)
 {
   SendUpdateVar(aVar);
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -12,16 +12,19 @@
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/ipc/ProcessChild.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "VRManager.h"
 #include "VRManagerParent.h"
 #include "VsyncBridgeParent.h"
+#if defined(XP_WIN)
+# include "mozilla/gfx/DeviceManagerD3D11.h"
+#endif
 
 namespace mozilla {
 namespace gfx {
 
 using namespace ipc;
 using namespace layers;
 
 GPUParent::GPUParent()
@@ -40,34 +43,52 @@ GPUParent::Init(base::ProcessId aParentP
   if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
     return false;
   }
 
   // Ensure gfxPrefs are initialized.
   gfxPrefs::GetSingleton();
   gfxConfig::Init();
   gfxVars::Initialize();
+#if defined(XP_WIN)
+  DeviceManagerD3D11::Init();
+#endif
   CompositorThreadHolder::Start();
   VRManager::ManagerInit();
   gfxPlatform::InitNullMetadata();
   return true;
 }
 
 bool
 GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs,
-                    nsTArray<GfxVarUpdate>&& vars)
+                    nsTArray<GfxVarUpdate>&& vars,
+                    const DevicePrefs& devicePrefs)
 {
   const nsTArray<gfxPrefs::Pref*>& globalPrefs = gfxPrefs::all();
   for (auto& setting : prefs) {
     gfxPrefs::Pref* pref = globalPrefs[setting.index()];
     pref->SetCachedValue(setting.value());
   }
   for (const auto& var : vars) {
     gfxVars::ApplyUpdate(var);
   }
+
+  // Inherit device preferences.
+  gfxConfig::Inherit(Feature::HW_COMPOSITING, devicePrefs.hwCompositing());
+  gfxConfig::Inherit(Feature::D3D11_COMPOSITING, devicePrefs.d3d11Compositing());
+  gfxConfig::Inherit(Feature::D3D9_COMPOSITING, devicePrefs.d3d9Compositing());
+  gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, devicePrefs.oglCompositing());
+  gfxConfig::Inherit(Feature::DIRECT2D, devicePrefs.useD2D1());
+
+#if defined(XP_WIN)
+  if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
+    DeviceManagerD3D11::Get()->CreateCompositorDevices();
+  }
+#endif
+
   return true;
 }
 
 bool
 GPUParent::RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint)
 {
   VsyncBridgeParent::Start(Move(aVsyncEndpoint));
   return true;
@@ -165,16 +186,19 @@ GPUParent::ActorDestroy(ActorDestroyReas
   // unreachable.
   ProcessChild::QuickExit();
 #endif
 
   if (mVsyncBridge) {
     mVsyncBridge->Shutdown();
   }
   CompositorThreadHolder::Shutdown();
+#if defined(XP_WIN)
+  DeviceManagerD3D11::Shutdown();
+#endif
   gfxVars::Shutdown();
   gfxConfig::Shutdown();
   gfxPrefs::DestroySingleton();
   XRE_ShutdownChildProcess();
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -20,17 +20,18 @@ public:
   GPUParent();
   ~GPUParent();
 
   bool Init(base::ProcessId aParentPid,
             MessageLoop* aIOLoop,
             IPC::Channel* aChannel);
 
   bool RecvInit(nsTArray<GfxPrefSetting>&& prefs,
-                nsTArray<GfxVarUpdate>&& vars) override;
+                nsTArray<GfxVarUpdate>&& vars,
+                const DevicePrefs& devicePrefs) override;
   bool RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) override;
   bool RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
   bool RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
   bool RecvUpdatePref(const GfxPrefSetting& pref) override;
   bool RecvUpdateVar(const GfxVarUpdate& pref) override;
   bool RecvNewWidgetCompositor(
     Endpoint<PCompositorBridgeParent>&& aEndpoint,
     const CSSToLayoutDeviceScale& aScale,
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -10,16 +10,17 @@
 #include "FilterSupport.h"
 #include "FrameMetrics.h"
 #include "ImageTypes.h"
 #include "RegionBuilder.h"
 #include "base/process_util.h"
 #include "chrome/common/ipc_message_utils.h"
 #include "gfxPoint.h"
 #include "gfxRect.h"
+#include "gfxTelemetry.h"
 #include "gfxTypes.h"
 #include "ipc/IPCMessageUtils.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/layers/AsyncDragMetrics.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/GeckoContentController.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "nsRect.h"
@@ -225,16 +226,24 @@ template <>
 struct ParamTraits<mozilla::gfx::BackendType>
   : public ContiguousEnumSerializer<
              mozilla::gfx::BackendType,
              mozilla::gfx::BackendType::NONE,
              mozilla::gfx::BackendType::BACKEND_LAST>
 {};
 
 template <>
+struct ParamTraits<mozilla::gfx::FeatureStatus>
+  : public ContiguousEnumSerializer<
+             mozilla::gfx::FeatureStatus,
+             mozilla::gfx::FeatureStatus::Unused,
+             mozilla::gfx::FeatureStatus::LAST>
+{};
+
+template <>
 struct ParamTraits<mozilla::layers::ScaleMode>
   : public ContiguousEnumSerializer<
              mozilla::layers::ScaleMode,
              mozilla::layers::ScaleMode::SCALE_NONE,
              mozilla::layers::ScaleMode::SENTINEL>
 {};
 
 template <>
--- a/gfx/ipc/GraphicsMessages.ipdlh
+++ b/gfx/ipc/GraphicsMessages.ipdlh
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=8 et :
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
+using mozilla::gfx::FeatureStatus from "gfxTelemetry.h";
 using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
 using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
 
 namespace mozilla {
 namespace gfx {
 
 struct DeviceInitData
 {
@@ -18,16 +19,25 @@ struct DeviceInitData
 
   // Windows only.
   bool useD3D11;
   bool d3d11TextureSharingWorks;
   bool useD2D1;
   DxgiAdapterDesc adapter;
 };
 
+struct DevicePrefs
+{
+  FeatureStatus hwCompositing;
+  FeatureStatus d3d11Compositing;
+  FeatureStatus d3d9Compositing;
+  FeatureStatus oglCompositing;
+  FeatureStatus useD2D1;
+};
+
 union GfxVarValue
 {
   BackendType;
   bool;
   IntSize;
 };
 
 struct GfxVarUpdate
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -27,17 +27,19 @@ struct GfxPrefSetting {
   int32_t index;
   GfxPrefValue value;
 };
 
 sync protocol PGPU
 {
 parent:
   // Sent by the UI process to initiate core settings.
-  async Init(GfxPrefSetting[] prefs, GfxVarUpdate[] vars);
+  async Init(GfxPrefSetting[] prefs,
+             GfxVarUpdate[] vars,
+             DevicePrefs devicePrefs);
 
   async InitVsyncBridge(Endpoint<PVsyncBridgeParent> endpoint);
   async InitImageBridge(Endpoint<PImageBridgeParent> endpoint);
   async InitVRManager(Endpoint<PVRManagerParent> endpoint);
 
   // Called to update a gfx preference or variable.
   async UpdatePref(GfxPrefSetting pref);
   async UpdateVar(GfxVarUpdate var);
--- a/gfx/src/gfxTelemetry.h
+++ b/gfx/src/gfxTelemetry.h
@@ -43,17 +43,20 @@ enum class FeatureStatus
 
   // This feature was explicitly force-enabled by the user.
   ForceEnabled,
 
   // This feature was disabled due to the startup crash guard.
   CrashedOnStartup,
 
   // This feature was attempted but later determined to be broken.
-  Broken
+  Broken,
+
+  // Add new entries above here.
+  LAST
 };
 
 const char* FeatureStatusToString(FeatureStatus aStatus);
 bool IsFeatureStatusFailure(FeatureStatus aStatus);
 bool IsFeatureStatusSuccess(FeatureStatus aStatus);
 
 enum class TelemetryDeviceCode : uint32_t {
   Content = 0,
--- a/gfx/thebes/DeviceManagerD3D11.cpp
+++ b/gfx/thebes/DeviceManagerD3D11.cpp
@@ -306,18 +306,20 @@ DeviceManagerD3D11::CreateCompositorDevi
   }
 
   if (D3D11Checks::DoesRenderTargetViewNeedRecreating(mCompositorDevice)) {
     gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
                          FeatureStatus::Broken,
                          "RenderTargetViews need recreating");
   }
 
-  // It seems like this may only happen when we're using the NVIDIA gpu
-  D3D11Checks::WarnOnAdapterMismatch(mCompositorDevice);
+  if (XRE_IsParentProcess()) {
+    // It seems like this may only happen when we're using the NVIDIA gpu
+    D3D11Checks::WarnOnAdapterMismatch(mCompositorDevice);
+  }
 
   mCompositorDevice->SetExceptionMode(0);
   mIsWARP = false;
 }
 
 bool
 DeviceManagerD3D11::CreateDevice(IDXGIAdapter* aAdapter,
                                  D3D_DRIVER_TYPE aDriverType,
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -2029,17 +2029,17 @@ gfxWindowsPlatform::GetAcceleratedCompos
   if (gfxConfig::IsEnabled(Feature::OPENGL_COMPOSITING) && gfxPrefs::LayersPreferOpenGL()) {
     aBackends.AppendElement(LayersBackend::LAYERS_OPENGL);
   }
 
   if (gfxConfig::IsEnabled(Feature::D3D9_COMPOSITING) && gfxPrefs::LayersPreferD3D9()) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D9);
   }
 
-  if (DeviceManagerD3D11::Get()->GetCompositorDevice()) {
+  if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D11);
   } else {
     NS_WARNING("Direct3D 11-accelerated layers are not supported on this system.");
   }
 
   if (gfxConfig::IsEnabled(Feature::D3D9_COMPOSITING) && !gfxPrefs::LayersPreferD3D9()) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D9);
   }