Bug 1305889 - Part 3: Enumerate Oculus Touch Controllers; r?kip
MozReview-Commit-ID: Ep57r4hxrRt
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -116,16 +116,33 @@ static pfn_ovr_GetMirrorTextureBufferGL
#else
#define BUILD_BITS 32
#endif
#define OVR_PRODUCT_VERSION 1
#define OVR_MAJOR_VERSION 1
#define OVR_MINOR_VERSION 10
+static const ovrButton kOculusTouchLButton[] = {
+ ovrButton_X,
+ ovrButton_Y,
+ ovrButton_LThumb
+};
+
+static const ovrButton kOculusTouchRButton[] = {
+ ovrButton_A,
+ ovrButton_B,
+ ovrButton_RThumb
+};
+
+static const uint32_t kNumOculusButton = sizeof(kOculusTouchLButton) /
+ sizeof(ovrButton);
+static const uint32_t kNumOculusAxis = 2;
+static const uint32_t kNumOculusHaptcs = 0; // TODO: Bug 1305892
+
static bool
InitializeOculusCAPI()
{
static PRLibrary *ovrlib = nullptr;
if (!ovrlib) {
nsTArray<nsCString> libSearchPaths;
nsCString libName;
@@ -620,142 +637,16 @@ VRDisplayOculus::StopPresentation()
ovr_SubmitFrame(mSession, 0, nullptr, nullptr, 0);
if (mTextureSet) {
ovr_DestroyTextureSwapChain(mSession, mTextureSet);
mTextureSet = nullptr;
}
}
-/*static*/ already_AddRefed<VRSystemManagerOculus>
-VRSystemManagerOculus::Create()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculusEnabled())
- {
- return nullptr;
- }
-
- if (!InitializeOculusCAPI()) {
- return nullptr;
- }
-
- RefPtr<VRSystemManagerOculus> manager = new VRSystemManagerOculus();
- return manager.forget();
-}
-
-bool
-VRSystemManagerOculus::Init()
-{
- if (!mOculusInitialized) {
- nsIThread* thread = nullptr;
- NS_GetCurrentThread(&thread);
- mOculusThread = already_AddRefed<nsIThread>(thread);
-
- ovrInitParams params;
- memset(¶ms, 0, sizeof(params));
- params.Flags = ovrInit_RequestVersion;
- params.RequestedMinorVersion = OVR_MINOR_VERSION;
- params.LogCallback = nullptr;
- params.ConnectionTimeoutMS = 0;
-
- ovrResult orv = ovr_Initialize(¶ms);
-
- if (orv == ovrSuccess) {
- mOculusInitialized = true;
- }
- }
-
- return mOculusInitialized;
-}
-
-void
-VRSystemManagerOculus::Destroy()
-{
- if (mOculusInitialized) {
- MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread);
- mOculusThread = nullptr;
-
- mHMDInfo = nullptr;
-
- ovr_Shutdown();
- mOculusInitialized = false;
- }
-}
-
-void
-VRSystemManagerOculus::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
-{
- if (!mOculusInitialized) {
- return;
- }
-
- // ovr_Create can be slow when no HMD is present and we wish
- // to keep the same oculus session when possible, so we detect
- // presence of an HMD with ovr_GetHmdDesc before calling ovr_Create
- ovrHmdDesc desc = ovr_GetHmdDesc(NULL);
- if (desc.Type == ovrHmd_None) {
- // No HMD connected.
- mHMDInfo = nullptr;
- } else if (mHMDInfo == nullptr) {
- // HMD Detected
- ovrSession session;
- ovrGraphicsLuid luid;
- ovrResult orv = ovr_Create(&session, &luid);
- if (orv == ovrSuccess) {
- mSession = session;
- mHMDInfo = new VRDisplayOculus(session);
- }
- }
-
- if (mHMDInfo) {
- aHMDResult.AppendElement(mHMDInfo);
- }
-}
-
-void
-VRSystemManagerOculus::HandleInput()
-{
-}
-
-void
-VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
- uint64_t aButtonPressed)
-{
-}
-
-void
-VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
- float aValue)
-{
-}
-
-void
-VRSystemManagerOculus::HandlePoseTracking(uint32_t aControllerIdx,
- const GamepadPoseState& aPose,
- VRControllerHost* aController)
-{
-}
-
-void
-VRSystemManagerOculus::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
-{
-}
-
-void
-VRSystemManagerOculus::ScanForControllers()
-{
-}
-
-void
-VRSystemManagerOculus::RemoveControllers()
-{
-}
-
already_AddRefed<CompositingRenderTargetD3D11>
VRDisplayOculus::GetNextRenderTarget()
{
int currentRenderTarget = 0;
DebugOnly<ovrResult> orv = ovr_GetTextureSwapChainCurrentIndex(mSession, mTextureSet, ¤tRenderTarget);
MOZ_ASSERT(orv == ovrSuccess, "ovr_GetTextureSwapChainCurrentIndex failed.");
mRenderTargets[currentRenderTarget]->ClearOnBind();
@@ -935,10 +826,237 @@ VRDisplayOculus::SubmitFrame(TextureSour
}
void
VRDisplayOculus::NotifyVSync()
{
ovrSessionStatus sessionStatus;
ovrResult ovr = ovr_GetSessionStatus(mSession, &sessionStatus);
mDisplayInfo.mIsConnected = (ovr == ovrSuccess && sessionStatus.HmdPresent);
- mDisplayInfo.mIsMounted = (ovr == ovrSuccess && sessionStatus.HmdMounted);
+}
+
+VRControllerOculus::VRControllerOculus()
+ : VRControllerHost(VRDeviceType::Oculus)
+{
+ MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
+ mControllerInfo.mControllerName.AssignLiteral("Oculus Touch Controller");
+ mControllerInfo.mMappingType = GamepadMappingType::_empty;
+ mControllerInfo.mHand = GamepadHand::_empty;
+ mControllerInfo.mNumButtons = kNumOculusButton;
+ mControllerInfo.mNumAxes = kNumOculusAxis;
+}
+
+VRControllerOculus::~VRControllerOculus()
+{
+ MOZ_COUNT_DTOR_INHERITED(VRControllerOculus, VRControllerHost);
+}
+
+/*static*/ already_AddRefed<VRSystemManagerOculus>
+VRSystemManagerOculus::Create()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculusEnabled())
+ {
+ return nullptr;
+ }
+
+ if (!InitializeOculusCAPI()) {
+ return nullptr;
+ }
+
+ RefPtr<VRSystemManagerOculus> manager = new VRSystemManagerOculus();
+ return manager.forget();
+}
+
+bool
+VRSystemManagerOculus::Init()
+{
+ if (!mOculusInitialized) {
+ nsIThread* thread = nullptr;
+ NS_GetCurrentThread(&thread);
+ mOculusThread = already_AddRefed<nsIThread>(thread);
+
+ ovrInitParams params;
+ memset(¶ms, 0, sizeof(params));
+ params.Flags = ovrInit_RequestVersion;
+ params.RequestedMinorVersion = OVR_MINOR_VERSION;
+ params.LogCallback = nullptr;
+ params.ConnectionTimeoutMS = 0;
+
+ ovrResult orv = ovr_Initialize(¶ms);
+
+ if (orv == ovrSuccess) {
+ mOculusInitialized = true;
+ }
+ }
+
+ return mOculusInitialized;
+}
+
+void
+VRSystemManagerOculus::Destroy()
+{
+ if (mOculusInitialized) {
+ MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread);
+ mOculusThread = nullptr;
+ mSession = nullptr;
+ mHMDInfo = nullptr;
+
+ ovr_Shutdown();
+ mOculusInitialized = false;
+ }
+}
+
+void
+VRSystemManagerOculus::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
+{
+ if (!mOculusInitialized) {
+ return;
+ }
+
+ // ovr_Create can be slow when no HMD is present and we wish
+ // to keep the same oculus session when possible, so we detect
+ // presence of an HMD with ovr_GetHmdDesc before calling ovr_Create
+ ovrHmdDesc desc = ovr_GetHmdDesc(NULL);
+ if (desc.Type == ovrHmd_None) {
+ // No HMD connected.
+ mHMDInfo = nullptr;
+ } else if (mHMDInfo == nullptr) {
+ // HMD Detected
+ ovrSession session;
+ ovrGraphicsLuid luid;
+ ovrResult orv = ovr_Create(&session, &luid);
+ if (orv == ovrSuccess) {
+ mSession = session;
+ mHMDInfo = new VRDisplayOculus(session);
+ }
+ }
+
+ if (mHMDInfo) {
+ aHMDResult.AppendElement(mHMDInfo);
+ }
}
+
+void
+VRSystemManagerOculus::HandleInput()
+{
+ // mSession is available after VRDisplay is created
+ // at GetHMDs().
+ if (!mSession) {
+ return;
+ }
+
+ RefPtr<impl::VRControllerOculus> controller;
+ ovrInputState inputState;
+ bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
+ &inputState) == ovrSuccess;
+
+ if (!hasInputState) {
+ return;
+ }
+
+ for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
+ controller = mOculusController[i];
+ HandleButtonPress(controller->GetIndex(), inputState.Buttons);
+ }
+}
+
+void
+VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
+ uint64_t aButtonPressed)
+{
+ // TODO: Bug 1305890
+}
+
+void
+VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+ float aValue)
+{
+ // TODO: Bug 1305890
+}
+
+void
+VRSystemManagerOculus::HandlePoseTracking(uint32_t aControllerIdx,
+ const GamepadPoseState& aPose,
+ VRControllerHost* aController)
+{
+ // TODO: Bug 1305891
+}
+
+void
+VRSystemManagerOculus::GetControllers(nsTArray<RefPtr<VRControllerHost>>&
+ aControllerResult)
+{
+ if (!mOculusInitialized) {
+ return;
+ }
+
+ aControllerResult.Clear();
+ for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
+ aControllerResult.AppendElement(mOculusController[i]);
+ }
+}
+
+void
+VRSystemManagerOculus::ScanForControllers()
+{
+ // mSession is available after VRDisplay is created
+ // at GetHMDs().
+ if (!mSession) {
+ return;
+ }
+
+ ovrInputState inputState;
+ bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
+ &inputState) == ovrSuccess;
+ ovrControllerType activeControllerArray[2];
+ uint32_t newControllerCount = 0;
+
+ if (inputState.ControllerType & ovrControllerType_LTouch) {
+ activeControllerArray[newControllerCount] = ovrControllerType_LTouch;
+ ++newControllerCount;
+ }
+
+ if (inputState.ControllerType & ovrControllerType_RTouch) {
+ activeControllerArray[newControllerCount] = ovrControllerType_RTouch;
+ ++newControllerCount;
+ }
+
+ if (newControllerCount != mControllerCount) {
+ // controller count is changed, removing the existing gamepads first.
+ for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
+ RemoveGamepad(mOculusController[i]->GetIndex());
+ }
+
+ mControllerCount = 0;
+ mOculusController.Clear();
+
+ // Re-adding controllers to VRControllerManager.
+ for (uint32_t i = 0; i < newControllerCount; ++i) {
+ GamepadHand hand;
+
+ switch (activeControllerArray[i]) {
+ case ovrControllerType::ovrControllerType_LTouch:
+ hand = GamepadHand::Left;
+ break;
+ case ovrControllerType::ovrControllerType_RTouch:
+ hand = GamepadHand::Right;
+ break;
+ }
+ RefPtr<VRControllerOculus> oculusController = new VRControllerOculus();
+ oculusController->SetIndex(mControllerCount);
+ oculusController->SetHand(hand);
+ mOculusController.AppendElement(oculusController);
+
+ // Not already present, add it.
+ AddGamepad(oculusController->GetControllerInfo());
+ ++mControllerCount;
+ }
+ }
+}
+
+void
+VRSystemManagerOculus::RemoveControllers()
+{
+ mOculusController.Clear();
+ mControllerCount = 0;
+}
\ No newline at end of file
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -81,16 +81,25 @@ protected:
bool UpdateConstantBuffers();
struct Vertex
{
float position[2];
};
};
+class VRControllerOculus : public VRControllerHost
+{
+public:
+ explicit VRControllerOculus();
+
+protected:
+ virtual ~VRControllerOculus();
+};
+
} // namespace impl
class VRSystemManagerOculus : public VRSystemManager
{
public:
static already_AddRefed<VRSystemManagerOculus> Create();
virtual bool Init() override;
virtual void Destroy() override;
@@ -98,29 +107,30 @@ public:
virtual void HandleInput() override;
virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
aControllerResult) override;
virtual void ScanForControllers() override;
virtual void RemoveControllers() override;
protected:
VRSystemManagerOculus()
- : mOculusInitialized(false)
+ : mSession(nullptr), mOculusInitialized(false)
{ }
private:
virtual void HandleButtonPress(uint32_t aControllerIdx,
uint64_t aButtonPressed) override;
virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
float aValue) override;
virtual void HandlePoseTracking(uint32_t aControllerIdx,
const dom::GamepadPoseState& aPose,
VRControllerHost* aController) override;
RefPtr<impl::VRDisplayOculus> mHMDInfo;
+ nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
RefPtr<nsIThread> mOculusThread;
ovrSession mSession;
bool mOculusInitialized;
};
} // namespace gfx
} // namespace mozilla
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -419,17 +419,17 @@ VRDisplayOpenVR::NotifyVSync()
// Make sure we respond to OpenVR events even when not presenting
PollEvents();
}
VRControllerOpenVR::VRControllerOpenVR()
: VRControllerHost(VRDeviceType::OpenVR)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
- mControllerInfo.mControllerName.AssignLiteral("OpenVR Gamepad");
+ mControllerInfo.mControllerName.AssignLiteral("OpenVR Controller");
mControllerInfo.mMappingType = GamepadMappingType::_empty;
mControllerInfo.mHand = GamepadHand::_empty;
mControllerInfo.mNumButtons = gNumOpenVRButtonMask;
mControllerInfo.mNumAxes = gNumOpenVRAxis;
}
VRControllerOpenVR::~VRControllerOpenVR()
{