зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
531cd887a0
Коммит
8dc97eb398
|
@ -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();
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче