Bug 1299928 - Part 3: Construct IPC channel between Gamepad and VRManager; r=kip
authorDaosheng Mu <daoshengmu@gmail.com>
Tue, 04 Oct 2016 16:30:04 +0800
changeset 318205 16414aeacf43c81fbccf15578bbf03712a9c3431
parent 318204 2ad2da73d53acded8d280e59a7d4fb27320ed1ca
child 318206 c56ec883e2f395ecdfc63437dd89d07c7b846ccd
push id33213
push usercbook@mozilla.com
push dateMon, 17 Oct 2016 10:20:25 +0000
treeherderautoland@99eb47ffccb9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip
bugs1299928
milestone52.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 1299928 - Part 3: Construct IPC channel between Gamepad and VRManager; r=kip MozReview-Commit-ID: 9hpxlLlIdh7
dom/gamepad/GamepadManager.cpp
dom/gamepad/GamepadManager.h
gfx/vr/gfxVR.h
gfx/vr/ipc/PVRManager.ipdl
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerChild.h
gfx/vr/ipc/VRMessageUtils.h
gfx/vr/moz.build
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -23,16 +23,17 @@
 #include "nsGlobalWindow.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIServiceManager.h"
 #include "nsThreadUtils.h"
+#include "VRManagerChild.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 
 #include <cstddef>
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
@@ -104,16 +105,21 @@ GamepadManager::Observe(nsISupports* aSu
 void
 GamepadManager::StopMonitoring()
 {
   for (uint32_t i = 0; i < mChannelChildren.Length(); ++i) {
     mChannelChildren[i]->SendGamepadListenerRemoved();
   }
   mChannelChildren.Clear();
   mGamepads.Clear();
+
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
+  mVRChannelChild = gfx::VRManagerChild::Get();
+  mVRChannelChild->SendControllerListenerRemoved();
+#endif
 }
 
 void
 GamepadManager::BeginShutdown()
 {
   mShuttingDown = true;
   StopMonitoring();
   // Don't let windows call back to unregister during shutdown
@@ -610,18 +616,22 @@ GamepadManager::ActorCreated(PBackground
   if (NS_WARN_IF(!initedChild)) {
     ActorFailed();
     return;
   }
   MOZ_ASSERT(initedChild == child);
   child->SendGamepadListenerAdded();
   mChannelChildren.AppendElement(child);
 
-  // TODO: Add more event channels to mChannelChildren if you would
-  // like to support more kinds of devices.
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
+  // Construct VRManagerChannel and ask adding the connected
+  // VR controllers to GamepadManager
+  mVRChannelChild = gfx::VRManagerChild::Get();
+  mVRChannelChild->SendControllerListenerAdded();
+#endif
 }
 
 //Override nsIIPCBackgroundChildCreateCallback
 void
 GamepadManager::ActorFailed()
 {
   MOZ_CRASH("Gamepad IPC actor create failed!");
 }
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -10,16 +10,19 @@
 #include "nsIIPCBackgroundChildCreateCallback.h"
 #include "nsIObserver.h"
 // Needed for GamepadMappingType
 #include "mozilla/dom/GamepadBinding.h"
 
 class nsGlobalWindow;
 
 namespace mozilla {
+namespace gfx {
+class VRManagerChild;
+} // namespace gfx
 namespace dom {
 
 class EventTarget;
 class Gamepad;
 class GamepadChangeEvent;
 class GamepadEventChannelChild;
 
 class GamepadManager final : public nsIObserver,
@@ -108,16 +111,17 @@ class GamepadManager final : public nsIO
   // true when shutdown has begun
   bool mShuttingDown;
 
   // Gamepad IPDL child
   // This pointer is only used by this singleton instance and
   // will be destroyed during the IPDL shutdown chain, so we
   // don't need to refcount it here.
   nsTArray<GamepadEventChannelChild *> mChannelChildren;
+  gfx::VRManagerChild* mVRChannelChild;
 
  private:
 
   nsresult Init();
 
   bool MaybeWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex);
   // Returns true if we have already sent data from this gamepad
   // to this window. This should only return true if the user
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -10,16 +10,17 @@
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TypedEnumBits.h"
+#include "mozilla/dom/GamepadBinding.h"
 
 namespace mozilla {
 namespace layers {
 class PTextureParent;
 }
 namespace gfx {
 class VRLayerParent;
 class VRDisplayHost;
@@ -204,12 +205,42 @@ public:
   virtual void Destroy() = 0;
   virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) = 0;
 
 protected:
   VRDisplayManager() { }
   virtual ~VRDisplayManager() { }
 };
 
+struct VRControllerInfo
+{
+  VRDeviceType GetType() const { return mType; }
+  uint32_t GetControllerID() const { return mControllerID; }
+  const nsCString& GetControllerName() const { return mControllerName; }
+  dom::GamepadMappingType GetMappingType() const { return mMappingType; }
+  uint32_t GetNumButtons() const { return mNumButtons; }
+  uint32_t GetNumAxes() const { return mNumAxes; }
+
+  uint32_t mControllerID;
+  VRDeviceType mType;
+  nsCString mControllerName;
+  dom::GamepadMappingType mMappingType;
+  uint32_t mNumButtons;
+  uint32_t mNumAxes;
+
+  bool operator==(const VRControllerInfo& other) const {
+  return mType == other.mType &&
+         mControllerID == other.mControllerID &&
+         mControllerName == other.mControllerName &&
+         mMappingType == other.mMappingType &&
+         mNumButtons == other.mNumButtons &&
+         mNumAxes == other.mNumAxes;
+  }
+
+  bool operator!=(const VRControllerInfo& other) const {
+    return !(*this == other);
+  }
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* GFX_VR_H */
--- a/gfx/vr/ipc/PVRManager.ipdl
+++ b/gfx/vr/ipc/PVRManager.ipdl
@@ -5,23 +5,25 @@
  * 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 LayersSurfaces;
 include protocol PLayer;
 include protocol PTexture;
 include protocol PVRLayer;
 include LayersMessages;
+include GamepadEventTypes;
 
 include "VRMessageUtils.h";
 
 using struct mozilla::gfx::VRFieldOfView from "gfxVR.h";
 using struct mozilla::gfx::VRDisplayInfo from "gfxVR.h";
 using struct mozilla::gfx::VRSensorUpdate from "gfxVR.h";
 using struct mozilla::gfx::VRHMDSensorState from "gfxVR.h";
+using struct mozilla::gfx::VRControllerInfo from "gfxVR.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
 
 
 namespace mozilla {
 namespace gfx {
 
 /**
@@ -51,27 +53,34 @@ parent:
   // Reset the sensor of the display identified by aDisplayID so that the current
   // sensor state is the "Zero" position.
   async ResetSensor(uint32_t aDisplayID);
 
   sync GetSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
   sync GetImmediateSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
   sync SetHaveEventListener(bool aHaveEventListener);
 
+  async ControllerListenerAdded();
+  async ControllerListenerRemoved();
+  // GetControllers synchronously returns the VR controllers that have already been
+  // enumerated by RefreshVRControllers() but does not enumerate new ones.
+  sync GetControllers() returns(VRControllerInfo[] aControllerInfo);
+
 child:
 
   async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
 
   // Notify children of updated VR display enumeration and details.  This will
   // be sent to all children when the parent receives RefreshDisplays, even
   // if no changes have been detected.  This ensures that Promises exposed
   // through DOM calls are always resolved.
   async UpdateDisplayInfo(VRDisplayInfo[] aDisplayUpdates);
 
   async NotifyVSync();
   async NotifyVRVSync(uint32_t aDisplayID);
+  async GamepadUpdate(GamepadChangeEvent aGamepadEvent);
 
   async __delete__();
 
 };
 
 } // gfx
 } // mozilla
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -3,22 +3,24 @@
  */
 /* 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 "VRManagerChild.h"
 #include "VRManagerParent.h"
 #include "VRDisplayClient.h"
+#include "nsGlobalWindow.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/layers/CompositorThread.h" // for CompositorThread
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/VREventObserver.h"
 #include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/GamepadManager.h"
 #include "mozilla/layers/TextureClient.h"
 #include "nsContentUtils.h"
 
 using layers::TextureClient;
 
 namespace {
 const nsTArray<RefPtr<dom::VREventObserver>>::index_type kNoIndex =
   nsTArray<RefPtr<dom::VREventObserver> >::NoIndex;
@@ -476,16 +478,32 @@ VRManagerChild::RecvNotifyVRVSync(const 
     if (display->GetDisplayInfo().GetDisplayID() == aDisplayID) {
       display->NotifyVRVsync();
     }
   }
 
   return true;
 }
 
+bool
+VRManagerChild::RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
+{
+  // VRManagerChild could be at other processes,
+  // but GamepadManager is only allowed to be run at Content process.
+  if (XRE_IsContentProcess()) {
+    RefPtr<dom::GamepadManager> serivce(dom::GamepadManager::GetService());
+
+    if (serivce) {
+      serivce->Update(aGamepadEvent);
+    }
+  }
+
+  return true;
+}
+
 void
 VRManagerChild::RunFrameRequestCallbacks()
 {
   TimeStamp nowTime = TimeStamp::Now();
   mozilla::TimeDuration duration = nowTime - mStartTimeStamp;
   DOMHighResTimeStamp timeStamp = duration.ToMilliseconds();
 
 
--- a/gfx/vr/ipc/VRManagerChild.h
+++ b/gfx/vr/ipc/VRManagerChild.h
@@ -109,17 +109,17 @@ protected:
   virtual bool DeallocPVRLayerChild(PVRLayerChild* actor) override;
 
   virtual bool RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates) override;
 
   virtual bool RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
 
   virtual bool RecvNotifyVSync() override;
   virtual bool RecvNotifyVRVSync(const uint32_t& aDisplayID) override;
-
+  virtual bool RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override;
 
   // ShmemAllocator
 
   virtual bool AllocShmem(size_t aSize,
                           ipc::SharedMemory::SharedMemoryType aType,
                           ipc::Shmem* aShmem) override;
 
   virtual bool AllocUnsafeShmem(size_t aSize,
--- a/gfx/vr/ipc/VRMessageUtils.h
+++ b/gfx/vr/ipc/VRMessageUtils.h
@@ -154,11 +154,40 @@ struct ParamTraits<mozilla::gfx::VRField
         !ReadParam(aMsg, aIter, &(aResult->leftDegrees))) {
       return false;
     }
 
     return true;
   }
 };
 
+template <>
+struct ParamTraits<mozilla::gfx::VRControllerInfo>
+{
+  typedef mozilla::gfx::VRControllerInfo paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.mType);
+    WriteParam(aMsg, aParam.mControllerID);
+    WriteParam(aMsg, aParam.mControllerName);
+    WriteParam(aMsg, aParam.mMappingType);
+    WriteParam(aMsg, aParam.mNumButtons);
+    WriteParam(aMsg, aParam.mNumAxes);
+  }
+
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  {
+    if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mControllerID)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mControllerName)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mMappingType)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mNumButtons)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mNumAxes))) {
+      return false;
+    }
+
+    return true;
+  }
+};
 } // namespace IPC
 
 #endif // mozilla_gfx_vr_VRMessageUtils_h
--- a/gfx/vr/moz.build
+++ b/gfx/vr/moz.build
@@ -11,16 +11,17 @@ EXPORTS += [
     'ipc/VRManagerParent.h',
     'ipc/VRMessageUtils.h',
     'VRDisplayClient.h',
     'VRDisplayPresentation.h',
     'VRManager.h',
 ]
 
 LOCAL_INCLUDES += [
+    '/dom/base',
     '/gfx/layers/d3d11',
     '/gfx/thebes',
 ]
 
 UNIFIED_SOURCES += [
     'gfxVR.cpp',
     'gfxVROpenVR.cpp',
     'gfxVROSVR.cpp',