Bug 1430038 - Part 3: Construct IPC connection for VR/GPU process; r?kip, jimm, jgilbert draft
authorDaosheng Mu <daoshengmu@gmail.com>
Mon, 06 Aug 2018 22:47:18 -0700
changeset 827383 31128466ace0b3cbc76c09530db66f6c429c3455
parent 827382 401b81d450ba648d982b8e433834e5f728bd8803
push id118524
push userbmo:dmu@mozilla.com
push dateTue, 07 Aug 2018 23:12:13 +0000
reviewerskip, jimm, jgilbert
bugs1430038
milestone63.0a1
Bug 1430038 - Part 3: Construct IPC connection for VR/GPU process; r?kip, jimm, jgilbert Summary: MozReview-Commit-ID: 2kOyfC4TFZP Tags: #secure-revision Differential Revision: https://phabricator.services.mozilla.com/D2879 MozReview-Commit-ID: 17O2xbRMOFJ
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUChild.h
gfx/ipc/GPUParent.cpp
gfx/ipc/GPUParent.h
gfx/ipc/GPUProcessHost.cpp
gfx/ipc/GraphicsMessages.ipdlh
gfx/ipc/PGPU.ipdl
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPrefs.cpp
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -3,16 +3,17 @@
 /* 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 "GPUProcessManager.h"
+#include "VRProcessManager.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TelemetryIPC.h"
 #include "mozilla/dom/CheckerboardReportService.h"
 #include "mozilla/dom/MemoryReportRequest.h"
 #include "mozilla/gfx/gfxVars.h"
 #if defined(XP_WIN)
 # include "mozilla/gfx/DeviceManagerDx.h"
 #endif
@@ -105,16 +106,22 @@ GPUChild::EnsureGPUReady()
   }
 
   gfxPlatform::GetPlatform()->ImportGPUDeviceData(data);
   Telemetry::AccumulateTimeDelta(Telemetry::GPU_PROCESS_LAUNCH_TIME_MS_2, mHost->GetLaunchTime());
   mGPUReady = true;
   return true;
 }
 
+base::ProcessHandle
+GPUChild::GetChildProcessHandle()
+{
+  return mHost->GetChildProcessHandle();
+}
+
 PAPZInputBridgeChild*
 GPUChild::AllocPAPZInputBridgeChild(const LayersId& aLayersId)
 {
   APZInputBridgeChild* child = new APZInputBridgeChild();
   child->AddRef();
   return child;
 }
 
@@ -166,16 +173,34 @@ GPUChild::RecvInitCrashReporter(Shmem&& 
     GeckoProcessType_GPU,
     aShmem,
     aThreadId);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+GPUChild::RecvCreateVRProcess()
+{
+  // Make sure create VR process at the main process
+  MOZ_ASSERT(XRE_IsParentProcess());
+  if (gfxPrefs::VRProcessEnabled()) {
+    VRProcessManager::Initialize();
+    VRProcessManager* vr = VRProcessManager::Get();
+    MOZ_ASSERT(vr, "VRProcessManager must be initialized first.");
+
+    if (vr) {
+      vr->LaunchVRProcess();
+    }
+  }
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 GPUChild::RecvNotifyUiObservers(const nsCString& aTopic)
 {
   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
   MOZ_ASSERT(obsSvc);
   if (obsSvc) {
     obsSvc->NotifyObservers(nullptr, aTopic.get(), nullptr);
   }
   return IPC_OK();
--- a/gfx/ipc/GPUChild.h
+++ b/gfx/ipc/GPUChild.h
@@ -31,27 +31,29 @@ class GPUChild final
 
 public:
   explicit GPUChild(GPUProcessHost* aHost);
   ~GPUChild();
 
   void Init();
 
   bool EnsureGPUReady();
+  base::ProcessHandle GetChildProcessHandle();
 
   PAPZInputBridgeChild* AllocPAPZInputBridgeChild(const LayersId& aLayersId) override;
   bool DeallocPAPZInputBridgeChild(PAPZInputBridgeChild* aActor) override;
 
   // gfxVarReceiver overrides.
   void OnVarChanged(const GfxVarUpdate& aVar) override;
 
   // PGPUChild overrides.
   mozilla::ipc::IPCResult RecvInitComplete(const GPUDeviceData& aData) override;
   mozilla::ipc::IPCResult RecvReportCheckerboard(const uint32_t& aSeverity, const nsCString& aLog) override;
   mozilla::ipc::IPCResult RecvInitCrashReporter(Shmem&& shmem, const NativeThreadId& aThreadId) override;
+  mozilla::ipc::IPCResult RecvCreateVRProcess() override;
 
   mozilla::ipc::IPCResult RecvAccumulateChildHistograms(InfallibleTArray<HistogramAccumulation>&& aAccumulations) override;
   mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(InfallibleTArray<KeyedHistogramAccumulation>&& aAccumulations) override;
   mozilla::ipc::IPCResult RecvUpdateChildScalars(InfallibleTArray<ScalarAction>&& aScalarActions) override;
   mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(InfallibleTArray<KeyedScalarAction>&& aScalarActions) override;
   mozilla::ipc::IPCResult RecvRecordChildEvents(nsTArray<ChildEventData>&& events) override;
   mozilla::ipc::IPCResult RecvRecordDiscardedData(const DiscardedData& aDiscardedData) override;
 
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -36,16 +36,17 @@
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "mozilla/HangDetails.h"
 #include "nsDebugImpl.h"
 #include "nsIGfxInfo.h"
 #include "nsThreadManager.h"
 #include "prenv.h"
 #include "ProcessUtils.h"
+#include "VRGPUChild.h"
 #include "VRManager.h"
 #include "VRManagerParent.h"
 #include "VRThread.h"
 #include "VsyncBridgeParent.h"
 #if defined(XP_WIN)
 # include "mozilla/gfx/DeviceManagerDx.h"
 # include <process.h>
 # include <dwrite.h>
@@ -302,16 +303,26 @@ GPUParent::RecvInitImageBridge(Endpoint<
 mozilla::ipc::IPCResult
 GPUParent::RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint)
 {
   VRManagerParent::CreateForGPUProcess(std::move(aEndpoint));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+GPUParent::RecvInitVR(Endpoint<PVRGPUChild>&& aEndpoint)
+{
+  gfx::VRGPUChild::InitForGPUProcess(std::move(aEndpoint));
+
+  // TODO:: Bug 1481327: init VR process shared memory handle via VRGPUChild::Get();
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 GPUParent::RecvInitUiCompositorController(const LayersId& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint)
 {
   UiCompositorControllerParent::Start(aRootLayerTreeId, std::move(aEndpoint));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 GPUParent::RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint)
@@ -460,16 +471,25 @@ GPUParent::RecvRequestMemoryReport(const
 {
   nsPrintfCString processName("GPU (pid %u)", (unsigned)getpid());
 
   mozilla::dom::MemoryReportRequestClient::Start(
     aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+GPUParent::RecvShutdownVR()
+{
+  if (gfxPrefs::VRProcessEnabled()) {
+    VRGPUChild::ShutDown();
+  }
+  return IPC_OK();
+}
+
 void
 GPUParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (AbnormalShutdown == aWhy) {
     NS_WARNING("Shutting down GPU process early due to a crash!");
     ProcessChild::QuickExit();
   }
 
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -38,16 +38,17 @@ public:
   mozilla::ipc::IPCResult RecvInit(nsTArray<GfxPrefSetting>&& prefs,
                                    nsTArray<GfxVarUpdate>&& vars,
                                    const DevicePrefs& devicePrefs,
                                    nsTArray<LayerTreeIdMapping>&& mappings) override;
   mozilla::ipc::IPCResult RecvInitCompositorManager(Endpoint<PCompositorManagerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) override;
   mozilla::ipc::IPCResult RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
+  mozilla::ipc::IPCResult RecvInitVR(Endpoint<PVRGPUChild>&& aVRGPUChild) override;
   mozilla::ipc::IPCResult RecvInitUiCompositorController(const LayersId& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvUpdatePref(const GfxPrefSetting& pref) override;
   mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref) override;
   mozilla::ipc::IPCResult RecvNewContentCompositorManager(Endpoint<PCompositorManagerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
   mozilla::ipc::IPCResult RecvNewContentVideoDecoderManager(Endpoint<PVideoDecoderManagerParent>&& aEndpoint) override;
@@ -56,16 +57,17 @@ public:
   mozilla::ipc::IPCResult RecvAddLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) override;
   mozilla::ipc::IPCResult RecvRemoveLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) override;
   mozilla::ipc::IPCResult RecvNotifyGpuObservers(const nsCString& aTopic) override;
   mozilla::ipc::IPCResult RecvRequestMemoryReport(
     const uint32_t& generation,
     const bool& anonymize,
     const bool& minimizeMemoryUsage,
     const MaybeFileDesc& DMDFile) override;
+  mozilla::ipc::IPCResult RecvShutdownVR() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
 private:
   const TimeStamp mLaunchTime;
   RefPtr<VsyncBridgeParent> mVsyncBridge;
 #ifdef MOZ_GECKO_PROFILER
   RefPtr<ChildProfilerController> mProfilerController;
--- a/gfx/ipc/GPUProcessHost.cpp
+++ b/gfx/ipc/GPUProcessHost.cpp
@@ -155,16 +155,18 @@ GPUProcessHost::InitAfterConnect(bool aS
 void
 GPUProcessHost::Shutdown()
 {
   MOZ_ASSERT(!mShutdownRequested);
 
   mListener = nullptr;
 
   if (mGPUChild) {
+    mGPUChild->SendShutdownVR();
+
     // OnChannelClosed uses this to check if the shutdown was expected or
     // unexpected.
     mShutdownRequested = true;
 
     // The channel might already be closed if we got here unexpectedly.
     if (!mChannelClosed) {
       mGPUChild->Close();
     }
--- a/gfx/ipc/GraphicsMessages.ipdlh
+++ b/gfx/ipc/GraphicsMessages.ipdlh
@@ -10,16 +10,29 @@ using struct mozilla::null_t from "ipc/I
 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";
 using gfxImageFormat from "mozilla/gfx/Types.h";
 
 namespace mozilla {
 namespace gfx {
 
+union GfxPrefValue {
+  bool;
+  int32_t;
+  uint32_t;
+  float;
+  nsCString;
+};
+
+struct GfxPrefSetting {
+  int32_t index;
+  GfxPrefValue value;
+};
+
 struct D3D11DeviceStatus
 {
   bool isWARP;
   bool textureSharingWorks;
   uint32_t featureLevel;
   DxgiAdapterDesc adapter;
   int32_t sequenceNumber;
   bool useNV12;
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -5,16 +5,17 @@
 
 include GraphicsMessages;
 include MemoryReportTypes;
 include HangTypes;
 include protocol PAPZInputBridge;
 include protocol PCompositorManager;
 include protocol PImageBridge;
 include protocol PProfiler;
+include protocol PVRGPU;
 include protocol PVRManager;
 include protocol PVsyncBridge;
 include protocol PUiCompositorController;
 include protocol PVideoDecoderManager;
 
 using base::ProcessId from "base/process.h";
 using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
 using mozilla::Telemetry::HistogramAccumulation from "mozilla/TelemetryComms.h";
@@ -25,29 +26,16 @@ using mozilla::Telemetry::ChildEventData
 using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
 using mozilla::gfx::Feature from "gfxFeature.h";
 using mozilla::gfx::Fallback from "gfxFallback.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 
 namespace mozilla {
 namespace gfx {
 
-union GfxPrefValue {
-  bool;
-  int32_t;
-  uint32_t;
-  float;
-  nsCString;
-};
-
-struct GfxPrefSetting {
-  int32_t index;
-  GfxPrefValue value;
-};
-
 struct LayerTreeIdMapping {
   LayersId layersId;
   ProcessId ownerId;
 };
 
 // This protocol allows the UI process to talk to the GPU process. There is one
 // instance of this protocol, with the GPUParent living on the main thread of
 // the GPU process and the GPUChild living on the main thread of the UI process.
@@ -67,17 +55,18 @@ parent:
              LayerTreeIdMapping[] mapping);
 
   async InitCompositorManager(Endpoint<PCompositorManagerParent> endpoint);
   async InitVsyncBridge(Endpoint<PVsyncBridgeParent> endpoint);
   async InitImageBridge(Endpoint<PImageBridgeParent> endpoint);
   async InitVRManager(Endpoint<PVRManagerParent> endpoint);
   async InitUiCompositorController(LayersId rootLayerTreeId, Endpoint<PUiCompositorControllerParent> endpoint);
   async InitProfiler(Endpoint<PProfilerChild> endpoint);
-
+  // Forward GPU process its endpoints to the VR process.
+  async InitVR(Endpoint<PVRGPUChild> endpoint);
   // Called to update a gfx preference or variable.
   async UpdatePref(GfxPrefSetting pref);
   async UpdateVar(GfxVarUpdate var);
 
   // Create a new content-process compositor bridge.
   async NewContentCompositorManager(Endpoint<PCompositorManagerParent> endpoint);
   async NewContentImageBridge(Endpoint<PImageBridgeParent> endpoint);
   async NewContentVRManager(Endpoint<PVRManagerParent> endpoint);
@@ -98,30 +87,33 @@ parent:
   // Have a message be broadcasted to the GPU process by the GPU process
   // observer service.
   async NotifyGpuObservers(nsCString aTopic);
 
   async RequestMemoryReport(uint32_t generation,
                             bool anonymize,
                             bool minimizeMemoryUsage,
                             MaybeFileDesc DMDFile);
+  async ShutdownVR();
 
 child:
   // Sent when the GPU process has initialized devices. This occurs once, after
   // Init().
   async InitComplete(GPUDeviceData data);
 
   // Sent when APZ detects checkerboarding and apz checkerboard reporting is enabled.
   async ReportCheckerboard(uint32_t severity, nsCString log);
 
   // Graphics errors, analogous to PContent::GraphicsError
   async GraphicsError(nsCString aError);
 
   async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
 
+  async CreateVRProcess();
+
   // Have a message be broadcasted to the UI process by the UI process
   // observer service.
   async NotifyUiObservers(nsCString aTopic);
 
   // Messages for reporting telemetry to the UI process.
   async AccumulateChildHistograms(HistogramAccumulation[] accumulations);
   async AccumulateChildKeyedHistograms(KeyedHistogramAccumulation[] accumulations);
   async UpdateChildScalars(ScalarAction[] actions);
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -149,16 +149,17 @@ DeviceManagerDx::ReleaseD3D11()
   mD3D11Module.reset();
   sD3D11CreateDeviceFn = nullptr;
 }
 
 static inline bool
 ProcessOwnsCompositor()
 {
   return XRE_GetProcessType() == GeckoProcessType_GPU ||
+         XRE_GetProcessType() == GeckoProcessType_VR ||
          (XRE_IsParentProcess() && !gfxConfig::IsEnabled(Feature::GPU_PROCESS));
 }
 
 bool
 DeviceManagerDx::CreateCompositorDevices()
 {
   MOZ_ASSERT(ProcessOwnsCompositor());
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -26,16 +26,17 @@
 
 #include "gfxCrashReporterUtils.h"
 #include "gfxPlatform.h"
 #include "gfxPrefs.h"
 #include "gfxEnv.h"
 #include "gfxTextRun.h"
 #include "gfxUserFontSet.h"
 #include "gfxConfig.h"
+#include "VRProcessManager.h"
 #include "VRThread.h"
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #else
 #include <unistd.h>
 #endif
@@ -1008,16 +1009,17 @@ gfxPlatform::Shutdown()
     // We should only support the default GL provider on Windows; then, this
     // could go away. Unfortunately, we currently support WGL (the default) for
     // WebGL on Optimus.
     GLContextProviderEGL::Shutdown();
 #endif
 
     if (XRE_IsParentProcess()) {
       GPUProcessManager::Shutdown();
+      VRProcessManager::Shutdown();
     }
 
     gfx::Factory::ShutDown();
 
     delete gGfxPlatformPrefsLock;
 
     gfxVars::Shutdown();
     gfxPrefs::DestroySingleton();
--- a/gfx/thebes/gfxPrefs.cpp
+++ b/gfx/thebes/gfxPrefs.cpp
@@ -8,16 +8,18 @@
 #include "MainThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Unused.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/gfx/GPUChild.h"
 #include "mozilla/gfx/GPUProcessManager.h"
+#include "VRProcessManager.h"
+#include "VRChild.h"
 
 using namespace mozilla;
 
 nsTArray<gfxPrefs::Pref*>* gfxPrefs::sGfxPrefList = nullptr;
 gfxPrefs* gfxPrefs::sInstance = nullptr;
 bool gfxPrefs::sInstanceHasBeenDestroyed = false;
 
 gfxPrefs&
@@ -87,16 +89,23 @@ gfxPrefs::Pref::OnChange()
 {
   if (auto gpm = gfx::GPUProcessManager::Get()) {
     if (gfx::GPUChild* gpu = gpm->GetGPUChild()) {
       GfxPrefValue value;
       GetLiveValue(&value);
       Unused << gpu->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
     }
   }
+  if (auto vpm = gfx::VRProcessManager::Get()) {
+    if (gfx::VRChild* vr = vpm->GetVRChild()) {
+      GfxPrefValue value;
+      GetLiveValue(&value);
+      Unused << vr->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
+    }
+  }
   FireChangeCallback();
 }
 
 void
 gfxPrefs::Pref::FireChangeCallback()
 {
   if (mChangeCallback) {
     GfxPrefValue value;