Bug 1436791 - Implement gfxVRExternal,r=rbarker

- gfxVRExternal Enables other processes to present
  real or simulated VR hardware to Firefox.
- This functionality is disabled by default, under
  dom.vr.external.enabled.
- VRDisplayInfo, VRControllerInfo, and associated
  structs have been restructured to ensure internal
  state is not exposed via shmem interface.
- Some refactoring to convert structs to
  POD types, enabling them to be located
  in shmem and be memcpy'd.
- Work needed before unpreffing marked
  with "TODO" comments.
MozReview-Commit-ID: FbsusbxuoQ8

--HG--
extra : rebase_source : 8a448169c3f47411c705a4d9fd462a1f9363dfd9
extra : amend_source : e6702549527292e2850d16e8f503f0be9848159f
This commit is contained in:
Kearwood Gilbert 2018-03-13 17:09:54 -07:00
Родитель 45bc54de16
Коммит d0b2b8da65
24 изменённых файлов: 1377 добавлений и 471 удалений

Просмотреть файл

@ -393,7 +393,7 @@ VRDisplay::LastRelease()
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),
@ -914,9 +914,9 @@ VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
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));

Просмотреть файл

@ -32,19 +32,20 @@ VRMockDisplay::VRMockDisplay(const nsCString& aID, uint32_t aDeviceID)
, 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*
@ -55,8 +56,8 @@ VRMockDisplay::WrapObject(JSContext* aCx, JS::Handle<JSObject*> 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
@ -65,11 +66,11 @@ VRMockDisplay::SetEyeParameter(VREye aEye, double aOffsetX, double aOffsetY,
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

Просмотреть файл

@ -29,7 +29,7 @@ public:
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;

Просмотреть файл

@ -364,6 +364,7 @@ private:
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);

Просмотреть файл

@ -108,7 +108,7 @@ VRDisplayClient::FireEvents()
}
// 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);
@ -116,7 +116,7 @@ VRDisplayClient::FireEvents()
}
// 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);
@ -145,7 +145,7 @@ VRDisplayClient::GetIsConnected() const
void
VRDisplayClient::NotifyDisconnected()
{
mDisplayInfo.mIsConnected = false;
mDisplayInfo.mDisplayState.mIsConnected = false;
}
void

Просмотреть файл

@ -78,6 +78,7 @@ VRDisplayHost::VRDisplayHost(VRDeviceType aType)
mDisplayInfo.mGroupMask = kVRGroupContent;
mDisplayInfo.mFrameId = 0;
mDisplayInfo.mPresentingGeneration = 0;
mDisplayInfo.mDisplayState.mDisplayName[0] = '\0';
}
VRDisplayHost::~VRDisplayHost()
@ -160,7 +161,7 @@ VRDisplayHost::SetGroupMask(uint32_t aGroupMask)
bool
VRDisplayHost::GetIsConnected()
{
return mDisplayInfo.mIsConnected;
return mDisplayInfo.mDisplayState.mIsConnected;
}
void
@ -421,13 +422,12 @@ VRDisplayHost::CheckClearDisplayInfoDirty()
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();
@ -447,25 +447,25 @@ VRControllerHost::GetControllerInfo() const
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
@ -483,7 +483,7 @@ VRControllerHost::GetPose()
dom::GamepadHand
VRControllerHost::GetHand()
{
return mControllerInfo.mHand;
return mControllerInfo.mControllerState.mHand;
}
void

Просмотреть файл

@ -147,10 +147,6 @@ protected:
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;
};

Просмотреть файл

@ -18,6 +18,7 @@
#include "gfxPrefs.h"
#include "gfxVR.h"
#include "gfxVRExternal.h"
#if defined(XP_WIN)
#include "gfxVROculus.h"
#endif
@ -76,6 +77,10 @@ VRManager::VRManager()
* 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
@ -513,6 +518,13 @@ VRManager::GetPuppetManager()
return mPuppetManager;
}
VRSystemManagerExternal*
VRManager::GetExternalManager()
{
MOZ_ASSERT(mExternalManager);
return mExternalManager;
}
template<class T>
void
VRManager::NotifyGamepadChange(uint32_t aIndex, const T& aInfo)

Просмотреть файл

@ -24,6 +24,7 @@ class VRLayerParent;
class VRManagerParent;
class VRDisplayHost;
class VRSystemManagerPuppet;
class VRSystemManagerExternal;
class VRManager
{
@ -49,6 +50,7 @@ public:
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);
@ -89,6 +91,7 @@ private:
TimeStamp mLastDisplayEnumerationTime;
TimeStamp mLastActiveTime;
RefPtr<VRSystemManagerPuppet> mPuppetManager;
RefPtr<VRSystemManagerExternal> mExternalManager;
bool mVRDisplaysRequested;
bool mVRControllersRequested;
};

Просмотреть файл

@ -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 */

Просмотреть файл

@ -43,11 +43,11 @@ VRSystemManager::AllocateControllerID()
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();
}
@ -194,10 +194,42 @@ VRHMDSensorState::CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms)
}
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;
}

Просмотреть файл

@ -7,6 +7,7 @@
#ifndef GFX_VR_H
#define GFX_VR_H
#include "moz_external_vr.h"
#include "nsTArray.h"
#include "nsString.h"
#include "nsCOMPtr.h"
@ -32,139 +33,6 @@ 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
@ -174,57 +42,47 @@ struct VRHMDSensorState {
// 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
{
VRDeviceType GetType() const { return mType; }
uint32_t GetDisplayID() const { return mDisplayID; }
const nsCString& GetDisplayName() const { return mDisplayName; }
VRDisplayCapabilityFlags GetCapabilities() const { return 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; }
uint32_t GetPresentingGroups() const { return mPresentingGroups; }
uint32_t GetGroupMask() const { return mGroupMask; }
const Size& GetStageSize() const { return mStageSize; }
const Matrix4x4& GetSittingToStandingTransform() const { return mSittingToStandingTransform; }
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;
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 char* GetDisplayName() const { return mDisplayState.mDisplayName; }
VRDisplayCapabilityFlags GetCapabilities() const { return mDisplayState.mCapabilityFlags; }
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;
const Matrix4x4 GetSittingToStandingTransform() const;
uint64_t GetFrameId() const { return mFrameId; }
bool operator==(const VRDisplayInfo& other) const {
for (size_t i = 0; i < kVRMaxLatencyFrames; i++) {
@ -232,21 +90,12 @@ struct VRDisplayInfo
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;
}
@ -254,11 +103,6 @@ struct VRDisplayInfo
bool operator!=(const VRDisplayInfo& other) const {
return !(*this == other);
}
const VRHMDSensorState& GetSensorState() const
{
return mLastSensorState[mFrameId % kVRMaxLatencyFrames];
}
};
struct VRSubmitFrameResultInfo
@ -280,34 +124,29 @@ 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 {

463
gfx/vr/gfxVRExternal.cpp Normal file
Просмотреть файл

@ -0,0 +1,463 @@
/* -*- 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;
}
#if defined(XP_MACOSX)
if (mShmemFD == 0) {
mShmemFD = shm_open(kShmemName, O_RDWR, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
}
if (mShmemFD <= 0) {
mShmemFD = 0;
return;
}
struct stat sb;
fstat(mShmemFD, &sb);
off_t length = sb.st_size;
if (length < (off_t)sizeof(VRExternalShmem)) {
// TODO - Implement logging
CloseShmem();
return;
}
mExternalShmem = (VRExternalShmem*)mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, mShmemFD, 0);
if (mExternalShmem == MAP_FAILED) {
// TODO - Implement logging
mExternalShmem = NULL;
CloseShmem();
return;
}
#elif defined(XP_WIN)
if (mShmemFile == NULL) {
mShmemFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, kShmemName);
if (mShmemFile == NULL) {
// TODO - Implement logging
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) {
// TODO - Implement logging
CloseShmem();
return;
}
#endif
CheckForShutdown();
}
void
VRSystemManagerExternal::CheckForShutdown()
{
if (mExternalShmem) {
if (mExternalShmem->generationA == -1 && mExternalShmem->generationB == -1) {
Shutdown();
}
}
}
void
VRSystemManagerExternal::CloseShmem()
{
#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
}
/*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) {
// TODO - Add locking here for non-x86 platforms
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));
}
}
}
}

126
gfx/vr/gfxVRExternal.h Normal file
Просмотреть файл

@ -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 */

Просмотреть файл

@ -213,7 +213,7 @@ VRDisplayGVR::VRDisplayGVR()
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 |
@ -409,7 +409,7 @@ VRDisplayGVR::GetSensorState()
result.linearVelocity[2] = 0.0f;
UpdateHeadToEye(context);
result.CalcViewMatrices(mHeadToEyes);
CalcViewMatrices(&result, mHeadToEyes);
return result;
}
@ -596,12 +596,15 @@ 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()

Просмотреть файл

@ -213,14 +213,15 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
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)
@ -233,7 +234,7 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
// 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);
}
@ -248,8 +249,8 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
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 =
@ -258,9 +259,9 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
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),

Просмотреть файл

@ -806,44 +806,44 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
, 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();
@ -866,14 +866,15 @@ VRDisplayOculus::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = n
{
// 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));
@ -890,39 +891,40 @@ 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
@ -1019,7 +1021,7 @@ 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;
}
@ -1299,8 +1301,8 @@ VRDisplayOculus::SubmitFrame(ID3D11Texture2D* aSource,
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)
@ -1312,6 +1314,8 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand, uint32_t aDisplay
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
VRControllerState& state = mControllerInfo.mControllerState;
char* touchID = "";
switch (aHand) {
case dom::GamepadHand::Left:
@ -1324,17 +1328,18 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand, uint32_t aDisplay
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

Просмотреть файл

@ -58,36 +58,38 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
{
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();
@ -111,12 +113,12 @@ VRDisplayOpenVR::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = n
{
// 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;
@ -134,58 +136,59 @@ VRDisplayOpenVR::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = n
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;
}
}
@ -212,22 +215,22 @@ VRDisplayOpenVR::Refresh()
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:
@ -428,19 +431,17 @@ VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplay
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()
@ -464,31 +465,31 @@ VRControllerOpenVR::GetTrackedIndex()
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

Просмотреть файл

@ -112,8 +112,6 @@ private:
// The index of tracked devices from ::vr::IVRSystem.
uint32_t mTrackedIndex;
nsTArray<float> mTrigger;
nsTArray<float> mAxisMove;
RefPtr<VRThread> mVibrateThread;
Atomic<bool> mIsVibrateStopped;
};

Просмотреть файл

@ -56,48 +56,50 @@ VRDisplayPuppet::VRDisplayPuppet()
{
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;
@ -128,12 +130,13 @@ 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
@ -154,7 +157,7 @@ VRDisplayPuppet::GetSensorState()
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);
@ -572,7 +575,7 @@ void
VRDisplayPuppet::Refresh()
{
// We update mIsConneced once per refresh.
mDisplayInfo.mIsConnected = true;
mDisplayInfo.mDisplayState.mIsConnected = true;
}
VRControllerPuppet::VRControllerPuppet(dom::GamepadHand aHand, uint32_t aDisplayID)
@ -581,10 +584,11 @@ VRControllerPuppet::VRControllerPuppet(dom::GamepadHand aHand, uint32_t aDisplay
, 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()
@ -668,13 +672,13 @@ VRControllerPuppet::GetPoseMoveState()
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()

Просмотреть файл

@ -98,7 +98,6 @@ private:
uint64_t mButtonPressState;
uint64_t mButtonTouchState;
float mAxisMoveState[3];
float mAxisMove[3];
dom::GamepadPoseState mPoseState;
};

Просмотреть файл

@ -26,6 +26,72 @@ 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);
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);
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>
{
@ -35,21 +101,11 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo>
{
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]);
}
@ -59,25 +115,13 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo>
{
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;
@ -191,6 +235,59 @@ struct ParamTraits<mozilla::gfx::VRFieldOfView>
}
};
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>
{
@ -200,20 +297,16 @@ struct ParamTraits<mozilla::gfx::VRControllerInfo>
{
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;
}

Просмотреть файл

@ -5,6 +5,7 @@
# 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',
@ -39,6 +40,7 @@ UNIFIED_SOURCES += [
# which define Size and Points types in the root namespace that
# often conflict with our own types.
SOURCES += [
'gfxVRExternal.cpp',
'gfxVRPuppet.cpp',
'VRDisplayHost.cpp',
]

Просмотреть файл

@ -5344,6 +5344,8 @@ pref("dom.vr.enabled", false);
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