Bug 1293333 - Part 1: Implement window.onvrdisplayactivate and window.onvrdisplaydeactivate events r=daoshengmu,Ehsan

MozReview-Commit-ID: 746L5KObBcg

--HG--
extra : rebase_source : 3efa9171be4ec2aa6dc12bd4651e197571cf33c6
This commit is contained in:
Kearwood (Kip) Gilbert 2016-10-18 18:18:10 -04:00
Родитель 531cd887a0
Коммит 8dc97eb398
24 изменённых файлов: 420 добавлений и 10 удалений

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

@ -950,7 +950,9 @@ GK_ATOM(onussdreceived, "onussdreceived")
GK_ATOM(onversionchange, "onversionchange")
GK_ATOM(onvoicechange, "onvoicechange")
GK_ATOM(onvoiceschanged, "onvoiceschanged")
GK_ATOM(onvrdisplayactivate, "onvrdisplayactivate")
GK_ATOM(onvrdisplayconnect, "onvrdisplayconnect")
GK_ATOM(onvrdisplaydeactivate, "onvrdisplaydeactivate")
GK_ATOM(onvrdisplaydisconnect, "onvrdisplaydisconnect")
GK_ATOM(onvrdisplaypresentchange, "onvrdisplaypresentchange")
GK_ATOM(onwebkitAnimationEnd, "onwebkitAnimationEnd")

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

@ -202,6 +202,8 @@
#include "mozilla/dom/GamepadManager.h"
#include "mozilla/dom/VRDisplay.h"
#include "mozilla/dom/VRDisplayEvent.h"
#include "mozilla/dom/VRDisplayEventBinding.h"
#include "mozilla/dom/VREventObserver.h"
#include "nsRefreshDriver.h"
@ -13172,7 +13174,9 @@ nsGlobalWindow::SetHasGamepadEventListener(bool aHasGamepad/* = true*/)
void
nsGlobalWindow::EventListenerAdded(nsIAtom* aType)
{
if (aType == nsGkAtoms::onvrdisplayconnect ||
if (aType == nsGkAtoms::onvrdisplayactivate ||
aType == nsGkAtoms::onvrdisplayconnect ||
aType == nsGkAtoms::onvrdisplaydeactivate ||
aType == nsGkAtoms::onvrdisplaydisconnect ||
aType == nsGkAtoms::onvrdisplaypresentchange) {
NotifyVREventListenerAdded();
@ -13353,6 +13357,62 @@ nsGlobalWindow::NotifyActiveVRDisplaysChanged()
}
}
void
nsGlobalWindow::DispatchVRDisplayActivate(uint32_t aDisplayID,
mozilla::dom::VRDisplayEventReason aReason)
{
for (auto display : mVRDisplays) {
if (display->DisplayId() == aDisplayID
&& !display->IsAnyPresenting()) {
// We only want to trigger this event if nobody is presenting to the
// display already.
VRDisplayEventInit init;
init.mBubbles = true;
init.mCancelable = false;
init.mDisplay = display;
init.mReason.Construct(aReason);
RefPtr<VRDisplayEvent> event =
VRDisplayEvent::Constructor(this,
NS_LITERAL_STRING("vrdisplayactivate"),
init);
// vrdisplayactivate is a trusted event, allowing VRDisplay.requestPresent
// to be used in response to link traversal, user request (chrome UX), and
// HMD mounting detection sensors.
event->SetTrusted(true);
bool defaultActionEnabled;
Unused << DispatchEvent(event, &defaultActionEnabled);
break;
}
}
}
void
nsGlobalWindow::DispatchVRDisplayDeactivate(uint32_t aDisplayID,
mozilla::dom::VRDisplayEventReason aReason)
{
for (auto display : mVRDisplays) {
if (display->DisplayId() == aDisplayID && display->IsPresenting()) {
// We only want to trigger this event to content that is presenting to
// the display already.
VRDisplayEventInit init;
init.mBubbles = true;
init.mCancelable = false;
init.mDisplay = display;
init.mReason.Construct(aReason);
RefPtr<VRDisplayEvent> event =
VRDisplayEvent::Constructor(this,
NS_LITERAL_STRING("vrdisplaydeactivate"),
init);
bool defaultActionEnabled;
Unused << DispatchEvent(event, &defaultActionEnabled);
break;
}
}
}
// nsGlobalChromeWindow implementation

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

@ -137,6 +137,7 @@ class TabGroup;
class Timeout;
class U2F;
class VRDisplay;
enum class VRDisplayEventReason : uint8_t;
class VREventObserver;
class WakeLock;
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
@ -758,6 +759,11 @@ public:
// Called to inform that the set of active VR displays has changed.
void NotifyActiveVRDisplaysChanged();
void DispatchVRDisplayActivate(uint32_t aDisplayID,
mozilla::dom::VRDisplayEventReason aReason);
void DispatchVRDisplayDeactivate(uint32_t aDisplayID,
mozilla::dom::VRDisplayEventReason aReason);
#define EVENT(name_, id_, type_, struct_) \
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
{ \

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

@ -607,6 +607,14 @@ WINDOW_ONLY_EVENT(devicelight,
eDeviceLight,
EventNameType_None,
eBasicEventClass)
WINDOW_ONLY_EVENT(vrdisplayactivate,
eVRDisplayActivate,
EventNameType_None,
eBasicEventClass)
WINDOW_ONLY_EVENT(vrdisplaydeactivate,
eVRDisplayDeactivate,
EventNameType_None,
eBasicEventClass)
WINDOW_ONLY_EVENT(vrdisplayconnect,
eVRDisplayConnect,
EventNameType_None,

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

@ -464,9 +464,12 @@ VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, nullptr);
if (mClient->GetIsPresenting()) {
if (!IsPresenting() && IsAnyPresenting()) {
// Only one presentation allowed per VRDisplay
// on a first-come-first-serve basis.
// If this Javascript context is presenting, then we can replace our
// presentation with a new one containing new layers but we should never
// replace the presentation of another context.
promise->MaybeRejectWithUndefined();
} else {
mPresentation = mClient->BeginPresentation(aLayers);
@ -585,6 +588,14 @@ VRDisplay::IsPresenting() const
return mPresentation != nullptr;
}
bool
VRDisplay::IsAnyPresenting() const
{
// IsAnyPresenting returns true if any Javascript context is presenting
// even if this context is not presenting.
return IsPresenting() || mClient->GetIsPresenting();
}
bool
VRDisplay::IsConnected() const
{

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

@ -274,6 +274,7 @@ public:
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
bool IsPresenting() const;
bool IsAnyPresenting() const;
bool IsConnected() const;
VRDisplayCapabilities* Capabilities();

94
dom/vr/VRDisplayEvent.cpp Normal file
Просмотреть файл

@ -0,0 +1,94 @@
/* -*- 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 "VRDisplayEvent.h"
#include "js/GCAPI.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(VRDisplayEvent)
NS_IMPL_ADDREF_INHERITED(VRDisplayEvent, Event)
NS_IMPL_RELEASE_INHERITED(VRDisplayEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRDisplayEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(VRDisplayEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRDisplayEvent, Event)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(VRDisplayEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
VRDisplayEvent::VRDisplayEvent(mozilla::dom::EventTarget* aOwner)
: Event(aOwner, nullptr, nullptr)
{
}
VRDisplayEvent::~VRDisplayEvent()
{
}
VRDisplay*
VRDisplayEvent::Display()
{
return mDisplay;
}
JSObject*
VRDisplayEvent::WrapObjectInternal(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return VRDisplayEventBinding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<VRDisplayEvent>
VRDisplayEvent::Constructor(mozilla::dom::EventTarget* aOwner,
const nsAString& aType,
const VRDisplayEventInit& aEventInitDict)
{
RefPtr<VRDisplayEvent> e = new VRDisplayEvent(aOwner);
bool trusted = e->Init(aOwner);
e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
if (aEventInitDict.mReason.WasPassed()) {
e->mReason = Some(aEventInitDict.mReason.Value());
}
e->SetTrusted(trusted);
e->SetComposed(aEventInitDict.mComposed);
return e.forget();
}
already_AddRefed<VRDisplayEvent>
VRDisplayEvent::Constructor(const GlobalObject& aGlobal, const nsAString& aType,
const VRDisplayEventInit& aEventInitDict,
ErrorResult& aRv)
{
nsCOMPtr<mozilla::dom::EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
return Constructor(owner, aType, aEventInitDict);
}
Nullable<VRDisplayEventReason>
VRDisplayEvent::GetReason() const
{
if (mReason.isSome()) {
return mReason.value();
} else {
return nullptr;
}
}
} // namespace dom
} // namespace mozilla

58
dom/vr/VRDisplayEvent.h Normal file
Просмотреть файл

@ -0,0 +1,58 @@
/* -*- 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 mozilla_dom_VRDisplayEvent_h_
#define mozilla_dom_VRDisplayEvent_h_
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/VRDisplayEventBinding.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Event.h"
#include "gfxVR.h"
struct JSContext;
namespace mozilla {
namespace gfx {
class VRDisplay;
} // namespace gfx
namespace dom {
class VRDisplayEvent final : public Event
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(VRDisplayEvent, Event)
VRDisplay* Display();
Nullable<VRDisplayEventReason> GetReason() const;
protected:
virtual ~VRDisplayEvent();
explicit VRDisplayEvent(mozilla::dom::EventTarget* aOwner);
VRDisplayEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
InternalClipboardEvent* aEvent);
Maybe<VRDisplayEventReason> mReason;
RefPtr<VRDisplay> mDisplay;
public:
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<VRDisplayEvent> Constructor(mozilla::dom::EventTarget* aOwner, const nsAString& aType, const VRDisplayEventInit& aEventInitDict);
static already_AddRefed<VRDisplayEvent> Constructor(const GlobalObject& aGlobal, const nsAString& aType, const VRDisplayEventInit& aEventInitDict, ErrorResult& aRv);
};
} // namespace dom
} // namespace mozilla
#endif

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

@ -16,7 +16,8 @@ namespace dom {
using namespace gfx;
/**
* This class is used by nsGlobalWindow to implement window.onvrdisplayconnected,
* This class is used by nsGlobalWindow to implement window.onvrdisplayactivate,
* window.onvrdisplaydeactivate, window.onvrdisplayconnected,
* window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange.
*/
VREventObserver::VREventObserver(nsGlobalWindow* aGlobalWindow)
@ -38,6 +39,46 @@ VREventObserver::~VREventObserver()
}
}
void
VREventObserver::NotifyVRDisplayMounted(uint32_t aDisplayID)
{
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
mWindow->DispatchVRDisplayActivate(aDisplayID,
VRDisplayEventReason::Mounted);
}
}
void
VREventObserver::NotifyVRDisplayNavigation(uint32_t aDisplayID)
{
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
mWindow->DispatchVRDisplayActivate(aDisplayID,
VRDisplayEventReason::Navigation);
}
}
void
VREventObserver::NotifyVRDisplayRequested(uint32_t aDisplayID)
{
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
mWindow->DispatchVRDisplayActivate(aDisplayID,
VRDisplayEventReason::Requested);
}
}
void
VREventObserver::NotifyVRDisplayUnmounted(uint32_t aDisplayID)
{
if (mWindow->AsInner()->IsCurrentInnerWindow()) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
mWindow->DispatchVRDisplayDeactivate(aDisplayID,
VRDisplayEventReason::Unmounted);
}
}
void
VREventObserver::NotifyVRDisplayConnect()
{

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

@ -7,6 +7,8 @@
#ifndef mozilla_dom_VREventObserver_h
#define mozilla_dom_VREventObserver_h
#include "mozilla/dom/VRDisplayEventBinding.h"
class nsGlobalWindow;
namespace mozilla {
@ -18,6 +20,10 @@ public:
~VREventObserver();
explicit VREventObserver(nsGlobalWindow* aGlobalWindow);
void NotifyVRDisplayMounted(uint32_t aDisplayID);
void NotifyVRDisplayUnmounted(uint32_t aDisplayID);
void NotifyVRDisplayNavigation(uint32_t aDisplayID);
void NotifyVRDisplayRequested(uint32_t aDisplayID);
void NotifyVRDisplayConnect();
void NotifyVRDisplayDisconnect();
void NotifyVRDisplayPresentChange();

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

@ -6,11 +6,13 @@
EXPORTS.mozilla.dom += [
'VRDisplay.h',
'VRDisplayEvent.h',
'VREventObserver.h',
]
UNIFIED_SOURCES = [
'VRDisplay.cpp',
'VRDisplayEvent.cpp',
'VREventObserver.cpp',
]

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

@ -0,0 +1,23 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
enum VRDisplayEventReason {
"mounted",
"navigation",
"requested",
"unmounted",
};
dictionary VRDisplayEventInit : EventInit {
required VRDisplay display;
VRDisplayEventReason reason;
};
[Pref="dom.vr.enabled",
Constructor(DOMString type, VRDisplayEventInit eventInitDict)]
interface VRDisplayEvent : Event {
readonly attribute VRDisplay display;
readonly attribute VRDisplayEventReason? reason;
};

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

@ -472,6 +472,10 @@ partial interface Window {
[Pref="dom.vr.enabled"]
attribute EventHandler onvrdisplaydisconnect;
[Pref="dom.vr.enabled"]
attribute EventHandler onvrdisplayactivate;
[Pref="dom.vr.enabled"]
attribute EventHandler onvrdisplaydeactivate;
[Pref="dom.vr.enabled"]
attribute EventHandler onvrdisplaypresentchange;
};

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

@ -573,6 +573,7 @@ WEBIDL_FILES = [
'VideoTrack.webidl',
'VideoTrackList.webidl',
'VRDisplay.webidl',
'VRDisplayEvent.webidl',
'VTTCue.webidl',
'VTTRegion.webidl',
'WaveShaperNode.webidl',

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

@ -29,6 +29,7 @@ using namespace mozilla::gfx;
VRDisplayClient::VRDisplayClient(const VRDisplayInfo& aDisplayInfo)
: mDisplayInfo(aDisplayInfo)
, bLastEventWasMounted(false)
, bLastEventWasPresenting(false)
, mPresentationCount(0)
{
@ -114,6 +115,18 @@ VRDisplayClient::NotifyVsync()
bLastEventWasPresenting = isPresenting;
vm->FireDOMVRDisplayPresentChangeEvent();
}
// Check if we need to trigger onvrdisplayactivate event
if (!bLastEventWasMounted && mDisplayInfo.mIsMounted) {
bLastEventWasMounted = true;
vm->FireDOMVRDisplayMountedEvent(mDisplayInfo.mDisplayID);
}
// Check if we need to trigger onvrdisplaydeactivate event
if (bLastEventWasMounted && !mDisplayInfo.mIsMounted) {
bLastEventWasMounted = false;
vm->FireDOMVRDisplayUnmountedEvent(mDisplayInfo.mDisplayID);
}
}
void

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

@ -49,6 +49,7 @@ protected:
VRDisplayInfo mDisplayInfo;
bool bLastEventWasMounted;
bool bLastEventWasPresenting;
TimeStamp mLastVSyncTime;

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

@ -78,10 +78,15 @@ enum class VRDisplayCapabilityFlags : uint16_t {
* 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 << 8) - 1
Cap_All = (1 << 9) - 1
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRDisplayCapabilityFlags)
@ -137,6 +142,7 @@ struct VRDisplayInfo
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; }
bool GetIsPresenting() const { return mIsPresenting; }
const Size& GetStageSize() const { return mStageSize; }
const Matrix4x4& GetSittingToStandingTransform() const { return mSittingToStandingTransform; }
@ -155,6 +161,7 @@ struct VRDisplayInfo
Point3D mEyeTranslation[VRDisplayInfo::NumEyes];
IntSize mEyeResolution;
bool mIsConnected;
bool mIsMounted;
bool mIsPresenting;
Size mStageSize;
Matrix4x4 mSittingToStandingTransform;
@ -166,6 +173,7 @@ struct VRDisplayInfo
mCapabilityFlags == other.mCapabilityFlags &&
mEyeResolution == other.mEyeResolution &&
mIsConnected == other.mIsConnected &&
mIsMounted == other.mIsMounted &&
mIsPresenting == other.mIsPresenting &&
mEyeFOV[0] == other.mEyeFOV[0] &&
mEyeFOV[1] == other.mEyeFOV[1] &&

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

@ -335,6 +335,7 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession)
mDisplayInfo.mDisplayName.AssignLiteral("Oculus VR HMD");
mDisplayInfo.mIsConnected = true;
mDisplayInfo.mIsMounted = false;
mDesc = ovr_GetHmdDesc(aSession);
@ -348,6 +349,7 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession)
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
}
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
mFOVPort[VRDisplayInfo::Eye_Left] = mDesc.DefaultEyeFov[ovrEye_Left];
@ -469,6 +471,7 @@ VRDisplayOculus::GetSensorState(double timeOffset)
result.linearAcceleration[2] = pose.LinearAcceleration.z;
}
result.flags |= VRDisplayCapabilityFlags::Cap_External;
result.flags |= VRDisplayCapabilityFlags::Cap_MountDetection;
result.flags |= VRDisplayCapabilityFlags::Cap_Present;
return result;
@ -937,4 +940,5 @@ VRDisplayOculus::NotifyVSync()
ovrSessionStatus sessionStatus;
ovrResult ovr = ovr_GetSessionStatus(mSession, &sessionStatus);
mDisplayInfo.mIsConnected = (ovr == ovrSuccess && sessionStatus.HmdPresent);
mDisplayInfo.mIsMounted = (ovr == ovrSuccess && sessionStatus.HmdMounted);
}

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

@ -137,6 +137,7 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
mDisplayInfo.mDisplayName.AssignLiteral("OpenVR HMD");
mDisplayInfo.mIsConnected = true;
mDisplayInfo.mIsMounted = false;
mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None |
VRDisplayCapabilityFlags::Cap_Orientation |
VRDisplayCapabilityFlags::Cap_Position |
@ -144,6 +145,12 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
VRDisplayCapabilityFlags::Cap_Present |
VRDisplayCapabilityFlags::Cap_StageParameters;
::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;
}
mVRCompositor->SetTrackingSpace(::vr::TrackingUniverseSeated);
uint32_t w, h;
@ -258,15 +265,31 @@ VRDisplayOpenVR::GetImmediateSensorState()
return GetSensorState(0.0f);
}
void
VRDisplayOpenVR::PollEvents()
{
::vr::VREvent_t event;
while (mVRSystem->PollNextEvent(&event, sizeof(event))) {
if (event.trackedDeviceIndex == ::vr::k_unTrackedDeviceIndex_Hmd) {
switch (event.eventType) {
case ::vr::VREvent_TrackedDeviceUserInteractionStarted:
mDisplayInfo.mIsMounted = true;
break;
case ::vr::VREvent_TrackedDeviceUserInteractionEnded:
mDisplayInfo.mIsMounted = false;
break;
default:
// ignore
break;
}
}
}
}
VRHMDSensorState
VRDisplayOpenVR::GetSensorState(double timeOffset)
{
{
::vr::VREvent_t event;
while (mVRSystem->PollNextEvent(&event, sizeof(event))) {
// ignore
}
}
PollEvents();
::vr::TrackedDevicePose_t poses[::vr::k_unMaxTrackedDeviceCount];
// Note: We *must* call WaitGetPoses in order for any rendering to happen at all
@ -392,6 +415,9 @@ VRDisplayOpenVR::NotifyVSync()
{
// We update mIsConneced once per frame.
mDisplayInfo.mIsConnected = vr_IsHmdPresent();
// Make sure we respond to OpenVR events even when not presenting
PollEvents();
}
VRSystemManagerOpenVR::VRSystemManagerOpenVR()

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

@ -66,6 +66,7 @@ protected:
bool mIsPresenting;
void UpdateStageParameters();
void PollEvents();
};
class VRControllerOpenVR : public VRControllerHost

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

@ -505,6 +505,22 @@ VRManagerChild::RunFrameRequestCallbacks()
}
}
void
VRManagerChild::FireDOMVRDisplayMountedEvent(uint32_t aDisplayID)
{
nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(this,
&VRManagerChild::FireDOMVRDisplayMountedEventInternal,
aDisplayID));
}
void
VRManagerChild::FireDOMVRDisplayUnmountedEvent(uint32_t aDisplayID)
{
nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(this,
&VRManagerChild::FireDOMVRDisplayUnmountedEventInternal,
aDisplayID));
}
void
VRManagerChild::FireDOMVRDisplayConnectEvent()
{
@ -526,6 +542,22 @@ VRManagerChild::FireDOMVRDisplayPresentChangeEvent()
&VRManagerChild::FireDOMVRDisplayPresentChangeEventInternal));
}
void
VRManagerChild::FireDOMVRDisplayMountedEventInternal(uint32_t aDisplayID)
{
for (auto& listener : mListeners) {
listener->NotifyVRDisplayMounted(aDisplayID);
}
}
void
VRManagerChild::FireDOMVRDisplayUnmountedEventInternal(uint32_t aDisplayID)
{
for (auto& listener : mListeners) {
listener->NotifyVRDisplayUnmounted(aDisplayID);
}
}
void
VRManagerChild::FireDOMVRDisplayConnectEventInternal()
{

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

@ -80,6 +80,8 @@ public:
void RunFrameRequestCallbacks();
void UpdateDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayUpdates);
void FireDOMVRDisplayMountedEvent(uint32_t aDisplayID);
void FireDOMVRDisplayUnmountedEvent(uint32_t aDisplayID);
void FireDOMVRDisplayConnectEvent();
void FireDOMVRDisplayDisconnectEvent();
void FireDOMVRDisplayPresentChangeEvent();
@ -138,6 +140,8 @@ protected:
private:
void FireDOMVRDisplayMountedEventInternal(uint32_t aDisplayID);
void FireDOMVRDisplayUnmountedEventInternal(uint32_t aDisplayID);
void FireDOMVRDisplayConnectEventInternal();
void FireDOMVRDisplayDisconnectEventInternal();
void FireDOMVRDisplayPresentChangeEventInternal();

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

@ -39,6 +39,7 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo>
WriteParam(aMsg, aParam.mCapabilityFlags);
WriteParam(aMsg, aParam.mEyeResolution);
WriteParam(aMsg, aParam.mIsConnected);
WriteParam(aMsg, aParam.mIsMounted);
WriteParam(aMsg, aParam.mIsPresenting);
WriteParam(aMsg, aParam.mStageSize);
WriteParam(aMsg, aParam.mSittingToStandingTransform);
@ -56,6 +57,7 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo>
!ReadParam(aMsg, aIter, &(aResult->mCapabilityFlags)) ||
!ReadParam(aMsg, aIter, &(aResult->mEyeResolution)) ||
!ReadParam(aMsg, aIter, &(aResult->mIsConnected)) ||
!ReadParam(aMsg, aIter, &(aResult->mIsMounted)) ||
!ReadParam(aMsg, aIter, &(aResult->mIsPresenting)) ||
!ReadParam(aMsg, aIter, &(aResult->mStageSize)) ||
!ReadParam(aMsg, aIter, &(aResult->mSittingToStandingTransform))) {

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

@ -378,6 +378,8 @@ NS_EVENT_MESSAGE(eOrientationChange)
#endif
// WebVR events
NS_EVENT_MESSAGE(eVRDisplayActivate)
NS_EVENT_MESSAGE(eVRDisplayDeactivate)
NS_EVENT_MESSAGE(eVRDisplayConnect)
NS_EVENT_MESSAGE(eVRDisplayDisconnect)
NS_EVENT_MESSAGE(eVRDisplayPresentChange)