mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1466701 - Refactor gfxVROSVR.cpp to use gfxVRExternal interface r=daoshengmu
Differential Revision: https://phabricator.services.mozilla.com/D7352 --HG-- rename : gfx/vr/osvr/ClientKit/ClientKitC.h => gfx/vr/service/osvr/ClientKit/ClientKitC.h rename : gfx/vr/osvr/ClientKit/ContextC.h => gfx/vr/service/osvr/ClientKit/ContextC.h rename : gfx/vr/osvr/ClientKit/DisplayC.h => gfx/vr/service/osvr/ClientKit/DisplayC.h rename : gfx/vr/osvr/ClientKit/Export.h => gfx/vr/service/osvr/ClientKit/Export.h rename : gfx/vr/osvr/ClientKit/InterfaceC.h => gfx/vr/service/osvr/ClientKit/InterfaceC.h rename : gfx/vr/osvr/ClientKit/InterfaceCallbackC.h => gfx/vr/service/osvr/ClientKit/InterfaceCallbackC.h rename : gfx/vr/osvr/ClientKit/InterfaceStateC.h => gfx/vr/service/osvr/ClientKit/InterfaceStateC.h rename : gfx/vr/osvr/ClientKit/SystemCallbackC.h => gfx/vr/service/osvr/ClientKit/SystemCallbackC.h rename : gfx/vr/osvr/ClientKit/TransformsC.h => gfx/vr/service/osvr/ClientKit/TransformsC.h rename : gfx/vr/osvr/Util/APIBaseC.h => gfx/vr/service/osvr/Util/APIBaseC.h rename : gfx/vr/osvr/Util/AnnotationMacrosC.h => gfx/vr/service/osvr/Util/AnnotationMacrosC.h rename : gfx/vr/osvr/Util/BoolC.h => gfx/vr/service/osvr/Util/BoolC.h rename : gfx/vr/osvr/Util/ChannelCountC.h => gfx/vr/service/osvr/Util/ChannelCountC.h rename : gfx/vr/osvr/Util/ClientCallbackTypesC.h => gfx/vr/service/osvr/Util/ClientCallbackTypesC.h rename : gfx/vr/osvr/Util/ClientOpaqueTypesC.h => gfx/vr/service/osvr/Util/ClientOpaqueTypesC.h rename : gfx/vr/osvr/Util/ClientReportTypesC.h => gfx/vr/service/osvr/Util/ClientReportTypesC.h rename : gfx/vr/osvr/Util/Export.h => gfx/vr/service/osvr/Util/Export.h rename : gfx/vr/osvr/Util/ImagingReportTypesC.h => gfx/vr/service/osvr/Util/ImagingReportTypesC.h rename : gfx/vr/osvr/Util/MatrixConventionsC.h => gfx/vr/service/osvr/Util/MatrixConventionsC.h rename : gfx/vr/osvr/Util/PlatformConfig.h => gfx/vr/service/osvr/Util/PlatformConfig.h rename : gfx/vr/osvr/Util/Pose3C.h => gfx/vr/service/osvr/Util/Pose3C.h rename : gfx/vr/osvr/Util/QuaternionC.h => gfx/vr/service/osvr/Util/QuaternionC.h rename : gfx/vr/osvr/Util/QuatlibInteropC.h => gfx/vr/service/osvr/Util/QuatlibInteropC.h rename : gfx/vr/osvr/Util/RadialDistortionParametersC.h => gfx/vr/service/osvr/Util/RadialDistortionParametersC.h rename : gfx/vr/osvr/Util/RenderingTypesC.h => gfx/vr/service/osvr/Util/RenderingTypesC.h rename : gfx/vr/osvr/Util/ReturnCodesC.h => gfx/vr/service/osvr/Util/ReturnCodesC.h rename : gfx/vr/osvr/Util/StdInt.h => gfx/vr/service/osvr/Util/StdInt.h rename : gfx/vr/osvr/Util/TimeValueC.h => gfx/vr/service/osvr/Util/TimeValueC.h rename : gfx/vr/osvr/Util/Vec2C.h => gfx/vr/service/osvr/Util/Vec2C.h rename : gfx/vr/osvr/Util/Vec3C.h => gfx/vr/service/osvr/Util/Vec3C.h extra : moz-landing-system : lando
This commit is contained in:
parent
8ec57ee636
commit
ce372ea306
@ -26,7 +26,6 @@
|
||||
#endif
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
#include "gfxVROpenVR.h"
|
||||
#include "gfxVROSVR.h"
|
||||
#endif
|
||||
|
||||
#include "gfxVRPuppet.h"
|
||||
@ -142,12 +141,6 @@ VRManager::VRManager()
|
||||
if (mgr) {
|
||||
mManagers.AppendElement(mgr);
|
||||
}
|
||||
|
||||
// OSVR is cross platform compatible
|
||||
mgr = VRSystemManagerOSVR::Create();
|
||||
if (mgr) {
|
||||
mManagers.AppendElement(mgr);
|
||||
}
|
||||
} // !mVRService
|
||||
#endif
|
||||
|
||||
|
@ -1,131 +0,0 @@
|
||||
/* -*- 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_OSVR_H
|
||||
#define GFX_VR_OSVR_H
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
|
||||
#include "VRDisplayLocal.h"
|
||||
|
||||
#include <osvr/ClientKit/ClientKitC.h>
|
||||
#include <osvr/ClientKit/DisplayC.h>
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
class MacIOSurface;
|
||||
#endif
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
namespace impl {
|
||||
|
||||
class VRDisplayOSVR : public VRDisplayLocal
|
||||
{
|
||||
public:
|
||||
void ZeroSensor() override;
|
||||
|
||||
protected:
|
||||
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 VRDisplayOSVR(OSVR_ClientContext* context,
|
||||
OSVR_ClientInterface* iface,
|
||||
OSVR_DisplayConfig* display);
|
||||
|
||||
protected:
|
||||
virtual ~VRDisplayOSVR()
|
||||
{
|
||||
Destroy();
|
||||
MOZ_COUNT_DTOR_INHERITED(VRDisplayOSVR, VRDisplayLocal);
|
||||
}
|
||||
void Destroy();
|
||||
|
||||
OSVR_ClientContext* m_ctx;
|
||||
OSVR_ClientInterface* m_iface;
|
||||
OSVR_DisplayConfig* m_display;
|
||||
|
||||
gfx::Matrix4x4 mHeadToEye[2];
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
class VRSystemManagerOSVR : public VRSystemManager
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<VRSystemManagerOSVR> 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;
|
||||
|
||||
protected:
|
||||
VRSystemManagerOSVR()
|
||||
: mOSVRInitialized(false)
|
||||
, mClientContextInitialized(false)
|
||||
, mDisplayConfigInitialized(false)
|
||||
, mInterfaceInitialized(false)
|
||||
, m_ctx(nullptr)
|
||||
, m_iface(nullptr)
|
||||
, m_display(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool Init();
|
||||
|
||||
RefPtr<impl::VRDisplayOSVR> mHMDInfo;
|
||||
bool mOSVRInitialized;
|
||||
bool mClientContextInitialized;
|
||||
bool mDisplayConfigInitialized;
|
||||
bool mInterfaceInitialized;
|
||||
RefPtr<nsIThread> mOSVRThread;
|
||||
|
||||
OSVR_ClientContext m_ctx;
|
||||
OSVR_ClientInterface m_iface;
|
||||
OSVR_DisplayConfig m_display;
|
||||
|
||||
private:
|
||||
// check if all components are initialized
|
||||
// and if not, it will try to initialize them
|
||||
void CheckOSVRStatus();
|
||||
void InitializeClientContext();
|
||||
void InitializeDisplay();
|
||||
void InitializeInterface();
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* GFX_VR_OSVR_H */
|
@ -51,11 +51,6 @@ UNIFIED_SOURCES += [
|
||||
'VRThread.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] != 'Android':
|
||||
UNIFIED_SOURCES += [
|
||||
'gfxVROSVR.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.
|
||||
|
@ -4,34 +4,25 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "OSVRSession.h"
|
||||
#include "prenv.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SharedLibrary.h"
|
||||
|
||||
#include "mozilla/gfx/Quaternion.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "../layers/d3d11/CompositorD3D11.h"
|
||||
#include "../layers/d3d11/TextureD3D11.h"
|
||||
#endif
|
||||
|
||||
#include "gfxVROSVR.h"
|
||||
|
||||
#include "mozilla/dom/GamepadEventTypes.h"
|
||||
#include "mozilla/dom/GamepadBinding.h"
|
||||
#if defined(XP_WIN)
|
||||
#include <d3d11.h>
|
||||
#include "mozilla/gfx/DeviceManagerDx.h"
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gfx::impl;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace {
|
||||
// need to typedef functions that will be used in the code below
|
||||
@ -208,194 +199,59 @@ SetFromTanRadians(double left, double right, double bottom, double top)
|
||||
return fovInfo;
|
||||
}
|
||||
|
||||
VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
|
||||
OSVR_ClientInterface* iface,
|
||||
OSVR_DisplayConfig* display)
|
||||
: VRDisplayLocal(VRDeviceType::OSVR)
|
||||
, m_ctx(context)
|
||||
, m_iface(iface)
|
||||
, m_display(display)
|
||||
OSVRSession::OSVRSession()
|
||||
: VRSession()
|
||||
, mRuntimeLoaded(false)
|
||||
, mOSVRInitialized(false)
|
||||
, mClientContextInitialized(false)
|
||||
, mDisplayConfigInitialized(false)
|
||||
, mInterfaceInitialized(false)
|
||||
, m_ctx(nullptr)
|
||||
, m_iface(nullptr)
|
||||
, m_display(nullptr)
|
||||
{
|
||||
|
||||
MOZ_COUNT_CTOR_INHERITED(VRDisplayOSVR, VRDisplayLocal);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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();
|
||||
mHeadToEye[eye] = pose;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOSVR::Destroy()
|
||||
OSVRSession::~OSVRSession()
|
||||
{
|
||||
// destroy non-owning pointers
|
||||
m_ctx = nullptr;
|
||||
m_iface = nullptr;
|
||||
m_display = nullptr;
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOSVR::ZeroSensor()
|
||||
{
|
||||
// recenter pose aka reset yaw
|
||||
osvr_ClientSetRoomRotationUsingHead(*m_ctx);
|
||||
}
|
||||
|
||||
VRHMDSensorState
|
||||
VRDisplayOSVR::GetSensorState()
|
||||
{
|
||||
|
||||
//update client context before anything
|
||||
//this usually goes into app's mainloop
|
||||
osvr_ClientUpdate(*m_ctx);
|
||||
|
||||
VRHMDSensorState result{};
|
||||
OSVR_TimeValue timestamp;
|
||||
|
||||
OSVR_OrientationState orientation;
|
||||
|
||||
OSVR_ReturnCode ret =
|
||||
osvr_GetOrientationState(*m_iface, ×tamp, &orientation);
|
||||
|
||||
result.timestamp = timestamp.seconds;
|
||||
result.inputFrameID = mDisplayInfo.mFrameId;
|
||||
|
||||
if (ret == OSVR_RETURN_SUCCESS) {
|
||||
result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
|
||||
result.pose.orientation[0] = orientation.data[1];
|
||||
result.pose.orientation[1] = orientation.data[2];
|
||||
result.pose.orientation[2] = orientation.data[3];
|
||||
result.pose.orientation[3] = orientation.data[0];
|
||||
} else {
|
||||
// default to an identity quaternion
|
||||
result.pose.orientation[3] = 1.0f;
|
||||
}
|
||||
|
||||
OSVR_PositionState position;
|
||||
ret = osvr_GetPositionState(*m_iface, ×tamp, &position);
|
||||
if (ret == OSVR_RETURN_SUCCESS) {
|
||||
result.flags |= VRDisplayCapabilityFlags::Cap_Position;
|
||||
result.pose.position[0] = position.data[0];
|
||||
result.pose.position[1] = position.data[1];
|
||||
result.pose.position[2] = position.data[2];
|
||||
}
|
||||
|
||||
result.CalcViewMatrices(mHeadToEye);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
bool
|
||||
VRDisplayOSVR::SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
OSVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState)
|
||||
{
|
||||
// XXX Add code to submit frame
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
bool
|
||||
VRDisplayOSVR::SubmitFrame(MacIOSurface* aMacIOSurface,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
// XXX Add code to submit frame
|
||||
MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
VRDisplayOSVR::StartPresentation()
|
||||
{
|
||||
// XXX Add code to start VR Presentation
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOSVR::StopPresentation()
|
||||
{
|
||||
// XXX Add code to end VR Presentation
|
||||
}
|
||||
|
||||
already_AddRefed<VRSystemManagerOSVR>
|
||||
VRSystemManagerOSVR::Create()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!gfxPrefs::VREnabled() || !gfxPrefs::VROSVREnabled()) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
if (mOSVRInitialized) {
|
||||
return true;
|
||||
}
|
||||
if (!LoadOSVRRuntime()) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
RefPtr<VRSystemManagerOSVR> manager = new VRSystemManagerOSVR();
|
||||
return manager.forget();
|
||||
mRuntimeLoaded = true;
|
||||
// initialize client context
|
||||
InitializeClientContext();
|
||||
// try to initialize interface
|
||||
InitializeInterface();
|
||||
// try to initialize display object
|
||||
InitializeDisplay();
|
||||
// verify all components are initialized
|
||||
CheckOSVRStatus();
|
||||
|
||||
if (!mOSVRInitialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!InitState(aSystemState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::CheckOSVRStatus()
|
||||
OSVRSession::CheckOSVRStatus()
|
||||
{
|
||||
if (mOSVRInitialized) {
|
||||
return;
|
||||
@ -419,7 +275,7 @@ VRSystemManagerOSVR::CheckOSVRStatus()
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::InitializeClientContext()
|
||||
OSVRSession::InitializeClientContext()
|
||||
{
|
||||
// already initialized
|
||||
if (mClientContextInitialized) {
|
||||
@ -448,7 +304,7 @@ VRSystemManagerOSVR::InitializeClientContext()
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::InitializeInterface()
|
||||
OSVRSession::InitializeInterface()
|
||||
{
|
||||
// already initialized
|
||||
if (mInterfaceInitialized) {
|
||||
@ -465,7 +321,7 @@ VRSystemManagerOSVR::InitializeInterface()
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::InitializeDisplay()
|
||||
OSVRSession::InitializeDisplay()
|
||||
{
|
||||
// display is fully configured
|
||||
if (mDisplayConfigInitialized) {
|
||||
@ -500,44 +356,86 @@ VRSystemManagerOSVR::InitializeDisplay()
|
||||
}
|
||||
|
||||
bool
|
||||
VRSystemManagerOSVR::Init()
|
||||
OSVRSession::InitState(mozilla::gfx::VRSystemState& aSystemState)
|
||||
{
|
||||
VRDisplayState& state = aSystemState.displayState;
|
||||
strncpy(state.mDisplayName, "OSVR HMD", kVRDisplayNameMaxLen);
|
||||
state.mEightCC = GFX_VR_EIGHTCC('O', 'S', 'V', 'R', ' ', ' ', ' ', ' ');
|
||||
state.mIsConnected = true;
|
||||
state.mIsMounted = false;
|
||||
state.mCapabilityFlags = (VRDisplayCapabilityFlags)((int)VRDisplayCapabilityFlags::Cap_None |
|
||||
(int)VRDisplayCapabilityFlags::Cap_Orientation |
|
||||
(int)VRDisplayCapabilityFlags::Cap_Position |
|
||||
(int)VRDisplayCapabilityFlags::Cap_External |
|
||||
(int)VRDisplayCapabilityFlags::Cap_Present);
|
||||
state.mReportsDroppedFrames = false;
|
||||
|
||||
// OSVR server should be running in the background
|
||||
// It would load plugins and take care of detecting HMDs
|
||||
if (!mOSVRInitialized) {
|
||||
nsIThread* thread = nullptr;
|
||||
NS_GetCurrentThread(&thread);
|
||||
mOSVRThread = already_AddRefed<nsIThread>(thread);
|
||||
// XXX OSVR display topology allows for more than one viewer
|
||||
// will assume only one viewer for now (most likely stay that way)
|
||||
|
||||
// initialize client context
|
||||
InitializeClientContext();
|
||||
// try to initialize interface
|
||||
InitializeInterface();
|
||||
// try to initialize display object
|
||||
InitializeDisplay();
|
||||
// verify all components are initialized
|
||||
CheckOSVRStatus();
|
||||
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);
|
||||
state.mEyeFOV[eye] =
|
||||
SetFromTanRadians(-left, right, -bottom, top);
|
||||
}
|
||||
|
||||
return mOSVRInitialized;
|
||||
// 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);
|
||||
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);
|
||||
}
|
||||
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();
|
||||
mHeadToEye[eye] = pose;
|
||||
}
|
||||
|
||||
// default to an identity quaternion
|
||||
VRHMDSensorState& sensorState = aSystemState.sensorState;
|
||||
sensorState.flags = (VRDisplayCapabilityFlags)(
|
||||
(int)VRDisplayCapabilityFlags::Cap_Orientation |
|
||||
(int)VRDisplayCapabilityFlags::Cap_Position);
|
||||
sensorState.pose.orientation[3] = 1.0f; // Default to an identity quaternion
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::Destroy()
|
||||
OSVRSession::Shutdown()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::Shutdown()
|
||||
{
|
||||
if (mOSVRInitialized) {
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mOSVRThread);
|
||||
mOSVRThread = nullptr;
|
||||
mHMDInfo = nullptr;
|
||||
mOSVRInitialized = false;
|
||||
if (!mRuntimeLoaded) {
|
||||
return;
|
||||
}
|
||||
mOSVRInitialized = false;
|
||||
// client context may not have been initialized
|
||||
if (m_ctx) {
|
||||
osvr_ClientFreeDisplay(m_display);
|
||||
@ -548,91 +446,98 @@ VRSystemManagerOSVR::Shutdown()
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::NotifyVSync()
|
||||
OSVRSession::ProcessEvents(mozilla::gfx::VRSystemState& aSystemState)
|
||||
{
|
||||
VRSystemManager::NotifyVSync();
|
||||
|
||||
// TODO - Check for device disconnection or other OSVR events
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::Enumerate()
|
||||
OSVRSession::StartFrame(mozilla::gfx::VRSystemState& aSystemState)
|
||||
{
|
||||
// make sure context, interface and display are initialized
|
||||
CheckOSVRStatus();
|
||||
UpdateHeadsetPose(aSystemState);
|
||||
}
|
||||
|
||||
if (!Init()) {
|
||||
return;
|
||||
void
|
||||
OSVRSession::UpdateHeadsetPose(mozilla::gfx::VRSystemState& aState)
|
||||
{
|
||||
// Update client context before anything
|
||||
// this usually goes into app's mainloop
|
||||
osvr_ClientUpdate(m_ctx);
|
||||
|
||||
VRHMDSensorState result{};
|
||||
OSVR_TimeValue timestamp;
|
||||
|
||||
OSVR_OrientationState orientation;
|
||||
|
||||
OSVR_ReturnCode ret =
|
||||
osvr_GetOrientationState(m_iface, ×tamp, &orientation);
|
||||
|
||||
aState.sensorState.timestamp = timestamp.seconds;
|
||||
|
||||
if (ret == OSVR_RETURN_SUCCESS) {
|
||||
result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
|
||||
result.pose.orientation[0] = orientation.data[1];
|
||||
result.pose.orientation[1] = orientation.data[2];
|
||||
result.pose.orientation[2] = orientation.data[3];
|
||||
result.pose.orientation[3] = orientation.data[0];
|
||||
} else {
|
||||
// default to an identity quaternion
|
||||
result.pose.orientation[3] = 1.0f;
|
||||
}
|
||||
|
||||
mHMDInfo = new VRDisplayOSVR(&m_ctx, &m_iface, &m_display);
|
||||
OSVR_PositionState position;
|
||||
ret = osvr_GetPositionState(m_iface, ×tamp, &position);
|
||||
if (ret == OSVR_RETURN_SUCCESS) {
|
||||
result.flags |= VRDisplayCapabilityFlags::Cap_Position;
|
||||
result.pose.position[0] = position.data[0];
|
||||
result.pose.position[1] = position.data[1];
|
||||
result.pose.position[2] = position.data[2];
|
||||
}
|
||||
|
||||
result.CalcViewMatrices(mHeadToEye);
|
||||
}
|
||||
|
||||
bool
|
||||
VRSystemManagerOSVR::ShouldInhibitEnumeration()
|
||||
OSVRSession::ShouldQuit() const
|
||||
{
|
||||
if (VRSystemManager::ShouldInhibitEnumeration()) {
|
||||
return true;
|
||||
}
|
||||
if (mHMDInfo) {
|
||||
// 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
|
||||
VRSystemManagerOSVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
|
||||
{
|
||||
if (mHMDInfo) {
|
||||
aHMDResult.AppendElement(mHMDInfo);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
VRSystemManagerOSVR::GetIsPresenting()
|
||||
OSVRSession::StartPresentation()
|
||||
{
|
||||
if (mHMDInfo) {
|
||||
VRDisplayInfo displayInfo(mHMDInfo->GetDisplayInfo());
|
||||
return displayInfo.GetPresentingGroups() != kVRGroupNone;
|
||||
}
|
||||
|
||||
return false;
|
||||
// TODO Implement
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::HandleInput()
|
||||
OSVRSession::StopPresentation()
|
||||
{
|
||||
// TODO Implement
|
||||
}
|
||||
|
||||
bool
|
||||
OSVRSession::SubmitFrame(const mozilla::gfx::VRLayer_Stereo_Immersive& aLayer)
|
||||
{
|
||||
return false;
|
||||
// TODO Implement
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::VibrateHaptic(uint32_t aControllerIdx,
|
||||
uint32_t aHapticIndex,
|
||||
double aIntensity,
|
||||
double aDuration,
|
||||
const VRManagerPromise& aPromise)
|
||||
OSVRSession::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
|
||||
float aIntensity, float aDuration)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::StopVibrateHaptic(uint32_t aControllerIdx)
|
||||
OSVRSession::StopVibrateHaptic(uint32_t aControllerIdx)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
|
||||
OSVRSession::StopAllHaptics()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::ScanForControllers()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
VRSystemManagerOSVR::RemoveControllers()
|
||||
{
|
||||
}
|
||||
}
|
71
gfx/vr/service/OSVRSession.h
Normal file
71
gfx/vr/service/OSVRSession.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* -*- 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_SERVICE_OSVRSESSION_H
|
||||
#define GFX_VR_SERVICE_OSVRSESSION_H
|
||||
|
||||
#include "VRSession.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "moz_external_vr.h"
|
||||
|
||||
#include <osvr/ClientKit/ClientKitC.h>
|
||||
#include <osvr/ClientKit/DisplayC.h>
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <d3d11_1.h>
|
||||
#elif defined(XP_MACOSX)
|
||||
class MacIOSurface;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class OSVRSession : public VRSession
|
||||
{
|
||||
public:
|
||||
OSVRSession();
|
||||
virtual ~OSVRSession();
|
||||
|
||||
bool Initialize(mozilla::gfx::VRSystemState& aSystemState) override;
|
||||
void Shutdown() override;
|
||||
void ProcessEvents(mozilla::gfx::VRSystemState& aSystemState) override;
|
||||
void StartFrame(mozilla::gfx::VRSystemState& aSystemState) override;
|
||||
bool ShouldQuit() const override;
|
||||
bool StartPresentation() override;
|
||||
void StopPresentation() override;
|
||||
bool SubmitFrame(const mozilla::gfx::VRLayer_Stereo_Immersive& aLayer) override;
|
||||
void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
|
||||
float aIntensity, float aDuration) override;
|
||||
void StopVibrateHaptic(uint32_t aControllerIdx) override;
|
||||
void StopAllHaptics() override;
|
||||
|
||||
private:
|
||||
bool InitState(mozilla::gfx::VRSystemState& aSystemState);
|
||||
void UpdateHeadsetPose(mozilla::gfx::VRSystemState& aState);
|
||||
bool mRuntimeLoaded;
|
||||
bool mOSVRInitialized;
|
||||
bool mClientContextInitialized;
|
||||
bool mDisplayConfigInitialized;
|
||||
bool mInterfaceInitialized;
|
||||
OSVR_ClientContext m_ctx;
|
||||
OSVR_ClientInterface m_iface;
|
||||
OSVR_DisplayConfig m_display;
|
||||
gfx::Matrix4x4 mHeadToEye[2];
|
||||
|
||||
// check if all components are initialized
|
||||
// and if not, it will try to initialize them
|
||||
void CheckOSVRStatus();
|
||||
void InitializeClientContext();
|
||||
void InitializeDisplay();
|
||||
void InitializeInterface();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace gfx
|
||||
|
||||
#endif // GFX_VR_SERVICE_OSVRSESSION_H
|
@ -121,6 +121,9 @@ OpenVRSession::~OpenVRSession()
|
||||
bool
|
||||
OpenVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState)
|
||||
{
|
||||
if (!gfxPrefs::VREnabled() || !gfxPrefs::VROpenVREnabled()) {
|
||||
return false;
|
||||
}
|
||||
if (mVRSystem != nullptr) {
|
||||
// Already initialized
|
||||
return true;
|
||||
|
@ -5,11 +5,15 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRService.h"
|
||||
#include "OpenVRSession.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "base/thread.h" // for Thread
|
||||
#include <cstring> // for memcmp
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
#include "OpenVRSession.h"
|
||||
#include "OSVRSession.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace std;
|
||||
@ -208,11 +212,23 @@ VRService::ServiceInitialize()
|
||||
// Try to start a VRSession
|
||||
UniquePtr<VRSession> session;
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
// Try OpenVR
|
||||
session = MakeUnique<OpenVRSession>();
|
||||
if (!session->Initialize(mSystemState)) {
|
||||
session = nullptr;
|
||||
if (!session) {
|
||||
session = MakeUnique<OpenVRSession>();
|
||||
if (!session->Initialize(mSystemState)) {
|
||||
session = nullptr;
|
||||
}
|
||||
}
|
||||
// Try OSVR
|
||||
if (!session) {
|
||||
session = MakeUnique<OSVRSession>();
|
||||
if (!session->Initialize(mSystemState)) {
|
||||
session = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (session) {
|
||||
mSession = std::move(session);
|
||||
// Setting enumerationCompleted to true indicates to the browser
|
||||
|
@ -4,6 +4,12 @@
|
||||
# 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/.
|
||||
|
||||
# Build OSVR on all platforms except Android
|
||||
if CONFIG['OS_TARGET'] != 'Android':
|
||||
UNIFIED_SOURCES += [
|
||||
'OSVRSession.cpp',
|
||||
]
|
||||
|
||||
# Build OpenVR on Windows, Linux, and macOS desktop targets
|
||||
if CONFIG['OS_TARGET'] in ('WINNT', 'Linux', 'Darwin'):
|
||||
UNIFIED_SOURCES += [
|
||||
|
Loading…
Reference in New Issue
Block a user