--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -141,16 +141,17 @@ VRDisplayHost::CheckClearDisplayInfoDirt
if (mDisplayInfo == mLastUpdateDisplayInfo) {
return false;
}
mLastUpdateDisplayInfo = mDisplayInfo;
return true;
}
VRControllerHost::VRControllerHost(VRDeviceType aType)
+ : mVibrateIndex(0)
{
MOZ_COUNT_CTOR(VRControllerHost);
mControllerInfo.mType = aType;
mControllerInfo.mControllerID = VRSystemManager::AllocateDisplayID();
}
VRControllerHost::~VRControllerHost()
{
@@ -188,8 +189,19 @@ VRControllerHost::GetPose()
}
dom::GamepadHand
VRControllerHost::GetHand()
{
return mControllerInfo.mHand;
}
+void
+VRControllerHost::SetVibrateIndex(uint64_t aIndex)
+{
+ mVibrateIndex = aIndex;
+}
+
+uint64_t
+VRControllerHost::GetVibrateIndex()
+{
+ return mVibrateIndex;
+}
--- a/gfx/vr/VRDisplayHost.h
+++ b/gfx/vr/VRDisplayHost.h
@@ -88,23 +88,26 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRControllerHost)
const VRControllerInfo& GetControllerInfo() const;
void SetButtonPressed(uint64_t aBit);
uint64_t GetButtonPressed();
void SetPose(const dom::GamepadPoseState& aPose);
const dom::GamepadPoseState& GetPose();
dom::GamepadHand GetHand();
+ void SetVibrateIndex(uint64_t aIndex);
+ uint64_t GetVibrateIndex();
protected:
explicit VRControllerHost(VRDeviceType aType);
virtual ~VRControllerHost();
VRControllerInfo mControllerInfo;
// The current button pressed bit of button mask.
uint64_t mButtonPressed;
+ uint64_t mVibrateIndex;
dom::GamepadPoseState mPose;
};
} // namespace gfx
} // namespace mozilla
#endif /* GFX_VR_DISPLAY_HOST_H */
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -407,10 +407,20 @@ VRManager::NotifyGamepadChange(const T&
{
dom::GamepadChangeEvent e(aInfo);
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendGamepadUpdate(e);
}
}
+void
+VRManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration)
+{
+ for (uint32_t i = 0; i < mManagers.Length(); ++i) {
+ mManagers[i]->VibrateHaptic(aControllerIdx, aHapticIndex,
+ aIntensity, aDuration);
+ }
+}
+
} // namespace gfx
} // namespace mozilla
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -44,16 +44,18 @@ public:
void GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo);
void SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect);
RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
void CreateVRTestSystem();
+ void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration);
protected:
VRManager();
~VRManager();
private:
RefPtr<layers::TextureHost> mLastFrame;
--- a/gfx/vr/gfxVR.cpp
+++ b/gfx/vr/gfxVR.cpp
@@ -62,17 +62,18 @@ void
VRSystemManager::AddGamepad(const VRControllerInfo& controllerInfo)
{
dom::GamepadAdded a(NS_ConvertUTF8toUTF16(controllerInfo.GetControllerName()),
mControllerCount,
controllerInfo.GetMappingType(),
controllerInfo.GetHand(),
dom::GamepadServiceType::VR,
controllerInfo.GetNumButtons(),
- controllerInfo.GetNumAxes());
+ controllerInfo.GetNumAxes(),
+ controllerInfo.GetNumHaptics());
VRManager* vm = VRManager::Get();
MOZ_ASSERT(vm);
vm->NotifyGamepadChange<dom::GamepadAdded>(a);
}
void
VRSystemManager::RemoveGamepad(uint32_t aIndex)
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -209,33 +209,36 @@ 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; }
dom::GamepadHand GetHand() const { return mHand; }
uint32_t GetNumButtons() const { return mNumButtons; }
uint32_t GetNumAxes() const { return mNumAxes; }
+ uint32_t GetNumHaptics() const { return mNumHaptics; }
uint32_t mControllerID;
VRDeviceType mType;
nsCString mControllerName;
dom::GamepadMappingType mMappingType;
dom::GamepadHand mHand;
uint32_t mNumButtons;
uint32_t mNumAxes;
+ uint32_t mNumHaptics;
bool operator==(const VRControllerInfo& other) const {
return mType == other.mType &&
mControllerID == other.mControllerID &&
mControllerName == other.mControllerName &&
mMappingType == other.mMappingType &&
mHand == other.mHand &&
mNumButtons == other.mNumButtons &&
- mNumAxes == other.mNumAxes;
+ mNumAxes == other.mNumAxes &&
+ mNumHaptics == other.mNumHaptics;
}
bool operator!=(const VRControllerInfo& other) const {
return !(*this == other);
}
};
class VRSystemManager {
@@ -250,16 +253,19 @@ public:
virtual bool Init() = 0;
virtual void Destroy() = 0;
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) = 0;
virtual void HandleInput() = 0;
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) = 0;
virtual void ScanForControllers() = 0;
virtual void RemoveControllers() = 0;
+ virtual void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration, uint32_t aPromiseID) = 0;
+ virtual void StopVibrateHaptic(uint32_t aControllerIdx) = 0;
void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed, double aValue);
void NewAxisMove(uint32_t aIndex, uint32_t aAxis, double aValue);
void NewPoseState(uint32_t aIndex, const dom::GamepadPoseState& aPose);
void AddGamepad(const VRControllerInfo& controllerInfo);
void RemoveGamepad(uint32_t aIndex);
protected:
VRSystemManager() : mControllerCount(0) { }
--- a/gfx/vr/gfxVROSVR.cpp
+++ b/gfx/vr/gfxVROSVR.cpp
@@ -527,16 +527,30 @@ VRSystemManagerOSVR::GetHMDs(nsTArray<Re
}
void
VRSystemManagerOSVR::HandleInput()
{
}
void
+VRSystemManagerOSVR::VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID)
+{
+}
+
+void
+VRSystemManagerOSVR::StopVibrateHaptic(uint32_t aControllerIdx)
+{
+}
+
+void
VRSystemManagerOSVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
{
}
void
VRSystemManagerOSVR::ScanForControllers()
{
}
--- a/gfx/vr/gfxVROSVR.h
+++ b/gfx/vr/gfxVROSVR.h
@@ -67,16 +67,19 @@ public:
virtual bool Init() override;
virtual void Destroy() override;
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
virtual void HandleInput() override;
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
aControllerResult) override;
virtual void ScanForControllers() override;
virtual void RemoveControllers() override;
+ virtual void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration, uint32_t aPromiseID) override;
+ virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
protected:
VRSystemManagerOSVR()
: mOSVRInitialized(false)
, mClientContextInitialized(false)
, mDisplayConfigInitialized(false)
, mInterfaceInitialized(false)
, m_ctx(nullptr)
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -861,17 +861,18 @@ VRControllerOculus::VRControllerOculus(d
MOZ_ASSERT(kNumOculusButton ==
static_cast<uint32_t>(OculusLeftControllerButtonType::NumButtonType)
&& kNumOculusButton ==
static_cast<uint32_t>(OculusRightControllerButtonType::NumButtonType));
mControllerInfo.mNumButtons = kNumOculusButton;
mControllerInfo.mNumAxes = static_cast<uint32_t>(
- OculusControllerAxisType::NumVRControllerAxisType);;
+ OculusControllerAxisType::NumVRControllerAxisType);
+ mControllerInfo.mNumHaptics = kNumOculusHaptcs;
}
float
VRControllerOculus::GetAxisMove(uint32_t aAxis)
{
return mAxisMove[aAxis];
}
@@ -1185,16 +1186,31 @@ VRSystemManagerOculus::HandlePoseTrackin
MOZ_ASSERT(aController);
if (aPose != aController->GetPose()) {
aController->SetPose(aPose);
NewPoseState(aControllerIdx, aPose);
}
}
void
+VRSystemManagerOculus::VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID)
+{
+ // TODO: Bug 1305892
+}
+
+void
+VRSystemManagerOculus::StopVibrateHaptic(uint32_t aControllerIdx)
+{
+}
+
+void
VRSystemManagerOculus::GetControllers(nsTArray<RefPtr<VRControllerHost>>&
aControllerResult)
{
if (!mOculusInitialized) {
return;
}
aControllerResult.Clear();
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -121,16 +121,19 @@ public:
virtual bool Init() override;
virtual void Destroy() override;
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost> >& aHMDResult) override;
virtual void HandleInput() override;
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
aControllerResult) override;
virtual void ScanForControllers() override;
virtual void RemoveControllers() override;
+ virtual void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration, uint32_t aPromiseID) override;
+ virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
protected:
VRSystemManagerOculus()
: mSession(nullptr), mOculusInitialized(false)
{ }
private:
void HandleButtonPress(uint32_t aControllerIdx,
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -54,16 +54,18 @@ static pfn_VR_ShutdownInternal vr_Shutdo
static pfn_VR_IsHmdPresent vr_IsHmdPresent = nullptr;
static pfn_VR_IsRuntimeInstalled vr_IsRuntimeInstalled = nullptr;
static pfn_VR_GetStringForHmdError vr_GetStringForHmdError = nullptr;
static pfn_VR_GetGenericInterface vr_GetGenericInterface = nullptr;
#define BTN_MASK_FROM_ID(_id) \
vr::ButtonMaskFromId(vr::EVRButtonId::_id)
+static const uint32_t kNumOpenVRHaptcs = 1;
+
bool
LoadOpenVRRuntime()
{
static PRLibrary *openvrLib = nullptr;
std::string openvrPath = gfxPrefs::VROpenVRRuntime();
if (!openvrPath.c_str())
@@ -387,27 +389,35 @@ VRDisplayOpenVR::NotifyVSync()
// Make sure we respond to OpenVR events even when not presenting
PollEvents();
}
VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aNumButtons,
uint32_t aNumAxes)
: VRControllerHost(VRDeviceType::OpenVR)
, mTrigger(0)
+ , mVibrateThread(nullptr)
+ , mIsVibrating(false)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
mControllerInfo.mControllerName.AssignLiteral("OpenVR Gamepad");
mControllerInfo.mMappingType = GamepadMappingType::_empty;
mControllerInfo.mHand = aHand;
mControllerInfo.mNumButtons = aNumButtons;
mControllerInfo.mNumAxes = aNumAxes;
+ mControllerInfo.mNumHaptics = kNumOpenVRHaptcs;
}
VRControllerOpenVR::~VRControllerOpenVR()
{
+ if (mVibrateThread) {
+ mVibrateThread->Shutdown();
+ mVibrateThread = nullptr;
+ }
+
MOZ_COUNT_DTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
}
void
VRControllerOpenVR::SetTrackedIndex(uint32_t aTrackedIndex)
{
mTrackedIndex = aTrackedIndex;
}
@@ -425,16 +435,85 @@ VRControllerOpenVR::SetTrigger(float aVa
}
float
VRControllerOpenVR::GetTrigger()
{
return mTrigger;
}
+void
+VRControllerOpenVR::UpdateVibrateHaptic(vr::IVRSystem* aVRSystem,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint64_t aVibrateIndex,
+ uint32_t aPromiseID)
+{
+ // UpdateVibrateHaptic() only can be called by mVibrateThread
+ MOZ_ASSERT(mVibrateThread == NS_GetCurrentThread());
+ // Avoid the previous vibrate event to override the new one.
+ if (mVibrateIndex != aVibrateIndex) {
+ return;
+ }
+
+ double duration = (aIntensity == 0) ? 0 : aDuration;
+ // We expect OpenVR to vibrate for 5 ms, but we found it only response the
+ // commend ~ 3.9 ms. For duration time longer than 3.9 ms, we separate them
+ // to a loop of 3.9 ms for make users feel that is a continuous events.
+ uint32_t microSec = (duration < 3.9 ? duration : 3.9) * 1000 * aIntensity;
+ aVRSystem->TriggerHapticPulse(GetTrackedIndex(),
+ aHapticIndex, microSec);
+
+ // In OpenVR spec, it mentions TriggerHapticPulse() may not trigger another haptic pulse
+ // on this controller and axis combination for 5ms.
+ const double kVibrateRate = 5.0;
+ if (duration >= kVibrateRate) {
+ MOZ_ASSERT(mVibrateThread);
+
+ RefPtr<Runnable> runnable =
+ NewRunnableMethod<vr::IVRSystem*, uint32_t, double, double, uint64_t, uint32_t>
+ (this, &VRControllerOpenVR::UpdateVibrateHaptic, aVRSystem,
+ aHapticIndex, aIntensity, duration - kVibrateRate, aVibrateIndex, aPromiseID);
+ NS_DelayedDispatchToCurrentThread(runnable.forget(), kVibrateRate);
+ }
+}
+
+void
+VRControllerOpenVR::VibrateHaptic(vr::IVRSystem* aVRSystem,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID)
+{
+ // Spinning up the haptics thread at the first haptics call.
+ if (!mVibrateThread) {
+ nsresult rv = NS_NewThread(getter_AddRefs(mVibrateThread));
+ MOZ_ASSERT(mVibrateThread);
+
+ if (NS_FAILED(rv)) {
+ MOZ_ASSERT(false, "Failed to create async thread.");
+ }
+ }
+ ++mVibrateIndex;
+
+ mIsVibrating = true;
+ RefPtr<Runnable> runnable =
+ NewRunnableMethod<vr::IVRSystem*, uint32_t, double, double, uint64_t, uint32_t>
+ (this, &VRControllerOpenVR::UpdateVibrateHaptic, aVRSystem,
+ aHapticIndex, aIntensity, aDuration, mVibrateIndex, aPromiseID);
+ mVibrateThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
+}
+
+void
+VRControllerOpenVR::StopVibrateHaptic()
+{
+ mIsVibrating = false;
+}
+
VRSystemManagerOpenVR::VRSystemManagerOpenVR()
: mVRSystem(nullptr)
, mOpenVRInstalled(false)
{
}
/*static*/ already_AddRefed<VRSystemManagerOpenVR>
VRSystemManagerOpenVR::Create()
@@ -728,23 +807,58 @@ VRSystemManagerOpenVR::HandleAxisMove(ui
}
}
void
VRSystemManagerOpenVR::HandlePoseTracking(uint32_t aControllerIdx,
const GamepadPoseState& aPose,
VRControllerHost* aController)
{
+ MOZ_ASSERT(aController);
if (aPose != aController->GetPose()) {
aController->SetPose(aPose);
NewPoseState(aControllerIdx, aPose);
}
}
void
+VRSystemManagerOpenVR::VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID)
+{
+ // mVRSystem is available after VRDisplay is created
+ // at GetHMDs().
+ if (!mVRSystem) {
+ return;
+ }
+
+ RefPtr<impl::VRControllerOpenVR> controller = mOpenVRController[aControllerIdx];
+ MOZ_ASSERT(controller);
+
+ controller->VibrateHaptic(mVRSystem, aHapticIndex, aIntensity, aDuration, aPromiseID);
+}
+
+void
+VRSystemManagerOpenVR::StopVibrateHaptic(uint32_t aControllerIdx)
+{
+ // mVRSystem is available after VRDisplay is created
+ // at GetHMDs().
+ if (!mVRSystem) {
+ return;
+ }
+
+ RefPtr<impl::VRControllerOpenVR> controller = mOpenVRController[aControllerIdx];
+ MOZ_ASSERT(controller);
+
+ controller->StopVibrateHaptic();
+}
+
+void
VRSystemManagerOpenVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
{
if (!mOpenVRInstalled) {
return;
}
aControllerResult.Clear();
for (uint32_t i = 0; i < mOpenVRController.Length(); ++i) {
@@ -872,8 +986,9 @@ VRSystemManagerOpenVR::ScanForController
}
void
VRSystemManagerOpenVR::RemoveControllers()
{
mOpenVRController.Clear();
mControllerCount = 0;
}
+
--- a/gfx/vr/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -72,24 +72,39 @@ class VRControllerOpenVR : public VRCont
{
public:
explicit VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aNumButtons,
uint32_t aNumAxes);
void SetTrackedIndex(uint32_t aTrackedIndex);
uint32_t GetTrackedIndex();
void SetTrigger(float aValue);
float GetTrigger();
+ void VibrateHaptic(vr::IVRSystem* aVRSystem,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID);
+ void StopVibrateHaptic();
protected:
virtual ~VRControllerOpenVR();
private:
+ void UpdateVibrateHaptic(vr::IVRSystem* aVRSystem,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint64_t aVibrateIndex,
+ uint32_t aPromiseID);
+
// The index of tracked devices from vr::IVRSystem.
uint32_t mTrackedIndex;
float mTrigger;
+ nsCOMPtr<nsIThread> mVibrateThread;
+ bool mIsVibrating;
};
} // namespace impl
class VRSystemManagerOpenVR : public VRSystemManager
{
public:
static already_AddRefed<VRSystemManagerOpenVR> Create();
@@ -97,16 +112,22 @@ public:
virtual bool Init() override;
virtual void Destroy() override;
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost> >& aHMDResult) override;
virtual void HandleInput() override;
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
aControllerResult) override;
virtual void ScanForControllers() override;
virtual void RemoveControllers() override;
+ virtual void VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID) override;
+ virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
protected:
VRSystemManagerOpenVR();
private:
void HandleButtonPress(uint32_t aControllerIdx,
uint32_t aButton,
uint64_t aButtonMask,
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -34,16 +34,18 @@ static const uint32_t kPuppetAxes[] = {
0,
1,
2
};
static const uint32_t kNumPuppetAxis = sizeof(kPuppetAxes) /
sizeof(uint32_t);
+static const uint32_t kNumPuppetHaptcs = 1;
+
VRDisplayPuppet::VRDisplayPuppet()
: VRDisplayHost(VRDeviceType::Puppet)
, mIsPresenting(false)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayPuppet, VRDisplayHost);
mDisplayInfo.mDisplayName.AssignLiteral("Puppet HMD");
mDisplayInfo.mIsConnected = true;
@@ -231,16 +233,17 @@ VRControllerPuppet::VRControllerPuppet(d
, mButtonPressState(0)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerPuppet, VRControllerHost);
mControllerInfo.mControllerName.AssignLiteral("Puppet Gamepad");
mControllerInfo.mMappingType = GamepadMappingType::_empty;
mControllerInfo.mHand = aHand;
mControllerInfo.mNumButtons = kNumPuppetButtonMask;
mControllerInfo.mNumAxes = kNumPuppetAxis;
+ mControllerInfo.mNumHaptics = kNumPuppetHaptcs;
}
VRControllerPuppet::~VRControllerPuppet()
{
MOZ_COUNT_DTOR_INHERITED(VRControllerPuppet, VRControllerHost);
}
void
@@ -403,16 +406,30 @@ VRSystemManagerPuppet::HandlePoseTrackin
MOZ_ASSERT(aController);
if (aPose != aController->GetPose()) {
aController->SetPose(aPose);
NewPoseState(aControllerIdx, aPose);
}
}
void
+VRSystemManagerPuppet::VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID)
+{
+}
+
+void
+VRSystemManagerPuppet::StopVibrateHaptic(uint32_t aControllerIdx)
+{
+}
+
+void
VRSystemManagerPuppet::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
{
aControllerResult.Clear();
for (uint32_t i = 0; i < mPuppetController.Length(); ++i) {
aControllerResult.AppendElement(mPuppetController[i]);
}
}
--- a/gfx/vr/gfxVRPuppet.h
+++ b/gfx/vr/gfxVRPuppet.h
@@ -89,16 +89,22 @@ public:
virtual bool Init() override;
virtual void Destroy() override;
virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
virtual void HandleInput() override;
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
aControllerResult) override;
virtual void ScanForControllers() override;
virtual void RemoveControllers() override;
+ virtual void VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ uint32_t aPromiseID) override;
+ virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
protected:
VRSystemManagerPuppet();
private:
void HandleButtonPress(uint32_t aControllerIdx,
uint32_t aButton,
uint64_t aButtonMask,
--- a/gfx/vr/ipc/PVRManager.ipdl
+++ b/gfx/vr/ipc/PVRManager.ipdl
@@ -53,21 +53,25 @@ parent:
// sensor state is the "Zero" position.
async ResetSensor(uint32_t aDisplayID);
sync GetSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
sync SetHaveEventListener(bool aHaveEventListener);
async ControllerListenerAdded();
async ControllerListenerRemoved();
+ async VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration);
+
async CreateVRTestSystem();
async CreateVRServiceTestDisplay(nsCString aID, uint32_t aPromiseID);
async CreateVRServiceTestController(nsCString aID, uint32_t aPromiseID);
async SetDisplayInfoToMockDisplay(uint32_t aDeviceID, VRDisplayInfo aDisplayInfo);
async SetSensorStateToMockDisplay(uint32_t aDeviceID, VRHMDSensorState aSensorState);
+
async NewButtonEventToMockController(uint32_t aDeviceID, long aButton,
bool aPressed);
async NewAxisMoveEventToMockController(uint32_t aDeviceID, long aAxis,
double aValue);
async NewPoseMoveToMockController(uint32_t aDeviceID, GamepadPoseState aPose);
child:
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -441,16 +441,28 @@ VRManagerParent::RecvNewPoseMoveToMockCo
RefPtr<impl::VRControllerPuppet> controllerPuppet;
mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet));
MOZ_ASSERT(controllerPuppet);
controllerPuppet->SetPoseMoveState(pose);
return IPC_OK();
}
+mozilla::ipc::IPCResult
+VRManagerParent::RecvVibrateHaptic(const uint32_t& aControllerIdx,
+ const uint32_t& aHapticIndex,
+ const double& aIntensity,
+ const double& aDuration)
+{
+ VRManager* vm = VRManager::Get();
+ vm->VibrateHaptic(aControllerIdx, aHapticIndex, aIntensity,
+ aDuration);
+ return IPC_OK();
+}
+
bool
VRManagerParent::SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
{
// GamepadManager only exists at the content process
// or the same process in non-e10s mode.
if (mIsContentChild || IsSameProcess()) {
return PVRManagerParent::SendGamepadUpdate(aGamepadEvent);
} else {
--- a/gfx/vr/ipc/VRManagerParent.h
+++ b/gfx/vr/ipc/VRManagerParent.h
@@ -87,16 +87,18 @@ protected:
virtual mozilla::ipc::IPCResult RecvRefreshDisplays() override;
virtual mozilla::ipc::IPCResult RecvGetDisplays(nsTArray<VRDisplayInfo> *aDisplays) override;
virtual mozilla::ipc::IPCResult RecvResetSensor(const uint32_t& aDisplayID) override;
virtual mozilla::ipc::IPCResult RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
virtual mozilla::ipc::IPCResult RecvSetHaveEventListener(const bool& aHaveEventListener) override;
virtual mozilla::ipc::IPCResult RecvControllerListenerAdded() override;
virtual mozilla::ipc::IPCResult RecvControllerListenerRemoved() override;
+ virtual mozilla::ipc::IPCResult RecvVibrateHaptic(const uint32_t& aControllerIdx, const uint32_t& aHapticIndex,
+ const double& aIntensity, const double& aDuration) override;
virtual mozilla::ipc::IPCResult RecvCreateVRTestSystem() override;
virtual mozilla::ipc::IPCResult RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID) override;
virtual mozilla::ipc::IPCResult RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID) override;
virtual mozilla::ipc::IPCResult RecvSetDisplayInfoToMockDisplay(const uint32_t& aDeviceID,
const VRDisplayInfo& aDisplayInfo) override;
virtual mozilla::ipc::IPCResult RecvSetSensorStateToMockDisplay(const uint32_t& aDeviceID,
const VRHMDSensorState& aSensorState) override;
virtual mozilla::ipc::IPCResult RecvNewButtonEventToMockController(const uint32_t& aDeviceID, const long& aButton,