2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2014-07-09 23:24:49 +04:00
|
|
|
/* 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 "nsWrapperCache.h"
|
|
|
|
|
|
|
|
#include "mozilla/dom/Element.h"
|
2016-04-13 03:39:28 +03:00
|
|
|
#include "mozilla/dom/VRDisplayBinding.h"
|
2014-07-09 23:24:49 +04:00
|
|
|
#include "mozilla/dom/ElementBinding.h"
|
2016-04-13 03:39:28 +03:00
|
|
|
#include "mozilla/dom/VRDisplay.h"
|
2015-09-18 00:23:13 +03:00
|
|
|
#include "Navigator.h"
|
2014-07-09 23:24:49 +04:00
|
|
|
#include "gfxVR.h"
|
2016-02-25 02:54:50 +03:00
|
|
|
#include "VRDisplayClient.h"
|
2015-09-18 00:23:13 +03:00
|
|
|
#include "VRManagerChild.h"
|
2016-02-25 02:54:50 +03:00
|
|
|
#include "VRDisplayPresentation.h"
|
|
|
|
#include "nsIObserverService.h"
|
2014-07-09 23:24:49 +04:00
|
|
|
#include "nsIFrame.h"
|
2016-02-25 02:54:50 +03:00
|
|
|
#include "nsISupportsPrimitives.h"
|
2014-07-09 23:24:49 +04:00
|
|
|
|
|
|
|
using namespace mozilla::gfx;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
VRFieldOfView::VRFieldOfView(nsISupports* aParent,
|
|
|
|
double aUpDegrees, double aRightDegrees,
|
|
|
|
double aDownDegrees, double aLeftDegrees)
|
|
|
|
: mParent(aParent)
|
|
|
|
, mUpDegrees(aUpDegrees)
|
|
|
|
, mRightDegrees(aRightDegrees)
|
|
|
|
, mDownDegrees(aDownDegrees)
|
|
|
|
, mLeftDegrees(aLeftDegrees)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VRFieldOfView::VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
|
|
|
|
: mParent(aParent)
|
|
|
|
, mUpDegrees(aSrc.upDegrees)
|
|
|
|
, mRightDegrees(aSrc.rightDegrees)
|
|
|
|
, mDownDegrees(aSrc.downDegrees)
|
|
|
|
, mLeftDegrees(aSrc.leftDegrees)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
VRDisplayCapabilities::HasPosition() const
|
|
|
|
{
|
|
|
|
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Position);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
VRDisplayCapabilities::HasOrientation() const
|
|
|
|
{
|
|
|
|
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Orientation);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
VRDisplayCapabilities::HasExternalDisplay() const
|
|
|
|
{
|
|
|
|
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_External);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
VRDisplayCapabilities::CanPresent() const
|
|
|
|
{
|
|
|
|
return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Present);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
VRDisplayCapabilities::MaxLayers() const
|
|
|
|
{
|
|
|
|
return CanPresent() ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
2015-09-18 00:23:13 +03:00
|
|
|
/*static*/ bool
|
2016-04-13 03:39:28 +03:00
|
|
|
VRDisplay::RefreshVRDisplays(dom::Navigator* aNavigator)
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
|
|
|
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
2016-04-13 03:39:28 +03:00
|
|
|
return vm && vm->RefreshVRDisplaysWithCallback(aNavigator);
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void
|
2016-02-25 02:54:50 +03:00
|
|
|
VRDisplay::UpdateVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays, nsPIDOMWindowInner* aWindow)
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
nsTArray<RefPtr<VRDisplay>> displays;
|
2015-09-18 00:23:13 +03:00
|
|
|
|
|
|
|
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
2016-02-25 02:54:50 +03:00
|
|
|
nsTArray<RefPtr<gfx::VRDisplayClient>> updatedDisplays;
|
|
|
|
if (vm && vm->GetVRDisplays(updatedDisplays)) {
|
|
|
|
for (size_t i = 0; i < updatedDisplays.Length(); i++) {
|
|
|
|
RefPtr<gfx::VRDisplayClient> display = updatedDisplays[i];
|
|
|
|
bool isNewDisplay = true;
|
|
|
|
for (size_t j = 0; j < aDisplays.Length(); j++) {
|
|
|
|
if (aDisplays[j]->GetClient()->GetDisplayInfo() == display->GetDisplayInfo()) {
|
|
|
|
displays.AppendElement(aDisplays[j]);
|
|
|
|
isNewDisplay = false;
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
if (isNewDisplay) {
|
|
|
|
displays.AppendElement(new VRDisplay(aWindow, display));
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
aDisplays = displays;
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfView, mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfView, AddRef)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfView, Release)
|
2014-07-09 23:24:49 +04:00
|
|
|
|
|
|
|
|
2015-04-01 23:02:20 +03:00
|
|
|
JSObject*
|
2015-01-09 00:56:42 +03:00
|
|
|
VRFieldOfView::WrapObject(JSContext* aCx,
|
2015-04-01 23:02:20 +03:00
|
|
|
JS::Handle<JSObject*> aGivenProto)
|
|
|
|
{
|
|
|
|
return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
|
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(VREyeParameters)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VREyeParameters)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mFOV)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
|
|
tmp->mOffset = nullptr;
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VREyeParameters)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mFOV)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VREyeParameters)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOffset)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|
|
|
|
2015-04-01 23:02:20 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
|
|
|
|
|
|
|
|
VREyeParameters::VREyeParameters(nsISupports* aParent,
|
|
|
|
const gfx::Point3D& aEyeTranslation,
|
2016-02-25 02:54:50 +03:00
|
|
|
const gfx::VRFieldOfView& aFOV,
|
|
|
|
const gfx::IntSize& aRenderSize)
|
2015-04-01 23:02:20 +03:00
|
|
|
: mParent(aParent)
|
2016-02-25 02:54:50 +03:00
|
|
|
, mEyeTranslation(aEyeTranslation)
|
|
|
|
, mRenderSize(aRenderSize)
|
2015-04-01 23:02:20 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
mFOV = new VRFieldOfView(aParent, aFOV);
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
VRFieldOfView*
|
2016-02-25 02:54:50 +03:00
|
|
|
VREyeParameters::FieldOfView()
|
2015-04-01 23:02:20 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
return mFOV;
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VREyeParameters::GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
|
2015-04-01 23:02:20 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (!mOffset) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mOffset = dom::Float32Array::Create(aCx, this, 3, mEyeTranslation.components);
|
|
|
|
if (!mOffset) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
JS::ExposeObjectToActiveJS(mOffset);
|
|
|
|
aRetval.set(mOffset);
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
JSObject*
|
|
|
|
VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2015-04-01 23:02:20 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
JSObject*
|
|
|
|
VRStageParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2015-04-01 23:02:20 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
return VRStageParametersBinding::Wrap(aCx, this, aGivenProto);
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(VRStageParameters)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRStageParameters)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
|
|
tmp->mSittingToStandingTransformArray = nullptr;
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRStageParameters)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRStageParameters)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSittingToStandingTransformArray)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRStageParameters, AddRef)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRStageParameters, Release)
|
2015-04-01 23:02:20 +03:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRStageParameters::GetSittingToStandingTransform(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
2015-04-01 23:02:20 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (!mSittingToStandingTransformArray) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mSittingToStandingTransformArray = dom::Float32Array::Create(aCx, this, 16,
|
|
|
|
mSittingToStandingTransform.components);
|
|
|
|
if (!mSittingToStandingTransformArray) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
JS::ExposeObjectToActiveJS(mSittingToStandingTransformArray);
|
|
|
|
aRetval.set(mSittingToStandingTransformArray);
|
2015-04-01 23:02:20 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRDisplayCapabilities, mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRDisplayCapabilities, AddRef)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRDisplayCapabilities, Release)
|
|
|
|
|
2015-04-01 23:02:20 +03:00
|
|
|
JSObject*
|
2016-02-25 02:54:50 +03:00
|
|
|
VRDisplayCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
return VRDisplayCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(VRPose)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRPose)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
|
|
tmp->mPosition = nullptr;
|
|
|
|
tmp->mLinearVelocity = nullptr;
|
|
|
|
tmp->mLinearAcceleration = nullptr;
|
|
|
|
tmp->mOrientation = nullptr;
|
|
|
|
tmp->mAngularVelocity = nullptr;
|
|
|
|
tmp->mAngularAcceleration = nullptr;
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRPose)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRPose)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPosition)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearVelocity)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLinearAcceleration)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOrientation)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularVelocity)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAngularAcceleration)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPose, AddRef)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPose, Release)
|
|
|
|
|
|
|
|
VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
|
2014-07-09 23:24:49 +04:00
|
|
|
: mParent(aParent)
|
|
|
|
, mVRState(aState)
|
2016-02-25 02:54:50 +03:00
|
|
|
, mPosition(nullptr)
|
|
|
|
, mLinearVelocity(nullptr)
|
|
|
|
, mLinearAcceleration(nullptr)
|
|
|
|
, mOrientation(nullptr)
|
|
|
|
, mAngularVelocity(nullptr)
|
|
|
|
, mAngularAcceleration(nullptr)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
mTimeStamp = aState.timestamp * 1000.0f; // Converting from seconds to ms
|
|
|
|
mFrameId = aState.inputFrameID;
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRPose::GetPosition(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
if (!mPosition && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mPosition = dom::Float32Array::Create(aCx, this, 3, mVRState.position);
|
|
|
|
if (!mPosition) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mPosition) {
|
|
|
|
JS::ExposeObjectToActiveJS(mPosition);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
aRetval.set(mPosition);
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRPose::GetLinearVelocity(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
if (!mLinearVelocity && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mLinearVelocity = dom::Float32Array::Create(aCx, this, 3, mVRState.linearVelocity);
|
|
|
|
if (!mLinearVelocity) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
if (mLinearVelocity) {
|
|
|
|
JS::ExposeObjectToActiveJS(mLinearVelocity);
|
|
|
|
}
|
|
|
|
aRetval.set(mLinearVelocity);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRPose::GetLinearAcceleration(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (!mLinearAcceleration && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mLinearAcceleration = dom::Float32Array::Create(aCx, this, 3, mVRState.linearAcceleration);
|
|
|
|
if (!mLinearAcceleration) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mLinearAcceleration) {
|
|
|
|
JS::ExposeObjectToActiveJS(mLinearAcceleration);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
aRetval.set(mLinearAcceleration);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRPose::GetOrientation(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (!mOrientation && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mOrientation = dom::Float32Array::Create(aCx, this, 4, mVRState.orientation);
|
|
|
|
if (!mOrientation) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
if (mOrientation) {
|
|
|
|
JS::ExposeObjectToActiveJS(mOrientation);
|
|
|
|
}
|
|
|
|
aRetval.set(mOrientation);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRPose::GetAngularVelocity(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (!mAngularVelocity && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mAngularVelocity = dom::Float32Array::Create(aCx, this, 3, mVRState.angularVelocity);
|
|
|
|
if (!mAngularVelocity) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mAngularVelocity) {
|
|
|
|
JS::ExposeObjectToActiveJS(mAngularVelocity);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
aRetval.set(mAngularVelocity);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRPose::GetAngularAcceleration(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JSObject*> aRetval,
|
|
|
|
ErrorResult& aRv)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (!mAngularAcceleration && mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
|
|
|
// Lazily create the Float32Array
|
|
|
|
mAngularAcceleration = dom::Float32Array::Create(aCx, this, 3, mVRState.angularAcceleration);
|
|
|
|
if (!mAngularAcceleration) {
|
|
|
|
aRv.NoteJSContextException(aCx);
|
|
|
|
return;
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
if (mAngularAcceleration) {
|
|
|
|
JS::ExposeObjectToActiveJS(mAngularAcceleration);
|
|
|
|
}
|
|
|
|
aRetval.set(mAngularAcceleration);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
JSObject*
|
2016-02-25 02:54:50 +03:00
|
|
|
VRPose::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
return VRPoseBinding::Wrap(aCx, this, aGivenProto);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
/* virtual */ JSObject*
|
|
|
|
VRDisplay::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|
|
|
{
|
|
|
|
return VRDisplayBinding::Wrap(aCx, this, aGivenProto);
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
VRDisplay::VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient)
|
|
|
|
: DOMEventTargetHelper(aWindow)
|
|
|
|
, mClient(aClient)
|
|
|
|
, mDepthNear(0.01f) // Default value from WebVR Spec
|
|
|
|
, mDepthFar(10000.0f) // Default value from WebVR Spec
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(VRDisplay);
|
|
|
|
mDisplayId = aClient->GetDisplayInfo().GetDisplayID();
|
|
|
|
mDisplayName = NS_ConvertASCIItoUTF16(aClient->GetDisplayInfo().GetDisplayName());
|
|
|
|
mCapabilities = new VRDisplayCapabilities(aWindow, aClient->GetDisplayInfo().GetCapabilities());
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
VRDisplay::~VRDisplay()
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
ExitPresentInternal();
|
|
|
|
MOZ_COUNT_DTOR(VRDisplay);
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRDisplay::LastRelease()
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
// We don't want to wait for the CC to free up the presentation
|
|
|
|
// for use in other documents, so we do this in LastRelease().
|
|
|
|
ExitPresentInternal();
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
already_AddRefed<VREyeParameters>
|
|
|
|
VRDisplay::GetEyeParameters(VREye aEye)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
gfx::VRDisplayInfo::Eye eye = aEye == VREye::Left ? gfx::VRDisplayInfo::Eye_Left : gfx::VRDisplayInfo::Eye_Right;
|
|
|
|
RefPtr<VREyeParameters> params =
|
|
|
|
new VREyeParameters(GetParentObject(),
|
|
|
|
mClient->GetDisplayInfo().GetEyeTranslation(eye),
|
|
|
|
mClient->GetDisplayInfo().GetEyeFOV(eye),
|
|
|
|
mClient->GetDisplayInfo().SuggestedEyeResolution());
|
|
|
|
return params.forget();
|
|
|
|
}
|
2015-04-01 23:02:20 +03:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
VRDisplayCapabilities*
|
|
|
|
VRDisplay::Capabilities()
|
|
|
|
{
|
|
|
|
return mCapabilities;
|
|
|
|
}
|
2015-04-01 23:02:20 +03:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
VRStageParameters*
|
|
|
|
VRDisplay::GetStageParameters()
|
|
|
|
{
|
|
|
|
// XXX When we implement room scale experiences for OpenVR, we should return
|
|
|
|
// something here.
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-04-07 20:26:44 +03:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
already_AddRefed<VRPose>
|
|
|
|
VRDisplay::GetPose()
|
|
|
|
{
|
|
|
|
gfx::VRHMDSensorState state = mClient->GetSensorState();
|
|
|
|
RefPtr<VRPose> obj = new VRPose(GetParentObject(), state);
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
return obj.forget();
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
already_AddRefed<VRPose>
|
|
|
|
VRDisplay::GetImmediatePose()
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
gfx::VRHMDSensorState state = mClient->GetImmediateSensorState();
|
|
|
|
RefPtr<VRPose> obj = new VRPose(GetParentObject(), state);
|
|
|
|
|
|
|
|
return obj.forget();
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2015-04-07 20:26:44 +03:00
|
|
|
|
2015-09-18 00:23:13 +03:00
|
|
|
void
|
2016-02-25 02:54:50 +03:00
|
|
|
VRDisplay::ResetPose()
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
mClient->ZeroSensor();
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
already_AddRefed<Promise>
|
|
|
|
VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
|
|
|
if (!global) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
|
|
|
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
|
|
|
NS_ENSURE_TRUE(obs, nullptr);
|
|
|
|
|
|
|
|
if (IsPresenting()) {
|
|
|
|
// Only one presentation allowed per VRDisplay
|
|
|
|
// on a first-come-first-serve basis.
|
|
|
|
promise->MaybeRejectWithUndefined();
|
|
|
|
} else {
|
|
|
|
mPresentation = mClient->BeginPresentation(aLayers);
|
|
|
|
|
|
|
|
nsresult rv = obs->AddObserver(this, "inner-window-destroyed", false);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
mPresentation = nullptr;
|
|
|
|
promise->MaybeRejectWithUndefined();
|
|
|
|
} else {
|
|
|
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
2016-02-25 02:54:50 +03:00
|
|
|
return promise.forget();
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2015-04-01 23:02:20 +03:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
VRDisplay::Observe(nsISupports* aSubject, const char* aTopic,
|
|
|
|
const char16_t* aData)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
if (strcmp(aTopic, "inner-window-destroyed") == 0) {
|
|
|
|
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
|
|
|
NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
uint64_t innerID;
|
|
|
|
nsresult rv = wrapper->GetData(&innerID);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (!GetOwner() || GetOwner()->WindowID() == innerID) {
|
|
|
|
ExitPresentInternal();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This should not happen.
|
|
|
|
return NS_ERROR_FAILURE;
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2015-04-01 23:02:20 +03:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
already_AddRefed<Promise>
|
|
|
|
VRDisplay::ExitPresent(ErrorResult& aRv)
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
|
|
|
if (!global) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
ExitPresentInternal();
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
|
|
|
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
|
|
|
return promise.forget();
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRDisplay::ExitPresentInternal()
|
|
|
|
{
|
|
|
|
mPresentation = nullptr;
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRDisplay::GetLayers(nsTArray<VRLayer>& result)
|
|
|
|
{
|
|
|
|
if (mPresentation) {
|
|
|
|
mPresentation->GetDOMLayers(result);
|
|
|
|
} else {
|
|
|
|
result = nsTArray<VRLayer>();
|
|
|
|
}
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRDisplay::SubmitFrame(const Optional<NonNull<VRPose>>& aPose)
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
if (mPresentation) {
|
|
|
|
if (aPose.WasPassed()) {
|
|
|
|
mPresentation->SubmitFrame(aPose.Value().FrameID());
|
|
|
|
} else {
|
|
|
|
mPresentation->SubmitFrame(0);
|
|
|
|
}
|
|
|
|
}
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
int32_t
|
|
|
|
VRDisplay::RequestAnimationFrame(FrameRequestCallback& aCallback,
|
|
|
|
ErrorResult& aError)
|
2014-07-09 23:24:49 +04:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
int32_t handle;
|
|
|
|
aError = vm->ScheduleFrameRequestCallback(aCallback, &handle);
|
|
|
|
return handle;
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
void
|
|
|
|
VRDisplay::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError)
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
|
|
|
|
vm->CancelFrameRequestCallback(aHandle);
|
|
|
|
}
|
2014-07-09 23:24:49 +04:00
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
|
|
|
|
bool
|
|
|
|
VRDisplay::IsPresenting() const
|
|
|
|
{
|
|
|
|
return mClient->GetIsPresenting();
|
2015-09-18 00:23:13 +03:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
bool
|
|
|
|
VRDisplay::IsConnected() const
|
2015-09-18 00:23:13 +03:00
|
|
|
{
|
2016-02-25 02:54:50 +03:00
|
|
|
return mClient->GetIsConnected();
|
2014-07-09 23:24:49 +04:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:54:50 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(VRDisplay, DOMEventTargetHelper, mCapabilities)
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF_INHERITED(VRDisplay, DOMEventTargetHelper)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(VRDisplay, DOMEventTargetHelper)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(VRDisplay)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMEventTargetHelper)
|
|
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
|
|
|
2014-07-09 23:24:49 +04:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|