--- a/dom/vr/VRDisplay.cpp
+++ b/dom/vr/VRDisplay.cpp
@@ -388,17 +388,17 @@ VRDisplay::LastRelease()
// We don't want to wait for the CC to free up the presentation
// for use in other documents, so we do this in LastRelease().
Shutdown();
}
already_AddRefed<VREyeParameters>
VRDisplay::GetEyeParameters(VREye aEye)
{
- gfx::VRDisplayInfo::Eye eye = aEye == VREye::Left ? gfx::VRDisplayInfo::Eye_Left : gfx::VRDisplayInfo::Eye_Right;
+ gfx::VRDisplayState::Eye eye = aEye == VREye::Left ? gfx::VRDisplayState::Eye_Left : gfx::VRDisplayState::Eye_Right;
RefPtr<VREyeParameters> params =
new VREyeParameters(GetParentObject(),
mClient->GetDisplayInfo().GetEyeTranslation(eye),
mClient->GetDisplayInfo().GetEyeFOV(eye),
mClient->GetDisplayInfo().SuggestedEyeResolution());
return params.forget();
}
@@ -909,19 +909,19 @@ VRFrameInfo::Update(const gfx::VRDisplay
mVRState.timestamp = aState.timestamp + mTimeStampOffset;
// Avoid division by zero within ConstructProjectionMatrix
const float kEpsilon = 0.00001f;
if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
aDepthFar = aDepthNear + kEpsilon;
}
- const gfx::VRFieldOfView leftFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Left];
+ const gfx::VRFieldOfView leftFOV = aInfo.mDisplayState.mEyeFOV[gfx::VRDisplayState::Eye_Left];
mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
- const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
+ const gfx::VRFieldOfView rightFOV = aInfo.mDisplayState.mEyeFOV[gfx::VRDisplayState::Eye_Right];
mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
memcpy(mLeftView.components, aState.leftViewMatrix, sizeof(aState.leftViewMatrix));
memcpy(mRightView.components, aState.rightViewMatrix, sizeof(aState.rightViewMatrix));
}
VRFrameInfo::VRFrameInfo()
: mTimeStampOffset(0.0f)
{
--- a/dom/vr/VRServiceTest.cpp
+++ b/dom/vr/VRServiceTest.cpp
@@ -27,54 +27,55 @@ NS_IMPL_ADDREF_INHERITED(VRMockDisplay,
NS_IMPL_RELEASE_INHERITED(VRMockDisplay, DOMEventTargetHelper)
VRMockDisplay::VRMockDisplay(const nsCString& aID, uint32_t aDeviceID)
: mDeviceID(aDeviceID)
, mDisplayInfo{}
, mSensorState{}
, mTimestamp(TimeStamp::Now())
{
- mDisplayInfo.mDisplayName = aID;
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+ strncpy(state.mDisplayName, aID.BeginReading(), kVRDisplayNameMaxLen);
mDisplayInfo.mType = VRDeviceType::Puppet;
- mDisplayInfo.mIsConnected = true;
- mDisplayInfo.mIsMounted = false;
- mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
- VRDisplayCapabilityFlags::Cap_Orientation |
- VRDisplayCapabilityFlags::Cap_AngularAcceleration |
- VRDisplayCapabilityFlags::Cap_Position |
- VRDisplayCapabilityFlags::Cap_LinearAcceleration |
- VRDisplayCapabilityFlags::Cap_External |
- VRDisplayCapabilityFlags::Cap_Present |
- VRDisplayCapabilityFlags::Cap_StageParameters |
- VRDisplayCapabilityFlags::Cap_MountDetection;
+ state.mIsConnected = true;
+ state.mIsMounted = false;
+ state.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
+ VRDisplayCapabilityFlags::Cap_Orientation |
+ VRDisplayCapabilityFlags::Cap_AngularAcceleration |
+ VRDisplayCapabilityFlags::Cap_Position |
+ VRDisplayCapabilityFlags::Cap_LinearAcceleration |
+ VRDisplayCapabilityFlags::Cap_External |
+ VRDisplayCapabilityFlags::Cap_Present |
+ VRDisplayCapabilityFlags::Cap_StageParameters |
+ VRDisplayCapabilityFlags::Cap_MountDetection;
}
JSObject*
VRMockDisplay::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return VRMockDisplayBinding::Wrap(aCx, this, aGivenProto);
}
void VRMockDisplay::SetEyeResolution(unsigned long aRenderWidth, unsigned long aRenderHeight)
{
- mDisplayInfo.mEyeResolution.width = aRenderWidth;
- mDisplayInfo.mEyeResolution.height = aRenderHeight;
+ mDisplayInfo.mDisplayState.mEyeResolution.width = aRenderWidth;
+ mDisplayInfo.mDisplayState.mEyeResolution.height = aRenderHeight;
}
void
VRMockDisplay::SetEyeParameter(VREye aEye, double aOffsetX, double aOffsetY,
double aOffsetZ, double aUpDegree, double aRightDegree,
double aDownDegree, double aLeftDegree)
{
uint32_t eye = static_cast<uint32_t>(aEye);
- mDisplayInfo.mEyeFOV[eye] = gfx ::VRFieldOfView(aUpDegree, aRightDegree,
- aRightDegree, aLeftDegree);
- mDisplayInfo.mEyeTranslation[eye].x = aOffsetX;
- mDisplayInfo.mEyeTranslation[eye].y = aOffsetY;
- mDisplayInfo.mEyeTranslation[eye].z = aOffsetZ;
+ mDisplayInfo.mDisplayState.mEyeFOV[eye] = gfx ::VRFieldOfView(aUpDegree, aRightDegree,
+ aRightDegree, aLeftDegree);
+ mDisplayInfo.mDisplayState.mEyeTranslation[eye].x = aOffsetX;
+ mDisplayInfo.mDisplayState.mEyeTranslation[eye].y = aOffsetY;
+ mDisplayInfo.mDisplayState.mEyeTranslation[eye].z = aOffsetZ;
}
void
VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition,
const Nullable<Float32Array>& aLinearVelocity,
const Nullable<Float32Array>& aLinearAcceleration,
const Nullable<Float32Array>& aOrientation,
const Nullable<Float32Array>& aAngularVelocity,
--- a/dom/vr/VRServiceTest.h
+++ b/dom/vr/VRServiceTest.h
@@ -24,17 +24,17 @@ public:
VRMockDisplay(const nsCString& aID, uint32_t aDeviceID);
void SetEyeParameter(VREye aEye, double aOffsetX, double aOffsetY, double aOffsetZ,
double aUpDegree, double aRightDegree,
double aDownDegree, double aLeftDegree);
void SetEyeResolution(unsigned long aRenderWidth, unsigned long aRenderHeight);
void SetPose(const Nullable<Float32Array>& aPosition, const Nullable<Float32Array>& aLinearVelocity,
const Nullable<Float32Array>& aLinearAcceleration, const Nullable<Float32Array>& aOrientation,
const Nullable<Float32Array>& aAngularVelocity, const Nullable<Float32Array>& aAngularAcceleration);
- void SetMountState(bool aIsMounted) { mDisplayInfo.mIsMounted = aIsMounted; }
+ void SetMountState(bool aIsMounted) { mDisplayInfo.mDisplayState.mIsMounted = aIsMounted; }
void Update();
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
private:
~VRMockDisplay() = default;
uint32_t mDeviceID;
gfx::VRDisplayInfo mDisplayInfo;
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -360,16 +360,17 @@ private:
DECL_GFX_PREF(Live, "browser.ui.zoom.force-user-scalable", ForceUserScalable, bool, false);
DECL_GFX_PREF(Live, "browser.viewport.desktopWidth", DesktopViewportWidth, int32_t, 980);
DECL_GFX_PREF(Live, "dom.ipc.plugins.asyncdrawing.enabled", PluginAsyncDrawingEnabled, bool, false);
DECL_GFX_PREF(Live, "dom.meta-viewport.enabled", MetaViewportEnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.enabled", VREnabled, bool, false);
DECL_GFX_PREF(Live, "dom.vr.autoactivate.enabled", VRAutoActivateEnabled, bool, false);
DECL_GFX_PREF(Live, "dom.vr.controller_trigger_threshold", VRControllerTriggerThreshold, float, 0.1f);
+ DECL_GFX_PREF(Once, "dom.vr.external.enabled", VRExternalEnabled, bool, true);
DECL_GFX_PREF(Live, "dom.vr.navigation.timeout", VRNavigationTimeout, int32_t, 1000);
DECL_GFX_PREF(Once, "dom.vr.oculus.enabled", VROculusEnabled, bool, true);
DECL_GFX_PREF(Live, "dom.vr.oculus.invisible.enabled", VROculusInvisibleEnabled, bool, true);
DECL_GFX_PREF(Live, "dom.vr.oculus.present.timeout", VROculusPresentTimeout, int32_t, 500);
DECL_GFX_PREF(Live, "dom.vr.oculus.quit.timeout", VROculusQuitTimeout, int32_t, 10000);
DECL_GFX_PREF(Once, "dom.vr.openvr.enabled", VROpenVREnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.osvr.enabled", VROSVREnabled, bool, false);
DECL_GFX_PREF(Live, "dom.vr.controller.enumerate.interval", VRControllerEnumerateInterval, int32_t, 1000);
--- a/gfx/vr/VRDisplayClient.cpp
+++ b/gfx/vr/VRDisplayClient.cpp
@@ -103,25 +103,25 @@ VRDisplayClient::FireEvents()
// Check if we need to trigger onVRDisplayPresentChange event
if (bLastEventWasPresenting != isPresenting) {
bLastEventWasPresenting = isPresenting;
vm->FireDOMVRDisplayPresentChangeEvent(mDisplayInfo.mDisplayID);
}
// Check if we need to trigger onvrdisplayactivate event
- if (!bLastEventWasMounted && mDisplayInfo.mIsMounted) {
+ if (!bLastEventWasMounted && mDisplayInfo.mDisplayState.mIsMounted) {
bLastEventWasMounted = true;
if (gfxPrefs::VRAutoActivateEnabled()) {
vm->FireDOMVRDisplayMountedEvent(mDisplayInfo.mDisplayID);
}
}
// Check if we need to trigger onvrdisplaydeactivate event
- if (bLastEventWasMounted && !mDisplayInfo.mIsMounted) {
+ if (bLastEventWasMounted && !mDisplayInfo.mDisplayState.mIsMounted) {
bLastEventWasMounted = false;
if (gfxPrefs::VRAutoActivateEnabled()) {
vm->FireDOMVRDisplayUnmountedEvent(mDisplayInfo.mDisplayID);
}
}
// Check if we need to trigger VRDisplay.requestAnimationFrame
if (mLastEventFrameId != mDisplayInfo.mFrameId) {
@@ -140,17 +140,17 @@ bool
VRDisplayClient::GetIsConnected() const
{
return mDisplayInfo.GetIsConnected();
}
void
VRDisplayClient::NotifyDisconnected()
{
- mDisplayInfo.mIsConnected = false;
+ mDisplayInfo.mDisplayState.mIsConnected = false;
}
void
VRDisplayClient::UpdateSubmitFrameResult(const VRSubmitFrameResultInfo& aResult)
{
mSubmitFrameResult = aResult;
}
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -73,16 +73,17 @@ VRDisplayHost::VRDisplayHost(VRDeviceTyp
{
MOZ_COUNT_CTOR(VRDisplayHost);
mDisplayInfo.mType = aType;
mDisplayInfo.mDisplayID = VRSystemManager::AllocateDisplayID();
mDisplayInfo.mPresentingGroups = 0;
mDisplayInfo.mGroupMask = kVRGroupContent;
mDisplayInfo.mFrameId = 0;
mDisplayInfo.mPresentingGeneration = 0;
+ mDisplayInfo.mDisplayState.mDisplayName[0] = '\0';
}
VRDisplayHost::~VRDisplayHost()
{
if (mSubmitThread) {
mSubmitThread->Shutdown();
mSubmitThread = nullptr;
}
@@ -155,17 +156,17 @@ void
VRDisplayHost::SetGroupMask(uint32_t aGroupMask)
{
mDisplayInfo.mGroupMask = aGroupMask;
}
bool
VRDisplayHost::GetIsConnected()
{
- return mDisplayInfo.mIsConnected;
+ return mDisplayInfo.mDisplayState.mIsConnected;
}
void
VRDisplayHost::AddLayer(VRLayerParent *aLayer)
{
mLayers.AppendElement(aLayer);
mDisplayInfo.mPresentingGroups |= aLayer->GetGroup();
if (mLayers.Length() == 1) {
@@ -416,23 +417,22 @@ VRDisplayHost::CheckClearDisplayInfoDirt
return false;
}
mLastUpdateDisplayInfo = mDisplayInfo;
return true;
}
VRControllerHost::VRControllerHost(VRDeviceType aType, dom::GamepadHand aHand,
uint32_t aDisplayID)
- : mButtonPressed(0)
- , mButtonTouched(0)
+ : mControllerInfo{}
, mVibrateIndex(0)
{
MOZ_COUNT_CTOR(VRControllerHost);
mControllerInfo.mType = aType;
- mControllerInfo.mHand = aHand;
+ mControllerInfo.mControllerState.mHand = aHand;
mControllerInfo.mMappingType = dom::GamepadMappingType::_empty;
mControllerInfo.mDisplayID = aDisplayID;
mControllerInfo.mControllerID = VRSystemManager::AllocateControllerID();
}
VRControllerHost::~VRControllerHost()
{
MOZ_COUNT_DTOR(VRControllerHost);
@@ -442,35 +442,35 @@ const VRControllerInfo&
VRControllerHost::GetControllerInfo() const
{
return mControllerInfo;
}
void
VRControllerHost::SetButtonPressed(uint64_t aBit)
{
- mButtonPressed = aBit;
+ mControllerInfo.mControllerState.mButtonPressed = aBit;
}
uint64_t
VRControllerHost::GetButtonPressed()
{
- return mButtonPressed;
+ return mControllerInfo.mControllerState.mButtonPressed;
}
void
VRControllerHost::SetButtonTouched(uint64_t aBit)
{
- mButtonTouched = aBit;
+ mControllerInfo.mControllerState.mButtonTouched = aBit;
}
uint64_t
VRControllerHost::GetButtonTouched()
{
- return mButtonTouched;
+ return mControllerInfo.mControllerState.mButtonTouched;
}
void
VRControllerHost::SetPose(const dom::GamepadPoseState& aPose)
{
mPose = aPose;
}
@@ -478,17 +478,17 @@ const dom::GamepadPoseState&
VRControllerHost::GetPose()
{
return mPose;
}
dom::GamepadHand
VRControllerHost::GetHand()
{
- return mControllerInfo.mHand;
+ return mControllerInfo.mControllerState.mHand;
}
void
VRControllerHost::SetVibrateIndex(uint64_t aIndex)
{
mVibrateIndex = aIndex;
}
--- a/gfx/vr/VRDisplayHost.h
+++ b/gfx/vr/VRDisplayHost.h
@@ -142,20 +142,16 @@ public:
uint64_t GetVibrateIndex();
protected:
explicit VRControllerHost(VRDeviceType aType, dom::GamepadHand aHand,
uint32_t aDisplayID);
virtual ~VRControllerHost();
VRControllerInfo mControllerInfo;
- // The current button pressed bit of button mask.
- uint64_t mButtonPressed;
- // The current button touched bit of button mask.
- uint64_t mButtonTouched;
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
@@ -13,16 +13,17 @@
#include "mozilla/dom/VRDisplay.h"
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/Unused.h"
#include "gfxPrefs.h"
#include "gfxVR.h"
+#include "gfxVRExternal.h"
#if defined(XP_WIN)
#include "gfxVROculus.h"
#endif
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
#include "gfxVROpenVR.h"
#include "gfxVROSVR.h"
#endif
#if defined(MOZ_ANDROID_GOOGLE_VR)
@@ -71,16 +72,20 @@ VRManager::VRManager()
* native interface for Oculus HMD's.
*
* OpenvR comes second, as it is the native interface for HTC Vive
* which is the most common HMD at this time.
*
* OSVR will be used if Oculus SDK and OpenVR don't detect any HMDS,
* to support everyone else.
*/
+ mExternalManager = VRSystemManagerExternal::Create();
+ if (mExternalManager) {
+ mManagers.AppendElement(mExternalManager);
+ }
#if defined(XP_WIN)
// The Oculus runtime is supported only on Windows
mgr = VRSystemManagerOculus::Create();
if (mgr) {
mManagers.AppendElement(mgr);
}
#endif
@@ -508,16 +513,23 @@ VRManager::CreateVRTestSystem()
VRSystemManagerPuppet*
VRManager::GetPuppetManager()
{
MOZ_ASSERT(mPuppetManager);
return mPuppetManager;
}
+VRSystemManagerExternal*
+VRManager::GetExternalManager()
+{
+ MOZ_ASSERT(mExternalManager);
+ return mExternalManager;
+}
+
template<class T>
void
VRManager::NotifyGamepadChange(uint32_t aIndex, const T& aInfo)
{
dom::GamepadChangeEventBody body(aInfo);
dom::GamepadChangeEvent e(aIndex, dom::GamepadServiceType::VR, body);
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -19,16 +19,17 @@ namespace layers {
class TextureHost;
}
namespace gfx {
class VRLayerParent;
class VRManagerParent;
class VRDisplayHost;
class VRSystemManagerPuppet;
+class VRSystemManagerExternal;
class VRManager
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRManager)
public:
static void ManagerInit();
static VRManager* Get();
@@ -44,16 +45,17 @@ public:
void RemoveControllers();
template<class T> void NotifyGamepadChange(uint32_t aIndex, const T& aInfo);
RefPtr<gfx::VRDisplayHost> GetDisplay(const uint32_t& aDisplayID);
void GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo);
RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
void CreateVRTestSystem();
VRSystemManagerPuppet* GetPuppetManager();
+ VRSystemManagerExternal* GetExternalManager();
void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
double aIntensity, double aDuration, const VRManagerPromise& aPromise);
void StopVibrateHaptic(uint32_t aControllerIdx);
void NotifyVibrateHapticCompleted(const VRManagerPromise& aPromise);
void DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameResultInfo& aResult);
protected:
@@ -84,16 +86,17 @@ private:
VRControllerHostHashMap mVRControllers;
Atomic<bool> mInitialized;
TimeStamp mLastControllerEnumerationTime;
TimeStamp mLastDisplayEnumerationTime;
TimeStamp mLastActiveTime;
RefPtr<VRSystemManagerPuppet> mPuppetManager;
+ RefPtr<VRSystemManagerExternal> mExternalManager;
bool mVRDisplaysRequested;
bool mVRControllersRequested;
};
} // namespace gfx
} // namespace mozilla
#endif // GFX_VR_MANAGER_H
new file mode 100644
--- /dev/null
+++ b/gfx/vr/external_api/moz_external_vr.h
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef GFX_VR_EXTERNAL_API_H
+#define GFX_VR_EXTERNAL_API_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <type_traits>
+
+#ifdef MOZILLA_INTERNAL_API
+#include "mozilla/TypedEnumBits.h"
+#include "mozilla/gfx/2D.h"
+#endif // MOZILLA_INTERNAL_API
+
+namespace mozilla {
+#ifdef MOZILLA_INTERNAL_API
+namespace dom {
+ enum class GamepadHand : uint8_t;
+}
+#endif // MOZILLA_INTERNAL_API
+namespace gfx {
+
+// We assign VR presentations to groups with a bitmask.
+// Currently, we will only display either content or chrome.
+// Later, we will have more groups to support VR home spaces and
+// multitasking environments.
+// These values are not exposed to regular content and only affect
+// chrome-only API's. They may be changed at any time.
+static const uint32_t kVRGroupNone = 0;
+static const uint32_t kVRGroupContent = 1 << 0;
+static const uint32_t kVRGroupChrome = 1 << 1;
+static const uint32_t kVRGroupAll = 0xffffffff;
+
+static const int kVRDisplayNameMaxLen = 256;
+static const int kVRControllerNameMaxLen = 256;
+static const int kVRControllerMaxCount = 16;
+static const int kVRControllerMaxTriggers = 16;
+static const int kVRControllerMaxAxis = 16;
+static const int kVRLayerMaxCount = 8;
+
+struct Point3D_POD
+{
+ float x;
+ float y;
+ float z;
+};
+
+struct IntSize_POD
+{
+ int32_t width;
+ int32_t height;
+};
+
+struct FloatSize_POD
+{
+ float width;
+ float height;
+};
+
+#ifndef MOZILLA_INTERNAL_API
+
+enum class ControllerHand : uint8_t {
+ _empty,
+ Left,
+ Right,
+ EndGuard_
+};
+
+#endif // ifndef MOZILLA_INTERNAL_API
+
+enum class VRDisplayCapabilityFlags : uint16_t {
+ Cap_None = 0,
+ /**
+ * Cap_Position is set if the VRDisplay is capable of tracking its position.
+ */
+ Cap_Position = 1 << 1,
+ /**
+ * Cap_Orientation is set if the VRDisplay is capable of tracking its orientation.
+ */
+ Cap_Orientation = 1 << 2,
+ /**
+ * Cap_Present is set if the VRDisplay is capable of presenting content to an
+ * HMD or similar device. Can be used to indicate "magic window" devices that
+ * are capable of 6DoF tracking but for which requestPresent is not meaningful.
+ * If false then calls to requestPresent should always fail, and
+ * getEyeParameters should return null.
+ */
+ Cap_Present = 1 << 3,
+ /**
+ * Cap_External is set if the VRDisplay is separate from the device's
+ * primary display. If presenting VR content will obscure
+ * other content on the device, this should be un-set. When
+ * un-set, the application should not attempt to mirror VR content
+ * or update non-VR UI because that content will not be visible.
+ */
+ Cap_External = 1 << 4,
+ /**
+ * Cap_AngularAcceleration is set if the VRDisplay is capable of tracking its
+ * angular acceleration.
+ */
+ Cap_AngularAcceleration = 1 << 5,
+ /**
+ * Cap_LinearAcceleration is set if the VRDisplay is capable of tracking its
+ * linear acceleration.
+ */
+ Cap_LinearAcceleration = 1 << 6,
+ /**
+ * Cap_StageParameters is set if the VRDisplay is capable of room scale VR
+ * and can report the StageParameters to describe the space.
+ */
+ Cap_StageParameters = 1 << 7,
+ /**
+ * Cap_MountDetection is set if the VRDisplay is capable of sensing when the
+ * user is wearing the device.
+ */
+ Cap_MountDetection = 1 << 8,
+ /**
+ * Cap_All used for validity checking during IPC serialization
+ */
+ Cap_All = (1 << 9) - 1
+};
+
+#ifdef MOZILLA_INTERNAL_API
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRDisplayCapabilityFlags)
+#endif // MOZILLA_INTERNAL_API
+
+struct VRHMDSensorState {
+ int64_t inputFrameID;
+ double timestamp;
+ VRDisplayCapabilityFlags flags;
+
+ // These members will only change with inputFrameID:
+ float orientation[4];
+ float position[3];
+ float leftViewMatrix[16];
+ float rightViewMatrix[16];
+ float angularVelocity[3];
+ float angularAcceleration[3];
+ float linearVelocity[3];
+ float linearAcceleration[3];
+
+#ifdef MOZILLA_INTERNAL_API
+
+ void Clear() {
+ memset(this, 0, sizeof(VRHMDSensorState));
+ }
+
+ bool operator==(const VRHMDSensorState& other) const {
+ return inputFrameID == other.inputFrameID &&
+ timestamp == other.timestamp;
+ }
+
+ bool operator!=(const VRHMDSensorState& other) const {
+ return !(*this == other);
+ }
+
+ void CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms);
+
+#endif // MOZILLA_INTERNAL_API
+};
+
+struct VRFieldOfView {
+ double upDegrees;
+ double rightDegrees;
+ double downDegrees;
+ double leftDegrees;
+
+#ifdef MOZILLA_INTERNAL_API
+
+ VRFieldOfView() = default;
+ VRFieldOfView(double up, double right, double down, double left)
+ : upDegrees(up), rightDegrees(right), downDegrees(down), leftDegrees(left)
+ {}
+
+ void SetFromTanRadians(double up, double right, double down, double left)
+ {
+ upDegrees = atan(up) * 180.0 / M_PI;
+ rightDegrees = atan(right) * 180.0 / M_PI;
+ downDegrees = atan(down) * 180.0 / M_PI;
+ leftDegrees = atan(left) * 180.0 / M_PI;
+ }
+
+ bool operator==(const VRFieldOfView& other) const {
+ return other.upDegrees == upDegrees &&
+ other.downDegrees == downDegrees &&
+ other.rightDegrees == rightDegrees &&
+ other.leftDegrees == leftDegrees;
+ }
+
+ bool operator!=(const VRFieldOfView& other) const {
+ return !(*this == other);
+ }
+
+ bool IsZero() const {
+ return upDegrees == 0.0 ||
+ rightDegrees == 0.0 ||
+ downDegrees == 0.0 ||
+ leftDegrees == 0.0;
+ }
+
+ Matrix4x4 ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded) const;
+
+#endif // MOZILLA_INTERNAL_API
+
+};
+
+struct VRDisplayState
+{
+ enum Eye {
+ Eye_Left,
+ Eye_Right,
+ NumEyes
+ };
+
+ char mDisplayName[kVRDisplayNameMaxLen];
+ VRDisplayCapabilityFlags mCapabilityFlags;
+ VRFieldOfView mEyeFOV[VRDisplayState::NumEyes];
+ Point3D_POD mEyeTranslation[VRDisplayState::NumEyes];
+ IntSize_POD mEyeResolution;
+ bool mIsConnected;
+ bool mIsMounted;
+ FloatSize_POD mStageSize;
+ // We can't use a Matrix4x4 here unless we ensure it's a POD type
+ float mSittingToStandingTransform[16];
+};
+
+struct VRControllerState
+{
+ char mControllerName[kVRControllerNameMaxLen];
+#ifdef MOZILLA_INTERNAL_API
+ dom::GamepadHand mHand;
+#else
+ ControllerHand mHand;
+#endif
+ uint32_t mNumButtons;
+ uint32_t mNumAxes;
+ uint32_t mNumTriggers;
+ uint32_t mNumHaptics;
+ // The current button pressed bit of button mask.
+ uint64_t mButtonPressed;
+ // The current button touched bit of button mask.
+ uint64_t mButtonTouched;
+ float mTriggerValue[kVRControllerMaxTriggers];
+ float mAxisValue[kVRControllerMaxAxis];
+};
+
+struct VRLayerEyeRect
+{
+ float x;
+ float y;
+ float width;
+ float height;
+};
+
+enum class VRLayerType : uint16_t {
+ LayerType_None = 0,
+ LayerType_2D_Content = 1,
+ LayerType_Stereo_Immersive = 2
+};
+
+enum class VRLayerTextureType : uint16_t {
+ LayerTextureType_None = 0,
+ LayerTextureType_DirectX = 1,
+ LayerTextureType_OpenGL = 2,
+ LayerTextureType_Vulkan = 3
+};
+
+struct VRLayer_2D_Content
+{
+ void* mTextureHandle;
+ VRLayerTextureType mTextureType;
+ uint64_t mFrameId;
+};
+
+struct VRLayer_Stereo_Immersive
+{
+ void* mTextureHandle;
+ VRLayerTextureType mTextureType;
+ uint64_t mFrameId;
+ VRLayerEyeRect mLeftEyeRect;
+ VRLayerEyeRect mRightEyeRect;
+};
+
+struct VRLayerState
+{
+ VRLayerType type;
+ union {
+ VRLayer_2D_Content layer_2d_content;
+ VRLayer_Stereo_Immersive layer_stereo_immersive;
+ };
+};
+
+struct VRBrowserState
+{
+ VRLayerState layerState[kVRLayerMaxCount];
+};
+
+struct VRSystemState
+{
+ VRDisplayState displayState;
+ VRHMDSensorState sensorState;
+ VRControllerState controllerState[kVRControllerMaxCount];
+};
+
+struct VRExternalShmem
+{
+ int64_t generationA;
+ VRSystemState state;
+ int64_t generationB;
+ int64_t browserGenerationA;
+ VRBrowserState browserState;
+ int64_t browserGenerationB;
+};
+
+// As we are memcpy'ing VRExternalShmem and its members around, it must be a POD type
+static_assert(std::is_pod<VRExternalShmem>::value, "VRExternalShmem must be a POD type.");
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* GFX_VR_EXTERNAL_API_H */
--- a/gfx/vr/gfxVR.cpp
+++ b/gfx/vr/gfxVR.cpp
@@ -38,21 +38,21 @@ VRSystemManager::AllocateControllerID()
* not active, in order to poll for respond to VR Platform API requests.
* This should be called very often, ideally once per frame.
* VRSystemManager::Refresh will not activate VR hardware or
* initialize VR runtimes that have not already been activated.
*/
void
VRSystemManager::NotifyVSync()
{
- // VRDisplayHost::NotifyVSync may modify mVRDisplays, so we iterate
- // through a local copy here.
- nsTArray<RefPtr<VRDisplayHost>> displays;
+ // VRDisplayHost::NotifyVSync may modify mVRDisplays, so we iterate
+ // through a local copy here.
+ nsTArray<RefPtr<VRDisplayHost>> displays;
GetHMDs(displays);
- for (const auto& display : displays) {
+ for (const auto& display : displays) {
display->NotifyVSync();
}
// Ensure that the controller state is updated at least
// on every 2d display VSync when not in a VR presentation.
if (!GetIsPresenting()) {
HandleInput();
}
@@ -189,15 +189,47 @@ VRHMDSensorState::CalcViewMatrices(const
gfx::Matrix4x4 matHead;
if (flags & VRDisplayCapabilityFlags::Cap_Orientation) {
matHead.SetRotationFromQuaternion(gfx::Quaternion(orientation[0], orientation[1],
orientation[2], orientation[3]));
}
matHead.PreTranslate(-position[0], -position[1], -position[2]);
- gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayInfo::Eye_Left];
+ gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayState::Eye_Left];
matView.Normalize();
memcpy(leftViewMatrix, matView.components, sizeof(matView.components));
- matView = matHead * aHeadToEyeTransforms[VRDisplayInfo::Eye_Right];
+ matView = matHead * aHeadToEyeTransforms[VRDisplayState::Eye_Right];
matView.Normalize();
memcpy(rightViewMatrix, matView.components, sizeof(matView.components));
}
+
+const IntSize
+VRDisplayInfo::SuggestedEyeResolution() const
+{
+ return IntSize(mDisplayState.mEyeResolution.width,
+ mDisplayState.mEyeResolution.height);
+}
+
+const Point3D
+VRDisplayInfo::GetEyeTranslation(uint32_t whichEye) const
+{
+ return Point3D(mDisplayState.mEyeTranslation[whichEye].x,
+ mDisplayState.mEyeTranslation[whichEye].y,
+ mDisplayState.mEyeTranslation[whichEye].z);
+}
+
+const Size
+VRDisplayInfo::GetStageSize() const
+{
+ return Size(mDisplayState.mStageSize.width,
+ mDisplayState.mStageSize.height);
+}
+
+const Matrix4x4
+VRDisplayInfo::GetSittingToStandingTransform() const
+{
+ Matrix4x4 m;
+ // If we could replace Matrix4x4 with a pod type, we could
+ // use it directly from the VRDisplayInfo struct.
+ memcpy(m.components, mDisplayState.mSittingToStandingTransform, sizeof(float) * 16);
+ return m;
+}
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -2,16 +2,17 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef GFX_VR_H
#define GFX_VR_H
+#include "moz_external_vr.h"
#include "nsTArray.h"
#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"
@@ -27,243 +28,86 @@ enum class GamepadHand : uint8_t;
struct GamepadPoseState;
}
namespace gfx {
class VRLayerParent;
class VRDisplayHost;
class VRControllerHost;
class VRManagerPromise;
-enum class VRDeviceType : uint16_t {
- Oculus,
- OpenVR,
- OSVR,
- GVR,
- Puppet,
- NumVRDeviceTypes
-};
-
-enum class VRDisplayCapabilityFlags : uint16_t {
- Cap_None = 0,
- /**
- * Cap_Position is set if the VRDisplay is capable of tracking its position.
- */
- Cap_Position = 1 << 1,
- /**
- * Cap_Orientation is set if the VRDisplay is capable of tracking its orientation.
- */
- Cap_Orientation = 1 << 2,
- /**
- * Cap_Present is set if the VRDisplay is capable of presenting content to an
- * HMD or similar device. Can be used to indicate "magic window" devices that
- * are capable of 6DoF tracking but for which requestPresent is not meaningful.
- * If false then calls to requestPresent should always fail, and
- * getEyeParameters should return null.
- */
- Cap_Present = 1 << 3,
- /**
- * Cap_External is set if the VRDisplay is separate from the device's
- * primary display. If presenting VR content will obscure
- * other content on the device, this should be un-set. When
- * un-set, the application should not attempt to mirror VR content
- * or update non-VR UI because that content will not be visible.
- */
- Cap_External = 1 << 4,
- /**
- * Cap_AngularAcceleration is set if the VRDisplay is capable of tracking its
- * angular acceleration.
- */
- Cap_AngularAcceleration = 1 << 5,
- /**
- * Cap_LinearAcceleration is set if the VRDisplay is capable of tracking its
- * linear acceleration.
- */
- Cap_LinearAcceleration = 1 << 6,
- /**
- * Cap_StageParameters is set if the VRDisplay is capable of room scale VR
- * and can report the StageParameters to describe the space.
- */
- Cap_StageParameters = 1 << 7,
- /**
- * Cap_MountDetection is set if the VRDisplay is capable of sensing when the
- * user is wearing the device.
- */
- Cap_MountDetection = 1 << 8,
- /**
- * Cap_All used for validity checking during IPC serialization
- */
- Cap_All = (1 << 9) - 1
-};
-
-MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRDisplayCapabilityFlags)
-
-struct VRFieldOfView {
- VRFieldOfView() = default;
- VRFieldOfView(double up, double right, double down, double left)
- : upDegrees(up), rightDegrees(right), downDegrees(down), leftDegrees(left)
- {}
-
- void SetFromTanRadians(double up, double right, double down, double left)
- {
- upDegrees = atan(up) * 180.0 / M_PI;
- rightDegrees = atan(right) * 180.0 / M_PI;
- downDegrees = atan(down) * 180.0 / M_PI;
- leftDegrees = atan(left) * 180.0 / M_PI;
- }
-
- bool operator==(const VRFieldOfView& other) const {
- return other.upDegrees == upDegrees &&
- other.downDegrees == downDegrees &&
- other.rightDegrees == rightDegrees &&
- other.leftDegrees == leftDegrees;
- }
-
- bool operator!=(const VRFieldOfView& other) const {
- return !(*this == other);
- }
-
- bool IsZero() const {
- return upDegrees == 0.0 ||
- rightDegrees == 0.0 ||
- downDegrees == 0.0 ||
- leftDegrees == 0.0;
- }
-
- Matrix4x4 ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded) const;
-
- double upDegrees;
- double rightDegrees;
- double downDegrees;
- double leftDegrees;
-};
-
-struct VRHMDSensorState {
- int64_t inputFrameID;
- double timestamp;
- VRDisplayCapabilityFlags flags;
-
- // These members will only change with inputFrameID:
- float orientation[4];
- float position[3];
- float leftViewMatrix[16];
- float rightViewMatrix[16];
- float angularVelocity[3];
- float angularAcceleration[3];
- float linearVelocity[3];
- float linearAcceleration[3];
-
- void Clear() {
- memset(this, 0, sizeof(VRHMDSensorState));
- }
-
- bool operator==(const VRHMDSensorState& other) const {
- return inputFrameID == other.inputFrameID &&
- timestamp == other.timestamp;
- }
-
- bool operator!=(const VRHMDSensorState& other) const {
- return !(*this == other);
- }
- void CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms);
-};
-
// The maximum number of frames of latency that we would expect before we
// should give up applying pose prediction.
// If latency is greater than one second, then the experience is not likely
// to be corrected by pose prediction. Setting this value too
// high may result in unnecessary memory allocation.
// As the current fastest refresh rate is 90hz, 100 is selected as a
// conservative value.
static const int kVRMaxLatencyFrames = 100;
-// We assign VR presentations to groups with a bitmask.
-// Currently, we will only display either content or chrome.
-// Later, we will have more groups to support VR home spaces and
-// multitasking environments.
-// These values are not exposed to regular content and only affect
-// chrome-only API's. They may be changed at any time.
-static const uint32_t kVRGroupNone = 0;
-static const uint32_t kVRGroupContent = 1 << 0;
-static const uint32_t kVRGroupChrome = 1 << 1;
-static const uint32_t kVRGroupAll = 0xffffffff;
+enum class VRDeviceType : uint16_t {
+ Oculus,
+ OpenVR,
+ OSVR,
+ GVR,
+ Puppet,
+ External,
+ NumVRDeviceTypes
+};
struct VRDisplayInfo
{
+ uint32_t mDisplayID;
+ VRDeviceType mType;
+ uint32_t mPresentingGroups;
+ uint32_t mGroupMask;
+ uint64_t mFrameId;
+ uint32_t mPresentingGeneration;
+ VRDisplayState mDisplayState;
+
+ VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames];
+ const VRHMDSensorState& GetSensorState() const
+ {
+ return mLastSensorState[mFrameId % kVRMaxLatencyFrames];
+ }
+
VRDeviceType GetType() const { return mType; }
uint32_t GetDisplayID() const { return mDisplayID; }
- const nsCString& GetDisplayName() const { return mDisplayName; }
- VRDisplayCapabilityFlags GetCapabilities() const { return mCapabilityFlags; }
+ const char* GetDisplayName() const { return mDisplayState.mDisplayName; }
+ VRDisplayCapabilityFlags GetCapabilities() const { return mDisplayState.mCapabilityFlags; }
- const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
- const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
- const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const { return mEyeFOV[whichEye]; }
- bool GetIsConnected() const { return mIsConnected; }
- bool GetIsMounted() const { return mIsMounted; }
+ const IntSize SuggestedEyeResolution() const;
+ const Point3D GetEyeTranslation(uint32_t whichEye) const;
+ const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const { return mDisplayState.mEyeFOV[whichEye]; }
+ bool GetIsConnected() const { return mDisplayState.mIsConnected; }
+ bool GetIsMounted() const { return mDisplayState.mIsMounted; }
uint32_t GetPresentingGroups() const { return mPresentingGroups; }
uint32_t GetGroupMask() const { return mGroupMask; }
- const Size& GetStageSize() const { return mStageSize; }
- const Matrix4x4& GetSittingToStandingTransform() const { return mSittingToStandingTransform; }
+ const Size GetStageSize() const;
+ const Matrix4x4 GetSittingToStandingTransform() const;
uint64_t GetFrameId() const { return mFrameId; }
- enum Eye {
- Eye_Left,
- Eye_Right,
- NumEyes
- };
-
- uint32_t mDisplayID;
- VRDeviceType mType;
- nsCString mDisplayName;
- VRDisplayCapabilityFlags mCapabilityFlags;
- VRFieldOfView mEyeFOV[VRDisplayInfo::NumEyes];
- Point3D mEyeTranslation[VRDisplayInfo::NumEyes];
- IntSize mEyeResolution;
- bool mIsConnected;
- bool mIsMounted;
- uint32_t mPresentingGroups;
- uint32_t mGroupMask;
- Size mStageSize;
- Matrix4x4 mSittingToStandingTransform;
- uint64_t mFrameId;
- uint32_t mPresentingGeneration;
- VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames];
-
bool operator==(const VRDisplayInfo& other) const {
for (size_t i = 0; i < kVRMaxLatencyFrames; i++) {
if (mLastSensorState[i] != other.mLastSensorState[i]) {
return false;
}
}
+ // Note that mDisplayState is asserted to be a POD type, so memcmp is safe
return mType == other.mType &&
mDisplayID == other.mDisplayID &&
- mDisplayName == other.mDisplayName &&
- mCapabilityFlags == other.mCapabilityFlags &&
- mEyeResolution == other.mEyeResolution &&
- mIsConnected == other.mIsConnected &&
- mIsMounted == other.mIsMounted &&
+ memcmp(&mDisplayState, &other.mDisplayState, sizeof(VRDisplayState)) == 0 &&
mPresentingGroups == other.mPresentingGroups &&
mGroupMask == other.mGroupMask &&
- mEyeFOV[0] == other.mEyeFOV[0] &&
- mEyeFOV[1] == other.mEyeFOV[1] &&
- mEyeTranslation[0] == other.mEyeTranslation[0] &&
- mEyeTranslation[1] == other.mEyeTranslation[1] &&
- mStageSize == other.mStageSize &&
- mSittingToStandingTransform == other.mSittingToStandingTransform &&
mFrameId == other.mFrameId &&
mPresentingGeneration == other.mPresentingGeneration;
}
bool operator!=(const VRDisplayInfo& other) const {
return !(*this == other);
}
-
- const VRHMDSensorState& GetSensorState() const
- {
- return mLastSensorState[mFrameId % kVRMaxLatencyFrames];
- }
};
struct VRSubmitFrameResultInfo
{
VRSubmitFrameResultInfo()
: mFrameNum(0),
mWidth(0),
mHeight(0)
@@ -275,44 +119,39 @@ struct VRSubmitFrameResultInfo
uint32_t mWidth;
uint32_t mHeight;
};
struct VRControllerInfo
{
VRDeviceType GetType() const { return mType; }
uint32_t GetControllerID() const { return mControllerID; }
- const nsCString& GetControllerName() const { return mControllerName; }
+ const char* GetControllerName() const { return mControllerState.mControllerName; }
dom::GamepadMappingType GetMappingType() const { return mMappingType; }
uint32_t GetDisplayID() const { return mDisplayID; }
- dom::GamepadHand GetHand() const { return mHand; }
- uint32_t GetNumButtons() const { return mNumButtons; }
- uint32_t GetNumAxes() const { return mNumAxes; }
- uint32_t GetNumHaptics() const { return mNumHaptics; }
+ dom::GamepadHand GetHand() const { return mControllerState.mHand; }
+ uint32_t GetNumButtons() const { return mControllerState.mNumButtons; }
+ uint32_t GetNumAxes() const { return mControllerState.mNumAxes; }
+ uint32_t GetNumHaptics() const { return mControllerState.mNumHaptics; }
uint32_t mControllerID;
VRDeviceType mType;
- nsCString mControllerName;
dom::GamepadMappingType mMappingType;
uint32_t mDisplayID;
- dom::GamepadHand mHand;
- uint32_t mNumButtons;
- uint32_t mNumAxes;
- uint32_t mNumHaptics;
-
+ VRControllerState mControllerState;
bool operator==(const VRControllerInfo& other) const {
return mType == other.mType &&
mControllerID == other.mControllerID &&
- mControllerName == other.mControllerName &&
+ strncmp(mControllerState.mControllerName, other.mControllerState.mControllerName, kVRControllerNameMaxLen) == 0 &&
mMappingType == other.mMappingType &&
mDisplayID == other.mDisplayID &&
- mHand == other.mHand &&
- mNumButtons == other.mNumButtons &&
- mNumAxes == other.mNumAxes &&
- mNumHaptics == other.mNumHaptics;
+ mControllerState.mHand == other.mControllerState.mHand &&
+ mControllerState.mNumButtons == other.mControllerState.mNumButtons &&
+ mControllerState.mNumAxes == other.mControllerState.mNumAxes &&
+ mControllerState.mNumHaptics == other.mControllerState.mNumHaptics;
}
bool operator!=(const VRControllerInfo& other) const {
return !(*this == other);
}
};
struct VRTelemetry
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVRExternal.cpp
@@ -0,0 +1,470 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 <math.h>
+
+#include "prlink.h"
+#include "prenv.h"
+#include "gfxPrefs.h"
+#include "mozilla/Preferences.h"
+
+#include "mozilla/gfx/Quaternion.h"
+
+#ifdef XP_WIN
+#include "CompositorD3D11.h"
+#include "TextureD3D11.h"
+static const char* kShmemName = "moz.gecko.vr_ext.0.0.1";
+#elif defined(XP_MACOSX)
+#include "mozilla/gfx/MacIOSurface.h"
+#include <sys/mman.h>
+#include <sys/stat.h> /* For mode constants */
+#include <fcntl.h> /* For O_* constants */
+#include <errno.h>
+static const char* kShmemName = "/moz.gecko.vr_ext.0.0.1";
+#endif
+
+#include "gfxVRExternal.h"
+#include "VRManagerParent.h"
+#include "VRManager.h"
+#include "VRThread.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsIScreenManager.h"
+
+#include "mozilla/dom/GamepadEventTypes.h"
+#include "mozilla/dom/GamepadBinding.h"
+#include "mozilla/Telemetry.h"
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::gfx::impl;
+using namespace mozilla::layers;
+using namespace mozilla::dom;
+
+static const uint32_t kNumExternalHaptcs = 1;
+
+VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState)
+ : VRDisplayHost(VRDeviceType::External)
+ , mIsPresenting(false)
+ , mLastSensorState{}
+{
+ MOZ_COUNT_CTOR_INHERITED(VRDisplayExternal, VRDisplayHost);
+ mDisplayInfo.mDisplayState = aDisplayState;
+
+ // default to an identity quaternion
+ mLastSensorState.orientation[3] = 1.0f;
+}
+
+VRDisplayExternal::~VRDisplayExternal()
+{
+ Destroy();
+ MOZ_COUNT_DTOR_INHERITED(VRDisplayExternal, VRDisplayHost);
+}
+
+void
+VRDisplayExternal::Destroy()
+{
+ StopPresentation();
+
+ // TODO - Implement
+}
+
+void
+VRDisplayExternal::ZeroSensor()
+{
+}
+
+void
+VRDisplayExternal::Refresh()
+{
+ VRManager *vm = VRManager::Get();
+ VRSystemManagerExternal* manager = vm->GetExternalManager();
+
+ manager->PullState(&mDisplayInfo.mDisplayState);
+}
+
+VRHMDSensorState
+VRDisplayExternal::GetSensorState()
+{
+ VRManager *vm = VRManager::Get();
+ VRSystemManagerExternal* manager = vm->GetExternalManager();
+
+ manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState);
+
+// result.CalcViewMatrices(headToEyeTransforms);
+ mLastSensorState.inputFrameID = mDisplayInfo.mFrameId;
+ return mLastSensorState;
+}
+
+void
+VRDisplayExternal::StartPresentation()
+{
+ if (mIsPresenting) {
+ return;
+ }
+ mIsPresenting = true;
+ mTelemetry.Clear();
+ mTelemetry.mPresentationStart = TimeStamp::Now();
+
+ // TODO - Implement this
+
+ // mTelemetry.mLastDroppedFrameCount = stats.m_nNumReprojectedFrames;
+}
+
+void
+VRDisplayExternal::StopPresentation()
+{
+ if (!mIsPresenting) {
+ return;
+ }
+
+ // TODO - Implement this
+
+/*
+ mIsPresenting = false;
+ const TimeDuration duration = TimeStamp::Now() - mTelemetry.mPresentationStart;
+ Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 2);
+ Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OPENVR,
+ duration.ToMilliseconds());
+
+ ::vr::Compositor_CumulativeStats stats;
+ mVRCompositor->GetCumulativeStats(&stats, sizeof(::vr::Compositor_CumulativeStats));
+ const uint32_t droppedFramesPerSec = (stats.m_nNumReprojectedFrames -
+ mTelemetry.mLastDroppedFrameCount) / duration.ToSeconds();
+ Telemetry::Accumulate(Telemetry::WEBVR_DROPPED_FRAMES_IN_OPENVR, droppedFramesPerSec);
+*/
+}
+
+#if defined(XP_WIN)
+
+bool
+VRDisplayExternal::SubmitFrame(ID3D11Texture2D* aSource,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect)
+{
+ // FINDME! Implement this
+ return false;
+}
+
+#elif defined(XP_MACOSX)
+
+bool
+VRDisplayExternal::SubmitFrame(MacIOSurface* aMacIOSurface,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect)
+{
+ const void* ioSurface = aMacIOSurface->GetIOSurfacePtr();
+ bool result = false;
+ if (ioSurface == nullptr) {
+ NS_WARNING("VRDisplayExternal::SubmitFrame() could not get an IOSurface");
+ } else {
+ // FINDME! Implement this
+ }
+ return result;
+}
+
+#endif
+
+VRControllerExternal::VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID,
+ uint32_t aNumButtons, uint32_t aNumTriggers,
+ uint32_t aNumAxes, const nsCString& aId)
+ : VRControllerHost(VRDeviceType::External, aHand, aDisplayID)
+{
+ MOZ_COUNT_CTOR_INHERITED(VRControllerExternal, VRControllerHost);
+
+ VRControllerState& state = mControllerInfo.mControllerState;
+ strncpy(state.mControllerName, aId.BeginReading(), kVRControllerNameMaxLen);
+ state.mNumButtons = aNumButtons;
+ state.mNumAxes = aNumAxes;
+ state.mNumTriggers = aNumTriggers;
+ state.mNumHaptics = kNumExternalHaptcs;
+}
+
+VRControllerExternal::~VRControllerExternal()
+{
+ MOZ_COUNT_DTOR_INHERITED(VRControllerExternal, VRControllerHost);
+}
+
+VRSystemManagerExternal::VRSystemManagerExternal()
+ : mExternalShmem(nullptr)
+{
+#if defined(XP_MACOSX)
+ mShmemFD = 0;
+#elif defined(XP_WIN)
+ mShmemFile = NULL;
+#endif
+}
+
+VRSystemManagerExternal::~VRSystemManagerExternal()
+{
+ CloseShmem();
+}
+
+void
+VRSystemManagerExternal::OpenShmem()
+{
+ if (mExternalShmem) {
+ return;
+ }
+ fprintf(stderr, "Opening Shmem...\n");
+#if defined(XP_MACOSX)
+
+ if (mShmemFD == 0) {
+ mShmemFD = shm_open(kShmemName, O_RDWR, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
+ }
+ if (mShmemFD <= 0) {
+ fprintf(stderr, "shm_open error: %i\n", errno); // findme! kip! hack! Need to properly log this...
+ mShmemFD = 0;
+ return;
+ }
+
+ struct stat sb;
+ fstat(mShmemFD, &sb);
+ off_t length = sb.st_size;
+ if (length < (off_t)sizeof(VRExternalShmem)) {
+ fprintf(stderr, "shmem size is smaller than sizeof(VRExternalShmem)\n");
+ CloseShmem();
+ return;
+ }
+
+ mExternalShmem = (VRExternalShmem*)mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, mShmemFD, 0);
+ if (mExternalShmem == MAP_FAILED) {
+ fprintf(stderr, "mmap failed for VRExternalShmem\n");
+ mExternalShmem = NULL;
+ CloseShmem();
+ return;
+ }
+
+#elif defined(XP_WIN)
+
+ if (mShmemFile == NULL) {
+ mShmemFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, kShmemName);
+ if (mShmemFile == NULL) {
+ fprintf(stderr, "Could not open file mapping object (%d).\n",
+ GetLastError());
+ CloseShmem();
+ return;
+ }
+ }
+ LARGE_INTEGER length;
+ length.QuadPart = sizeof(VRExternalShmem);
+ mExternalShmem = (VRExternalShmem*)MapViewOfFile(mShmemFile, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ length.QuadPart);
+
+ if (mExternalShmem == NULL) {
+ fprintf(stderr, "Could not map view of file (%d).\n",
+ GetLastError());
+ CloseShmem();
+ return;
+ }
+#endif
+ fprintf(stderr, "Opened Shmem\n");
+ CheckForShutdown();
+}
+
+void
+VRSystemManagerExternal::CheckForShutdown()
+{
+ if (mExternalShmem) {
+ if (mExternalShmem->generationA == -1 && mExternalShmem->generationB == -1) {
+ Shutdown();
+ }
+ }
+}
+
+void
+VRSystemManagerExternal::CloseShmem()
+{
+ fprintf(stderr, "Closing Shmem...\n");
+#if defined(XP_MACOSX)
+
+ if (mExternalShmem) {
+ munmap((void *)mExternalShmem, sizeof(VRExternalShmem));
+ mExternalShmem = NULL;
+ }
+ if (mShmemFD) {
+ close(mShmemFD);
+ }
+ mShmemFD = 0;
+
+#elif defined(XP_WIN)
+ if (mExternalShmem) {
+ UnmapViewOfFile((void *)mExternalShmem);
+ mExternalShmem = NULL;
+ }
+ if (mShmemFile) {
+ CloseHandle(mShmemFile);
+ mShmemFile = NULL;
+ }
+#endif
+ fprintf(stderr, "Closed Shmem\n");
+}
+
+/*static*/ already_AddRefed<VRSystemManagerExternal>
+VRSystemManagerExternal::Create()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!gfxPrefs::VREnabled() || !gfxPrefs::VRExternalEnabled()) {
+ return nullptr;
+ }
+
+ RefPtr<VRSystemManagerExternal> manager = new VRSystemManagerExternal();
+ return manager.forget();
+}
+
+void
+VRSystemManagerExternal::Destroy()
+{
+ Shutdown();
+}
+
+void
+VRSystemManagerExternal::Shutdown()
+{
+ if (mDisplay) {
+ mDisplay = nullptr;
+ }
+ RemoveControllers();
+ CloseShmem();
+}
+
+void
+VRSystemManagerExternal::NotifyVSync()
+{
+ VRSystemManager::NotifyVSync();
+
+ CheckForShutdown();
+
+ if (mDisplay) {
+ mDisplay->Refresh();
+ }
+}
+
+void
+VRSystemManagerExternal::Enumerate()
+{
+ if (mDisplay == nullptr) {
+ OpenShmem();
+ if (mExternalShmem) {
+ VRDisplayState displayState;
+ PullState(&displayState);
+ if (displayState.mIsConnected) {
+ mDisplay = new VRDisplayExternal(displayState);
+ }
+ }
+ }
+}
+
+bool
+VRSystemManagerExternal::ShouldInhibitEnumeration()
+{
+ if (VRSystemManager::ShouldInhibitEnumeration()) {
+ return true;
+ }
+ if (mDisplay) {
+ // When we find an a VR device, don't
+ // allow any further enumeration as it
+ // may get picked up redundantly by other
+ // API's.
+ return true;
+ }
+ return false;
+}
+
+void
+VRSystemManagerExternal::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
+{
+ if (mDisplay) {
+ aHMDResult.AppendElement(mDisplay);
+ }
+}
+
+bool
+VRSystemManagerExternal::GetIsPresenting()
+{
+ if (mDisplay) {
+ VRDisplayInfo displayInfo(mDisplay->GetDisplayInfo());
+ return displayInfo.GetPresentingGroups() != 0;
+ }
+
+ return false;
+}
+
+void
+VRSystemManagerExternal::HandleInput()
+{
+ // TODO - Implement This!
+}
+
+void
+VRSystemManagerExternal::VibrateHaptic(uint32_t aControllerIdx,
+ uint32_t aHapticIndex,
+ double aIntensity,
+ double aDuration,
+ const VRManagerPromise& aPromise)
+{
+ // TODO - Implement this
+}
+
+void
+VRSystemManagerExternal::StopVibrateHaptic(uint32_t aControllerIdx)
+{
+ // TODO - Implement this
+}
+
+void
+VRSystemManagerExternal::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
+{
+ aControllerResult.Clear();
+ for (uint32_t i = 0; i < mExternalController.Length(); ++i) {
+ aControllerResult.AppendElement(mExternalController[i]);
+ }
+}
+
+void
+VRSystemManagerExternal::ScanForControllers()
+{
+ // TODO - Implement this
+}
+
+void
+VRSystemManagerExternal::RemoveControllers()
+{
+ // The controller count is changed, removing the existing gamepads first.
+ for (uint32_t i = 0; i < mExternalController.Length(); ++i) {
+ RemoveGamepad(i);
+ }
+ mExternalController.Clear();
+ mControllerCount = 0;
+}
+
+void
+VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState /* = nullptr */)
+{
+ MOZ_ASSERT(mExternalShmem);
+ if (mExternalShmem) {
+ // FINDME!!! TODO!! HACK!! KIP!! Add locking here
+ // for non-x86 platforms, such as a spinlock
+ VRExternalShmem tmp;
+ memcpy(&tmp, (void *)mExternalShmem, sizeof(VRExternalShmem));
+ if (tmp.generationA == tmp.generationB && tmp.generationA != 0 && tmp.generationA != -1) {
+ memcpy(aDisplayState, &tmp.state.displayState, sizeof(VRDisplayState));
+ if (aSensorState) {
+ memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState));
+ }
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVRExternal.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef GFX_VR_EXTERNAL_H
+#define GFX_VR_EXTERNAL_H
+
+#include "nsTArray.h"
+#include "nsIScreen.h"
+#include "nsCOMPtr.h"
+#include "mozilla/RefPtr.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/EnumeratedArray.h"
+
+#include "gfxVR.h"
+#include "VRDisplayHost.h"
+
+#if defined(XP_MACOSX)
+class MacIOSurface;
+#endif
+namespace mozilla {
+namespace gfx {
+class VRThread;
+
+namespace impl {
+
+class VRDisplayExternal : public VRDisplayHost
+{
+public:
+ void ZeroSensor() override;
+
+protected:
+ virtual VRHMDSensorState GetSensorState() override;
+ virtual void StartPresentation() override;
+ virtual void StopPresentation() override;
+#if defined(XP_WIN)
+ virtual bool SubmitFrame(ID3D11Texture2D* aSource,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) override;
+#elif defined(XP_MACOSX)
+ virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) override;
+#endif
+
+public:
+ explicit VRDisplayExternal(const VRDisplayState& aDisplayState);
+ void Refresh();
+protected:
+ virtual ~VRDisplayExternal();
+ void Destroy();
+
+ VRTelemetry mTelemetry;
+ bool mIsPresenting;
+ VRHMDSensorState mLastSensorState;
+};
+
+class VRControllerExternal : public VRControllerHost
+{
+public:
+ explicit VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID, uint32_t aNumButtons,
+ uint32_t aNumTriggers, uint32_t aNumAxes,
+ const nsCString& aId);
+
+protected:
+ virtual ~VRControllerExternal();
+};
+
+} // namespace impl
+
+class VRSystemManagerExternal : public VRSystemManager
+{
+public:
+ static already_AddRefed<VRSystemManagerExternal> Create();
+
+ virtual void Destroy() override;
+ virtual void Shutdown() override;
+ virtual void NotifyVSync() override;
+ virtual void Enumerate() override;
+ virtual bool ShouldInhibitEnumeration() override;
+ virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
+ virtual bool GetIsPresenting() 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,
+ const VRManagerPromise& aPromise) override;
+ virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
+ void PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState = nullptr);
+
+protected:
+ VRSystemManagerExternal();
+ virtual ~VRSystemManagerExternal();
+
+private:
+ // there can only be one
+ RefPtr<impl::VRDisplayExternal> mDisplay;
+ nsTArray<RefPtr<impl::VRControllerExternal>> mExternalController;
+
+#if defined(XP_MACOSX)
+ int mShmemFD;
+#elif defined(XP_WIN)
+ HANDLE mShmemFile;
+#endif
+ volatile VRExternalShmem* mExternalShmem;
+
+ void OpenShmem();
+ void CloseShmem();
+ void CheckForShutdown();
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+
+#endif /* GFX_VR_EXTERNAL_H */
--- a/gfx/vr/gfxVRGVR.cpp
+++ b/gfx/vr/gfxVRGVR.cpp
@@ -208,17 +208,17 @@ VRDisplayGVR::VRDisplayGVR()
, mSwapChain(nullptr)
, mFrameBufferSize{0, 0}
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayGVR, VRDisplayHost);
MOZ_ASSERT(GetNonPresentingContext());
MOZ_ASSERT(!sContextObserver); // There can be only one GVR display at a time.
sContextObserver = this;
- mDisplayInfo.mDisplayName.AssignLiteral("GVR HMD");
+ strncpy(mDisplayInfo.mDisplayName, "GVR HMD", kVRDisplayNameMaxLen);
mDisplayInfo.mIsConnected = true;
mDisplayInfo.mIsMounted = true;
mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
VRDisplayCapabilityFlags::Cap_Orientation |
VRDisplayCapabilityFlags::Cap_Position | // Not yet...
VRDisplayCapabilityFlags::Cap_Present;
GVR_CHECK(gvr_refresh_viewer_profile(GetNonPresentingContext()));
@@ -404,17 +404,17 @@ VRDisplayGVR::GetSensorState()
result.position[0] = m._14;
result.position[1] = m._24;
result.position[2] = m._34;
result.linearVelocity[0] = 0.0f;
result.linearVelocity[1] = 0.0f;
result.linearVelocity[2] = 0.0f;
UpdateHeadToEye(context);
- result.CalcViewMatrices(mHeadToEyes);
+ CalcViewMatrices(&result, mHeadToEyes);
return result;
}
void
VRDisplayGVR::SetPaused(const bool aPaused)
{
if (aPaused) {
@@ -591,22 +591,25 @@ VRDisplayGVR::GetControllers(nsTArray<Re
{
aControllerResult.AppendElement(mController.get());
}
VRControllerGVR::VRControllerGVR(dom::GamepadHand aHand, uint32_t aDisplayID)
: VRControllerHost(VRDeviceType::GVR, aHand, aDisplayID)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerGVR, VRControllerHost);
- mControllerInfo.mControllerName.AssignLiteral("Daydream Controller");
+
+ VRControlerState& state = mControllerInfo.mControllerState;
+ strncpy(state.mControllerName, "Daydream Controller", kVRControllerNameMaxLen);
+
// The gvr_controller_button enum starts with GVR_CONTROLLER_BUTTON_NONE at index zero
// so the GVR controller has one less button than GVR_CONTROLLER_BUTTON_COUNT specifies.
- mControllerInfo.mNumButtons = GVR_CONTROLLER_BUTTON_COUNT - 1; // Skip dummy none button
- mControllerInfo.mNumAxes = 2;
- mControllerInfo.mNumHaptics = 0;
+ state.mNumButtons = GVR_CONTROLLER_BUTTON_COUNT - 1; // Skip dummy none button
+ state.mNumAxes = 2;
+ state.mNumHaptics = 0;
}
VRControllerGVR::~VRControllerGVR()
{
MOZ_COUNT_DTOR_INHERITED(VRControllerGVR, VRControllerHost);
}
void
--- a/gfx/vr/gfxVROSVR.cpp
+++ b/gfx/vr/gfxVROSVR.cpp
@@ -208,64 +208,65 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_Client
: VRDisplayHost(VRDeviceType::OSVR)
, m_ctx(context)
, m_iface(iface)
, m_display(display)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOSVR, VRDisplayHost);
- mDisplayInfo.mIsConnected = true;
- mDisplayInfo.mDisplayName.AssignLiteral("OSVR HMD");
- mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None;
- mDisplayInfo.mCapabilityFlags =
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+ state.mIsConnected = true;
+ strncpy(state.mDisplayName, "OSVR HMD", kVRDisplayNameMaxLen);
+ state.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None;
+ state.mCapabilityFlags =
VRDisplayCapabilityFlags::Cap_Orientation | VRDisplayCapabilityFlags::Cap_Position;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
// XXX OSVR display topology allows for more than one viewer
// will assume only one viewer for now (most likely stay that way)
OSVR_EyeCount numEyes;
osvr_ClientGetNumEyesForViewer(*m_display, 0, &numEyes);
for (uint8_t eye = 0; eye < numEyes; eye++) {
double left, right, bottom, top;
// XXX for now there is only one surface per eye
osvr_ClientGetViewerEyeSurfaceProjectionClippingPlanes(
*m_display, 0, eye, 0, &left, &right, &bottom, &top);
- mDisplayInfo.mEyeFOV[eye] =
+ state.mEyeFOV[eye] =
SetFromTanRadians(-left, right, -bottom, top);
}
// XXX Assuming there is only one display input for now
// however, it's possible to have more than one (dSight with 2 HDMI inputs)
OSVR_DisplayDimension width, height;
osvr_ClientGetDisplayDimensions(*m_display, 0, &width, &height);
for (uint8_t eye = 0; eye < numEyes; eye++) {
OSVR_ViewportDimension l, b, w, h;
osvr_ClientGetRelativeViewportForViewerEyeSurface(*m_display, 0, eye, 0, &l,
&b, &w, &h);
- mDisplayInfo.mEyeResolution.width = w;
- mDisplayInfo.mEyeResolution.height = h;
+ state.mEyeResolution.width = w;
+ state.mEyeResolution.height = h;
OSVR_Pose3 eyePose;
// Viewer eye pose may not be immediately available, update client context until we get it
OSVR_ReturnCode ret =
osvr_ClientGetViewerEyePose(*m_display, 0, eye, &eyePose);
while (ret != OSVR_RETURN_SUCCESS) {
osvr_ClientUpdate(*m_ctx);
ret = osvr_ClientGetViewerEyePose(*m_display, 0, eye, &eyePose);
}
- mDisplayInfo.mEyeTranslation[eye].x = eyePose.translation.data[0];
- mDisplayInfo.mEyeTranslation[eye].y = eyePose.translation.data[1];
- mDisplayInfo.mEyeTranslation[eye].z = eyePose.translation.data[2];
+ state.mEyeTranslation[eye].x = eyePose.translation.data[0];
+ state.mEyeTranslation[eye].y = eyePose.translation.data[1];
+ state.mEyeTranslation[eye].z = eyePose.translation.data[2];
Matrix4x4 pose;
pose.SetRotationFromQuaternion(gfx::Quaternion(osvrQuatGetX(&eyePose.rotation),
osvrQuatGetY(&eyePose.rotation),
osvrQuatGetZ(&eyePose.rotation),
osvrQuatGetW(&eyePose.rotation)));
pose.PreTranslate(eyePose.translation.data[0], eyePose.translation.data[1], eyePose.translation.data[2]);
pose.Invert();
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -801,54 +801,54 @@ VRDisplayOculus::VRDisplayOculus(VROculu
, mLinearSamplerState(nullptr)
, mVSConstantBuffer(nullptr)
, mPSConstantBuffer(nullptr)
, mVertexBuffer(nullptr)
, mInputLayout(nullptr)
, mEyeHeight(OVR_DEFAULT_EYE_HEIGHT)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
-
- mDisplayInfo.mDisplayName.AssignLiteral("Oculus VR HMD");
- mDisplayInfo.mIsConnected = true;
- mDisplayInfo.mIsMounted = false;
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+ strncpy(state.mDisplayName, "Oculus VR HMD", kVRDisplayNameMaxLen);
+ state.mIsConnected = true;
+ state.mIsMounted = false;
mDesc = ovr_GetHmdDesc(aSession->Get());
- mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None;
+ state.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None;
if (mDesc.AvailableTrackingCaps & ovrTrackingCap_Orientation) {
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Orientation;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Orientation;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
}
if (mDesc.AvailableTrackingCaps & ovrTrackingCap_Position) {
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Position;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_StageParameters;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Position;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_StageParameters;
}
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
- mFOVPort[VRDisplayInfo::Eye_Left] = mDesc.DefaultEyeFov[ovrEye_Left];
- mFOVPort[VRDisplayInfo::Eye_Right] = mDesc.DefaultEyeFov[ovrEye_Right];
+ mFOVPort[VRDisplayState::Eye_Left] = mDesc.DefaultEyeFov[ovrEye_Left];
+ mFOVPort[VRDisplayState::Eye_Right] = mDesc.DefaultEyeFov[ovrEye_Right];
- mDisplayInfo.mEyeFOV[VRDisplayInfo::Eye_Left] = FromFovPort(mFOVPort[VRDisplayInfo::Eye_Left]);
- mDisplayInfo.mEyeFOV[VRDisplayInfo::Eye_Right] = FromFovPort(mFOVPort[VRDisplayInfo::Eye_Right]);
+ state.mEyeFOV[VRDisplayState::Eye_Left] = FromFovPort(mFOVPort[VRDisplayState::Eye_Left]);
+ state.mEyeFOV[VRDisplayState::Eye_Right] = FromFovPort(mFOVPort[VRDisplayState::Eye_Right]);
float pixelsPerDisplayPixel = 1.0;
ovrSizei texSize[2];
// get eye texture sizes
- for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
+ for (uint32_t eye = 0; eye < VRDisplayState::NumEyes; eye++) {
texSize[eye] = ovr_GetFovTextureSize(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye], pixelsPerDisplayPixel);
}
// take the max of both for eye resolution
- mDisplayInfo.mEyeResolution.width = std::max(texSize[VRDisplayInfo::Eye_Left].w, texSize[VRDisplayInfo::Eye_Right].w);
- mDisplayInfo.mEyeResolution.height = std::max(texSize[VRDisplayInfo::Eye_Left].h, texSize[VRDisplayInfo::Eye_Right].h);
+ state.mEyeResolution.width = std::max(texSize[VRDisplayState::Eye_Left].w, texSize[VRDisplayState::Eye_Right].w);
+ state.mEyeResolution.height = std::max(texSize[VRDisplayState::Eye_Left].h, texSize[VRDisplayState::Eye_Right].h);
UpdateEyeParameters();
UpdateStageParameters();
}
VRDisplayOculus::~VRDisplayOculus() {
Destroy();
MOZ_COUNT_DTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
@@ -861,73 +861,75 @@ VRDisplayOculus::Destroy()
mSession = nullptr;
}
void
VRDisplayOculus::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = nullptr */)
{
// Note this must be called every frame, as the IPD adjustment can be changed
// by the user during a VR session.
- for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
+ for (uint32_t eye = 0; eye < VRDisplayState::NumEyes; eye++) {
// As of Oculus 1.17 SDK, we must use the ovr_GetRenderDesc2 function to return the updated
// version of ovrEyeRenderDesc. This is normally done by the Oculus static lib shim, but we
// need to do this explicitly as we are loading the Oculus runtime dll directly.
ovrEyeRenderDesc renderDesc = ovr_GetRenderDesc2(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye]);
- mDisplayInfo.mEyeTranslation[eye].x = renderDesc.HmdToEyePose.Position.x;
- mDisplayInfo.mEyeTranslation[eye].y = renderDesc.HmdToEyePose.Position.y;
- mDisplayInfo.mEyeTranslation[eye].z = renderDesc.HmdToEyePose.Position.z;
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+ state.mEyeTranslation[eye].x = renderDesc.HmdToEyePose.Position.x;
+ state.mEyeTranslation[eye].y = renderDesc.HmdToEyePose.Position.y;
+ state.mEyeTranslation[eye].z = renderDesc.HmdToEyePose.Position.z;
if (aHeadToEyeTransforms) {
Matrix4x4 pose;
pose.SetRotationFromQuaternion(gfx::Quaternion(renderDesc.HmdToEyePose.Orientation.x, renderDesc.HmdToEyePose.Orientation.y, renderDesc.HmdToEyePose.Orientation.z, renderDesc.HmdToEyePose.Orientation.w));
pose.PreTranslate(renderDesc.HmdToEyePose.Position.x, renderDesc.HmdToEyePose.Position.y, renderDesc.HmdToEyePose.Position.z);
pose.Invert();
aHeadToEyeTransforms[eye] = pose;
}
}
}
void
VRDisplayOculus::UpdateStageParameters()
{
if (!mSession->IsTrackingReady()) {
return;
}
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
ovrVector3f playArea;
ovrResult res = ovr_GetBoundaryDimensions(mSession->Get(), ovrBoundary_PlayArea, &playArea);
if (res == ovrSuccess) {
- mDisplayInfo.mStageSize.width = playArea.x;
- mDisplayInfo.mStageSize.height = playArea.z;
+ state.mStageSize.width = playArea.x;
+ state.mStageSize.height = playArea.z;
} else {
// If we fail, fall back to reasonable defaults.
// 1m x 1m space
- mDisplayInfo.mStageSize.width = 1.0f;
- mDisplayInfo.mStageSize.height = 1.0f;
+ state.mStageSize.width = 1.0f;
+ state.mStageSize.height = 1.0f;
}
mEyeHeight = ovr_GetFloat(mSession->Get(), OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
- mDisplayInfo.mSittingToStandingTransform._11 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._12 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._13 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._14 = 0.0f;
+ state.mSittingToStandingTransform[0] = 1.0f;
+ state.mSittingToStandingTransform[1] = 0.0f;
+ state.mSittingToStandingTransform[2] = 0.0f;
+ state.mSittingToStandingTransform[3] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._21 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._22 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._23 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._24 = 0.0f;
+ state.mSittingToStandingTransform[4] = 0.0f;
+ state.mSittingToStandingTransform[5] = 1.0f;
+ state.mSittingToStandingTransform[6] = 0.0f;
+ state.mSittingToStandingTransform[7] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._31 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._32 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._33 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._34 = 0.0f;
+ state.mSittingToStandingTransform[8] = 0.0f;
+ state.mSittingToStandingTransform[9] = 0.0f;
+ state.mSittingToStandingTransform[10] = 1.0f;
+ state.mSittingToStandingTransform[11] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._41 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._42 = mEyeHeight;
- mDisplayInfo.mSittingToStandingTransform._43 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._44 = 1.0f;
+ state.mSittingToStandingTransform[12] = 0.0f;
+ state.mSittingToStandingTransform[13] = mEyeHeight;
+ state.mSittingToStandingTransform[14] = 0.0f;
+ state.mSittingToStandingTransform[15] = 1.0f;
}
void
VRDisplayOculus::ZeroSensor()
{
if (!mSession->IsTrackingReady()) {
return;
}
@@ -1014,17 +1016,17 @@ VRDisplayOculus::GetSensorState(double a
}
void
VRDisplayOculus::StartPresentation()
{
if (!CreateD3DObjects()) {
return;
}
- mSession->StartPresentation(IntSize(mDisplayInfo.mEyeResolution.width * 2, mDisplayInfo.mEyeResolution.height));
+ mSession->StartPresentation(IntSize(mDisplayInfo.mDisplayState.mEyeResolution.width * 2, mDisplayInfo.mDisplayState.mEyeResolution.height));
if (!mSession->IsPresentationReady()) {
return;
}
if (!mQuadVS) {
if (FAILED(mDevice->CreateVertexShader(sLayerQuadVS.mData, sLayerQuadVS.mLength, nullptr, &mQuadVS))) {
NS_WARNING("Failed to create vertex shader for Oculus");
return;
@@ -1294,52 +1296,55 @@ VRDisplayOculus::SubmitFrame(ID3D11Textu
mSession->mSubmitThread = mSubmitThread;
return true;
}
void
VRDisplayOculus::Refresh()
{
- mDisplayInfo.mIsConnected = mSession->IsTrackingReady();
- mDisplayInfo.mIsMounted = mSession->IsMounted();
+ mDisplayInfo.mDisplayState.mIsConnected = mSession->IsTrackingReady();
+ mDisplayInfo.mDisplayState.mIsMounted = mSession->IsMounted();
}
VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand, uint32_t aDisplayID)
: VRControllerHost(VRDeviceType::Oculus, aHand, aDisplayID)
, mIndexTrigger(0.0f)
, mHandTrigger(0.0f)
, mVibrateThread(nullptr)
, mIsVibrateStopped(false)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
+ VRControllerState& state = mControllerInfo.mControllerState;
+
char* touchID = "";
switch (aHand) {
case dom::GamepadHand::Left:
touchID = "Oculus Touch (Left)";
break;
case dom::GamepadHand::Right:
touchID = "Oculus Touch (Right)";
break;
default:
MOZ_ASSERT(false);
break;
}
- mControllerInfo.mControllerName = touchID;
+
+ strncpy(state.mControllerName, touchID, kVRControllerNameMaxLen);
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);
- mControllerInfo.mNumHaptics = kNumOculusHaptcs;
+ state.mNumButtons = kNumOculusButton;
+ state.mNumAxes = static_cast<uint32_t>(
+ OculusControllerAxisType::NumVRControllerAxisType);
+ state.mNumHaptics = kNumOculusHaptcs;
}
float
VRControllerOculus::GetAxisMove(uint32_t aAxis)
{
return mAxisMove[aAxis];
}
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -53,46 +53,48 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::I
: VRDisplayHost(VRDeviceType::OpenVR)
, mVRSystem(aVRSystem)
, mVRChaperone(aVRChaperone)
, mVRCompositor(aVRCompositor)
, mIsPresenting(false)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOpenVR, VRDisplayHost);
- mDisplayInfo.mDisplayName.AssignLiteral("OpenVR HMD");
- mDisplayInfo.mIsConnected = mVRSystem->IsTrackedDeviceConnected(::vr::k_unTrackedDeviceIndex_Hmd);
- mDisplayInfo.mIsMounted = false;
- mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
- VRDisplayCapabilityFlags::Cap_Orientation |
- VRDisplayCapabilityFlags::Cap_Position |
- VRDisplayCapabilityFlags::Cap_External |
- VRDisplayCapabilityFlags::Cap_Present |
- VRDisplayCapabilityFlags::Cap_StageParameters;
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+
+ strncpy(state.mDisplayName, "OpenVR HMD", kVRDisplayNameMaxLen);
+ state.mIsConnected = mVRSystem->IsTrackedDeviceConnected(::vr::k_unTrackedDeviceIndex_Hmd);
+ state.mIsMounted = false;
+ state.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
+ VRDisplayCapabilityFlags::Cap_Orientation |
+ VRDisplayCapabilityFlags::Cap_Position |
+ VRDisplayCapabilityFlags::Cap_External |
+ VRDisplayCapabilityFlags::Cap_Present |
+ VRDisplayCapabilityFlags::Cap_StageParameters;
mIsHmdPresent = ::vr::VR_IsHmdPresent();
::vr::ETrackedPropertyError err;
bool bHasProximitySensor = mVRSystem->GetBoolTrackedDeviceProperty(::vr::k_unTrackedDeviceIndex_Hmd, ::vr::Prop_ContainsProximitySensor_Bool, &err);
if (err == ::vr::TrackedProp_Success && bHasProximitySensor) {
- mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
+ state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
}
mVRCompositor->SetTrackingSpace(::vr::TrackingUniverseSeated);
uint32_t w, h;
mVRSystem->GetRecommendedRenderTargetSize(&w, &h);
- mDisplayInfo.mEyeResolution.width = w;
- mDisplayInfo.mEyeResolution.height = h;
+ state.mEyeResolution.width = w;
+ state.mEyeResolution.height = h;
// SteamVR gives the application a single FOV to use; it's not configurable as with Oculus
for (uint32_t eye = 0; eye < 2; ++eye) {
// get l/r/t/b clip plane coordinates
float l, r, t, b;
mVRSystem->GetProjectionRaw(static_cast<::vr::Hmd_Eye>(eye), &l, &r, &t, &b);
- mDisplayInfo.mEyeFOV[eye].SetFromTanRadians(-t, r, b, -l);
+ state.mEyeFOV[eye].SetFromTanRadians(-t, r, b, -l);
}
UpdateEyeParameters();
UpdateStageParameters();
}
VRDisplayOpenVR::~VRDisplayOpenVR()
{
Destroy();
@@ -106,22 +108,22 @@ VRDisplayOpenVR::Destroy()
::vr::VR_Shutdown();
}
void
VRDisplayOpenVR::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = nullptr */)
{
// Note this must be called every frame, as the IPD adjustment can be changed
// by the user during a VR session.
- for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
+ for (uint32_t eye = 0; eye < VRDisplayState::NumEyes; eye++) {
::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye));
- mDisplayInfo.mEyeTranslation[eye].x = eyeToHead.m[0][3];
- mDisplayInfo.mEyeTranslation[eye].y = eyeToHead.m[1][3];
- mDisplayInfo.mEyeTranslation[eye].z = eyeToHead.m[2][3];
+ mDisplayInfo.mDisplayState.mEyeTranslation[eye].x = eyeToHead.m[0][3];
+ mDisplayInfo.mDisplayState.mEyeTranslation[eye].y = eyeToHead.m[1][3];
+ mDisplayInfo.mDisplayState.mEyeTranslation[eye].z = eyeToHead.m[2][3];
if (aHeadToEyeTransforms) {
Matrix4x4 pose;
// NOTE! eyeToHead.m is a 3x4 matrix, not 4x4. But
// because of its arrangement, we can copy the 12 elements in and
// then transpose them to the right place.
memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m));
pose.Transpose();
@@ -129,68 +131,69 @@ VRDisplayOpenVR::UpdateEyeParameters(gfx
aHeadToEyeTransforms[eye] = pose;
}
}
}
void
VRDisplayOpenVR::UpdateStageParameters()
{
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
float sizeX = 0.0f;
float sizeZ = 0.0f;
if (mVRChaperone->GetPlayAreaSize(&sizeX, &sizeZ)) {
::vr::HmdMatrix34_t t = mVRSystem->GetSeatedZeroPoseToStandingAbsoluteTrackingPose();
- mDisplayInfo.mStageSize.width = sizeX;
- mDisplayInfo.mStageSize.height = sizeZ;
+ state.mStageSize.width = sizeX;
+ state.mStageSize.height = sizeZ;
- mDisplayInfo.mSittingToStandingTransform._11 = t.m[0][0];
- mDisplayInfo.mSittingToStandingTransform._12 = t.m[1][0];
- mDisplayInfo.mSittingToStandingTransform._13 = t.m[2][0];
- mDisplayInfo.mSittingToStandingTransform._14 = 0.0f;
+ state.mSittingToStandingTransform[0] = t.m[0][0];
+ state.mSittingToStandingTransform[1] = t.m[1][0];
+ state.mSittingToStandingTransform[2] = t.m[2][0];
+ state.mSittingToStandingTransform[3] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._21 = t.m[0][1];
- mDisplayInfo.mSittingToStandingTransform._22 = t.m[1][1];
- mDisplayInfo.mSittingToStandingTransform._23 = t.m[2][1];
- mDisplayInfo.mSittingToStandingTransform._24 = 0.0f;
+ state.mSittingToStandingTransform[4] = t.m[0][1];
+ state.mSittingToStandingTransform[5] = t.m[1][1];
+ state.mSittingToStandingTransform[6] = t.m[2][1];
+ state.mSittingToStandingTransform[7] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._31 = t.m[0][2];
- mDisplayInfo.mSittingToStandingTransform._32 = t.m[1][2];
- mDisplayInfo.mSittingToStandingTransform._33 = t.m[2][2];
- mDisplayInfo.mSittingToStandingTransform._34 = 0.0f;
+ state.mSittingToStandingTransform[8] = t.m[0][2];
+ state.mSittingToStandingTransform[9] = t.m[1][2];
+ state.mSittingToStandingTransform[10] = t.m[2][2];
+ state.mSittingToStandingTransform[11] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._41 = t.m[0][3];
- mDisplayInfo.mSittingToStandingTransform._42 = t.m[1][3];
- mDisplayInfo.mSittingToStandingTransform._43 = t.m[2][3];
- mDisplayInfo.mSittingToStandingTransform._44 = 1.0f;
+ state.mSittingToStandingTransform[12] = t.m[0][3];
+ state.mSittingToStandingTransform[13] = t.m[1][3];
+ state.mSittingToStandingTransform[14] = t.m[2][3];
+ state.mSittingToStandingTransform[15] = 1.0f;
} else {
// If we fail, fall back to reasonable defaults.
// 1m x 1m space, 0.75m high in seated position
- mDisplayInfo.mStageSize.width = 1.0f;
- mDisplayInfo.mStageSize.height = 1.0f;
+ state.mStageSize.width = 1.0f;
+ state.mStageSize.height = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._11 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._12 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._13 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._14 = 0.0f;
+ state.mSittingToStandingTransform[0] = 1.0f;
+ state.mSittingToStandingTransform[1] = 0.0f;
+ state.mSittingToStandingTransform[2] = 0.0f;
+ state.mSittingToStandingTransform[3] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._21 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._22 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._23 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._24 = 0.0f;
+ state.mSittingToStandingTransform[4] = 0.0f;
+ state.mSittingToStandingTransform[5] = 1.0f;
+ state.mSittingToStandingTransform[6] = 0.0f;
+ state.mSittingToStandingTransform[7] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._31 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._32 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._33 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._34 = 0.0f;
+ state.mSittingToStandingTransform[9] = 0.0f;
+ state.mSittingToStandingTransform[10] = 0.0f;
+ state.mSittingToStandingTransform[11] = 1.0f;
+ state.mSittingToStandingTransform[12] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._41 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._42 = 0.75f;
- mDisplayInfo.mSittingToStandingTransform._43 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._44 = 1.0f;
+ state.mSittingToStandingTransform[13] = 0.0f;
+ state.mSittingToStandingTransform[14] = 0.75f;
+ state.mSittingToStandingTransform[15] = 0.0f;
+ state.mSittingToStandingTransform[16] = 1.0f;
}
}
void
VRDisplayOpenVR::ZeroSensor()
{
mVRSystem->ResetSeatedZeroPose();
UpdateStageParameters();
@@ -207,32 +210,32 @@ VRDisplayOpenVR::Refresh()
{
mIsHmdPresent = ::vr::VR_IsHmdPresent();
::vr::VREvent_t event;
while (mVRSystem && mVRSystem->PollNextEvent(&event, sizeof(event))) {
switch (event.eventType) {
case ::vr::VREvent_TrackedDeviceUserInteractionStarted:
if (event.trackedDeviceIndex == ::vr::k_unTrackedDeviceIndex_Hmd) {
- mDisplayInfo.mIsMounted = true;
+ mDisplayInfo.mDisplayState.mIsMounted = true;
}
break;
case ::vr::VREvent_TrackedDeviceUserInteractionEnded:
if (event.trackedDeviceIndex == ::vr::k_unTrackedDeviceIndex_Hmd) {
- mDisplayInfo.mIsMounted = false;
+ mDisplayInfo.mDisplayState.mIsMounted = false;
}
break;
case ::vr::EVREventType::VREvent_TrackedDeviceActivated:
if (event.trackedDeviceIndex == ::vr::k_unTrackedDeviceIndex_Hmd) {
- mDisplayInfo.mIsConnected = true;
+ mDisplayInfo.mDisplayState.mIsConnected = true;
}
break;
case ::vr::EVREventType::VREvent_TrackedDeviceDeactivated:
if (event.trackedDeviceIndex == ::vr::k_unTrackedDeviceIndex_Hmd) {
- mDisplayInfo.mIsConnected = false;
+ mDisplayInfo.mDisplayState.mIsConnected = false;
}
break;
case ::vr::EVREventType::VREvent_DriverRequestedQuit:
case ::vr::EVREventType::VREvent_Quit:
case ::vr::EVREventType::VREvent_ProcessQuit:
case ::vr::EVREventType::VREvent_QuitAcknowledged:
case ::vr::EVREventType::VREvent_QuitAborted_UserPrompt:
mIsHmdPresent = false;
@@ -423,29 +426,27 @@ VRDisplayOpenVR::SubmitFrame(MacIOSurfac
}
#endif
VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplayID,
uint32_t aNumButtons, uint32_t aNumTriggers,
uint32_t aNumAxes, const nsCString& aId)
: VRControllerHost(VRDeviceType::OpenVR, aHand, aDisplayID)
- , mTrigger(aNumTriggers)
- , mAxisMove(aNumAxes)
, mVibrateThread(nullptr)
, mIsVibrateStopped(false)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
- mAxisMove.SetLengthAndRetainStorage(aNumAxes);
- mTrigger.SetLengthAndRetainStorage(aNumTriggers);
- mControllerInfo.mControllerName = aId;
- mControllerInfo.mNumButtons = aNumButtons;
- mControllerInfo.mNumAxes = aNumAxes;
- mControllerInfo.mNumHaptics = kNumOpenVRHaptcs;
+ VRControllerState& state = mControllerInfo.mControllerState;
+ strncpy(state.mControllerName, aId.BeginReading(), kVRControllerNameMaxLen);
+ state.mNumButtons = aNumButtons;
+ state.mNumAxes = aNumAxes;
+ state.mNumTriggers = aNumTriggers;
+ state.mNumHaptics = kNumOpenVRHaptcs;
}
VRControllerOpenVR::~VRControllerOpenVR()
{
ShutdownVibrateHapticThread();
MOZ_COUNT_DTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
}
@@ -459,41 +460,41 @@ uint32_t
VRControllerOpenVR::GetTrackedIndex()
{
return mTrackedIndex;
}
float
VRControllerOpenVR::GetAxisMove(uint32_t aAxis)
{
- return mAxisMove[aAxis];
+ return mControllerInfo.mControllerState.mAxisValue[aAxis];
}
void
VRControllerOpenVR::SetAxisMove(uint32_t aAxis, float aValue)
{
- mAxisMove[aAxis] = aValue;
+ mControllerInfo.mControllerState.mAxisValue[aAxis] = aValue;
}
void
VRControllerOpenVR::SetTrigger(uint32_t aButton, float aValue)
{
- mTrigger[aButton] = aValue;
+ mControllerInfo.mControllerState.mTriggerValue[aButton] = aValue;
}
float
VRControllerOpenVR::GetTrigger(uint32_t aButton)
{
- return mTrigger[aButton];
+ return mControllerInfo.mControllerState.mTriggerValue[aButton];
}
void
VRControllerOpenVR::SetHand(dom::GamepadHand aHand)
{
- mControllerInfo.mHand = aHand;
+ mControllerInfo.mControllerState.mHand = aHand;
}
void
VRControllerOpenVR::UpdateVibrateHaptic(::vr::IVRSystem* aVRSystem,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint64_t aVibrateIndex,
--- a/gfx/vr/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -107,18 +107,16 @@ private:
double aIntensity,
double aDuration,
uint64_t aVibrateIndex,
const VRManagerPromise& aPromise);
void VibrateHapticComplete(const VRManagerPromise& aPromise);
// The index of tracked devices from ::vr::IVRSystem.
uint32_t mTrackedIndex;
- nsTArray<float> mTrigger;
- nsTArray<float> mAxisMove;
RefPtr<VRThread> mVibrateThread;
Atomic<bool> mIsVibrateStopped;
};
} // namespace impl
class VRSystemManagerOpenVR : public VRSystemManager
{
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -51,58 +51,60 @@ static const uint32_t kNumPuppetHaptcs =
VRDisplayPuppet::VRDisplayPuppet()
: VRDisplayHost(VRDeviceType::Puppet)
, mIsPresenting(false)
, mSensorState{}
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayPuppet, VRDisplayHost);
- mDisplayInfo.mDisplayName.AssignLiteral("Puppet HMD");
- mDisplayInfo.mIsConnected = true;
- mDisplayInfo.mIsMounted = false;
- mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
- VRDisplayCapabilityFlags::Cap_Orientation |
- VRDisplayCapabilityFlags::Cap_Position |
- VRDisplayCapabilityFlags::Cap_External |
- VRDisplayCapabilityFlags::Cap_Present |
- VRDisplayCapabilityFlags::Cap_StageParameters;
- mDisplayInfo.mEyeResolution.width = 1836; // 1080 * 1.7
- mDisplayInfo.mEyeResolution.height = 2040; // 1200 * 1.7
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+ strncpy(state.mDisplayName, "Puppet HMD", kVRDisplayNameMaxLen);
+ state.mIsConnected = true;
+ state.mIsMounted = false;
+ state.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
+ VRDisplayCapabilityFlags::Cap_Orientation |
+ VRDisplayCapabilityFlags::Cap_Position |
+ VRDisplayCapabilityFlags::Cap_External |
+ VRDisplayCapabilityFlags::Cap_Present |
+ VRDisplayCapabilityFlags::Cap_StageParameters;
+ state.mEyeResolution.width = 1836; // 1080 * 1.7
+ state.mEyeResolution.height = 2040; // 1200 * 1.7
// SteamVR gives the application a single FOV to use; it's not configurable as with Oculus
for (uint32_t eye = 0; eye < 2; ++eye) {
- mDisplayInfo.mEyeTranslation[eye].x = 0.0f;
- mDisplayInfo.mEyeTranslation[eye].y = 0.0f;
- mDisplayInfo.mEyeTranslation[eye].z = 0.0f;
- mDisplayInfo.mEyeFOV[eye] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
+ state.mEyeTranslation[eye].x = 0.0f;
+ state.mEyeTranslation[eye].y = 0.0f;
+ state.mEyeTranslation[eye].z = 0.0f;
+ state.mEyeFOV[eye] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
}
// default: 1m x 1m space, 0.75m high in seated position
- mDisplayInfo.mStageSize.width = 1.0f;
- mDisplayInfo.mStageSize.height = 1.0f;
+ state.mStageSize.width = 1.0f;
+ state.mStageSize.height = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._11 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._12 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._13 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._14 = 0.0f;
+ state.mSittingToStandingTransform[0] = 1.0f;
+ state.mSittingToStandingTransform[1] = 0.0f;
+ state.mSittingToStandingTransform[2] = 0.0f;
+ state.mSittingToStandingTransform[3] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._21 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._22 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._23 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._24 = 0.0f;
+ state.mSittingToStandingTransform[4] = 0.0f;
+ state.mSittingToStandingTransform[5] = 1.0f;
+ state.mSittingToStandingTransform[6] = 0.0f;
+ state.mSittingToStandingTransform[7] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._31 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._32 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._33 = 1.0f;
- mDisplayInfo.mSittingToStandingTransform._34 = 0.0f;
+ state.mSittingToStandingTransform[8] = 0.0f;
+ state.mSittingToStandingTransform[9] = 0.0f;
+ state.mSittingToStandingTransform[10] = 1.0f;
+ state.mSittingToStandingTransform[11] = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._41 = 0.0f;
- mDisplayInfo.mSittingToStandingTransform._42 = 0.75f;
- mDisplayInfo.mSittingToStandingTransform._43 = 0.0f;
+ state.mSittingToStandingTransform[12] = 0.0f;
+ state.mSittingToStandingTransform[13] = 0.75f;
+ state.mSittingToStandingTransform[14] = 0.0f;
+ state.mSittingToStandingTransform[15] = 1.0f;
gfx::Quaternion rot;
mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
mSensorState.orientation[0] = rot.x;
mSensorState.orientation[1] = rot.y;
mSensorState.orientation[2] = rot.z;
mSensorState.orientation[3] = rot.w;
@@ -123,22 +125,23 @@ VRDisplayPuppet::~VRDisplayPuppet()
{
MOZ_COUNT_DTOR_INHERITED(VRDisplayPuppet, VRDisplayHost);
}
void
VRDisplayPuppet::SetDisplayInfo(const VRDisplayInfo& aDisplayInfo)
{
// We are only interested in the eye and mount info of the display info.
- mDisplayInfo.mEyeResolution = aDisplayInfo.mEyeResolution;
- mDisplayInfo.mIsMounted = aDisplayInfo.mIsMounted;
- memcpy(&mDisplayInfo.mEyeFOV, &aDisplayInfo.mEyeFOV,
- sizeof(mDisplayInfo.mEyeFOV[0]) * VRDisplayInfo::NumEyes);
- memcpy(&mDisplayInfo.mEyeTranslation, &aDisplayInfo.mEyeTranslation,
- sizeof(mDisplayInfo.mEyeTranslation[0]) * VRDisplayInfo::NumEyes);
+ VRDisplayState& state = mDisplayInfo.mDisplayState;
+ state.mEyeResolution = aDisplayInfo.mDisplayState.mEyeResolution;
+ state.mIsMounted = aDisplayInfo.mDisplayState.mIsMounted;
+ memcpy(&state.mEyeFOV, &aDisplayInfo.mDisplayState.mEyeFOV,
+ sizeof(state.mEyeFOV[0]) * VRDisplayState::NumEyes);
+ memcpy(&state.mEyeTranslation, &aDisplayInfo.mDisplayState.mEyeTranslation,
+ sizeof(state.mEyeTranslation[0]) * VRDisplayState::NumEyes);
}
void
VRDisplayPuppet::Destroy()
{
StopPresentation();
}
@@ -149,17 +152,17 @@ VRDisplayPuppet::ZeroSensor()
VRHMDSensorState
VRDisplayPuppet::GetSensorState()
{
mSensorState.inputFrameID = mDisplayInfo.mFrameId;
Matrix4x4 matHeadToEye[2];
for (uint32_t eye = 0; eye < 2; ++eye) {
- matHeadToEye[eye].PreTranslate(mDisplayInfo.mEyeTranslation[eye]);
+ matHeadToEye[eye].PreTranslate(mDisplayInfo.GetEyeTranslation(eye));
}
mSensorState.CalcViewMatrices(matHeadToEye);
return mSensorState;
}
void
VRDisplayPuppet::SetSensorState(const VRHMDSensorState& aSensorState)
@@ -567,29 +570,30 @@ VRDisplayPuppet::SubmitFrame(const mozil
}
#endif
void
VRDisplayPuppet::Refresh()
{
// We update mIsConneced once per refresh.
- mDisplayInfo.mIsConnected = true;
+ mDisplayInfo.mDisplayState.mIsConnected = true;
}
VRControllerPuppet::VRControllerPuppet(dom::GamepadHand aHand, uint32_t aDisplayID)
: VRControllerHost(VRDeviceType::Puppet, aHand, aDisplayID)
, mButtonPressState(0)
, mButtonTouchState(0)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerPuppet, VRControllerHost);
- mControllerInfo.mControllerName.AssignLiteral("Puppet Gamepad");
- mControllerInfo.mNumButtons = kNumPuppetButtonMask;
- mControllerInfo.mNumAxes = kNumPuppetAxis;
- mControllerInfo.mNumHaptics = kNumPuppetHaptcs;
+ VRControllerState& state = mControllerInfo.mControllerState;
+ strncpy(state.mControllerName, "Puppet Gamepad", kVRControllerNameMaxLen);
+ state.mNumButtons = kNumPuppetButtonMask;
+ state.mNumAxes = kNumPuppetAxis;
+ state.mNumHaptics = kNumPuppetHaptcs;
}
VRControllerPuppet::~VRControllerPuppet()
{
MOZ_COUNT_DTOR_INHERITED(VRControllerPuppet, VRControllerHost);
}
void
@@ -663,23 +667,23 @@ const dom::GamepadPoseState&
VRControllerPuppet::GetPoseMoveState()
{
return mPoseState;
}
float
VRControllerPuppet::GetAxisMove(uint32_t aAxis)
{
- return mAxisMove[aAxis];
+ return mControllerInfo.mControllerState.mAxisValue[aAxis];
}
void
VRControllerPuppet::SetAxisMove(uint32_t aAxis, float aValue)
{
- mAxisMove[aAxis] = aValue;
+ mControllerInfo.mControllerState.mAxisValue[aAxis] = aValue;
}
VRSystemManagerPuppet::VRSystemManagerPuppet()
: mPuppetDisplayCount(0)
, mPuppetDisplayInfo{}
, mPuppetDisplaySensorState{}
{
}
--- a/gfx/vr/gfxVRPuppet.h
+++ b/gfx/vr/gfxVRPuppet.h
@@ -93,17 +93,16 @@ public:
protected:
virtual ~VRControllerPuppet();
private:
uint64_t mButtonPressState;
uint64_t mButtonTouchState;
float mAxisMoveState[3];
- float mAxisMove[3];
dom::GamepadPoseState mPoseState;
};
} // namespace impl
class VRSystemManagerPuppet : public VRSystemManager
{
public:
--- a/gfx/vr/ipc/VRMessageUtils.h
+++ b/gfx/vr/ipc/VRMessageUtils.h
@@ -22,67 +22,111 @@ struct ParamTraits<mozilla::gfx::VRDevic
mozilla::gfx::VRDeviceType(mozilla::gfx::VRDeviceType::NumVRDeviceTypes)> {};
template<>
struct ParamTraits<mozilla::gfx::VRDisplayCapabilityFlags> :
public BitFlagsEnumSerializer<mozilla::gfx::VRDisplayCapabilityFlags,
mozilla::gfx::VRDisplayCapabilityFlags::Cap_All> {};
template <>
+struct ParamTraits<mozilla::gfx::VRDisplayState>
+{
+ typedef mozilla::gfx::VRDisplayState paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ // TODO - VRDisplayState is asserted to be a POD type
+ // A simple memcpy may be sufficient here, or
+ // this code can be refactored out if we use
+ // shmem between the VR and content process.
+ nsCString displayName;
+ displayName.Assign(aParam.mDisplayName); // FINDME!! HACK! - Bounds checking?
+ WriteParam(aMsg, displayName);
+ WriteParam(aMsg, aParam.mCapabilityFlags);
+ WriteParam(aMsg, aParam.mEyeResolution.width);
+ WriteParam(aMsg, aParam.mEyeResolution.height);
+ WriteParam(aMsg, aParam.mIsConnected);
+ WriteParam(aMsg, aParam.mIsMounted);
+ WriteParam(aMsg, aParam.mStageSize.width);
+ WriteParam(aMsg, aParam.mStageSize.height);
+ for (int i = 0; i < 16; i++) {
+ // TODO - Should probably memcpy the whole array or
+ // convert Maxtrix4x4 to a POD type and use it
+ // instead
+ WriteParam(aMsg, aParam.mSittingToStandingTransform[i]);
+ }
+ for (int i = 0; i < mozilla::gfx::VRDisplayState::NumEyes; i++) {
+ WriteParam(aMsg, aParam.mEyeFOV[i]);
+ WriteParam(aMsg, aParam.mEyeTranslation[i].x);
+ WriteParam(aMsg, aParam.mEyeTranslation[i].y);
+ WriteParam(aMsg, aParam.mEyeTranslation[i].z);
+ }
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+ {
+ nsCString displayName;
+ if (!ReadParam(aMsg, aIter, &(displayName)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mCapabilityFlags)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mEyeResolution.width)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mEyeResolution.height)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mIsConnected)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mIsMounted)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mStageSize.width)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mStageSize.height))) {
+ return false;
+ }
+ for (int i = 0; i < 16; i++) {
+ if (!ReadParam(aMsg, aIter, &(aResult->mSittingToStandingTransform[i]))) {
+ return false;
+ }
+ }
+ strncpy(aResult->mDisplayName, displayName.BeginReading(), mozilla::gfx::kVRDisplayNameMaxLen); // FINDME! TODO! HACK! Safe? Better way?
+ for (int i = 0; i < mozilla::gfx::VRDisplayState::NumEyes; i++) {
+ if (!ReadParam(aMsg, aIter, &(aResult->mEyeFOV[i])) ||
+ !ReadParam(aMsg, aIter, &(aResult->mEyeTranslation[i].x)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mEyeTranslation[i].y)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mEyeTranslation[i].z))) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+template <>
struct ParamTraits<mozilla::gfx::VRDisplayInfo>
{
typedef mozilla::gfx::VRDisplayInfo paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mDisplayID);
- WriteParam(aMsg, aParam.mDisplayName);
- WriteParam(aMsg, aParam.mCapabilityFlags);
- WriteParam(aMsg, aParam.mEyeResolution);
- WriteParam(aMsg, aParam.mIsConnected);
- WriteParam(aMsg, aParam.mIsMounted);
WriteParam(aMsg, aParam.mPresentingGroups);
WriteParam(aMsg, aParam.mGroupMask);
- WriteParam(aMsg, aParam.mStageSize);
- WriteParam(aMsg, aParam.mSittingToStandingTransform);
WriteParam(aMsg, aParam.mFrameId);
WriteParam(aMsg, aParam.mPresentingGeneration);
- for (int i = 0; i < mozilla::gfx::VRDisplayInfo::NumEyes; i++) {
- WriteParam(aMsg, aParam.mEyeFOV[i]);
- WriteParam(aMsg, aParam.mEyeTranslation[i]);
- }
+ WriteParam(aMsg, aParam.mDisplayState);
for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) {
WriteParam(aMsg, aParam.mLastSensorState[i]);
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
!ReadParam(aMsg, aIter, &(aResult->mDisplayID)) ||
- !ReadParam(aMsg, aIter, &(aResult->mDisplayName)) ||
- !ReadParam(aMsg, aIter, &(aResult->mCapabilityFlags)) ||
- !ReadParam(aMsg, aIter, &(aResult->mEyeResolution)) ||
- !ReadParam(aMsg, aIter, &(aResult->mIsConnected)) ||
- !ReadParam(aMsg, aIter, &(aResult->mIsMounted)) ||
!ReadParam(aMsg, aIter, &(aResult->mPresentingGroups)) ||
!ReadParam(aMsg, aIter, &(aResult->mGroupMask)) ||
- !ReadParam(aMsg, aIter, &(aResult->mStageSize)) ||
- !ReadParam(aMsg, aIter, &(aResult->mSittingToStandingTransform)) ||
!ReadParam(aMsg, aIter, &(aResult->mFrameId)) ||
- !ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration))) {
+ !ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mDisplayState))) {
return false;
}
- for (int i = 0; i < mozilla::gfx::VRDisplayInfo::NumEyes; i++) {
- if (!ReadParam(aMsg, aIter, &(aResult->mEyeFOV[i])) ||
- !ReadParam(aMsg, aIter, &(aResult->mEyeTranslation[i]))) {
- return false;
- }
- }
for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) {
if (!ReadParam(aMsg, aIter, &(aResult->mLastSensorState[i]))) {
return false;
}
}
return true;
}
@@ -186,39 +230,88 @@ struct ParamTraits<mozilla::gfx::VRField
!ReadParam(aMsg, aIter, &(aResult->leftDegrees))) {
return false;
}
return true;
}
};
+
+template <>
+struct ParamTraits<mozilla::gfx::VRControllerState>
+{
+ typedef mozilla::gfx::VRControllerState paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ nsCString controllerName;
+ controllerName.Assign(aParam.mControllerName); // FINDME!! HACK! - Bounds checking?
+ WriteParam(aMsg, controllerName);
+ WriteParam(aMsg, aParam.mNumButtons);
+ WriteParam(aMsg, aParam.mNumAxes);
+ WriteParam(aMsg, aParam.mNumTriggers);
+ WriteParam(aMsg, aParam.mNumHaptics);
+ WriteParam(aMsg, aParam.mButtonPressed);
+ WriteParam(aMsg, aParam.mButtonTouched);
+ for (int i=0; i < mozilla::gfx::kVRControllerMaxAxis; i++) {
+ WriteParam(aMsg, aParam.mAxisValue[i]);
+ }
+ for (int i=0; i < mozilla::gfx::kVRControllerMaxTriggers; i++) {
+ WriteParam(aMsg, aParam.mTriggerValue[i]);
+ }
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+ {
+ nsCString controllerName;
+ if (!ReadParam(aMsg, aIter, &(controllerName)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mNumButtons)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mNumAxes)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mNumTriggers)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mNumHaptics)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mButtonPressed)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mButtonTouched))) {
+ return false;
+ }
+ for (int i=0; i < mozilla::gfx::kVRControllerMaxAxis; i++) {
+ if (!ReadParam(aMsg, aIter, &(aResult->mAxisValue[i]))) {
+ return false;
+ }
+ }
+ for (int i=0; i < mozilla::gfx::kVRControllerMaxTriggers; i++) {
+ if (!ReadParam(aMsg, aIter, &(aResult->mTriggerValue[i]))) {
+ return false;
+ }
+ }
+ strncpy(aResult->mControllerName, controllerName.BeginReading(), mozilla::gfx::kVRControllerNameMaxLen); // FINDME! TODO! HACK! Safe? Better way?
+
+ 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);
+ WriteParam(aMsg, aParam.mControllerState);
}
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))) {
+ !ReadParam(aMsg, aIter, &(aResult->mControllerState))) {
return false;
}
return true;
}
};
template <>
--- a/gfx/vr/moz.build
+++ b/gfx/vr/moz.build
@@ -1,15 +1,16 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS += [
+ 'external_api/moz_external_vr.h',
'gfxVR.h',
'ipc/VRLayerChild.h',
'ipc/VRManagerChild.h',
'ipc/VRManagerParent.h',
'ipc/VRMessageUtils.h',
'VRDisplayClient.h',
'VRDisplayPresentation.h',
'VRManager.h',
@@ -34,16 +35,17 @@ UNIFIED_SOURCES += [
'VRManager.cpp',
'VRThread.cpp',
]
# VRDisplayHost includes MacIOSurface.h which includes Mac headers
# which define Size and Points types in the root namespace that
# often conflict with our own types.
SOURCES += [
+ 'gfxVRExternal.cpp',
'gfxVRPuppet.cpp',
'VRDisplayHost.cpp',
]
# Build OpenVR on Windows, Linux, and macOS desktop targets
if CONFIG['OS_TARGET'] in ('WINNT', 'Linux', 'Darwin'):
DIRS += [
'openvr',
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5351,16 +5351,18 @@ pref("dom.vr.enabled", false);
// Window.vrdisplayactivate event when the headset's sensors detect it
// being worn. This can result in WebVR content taking over the headset
// when the user is using it outside the browser or inadvertent start of
// presentation due to the high sensitivity of the proximity sensor in some
// headsets, so it is off by default.
pref("dom.vr.autoactivate.enabled", false);
// The threshold value of trigger inputs for VR controllers
pref("dom.vr.controller_trigger_threshold", "0.1");
+// Enable external XR API integrations
+pref("dom.vr.external.enabled", false);
// Maximum number of milliseconds the browser will wait for content to call
// VRDisplay.requestPresent after emitting vrdisplayactivate during VR
// link traversal. This prevents a long running event handler for
// vrdisplayactivate from later calling VRDisplay.requestPresent, which would
// result in a non-responsive browser in the VR headset.
pref("dom.vr.navigation.timeout", 5000);
// Oculus device
#if defined(HAVE_64BIT_BUILD)