Bug 1469967 - Implement immersive mode for gfxVRExternal r=rbarker

- The VR External interface/shmem and gfxVRExternal are
  updated to enable entering VR, exiting VR, and submitting
  frames.
- You can now construct gfxVRExternal using a pointer to
  the VR External API shmem, if it is created elsewhere.

MozReview-Commit-ID: LZuoLvoEmKO

--HG--
extra : rebase_source : ab38ae4c34f9ac5cdd69e7222f12b1c758307057
This commit is contained in:
Kearwood "Kip" Gilbert 2018-05-08 11:31:28 -07:00
parent 742cfdad99
commit 89b524f028
18 changed files with 422 additions and 211 deletions

View File

@ -273,83 +273,8 @@ VRDisplayHost::SubmitFrameInternal(const layers::SurfaceDescriptor &aTexture,
#endif // !defined(MOZ_WIDGET_ANDROID)
AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplayHost");
mFrameStarted = false;
switch (aTexture.type()) {
#if defined(XP_WIN)
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
if (!CreateD3DObjects()) {
return;
}
const SurfaceDescriptorD3D10& surf = aTexture.get_SurfaceDescriptorD3D10();
RefPtr<ID3D11Texture2D> dxTexture;
HRESULT hr = mDevice->OpenSharedResource((HANDLE)surf.handle(),
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)getter_AddRefs(dxTexture));
if (FAILED(hr) || !dxTexture) {
NS_WARNING("Failed to open shared texture");
return;
}
// Similar to LockD3DTexture in TextureD3D11.cpp
RefPtr<IDXGIKeyedMutex> mutex;
dxTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
if (mutex) {
HRESULT hr = mutex->AcquireSync(0, 1000);
if (hr == WAIT_TIMEOUT) {
gfxDevCrash(LogReason::D3DLockTimeout) << "D3D lock mutex timeout";
}
else if (hr == WAIT_ABANDONED) {
gfxCriticalNote << "GFX: D3D11 lock mutex abandoned";
}
if (FAILED(hr)) {
NS_WARNING("Failed to lock the texture");
return;
}
}
bool success = SubmitFrame(dxTexture, surf.size(),
aLeftEyeRect, aRightEyeRect);
if (mutex) {
HRESULT hr = mutex->ReleaseSync(0);
if (FAILED(hr)) {
NS_WARNING("Failed to unlock the texture");
}
}
if (!success) {
return;
}
break;
}
#elif defined(XP_MACOSX)
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
const auto& desc = aTexture.get_SurfaceDescriptorMacIOSurface();
RefPtr<MacIOSurface> surf = MacIOSurface::LookupSurface(desc.surfaceId(),
desc.scaleFactor(),
!desc.isOpaque());
if (!surf) {
NS_WARNING("VRDisplayHost::SubmitFrame failed to get a MacIOSurface");
return;
}
IntSize texSize = gfx::IntSize(surf->GetDevicePixelWidth(),
surf->GetDevicePixelHeight());
if (!SubmitFrame(surf, texSize, aLeftEyeRect, aRightEyeRect)) {
return;
}
break;
}
#elif defined(MOZ_WIDGET_ANDROID)
case SurfaceDescriptor::TSurfaceTextureDescriptor: {
const SurfaceTextureDescriptor& desc = aTexture.get_SurfaceTextureDescriptor();
if (!SubmitFrame(desc, aLeftEyeRect, aRightEyeRect)) {
return;
}
break;
}
#endif
default: {
NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture");
return;
}
if (!SubmitFrame(aTexture, aFrameId, aLeftEyeRect, aRightEyeRect)) {
return;
}
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
@ -381,12 +306,6 @@ VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
#if !defined(MOZ_WIDGET_ANDROID)
if (!mSubmitThread) {
mSubmitThread = new VRThread(NS_LITERAL_CSTRING("VR_SubmitFrame"));
}
#endif // !defined(MOZ_WIDGET_ANDROID)
if ((mDisplayInfo.mGroupMask & aLayer->GetGroup()) == 0) {
// Suppress layers hidden by the group mask
return;
@ -397,12 +316,18 @@ VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
return;
}
mFrameStarted = false;
RefPtr<Runnable> submit =
NewRunnableMethod<StoreCopyPassByConstLRef<layers::SurfaceDescriptor>, uint64_t,
StoreCopyPassByConstLRef<gfx::Rect>, StoreCopyPassByConstLRef<gfx::Rect>>(
"gfx::VRDisplayHost::SubmitFrameInternal", this, &VRDisplayHost::SubmitFrameInternal,
aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
#if !defined(MOZ_WIDGET_ANDROID)
if (!mSubmitThread) {
mSubmitThread = new VRThread(NS_LITERAL_CSTRING("VR_SubmitFrame"));
}
mSubmitThread->Start();
mSubmitThread->PostTask(submit.forget());
#else

View File

@ -72,25 +72,13 @@ protected:
explicit VRDisplayHost(VRDeviceType aType);
virtual ~VRDisplayHost();
#if defined(XP_WIN)
// Subclasses should override this SubmitFrame function.
// Returns true if the SubmitFrame call will block as necessary
// to control timing of the next frame and throttle the render loop
// for the needed framerate.
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
const IntSize& aSize,
// This SubmitFrame() must be overridden by children and block until
// the next frame is ready to start and the resources in aTexture can
// safely be released.
virtual bool SubmitFrame(const layers::SurfaceDescriptor& aTexture,
uint64_t aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#elif defined(XP_MACOSX)
virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#elif defined(MOZ_WIDGET_ANDROID)
virtual bool SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aSurface,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#endif
VRDisplayInfo mDisplayInfo;

132
gfx/vr/VRDisplayLocal.cpp Normal file
View File

@ -0,0 +1,132 @@
/* -*- 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 "VRDisplayLocal.h"
#include "gfxPrefs.h"
#include "gfxVR.h"
#include "ipc/VRLayerParent.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/dom/GamepadBinding.h" // For GamepadMappingType
#include "VRThread.h"
#if defined(XP_WIN)
#include <d3d11.h>
#include "gfxWindowsPlatform.h"
#include "../layers/d3d11/CompositorD3D11.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/TextureD3D11.h"
#elif defined(XP_MACOSX)
#include "mozilla/gfx/MacIOSurface.h"
#endif
#if defined(MOZ_WIDGET_ANDROID)
#include "mozilla/layers/CompositorThread.h"
#endif // defined(MOZ_WIDGET_ANDROID)
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::layers;
VRDisplayLocal::VRDisplayLocal(VRDeviceType aType)
: VRDisplayHost(aType)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayLocal, VRDisplayHost);
}
VRDisplayLocal::~VRDisplayLocal()
{
MOZ_COUNT_DTOR_INHERITED(VRDisplayLocal, VRDisplayHost);
}
bool
VRDisplayLocal::SubmitFrame(const layers::SurfaceDescriptor &aTexture,
uint64_t aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
#if !defined(MOZ_WIDGET_ANDROID)
MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
#endif // !defined(MOZ_WIDGET_ANDROID)
switch (aTexture.type()) {
#if defined(XP_WIN)
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
if (!CreateD3DObjects()) {
return false;
}
const SurfaceDescriptorD3D10& surf = aTexture.get_SurfaceDescriptorD3D10();
RefPtr<ID3D11Texture2D> dxTexture;
HRESULT hr = mDevice->OpenSharedResource((HANDLE)surf.handle(),
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)getter_AddRefs(dxTexture));
if (FAILED(hr) || !dxTexture) {
NS_WARNING("Failed to open shared texture");
return false;
}
// Similar to LockD3DTexture in TextureD3D11.cpp
RefPtr<IDXGIKeyedMutex> mutex;
dxTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
if (mutex) {
HRESULT hr = mutex->AcquireSync(0, 1000);
if (hr == WAIT_TIMEOUT) {
gfxDevCrash(LogReason::D3DLockTimeout) << "D3D lock mutex timeout";
}
else if (hr == WAIT_ABANDONED) {
gfxCriticalNote << "GFX: D3D11 lock mutex abandoned";
}
if (FAILED(hr)) {
NS_WARNING("Failed to lock the texture");
return false;
}
}
bool success = SubmitFrame(dxTexture, surf.size(),
aLeftEyeRect, aRightEyeRect);
if (mutex) {
HRESULT hr = mutex->ReleaseSync(0);
if (FAILED(hr)) {
NS_WARNING("Failed to unlock the texture");
}
}
return success;
}
#elif defined(XP_MACOSX)
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
const auto& desc = aTexture.get_SurfaceDescriptorMacIOSurface();
RefPtr<MacIOSurface> surf = MacIOSurface::LookupSurface(desc.surfaceId(),
desc.scaleFactor(),
!desc.isOpaque());
if (!surf) {
NS_WARNING("VRDisplayHost::SubmitFrame failed to get a MacIOSurface");
return false;
}
IntSize texSize = gfx::IntSize(surf->GetDevicePixelWidth(),
surf->GetDevicePixelHeight());
if (!SubmitFrame(surf, texSize, aLeftEyeRect, aRightEyeRect)) {
return false;
}
return true;
}
#elif defined(MOZ_WIDGET_ANDROID)
case SurfaceDescriptor::TSurfaceTextureDescriptor: {
const SurfaceTextureDescriptor& desc = aTexture.get_SurfaceTextureDescriptor();
if (!SubmitFrame(desc, aLeftEyeRect, aRightEyeRect)) {
return false;
}
return true;
}
#endif
default: {
NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture");
return false;
}
}
}

61
gfx/vr/VRDisplayLocal.h Normal file
View File

@ -0,0 +1,61 @@
/* -*- 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_DISPLAY_LOCAL_H
#define GFX_VR_DISPLAY_LOCAL_H
#include "gfxVR.h"
#include "VRDisplayHost.h"
#if defined(XP_WIN)
#include <d3d11_1.h>
#elif defined(XP_MACOSX)
class MacIOSurface;
#endif
namespace mozilla {
namespace gfx {
class VRThread;
class VRDisplayLocal : public VRDisplayHost
{
public:
#if defined(XP_WIN)
// Subclasses should override this SubmitFrame function.
// Returns true if the SubmitFrame call will block as necessary
// to control timing of the next frame and throttle the render loop
// for the needed framerate.
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#elif defined(XP_MACOSX)
virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#elif defined(MOZ_WIDGET_ANDROID)
virtual bool SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aSurface,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#endif
protected:
explicit VRDisplayLocal(VRDeviceType aType);
virtual ~VRDisplayLocal();
private:
bool SubmitFrame(const layers::SurfaceDescriptor& aTexture,
uint64_t aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) final;
};
} // namespace gfx
} // namespace mozilla
#endif // GFX_VR_DISPLAY_LOCAL_H

View File

@ -231,6 +231,12 @@ VRManager::CheckForInactiveTimeout()
TimeDuration duration = TimeStamp::Now() - mLastActiveTime;
if (duration.ToMilliseconds() > gfxPrefs::VRInactiveTimeout()) {
Shutdown();
// We must not throttle the next enumeration request
// after an idle timeout, as it may result in the
// user needing to refresh the browser to detect
// VR hardware when leaving and returning to a VR
// site.
mLastDisplayEnumerationTime = TimeStamp();
}
}
}

View File

@ -235,6 +235,8 @@ struct VRDisplayState
FloatSize_POD mStageSize;
// We can't use a Matrix4x4 here unless we ensure it's a POD type
float mSittingToStandingTransform[16];
uint64_t mLastSubmittedFrameId;
bool mLastSubmittedFrameSuccessful;
uint32_t mPresentingGeneration;
};
@ -274,9 +276,8 @@ enum class VRLayerType : uint16_t {
enum class VRLayerTextureType : uint16_t {
LayerTextureType_None = 0,
LayerTextureType_DirectX = 1,
LayerTextureType_OpenGL = 2,
LayerTextureType_Vulkan = 3
LayerTextureType_D3D10SurfaceDescriptor = 1,
LayerTextureType_MacIOSurface = 2
};
struct VRLayer_2D_Content
@ -291,6 +292,7 @@ struct VRLayer_Stereo_Immersive
void* mTextureHandle;
VRLayerTextureType mTextureType;
uint64_t mFrameId;
uint64_t mInputFrameId;
VRLayerEyeRect mLeftEyeRect;
VRLayerEyeRect mRightEyeRect;
};
@ -315,6 +317,7 @@ struct VRBrowserState
struct VRSystemState
{
uint32_t presentingGeneration;
bool enumerationCompleted;
VRDisplayState displayState;
VRHMDSensorState sensorState;
VRControllerState controllerState[kVRControllerMaxCount];

View File

@ -102,8 +102,6 @@ VRDisplayExternal::GetSensorState()
manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState);
// result.CalcViewMatrices(headToEyeTransforms);
mLastSensorState.inputFrameID = mDisplayInfo.mFrameId;
return mLastSensorState;
}
@ -117,7 +115,15 @@ VRDisplayExternal::StartPresentation()
mTelemetry.Clear();
mTelemetry.mPresentationStart = TimeStamp::Now();
// TODO - Implement this
// Indicate that we are ready to start immersive mode
VRBrowserState state;
memset(&state, 0, sizeof(VRBrowserState));
state.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
VRManager *vm = VRManager::Get();
VRSystemManagerExternal* manager = vm->GetExternalManager();
manager->PushState(&state);
// TODO - Implement telemetry:
// mTelemetry.mLastDroppedFrameCount = stats.m_nNumReprojectedFrames;
}
@ -128,11 +134,18 @@ VRDisplayExternal::StopPresentation()
if (!mIsPresenting) {
return;
}
mIsPresenting = false;
// TODO - Implement this
// Indicate that we have stopped immersive mode
VRBrowserState state;
memset(&state, 0, sizeof(VRBrowserState));
VRManager *vm = VRManager::Get();
VRSystemManagerExternal* manager = vm->GetExternalManager();
manager->PushState(&state);
// TODO - Implement telemetry:
/*
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,
@ -146,47 +159,88 @@ VRDisplayExternal::StopPresentation()
*/
}
bool
VRDisplayExternal::PopulateLayerTexture(const layers::SurfaceDescriptor& aTexture,
VRLayerTextureType* aTextureType,
void** aTextureHandle)
{
switch (aTexture.type()) {
#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;
}
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
const SurfaceDescriptorD3D10& surf = aTexture.get_SurfaceDescriptorD3D10();
*aTextureType = VRLayerTextureType::LayerTextureType_D3D10SurfaceDescriptor;
*aTextureHandle = (void *)surf.handle();
return true;
}
#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;
}
#elif defined(MOZ_WIDGET_ANDROID)
bool
VRDisplayExternal::SubmitFrame(const layers::SurfaceTextureDescriptor& aSurface,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) {
return false;
}
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
const auto& desc = aTexture.get_SurfaceDescriptorMacIOSurface();
RefPtr<MacIOSurface> surf = MacIOSurface::LookupSurface(desc.surfaceId(),
desc.scaleFactor(),
!desc.isOpaque());
if (!surf) {
NS_WARNING("VRDisplayHost::SubmitFrame failed to get a MacIOSurface");
return false;
}
*aTextureType = VRLayerTextureType::LayerTextureType_MacIOSurface;
*aTextureHandle = (void *)surf->GetIOSurfacePtr();
return true;
}
#endif
default: {
MOZ_ASSERT(false);
return false;
}
}
}
bool
VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
uint64_t aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
VRBrowserState state;
memset(&state, 0, sizeof(VRBrowserState));
state.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
VRLayer_Stereo_Immersive& layer = state.layerState[0].layer_stereo_immersive;
if (!PopulateLayerTexture(aTexture, &layer.mTextureType, &layer.mTextureHandle)) {
return false;
}
layer.mFrameId = aFrameId;
layer.mInputFrameId = mDisplayInfo.mLastSensorState[mDisplayInfo.mFrameId % kVRMaxLatencyFrames].inputFrameID;
layer.mLeftEyeRect.x = aLeftEyeRect.x;
layer.mLeftEyeRect.y = aLeftEyeRect.y;
layer.mLeftEyeRect.width = aLeftEyeRect.width;
layer.mLeftEyeRect.height = aLeftEyeRect.height;
layer.mRightEyeRect.x = aRightEyeRect.x;
layer.mRightEyeRect.y = aRightEyeRect.y;
layer.mRightEyeRect.width = aRightEyeRect.width;
layer.mRightEyeRect.height = aRightEyeRect.height;
VRManager *vm = VRManager::Get();
VRSystemManagerExternal* manager = vm->GetExternalManager();
manager->PushState(&state);
VRDisplayState displayState;
memset(&displayState, 0, sizeof(VRDisplayState));
while (displayState.mLastSubmittedFrameId < aFrameId) {
if (manager->PullState(&displayState)) {
if (!displayState.mIsConnected) {
// Service has shut down or hardware has been disconnected
return false;
}
}
#ifdef XP_WIN
Sleep(0);
#else
sleep(0);
#endif
}
return displayState.mLastSubmittedFrameSuccessful;
}
VRControllerExternal::VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID,
uint32_t aNumButtons, uint32_t aNumTriggers,
@ -208,8 +262,9 @@ VRControllerExternal::~VRControllerExternal()
MOZ_COUNT_DTOR_INHERITED(VRControllerExternal, VRControllerHost);
}
VRSystemManagerExternal::VRSystemManagerExternal()
: mExternalShmem(nullptr)
VRSystemManagerExternal::VRSystemManagerExternal(VRExternalShmem* aAPIShmem /* = nullptr*/)
: mExternalShmem(aAPIShmem)
, mSameProcess(aAPIShmem != nullptr)
{
#if defined(XP_MACOSX)
mShmemFD = 0;
@ -323,6 +378,9 @@ VRSystemManagerExternal::CheckForShutdown()
void
VRSystemManagerExternal::CloseShmem()
{
if (mSameProcess) {
return;
}
#if defined(XP_MACOSX)
if (mExternalShmem) {
munmap((void *)mExternalShmem, sizeof(VRExternalShmem));
@ -347,15 +405,19 @@ VRSystemManagerExternal::CloseShmem()
}
/*static*/ already_AddRefed<VRSystemManagerExternal>
VRSystemManagerExternal::Create()
VRSystemManagerExternal::Create(VRExternalShmem* aAPIShmem /* = nullptr*/)
{
MOZ_ASSERT(NS_IsMainThread());
if (!gfxPrefs::VREnabled() || !gfxPrefs::VRExternalEnabled()) {
if (!gfxPrefs::VREnabled()) {
return nullptr;
}
RefPtr<VRSystemManagerExternal> manager = new VRSystemManagerExternal();
if (!gfxPrefs::VRExternalEnabled() && aAPIShmem == nullptr) {
return nullptr;
}
RefPtr<VRSystemManagerExternal> manager = new VRSystemManagerExternal(aAPIShmem);
return manager.forget();
}
@ -397,7 +459,17 @@ VRSystemManagerExternal::Enumerate()
OpenShmem();
if (mExternalShmem) {
VRDisplayState displayState;
PullState(&displayState);
memset(&displayState, 0, sizeof(VRDisplayState));
// We must block until enumeration has completed in order
// to signal that the WebVR promise should be resolved at the
// right time.
while (!PullState(&displayState)) {
#ifdef XP_WIN
Sleep(0);
#else
sleep(0);
#endif
}
if (displayState.mIsConnected) {
mDisplay = new VRDisplayExternal(displayState);
}
@ -488,9 +560,10 @@ VRSystemManagerExternal::RemoveControllers()
mControllerCount = 0;
}
void
bool
VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState /* = nullptr */)
{
bool success = false;
MOZ_ASSERT(mExternalShmem);
if (mExternalShmem) {
#if defined(MOZ_WIDGET_ANDROID)
@ -501,16 +574,39 @@ VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorSta
}
pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex));
mDoShutdown = aDisplayState->shutdown;
success = mExternalShmem->state.enumerationCompleted;
}
#else
VRExternalShmem tmp;
memcpy(&tmp, (void *)mExternalShmem, sizeof(VRExternalShmem));
if (tmp.generationA == tmp.generationB && tmp.generationA != 0 && tmp.generationA != -1) {
if (tmp.generationA == tmp.generationB && tmp.generationA != 0 && tmp.generationA != -1 && tmp.state.enumerationCompleted) {
memcpy(aDisplayState, &tmp.state.displayState, sizeof(VRDisplayState));
if (aSensorState) {
memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState));
}
success = true;
}
#endif // defined(MOZ_WIDGET_ANDROID)
}
return success;
}
void
VRSystemManagerExternal::PushState(VRBrowserState* aBrowserState)
{
MOZ_ASSERT(aBrowserState);
MOZ_ASSERT(mExternalShmem);
if (mExternalShmem) {
#if defined(MOZ_WIDGET_ANDROID)
if (pthread_mutex_lock((pthread_mutex_t*)&(mExternalShmem->browserMutex)) == 0) {
memcpy((void *)&(mExternalShmem->browserState), aBrowserState, sizeof(VRBrowserState));
pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->browserMutex));
}
#else
mExternalShmem->browserGenerationA++;
memcpy((void *)&(mExternalShmem->browserState), (void *)aBrowserState, sizeof(VRBrowserState));
mExternalShmem->browserGenerationB++;
#endif // defined(MOZ_WIDGET_ANDROID)
}
}

View File

@ -33,24 +33,14 @@ 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;
#elif defined(MOZ_WIDGET_ANDROID)
bool SubmitFrame(const layers::SurfaceTextureDescriptor& aSurface,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
#endif
VRHMDSensorState GetSensorState() override;
void StartPresentation() override;
void StopPresentation() override;
bool SubmitFrame(const layers::SurfaceDescriptor& aTexture,
uint64_t aFrameId,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
public:
explicit VRDisplayExternal(const VRDisplayState& aDisplayState);
@ -59,6 +49,11 @@ protected:
virtual ~VRDisplayExternal();
void Destroy();
private:
bool PopulateLayerTexture(const layers::SurfaceDescriptor& aTexture,
VRLayerTextureType* aTextureType,
void** aTextureHandle);
VRTelemetry mTelemetry;
bool mIsPresenting;
VRHMDSensorState mLastSensorState;
@ -80,7 +75,7 @@ protected:
class VRSystemManagerExternal : public VRSystemManager
{
public:
static already_AddRefed<VRSystemManagerExternal> Create();
static already_AddRefed<VRSystemManagerExternal> Create(VRExternalShmem* aAPIShmem = nullptr);
virtual void Destroy() override;
virtual void Shutdown() override;
@ -100,10 +95,11 @@ public:
double aDuration,
const VRManagerPromise& aPromise) override;
virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
void PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState = nullptr);
bool PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState = nullptr);
void PushState(VRBrowserState* aBrowserState);
protected:
VRSystemManagerExternal();
explicit VRSystemManagerExternal(VRExternalShmem* aAPIShmem = nullptr);
virtual ~VRSystemManagerExternal();
private:
@ -120,6 +116,7 @@ private:
#endif
volatile VRExternalShmem* mExternalShmem;
bool mSameProcess;
void OpenShmem();
void CloseShmem();

View File

@ -211,13 +211,13 @@ SetFromTanRadians(double left, double right, double bottom, double top)
VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
OSVR_ClientInterface* iface,
OSVR_DisplayConfig* display)
: VRDisplayHost(VRDeviceType::OSVR)
: VRDisplayLocal(VRDeviceType::OSVR)
, m_ctx(context)
, m_iface(iface)
, m_display(display)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOSVR, VRDisplayHost);
MOZ_COUNT_CTOR_INHERITED(VRDisplayOSVR, VRDisplayLocal);
VRDisplayState& state = mDisplayInfo.mDisplayState;
state.mIsConnected = true;

View File

@ -14,7 +14,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/EnumeratedArray.h"
#include "VRDisplayHost.h"
#include "VRDisplayLocal.h"
#include <osvr/ClientKit/ClientKitC.h>
#include <osvr/ClientKit/DisplayC.h>
@ -26,7 +26,7 @@ namespace mozilla {
namespace gfx {
namespace impl {
class VRDisplayOSVR : public VRDisplayHost
class VRDisplayOSVR : public VRDisplayLocal
{
public:
void ZeroSensor() override;
@ -57,7 +57,7 @@ protected:
virtual ~VRDisplayOSVR()
{
Destroy();
MOZ_COUNT_DTOR_INHERITED(VRDisplayOSVR, VRDisplayHost);
MOZ_COUNT_DTOR_INHERITED(VRDisplayOSVR, VRDisplayLocal);
}
void Destroy();

View File

@ -795,7 +795,7 @@ VROculusSession::UnloadOvrLib()
}
VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
: VRDisplayHost(VRDeviceType::Oculus)
: VRDisplayLocal(VRDeviceType::Oculus)
, mSession(aSession)
, mQuadVS(nullptr)
, mQuadPS(nullptr)
@ -806,7 +806,7 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
, mInputLayout(nullptr)
, mEyeHeight(OVR_DEFAULT_EYE_HEIGHT)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
MOZ_COUNT_CTOR_INHERITED(VRDisplayOculus, VRDisplayLocal);
VRDisplayState& state = mDisplayInfo.mDisplayState;
strncpy(state.mDisplayName, "Oculus VR HMD", kVRDisplayNameMaxLen);
state.mIsConnected = true;
@ -852,7 +852,7 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
VRDisplayOculus::~VRDisplayOculus() {
Destroy();
MOZ_COUNT_DTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
MOZ_COUNT_DTOR_INHERITED(VRDisplayOculus, VRDisplayLocal);
}
void

View File

@ -15,7 +15,7 @@
#include "mozilla/EnumeratedArray.h"
#include "gfxVR.h"
#include "VRDisplayHost.h"
#include "VRDisplayLocal.h"
#include "ovr_capi_dynamic.h"
struct ID3D11Device;
@ -90,7 +90,7 @@ private:
void StopRendering();
};
class VRDisplayOculus : public VRDisplayHost
class VRDisplayOculus : public VRDisplayLocal
{
public:
void ZeroSensor() override;

View File

@ -50,13 +50,13 @@ static const uint32_t kNumOpenVRHaptcs = 1;
VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
::vr::IVRChaperone *aVRChaperone,
::vr::IVRCompositor *aVRCompositor)
: VRDisplayHost(VRDeviceType::OpenVR)
: VRDisplayLocal(VRDeviceType::OpenVR)
, mVRSystem(aVRSystem)
, mVRChaperone(aVRChaperone)
, mVRCompositor(aVRCompositor)
, mIsPresenting(false)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOpenVR, VRDisplayHost);
MOZ_COUNT_CTOR_INHERITED(VRDisplayOpenVR, VRDisplayLocal);
VRDisplayState& state = mDisplayInfo.mDisplayState;
@ -98,7 +98,7 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
VRDisplayOpenVR::~VRDisplayOpenVR()
{
Destroy();
MOZ_COUNT_DTOR_INHERITED(VRDisplayOpenVR, VRDisplayHost);
MOZ_COUNT_DTOR_INHERITED(VRDisplayOpenVR, VRDisplayLocal);
}
void
@ -350,11 +350,11 @@ VRDisplayOpenVR::StopPresentation()
}
bool
VRDisplayOpenVR::SubmitFrame(void* aTextureHandle,
::vr::ETextureType aTextureType,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
VRDisplayOpenVR::SubmitFrameOpenVRHandle(void* aTextureHandle,
::vr::ETextureType aTextureType,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
if (!mIsPresenting) {
@ -400,9 +400,9 @@ VRDisplayOpenVR::SubmitFrame(ID3D11Texture2D* aSource,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
return SubmitFrame((void *)aSource,
::vr::ETextureType::TextureType_DirectX,
aSize, aLeftEyeRect, aRightEyeRect);
return SubmitFrameOpenVRHandle((void *)aSource,
::vr::ETextureType::TextureType_DirectX,
aSize, aLeftEyeRect, aRightEyeRect);
}
#elif defined(XP_MACOSX)
@ -418,9 +418,9 @@ VRDisplayOpenVR::SubmitFrame(MacIOSurface* aMacIOSurface,
if (ioSurface == nullptr) {
NS_WARNING("VRDisplayOpenVR::SubmitFrame() could not get an IOSurface");
} else {
result = SubmitFrame((void *)ioSurface,
::vr::ETextureType::TextureType_IOSurface,
aSize, aLeftEyeRect, aRightEyeRect);
result = SubmitFrameOpenVRHandle((void *)ioSurface,
::vr::ETextureType::TextureType_IOSurface,
aSize, aLeftEyeRect, aRightEyeRect);
}
return result;
}

View File

@ -17,7 +17,7 @@
#include "openvr.h"
#include "gfxVR.h"
#include "VRDisplayHost.h"
#include "VRDisplayLocal.h"
#if defined(XP_MACOSX)
class MacIOSurface;
@ -28,7 +28,7 @@ class VRThread;
namespace impl {
class VRDisplayOpenVR : public VRDisplayHost
class VRDisplayOpenVR : public VRDisplayLocal
{
public:
void ZeroSensor() override;
@ -70,11 +70,11 @@ protected:
void UpdateStageParameters();
void UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms = nullptr);
bool SubmitFrame(void* aTextureHandle,
::vr::ETextureType aTextureType,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect);
bool SubmitFrameOpenVRHandle(void* aTextureHandle,
::vr::ETextureType aTextureType,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect);
};
class VRControllerOpenVR : public VRControllerHost

View File

@ -50,11 +50,11 @@ static const uint32_t kNumPuppetAxis = 3;
static const uint32_t kNumPuppetHaptcs = 1;
VRDisplayPuppet::VRDisplayPuppet()
: VRDisplayHost(VRDeviceType::Puppet)
: VRDisplayLocal(VRDeviceType::Puppet)
, mIsPresenting(false)
, mSensorState{}
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayPuppet, VRDisplayHost);
MOZ_COUNT_CTOR_INHERITED(VRDisplayPuppet, VRDisplayLocal);
VRDisplayState& state = mDisplayInfo.mDisplayState;
strncpy(state.mDisplayName, "Puppet HMD", kVRDisplayNameMaxLen);
@ -123,7 +123,7 @@ VRDisplayPuppet::VRDisplayPuppet()
VRDisplayPuppet::~VRDisplayPuppet()
{
MOZ_COUNT_DTOR_INHERITED(VRDisplayPuppet, VRDisplayHost);
MOZ_COUNT_DTOR_INHERITED(VRDisplayPuppet, VRDisplayLocal);
}
void

View File

@ -12,7 +12,7 @@
#include "nsRefPtrHashtable.h"
#include "gfxVR.h"
#include "VRDisplayHost.h"
#include "VRDisplayLocal.h"
#if defined(XP_MACOSX)
class MacIOSurface;
@ -21,7 +21,7 @@ namespace mozilla {
namespace gfx {
namespace impl {
class VRDisplayPuppet : public VRDisplayHost
class VRDisplayPuppet : public VRDisplayLocal
{
public:
void SetDisplayInfo(const VRDisplayInfo& aDisplayInfo);

View File

@ -47,6 +47,7 @@ struct ParamTraits<mozilla::gfx::VRDisplayState>
WriteParam(aMsg, aParam.mIsMounted);
WriteParam(aMsg, aParam.mStageSize.width);
WriteParam(aMsg, aParam.mStageSize.height);
WriteParam(aMsg, aParam.mLastSubmittedFrameId);
WriteParam(aMsg, aParam.mPresentingGeneration);
for (int i = 0; i < 16; i++) {
// TODO - Should probably memcpy the whole array or
@ -73,6 +74,7 @@ struct ParamTraits<mozilla::gfx::VRDisplayState>
!ReadParam(aMsg, aIter, &(aResult->mIsMounted)) ||
!ReadParam(aMsg, aIter, &(aResult->mStageSize.width)) ||
!ReadParam(aMsg, aIter, &(aResult->mStageSize.height)) ||
!ReadParam(aMsg, aIter, &(aResult->mLastSubmittedFrameId)) ||
!ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration))) {
return false;
}

View File

@ -47,6 +47,7 @@ SOURCES += [
'gfxVRExternal.cpp',
'gfxVRPuppet.cpp',
'VRDisplayHost.cpp',
'VRDisplayLocal.cpp',
]
# Build OpenVR on Windows, Linux, and macOS desktop targets