Bug 1148005; Update WebVR APIs based on latest spec changes; r=baku

This commit is contained in:
Vladimir Vukicevic 2015-04-01 16:02:20 -04:00
parent 174822e82b
commit 223017214a
4 changed files with 219 additions and 138 deletions

View File

@ -1265,15 +1265,6 @@ DOMInterfaces = {
'wrapperCache': False,
}],
'VRFieldOfView': {
'wrapperCache': False,
},
'VRFieldOfViewReadOnly': {
'concrete': False,
'wrapperCache': False,
},
'VRDevice': {
'concrete': False
},

View File

@ -17,30 +17,109 @@ using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
VRFieldOfView*
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfViewReadOnly, mParent)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfViewReadOnly, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfViewReadOnly, Release)
JSObject*
VRFieldOfViewReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return VRFieldOfViewReadOnlyBinding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<VRFieldOfView>
VRFieldOfView::Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
ErrorResult& aRV)
{
return new VRFieldOfView(aParams.mUpDegrees, aParams.mRightDegrees,
aParams.mDownDegrees, aParams.mLeftDegrees);
nsRefPtr<VRFieldOfView> fov =
new VRFieldOfView(aGlobal.GetAsSupports(),
aParams.mUpDegrees, aParams.mRightDegrees,
aParams.mDownDegrees, aParams.mLeftDegrees);
return fov.forget();
}
VRFieldOfView*
already_AddRefed<VRFieldOfView>
VRFieldOfView::Constructor(const GlobalObject& aGlobal,
double aUpDegrees, double aRightDegrees,
double aDownDegrees, double aLeftDegrees,
ErrorResult& aRV)
{
return new VRFieldOfView(aUpDegrees, aRightDegrees, aDownDegrees,
aLeftDegrees);
nsRefPtr<VRFieldOfView> fov =
new VRFieldOfView(aGlobal.GetAsSupports(),
aUpDegrees, aRightDegrees, aDownDegrees,
aLeftDegrees);
return fov.forget();
}
bool
JSObject*
VRFieldOfView::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector)
JS::Handle<JSObject*> aGivenProto)
{
return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto, aReflector);
return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VREyeParameters, mParent, mMinFOV, mMaxFOV, mRecFOV, mCurFOV, mEyeTranslation, mRenderRect)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
VREyeParameters::VREyeParameters(nsISupports* aParent,
const gfx::VRFieldOfView& aMinFOV,
const gfx::VRFieldOfView& aMaxFOV,
const gfx::VRFieldOfView& aRecFOV,
const gfx::Point3D& aEyeTranslation,
const gfx::VRFieldOfView& aCurFOV,
const gfx::IntRect& aRenderRect)
: mParent(aParent)
{
mMinFOV = new VRFieldOfView(aParent, aMinFOV);
mMaxFOV = new VRFieldOfView(aParent, aMaxFOV);
mRecFOV = new VRFieldOfView(aParent, aRecFOV);
mCurFOV = new VRFieldOfView(aParent, aCurFOV);
mEyeTranslation = new DOMPoint(aParent, aEyeTranslation.x, aEyeTranslation.y, aEyeTranslation.z, 0.0);
mRenderRect = new DOMRect(aParent, aRenderRect.x, aRenderRect.y, aRenderRect.width, aRenderRect.height);
}
VRFieldOfView*
VREyeParameters::MinimumFieldOfView()
{
return mMinFOV;
}
VRFieldOfView*
VREyeParameters::MaximumFieldOfView()
{
return mMaxFOV;
}
VRFieldOfView*
VREyeParameters::RecommendedFieldOfView()
{
return mRecFOV;
}
VRFieldOfView*
VREyeParameters::CurrentFieldOfView()
{
return mCurFOV;
}
DOMPoint*
VREyeParameters::EyeTranslation()
{
return mEyeTranslation;
}
DOMRect*
VREyeParameters::RenderRect()
{
return mRenderRect;
}
JSObject*
VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRPositionState, mParent)
@ -126,37 +205,8 @@ PositionSensorVRDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenP
return PositionSensorVRDeviceBinding::Wrap(aCx, this, aGivenProto);
}
static void
ReleaseHMDInfoRef(void *, nsIAtom*, void *aPropertyValue, void *)
{
if (aPropertyValue) {
static_cast<VRHMDInfo*>(aPropertyValue)->Release();
}
}
void
HMDVRDevice::XxxToggleElementVR(Element& aElement)
{
VRHMDInfo* hmdPtr = static_cast<VRHMDInfo*>(aElement.GetProperty(nsGkAtoms::vr_state));
if (hmdPtr) {
aElement.DeleteProperty(nsGkAtoms::vr_state);
return;
}
nsRefPtr<VRHMDInfo> hmdRef = mHMD;
aElement.SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(),
ReleaseHMDInfoRef,
true);
}
namespace {
gfx::VRHMDInfo::Eye
EyeToEye(const VREye& aEye)
{
return aEye == VREye::Left ? gfx::VRHMDInfo::Eye_Left : gfx::VRHMDInfo::Eye_Right;
}
class HMDInfoVRDevice : public HMDVRDevice
{
public:
@ -193,46 +243,22 @@ public:
mHMD->SetFOV(left, right, zNear, zFar);
}
virtual already_AddRefed<DOMPoint> GetEyeTranslation(VREye aEye) override
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) override
{
gfx::Point3D p = mHMD->GetEyeTranslation(EyeToEye(aEye));
nsRefPtr<DOMPoint> obj = new DOMPoint(mParent, p.x, p.y, p.z, 0.0);
return obj.forget();
}
virtual VRFieldOfView* GetCurrentEyeFieldOfView(VREye aEye) override
{
return CopyFieldOfView(mHMD->GetEyeFOV(EyeToEye(aEye)));
}
virtual VRFieldOfView* GetRecommendedEyeFieldOfView(VREye aEye) override
{
return CopyFieldOfView(mHMD->GetRecommendedEyeFOV(EyeToEye(aEye)));
}
virtual VRFieldOfView* GetMaximumEyeFieldOfView(VREye aEye) override
{
return CopyFieldOfView(mHMD->GetMaximumEyeFOV(EyeToEye(aEye)));
}
virtual already_AddRefed<DOMRect> GetRecommendedEyeRenderRect(VREye aEye) override
{
const IntSize& a(mHMD->SuggestedEyeResolution());
nsRefPtr<DOMRect> obj =
new DOMRect(mParent,
(aEye == VREye::Left) ? 0 : a.width, 0,
a.width, a.height);
return obj.forget();
gfx::IntSize sz(mHMD->SuggestedEyeResolution());
gfx::VRHMDInfo::Eye eye = aEye == VREye::Left ? gfx::VRHMDInfo::Eye_Left : gfx::VRHMDInfo::Eye_Right;
nsRefPtr<VREyeParameters> params =
new VREyeParameters(mParent,
gfx::VRFieldOfView(15, 15, 15, 15), // XXX min?
mHMD->GetMaximumEyeFOV(eye),
mHMD->GetRecommendedEyeFOV(eye),
mHMD->GetEyeTranslation(eye),
mHMD->GetEyeFOV(eye),
gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height));
return params.forget();
}
protected:
VRFieldOfView*
CopyFieldOfView(const gfx::VRFieldOfView& aSrc)
{
return new VRFieldOfView(aSrc.upDegrees, aSrc.rightDegrees,
aSrc.downDegrees, aSrc.leftDegrees);
}
};
class HMDPositionVRDevice : public PositionSensorVRDevice
@ -258,20 +284,33 @@ public:
}
}
virtual already_AddRefed<VRPositionState> GetState(double timeOffset) override
virtual already_AddRefed<VRPositionState> GetState() override
{
if (!mTracking) {
mHMD->StartSensorTracking();
mTracking = true;
}
gfx::VRHMDSensorState state = mHMD->GetSensorState(timeOffset);
gfx::VRHMDSensorState state = mHMD->GetSensorState();
nsRefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
return obj.forget();
}
virtual void ZeroSensor() override
virtual already_AddRefed<VRPositionState> GetImmediateState() override
{
if (!mTracking) {
mHMD->StartSensorTracking();
mTracking = true;
}
gfx::VRHMDSensorState state = mHMD->GetSensorState();
nsRefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
return obj.forget();
}
virtual void ResetSensor() override
{
mHMD->ZeroSensor();
}

View File

@ -26,24 +26,36 @@ namespace dom {
class Element;
class VRFieldOfViewReadOnly : public NonRefcountedDOMObject
class VRFieldOfViewReadOnly : public nsWrapperCache
{
public:
VRFieldOfViewReadOnly(double aUpDegrees, double aRightDegrees,
VRFieldOfViewReadOnly(nsISupports* aParent,
double aUpDegrees, double aRightDegrees,
double aDownDegrees, double aLeftDegrees)
: mUpDegrees(aUpDegrees)
: mParent(aParent)
, mUpDegrees(aUpDegrees)
, mRightDegrees(aRightDegrees)
, mDownDegrees(aDownDegrees)
, mLeftDegrees(aLeftDegrees)
{
}
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfViewReadOnly)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfViewReadOnly)
double UpDegrees() const { return mUpDegrees; }
double RightDegrees() const { return mRightDegrees; }
double DownDegrees() const { return mDownDegrees; }
double LeftDegrees() const { return mLeftDegrees; }
nsISupports* GetParentObject() const { return mParent; }
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
virtual ~VRFieldOfViewReadOnly() {}
nsCOMPtr<nsISupports> mParent;
double mUpDegrees;
double mRightDegrees;
double mDownDegrees;
@ -53,22 +65,30 @@ protected:
class VRFieldOfView final : public VRFieldOfViewReadOnly
{
public:
explicit VRFieldOfView(double aUpDegrees = 0.0, double aRightDegrees = 0.0,
double aDownDegrees = 0.0, double aLeftDegrees = 0.0)
: VRFieldOfViewReadOnly(aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
: VRFieldOfViewReadOnly(aParent,
aSrc.upDegrees, aSrc.rightDegrees,
aSrc.downDegrees, aSrc.leftDegrees)
{}
static VRFieldOfView*
explicit VRFieldOfView(nsISupports* aParent,
double aUpDegrees = 0.0, double aRightDegrees = 0.0,
double aDownDegrees = 0.0, double aLeftDegrees = 0.0)
: VRFieldOfViewReadOnly(aParent,
aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
{}
static already_AddRefed<VRFieldOfView>
Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
ErrorResult& aRv);
static VRFieldOfView*
static already_AddRefed<VRFieldOfView>
Constructor(const GlobalObject& aGlobal,
double aUpDegrees, double aRightDegrees,
double aDownDegrees, double aLeftDegrees,
ErrorResult& aRv);
bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void SetUpDegrees(double aVal) { mUpDegrees = aVal; }
void SetRightDegrees(double aVal) { mRightDegrees = aVal; }
@ -80,7 +100,7 @@ class VRPositionState final : public nsWrapperCache
{
~VRPositionState() {}
public:
explicit VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPositionState)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPositionState)
@ -117,6 +137,43 @@ protected:
nsRefPtr<DOMPoint> mAngularAcceleration;
};
class VREyeParameters final : public nsWrapperCache
{
public:
VREyeParameters(nsISupports* aParent,
const gfx::VRFieldOfView& aMinFOV,
const gfx::VRFieldOfView& aMaxFOV,
const gfx::VRFieldOfView& aRecFOV,
const gfx::Point3D& aEyeTranslation,
const gfx::VRFieldOfView& aCurFOV,
const gfx::IntRect& aRenderRect);
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
VRFieldOfView* MinimumFieldOfView();
VRFieldOfView* MaximumFieldOfView();
VRFieldOfView* RecommendedFieldOfView();
DOMPoint* EyeTranslation();
VRFieldOfView* CurrentFieldOfView();
DOMRect* RenderRect();
nsISupports* GetParentObject() const { return mParent; }
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
~VREyeParameters() {}
nsCOMPtr<nsISupports> mParent;
nsRefPtr<VRFieldOfView> mMinFOV;
nsRefPtr<VRFieldOfView> mMaxFOV;
nsRefPtr<VRFieldOfView> mRecFOV;
nsRefPtr<DOMPoint> mEyeTranslation;
nsRefPtr<VRFieldOfView> mCurFOV;
nsRefPtr<DOMRect> mRenderRect;
};
class VRDevice : public nsISupports,
public nsWrapperCache
{
@ -176,20 +233,14 @@ protected:
class HMDVRDevice : public VRDevice
{
public:
virtual already_AddRefed<DOMPoint> GetEyeTranslation(VREye aEye) = 0;
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) = 0;
virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
const VRFieldOfViewInit& aRightFOV,
double zNear, double zFar) = 0;
virtual VRFieldOfView* GetCurrentEyeFieldOfView(VREye aEye) = 0;
virtual VRFieldOfView* GetRecommendedEyeFieldOfView(VREye aEye) = 0;
virtual VRFieldOfView* GetMaximumEyeFieldOfView(VREye aEye) = 0;
virtual already_AddRefed<DOMRect> GetRecommendedEyeRenderRect(VREye aEye) = 0;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void XxxToggleElementVR(Element& aElement);
gfx::VRHMDInfo *GetHMD() { return mHMD.get(); }
protected:
@ -206,9 +257,11 @@ protected:
class PositionSensorVRDevice : public VRDevice
{
public:
virtual already_AddRefed<VRPositionState> GetState(double timeOffset) = 0;
virtual already_AddRefed<VRPositionState> GetState() = 0;
virtual void ZeroSensor() = 0;
virtual already_AddRefed<VRPositionState> GetImmediateState() = 0;
virtual void ResetSensor() = 0;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;

View File

@ -52,6 +52,20 @@ interface VRPositionState {
readonly attribute DOMPoint? angularAcceleration;
};
[Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDevice.h"]
interface VREyeParameters {
/* These values are expected to be static per-device/per-user */
[Constant, Cached] readonly attribute VRFieldOfView minimumFieldOfView;
[Constant, Cached] readonly attribute VRFieldOfView maximumFieldOfView;
[Constant, Cached] readonly attribute VRFieldOfView recommendedFieldOfView;
[Constant, Cached] readonly attribute DOMPoint eyeTranslation;
/* These values will vary after a FOV has been set */
[Constant, Cached] readonly attribute VRFieldOfView currentFieldOfView;
[Constant, Cached] readonly attribute DOMRect renderRect;
};
[Pref="dom.vr.enabled"]
interface VRDevice {
/**
@ -59,38 +73,26 @@ interface VRDevice {
* VR Device is a part of. All VRDevice/Sensors that come
* from the same hardware will have the same hardwareId
*/
[Pure] readonly attribute DOMString hardwareUnitId;
[Constant] readonly attribute DOMString hardwareUnitId;
/**
* An identifier for this distinct sensor/device on a physical
* hardware device. This shouldn't change across browser
* restrats, allowing configuration data to be saved based on it.
*/
[Pure] readonly attribute DOMString deviceId;
[Constant] readonly attribute DOMString deviceId;
/**
* a device name, a user-readable name identifying it
*/
[Pure] readonly attribute DOMString deviceName;
[Constant] readonly attribute DOMString deviceName;
};
[Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDevice.h"]
interface HMDVRDevice : VRDevice {
/* The translation that should be applied to the view matrix for rendering each eye */
DOMPoint getEyeTranslation(VREye whichEye);
// the FOV that the HMD was configured with
[NewObject]
VRFieldOfView getCurrentEyeFieldOfView(VREye whichEye);
// the recommended FOV, per eye.
[NewObject]
VRFieldOfView getRecommendedEyeFieldOfView(VREye whichEye);
// the maximum FOV, per eye. Above this, rendering will look broken.
[NewObject]
VRFieldOfView getMaximumEyeFieldOfView(VREye whichEye);
// Return the current VREyeParameters for the given eye
VREyeParameters getEyeParameters(VREye whichEye);
// Set a field of view. If either of the fields of view is null,
// or if their values are all zeros, then the recommended field of view
@ -99,34 +101,30 @@ interface HMDVRDevice : VRDevice {
optional VRFieldOfViewInit rightFOV,
optional double zNear = 0.01,
optional double zFar = 10000.0);
// return a recommended rect for this eye. Only useful for Canvas rendering,
// the x/y coordinates will be the location in the canvas where this eye should
// begin, and the width/height are the dimensions. Any canvas in the appropriate
// ratio will work.
DOMRect getRecommendedEyeRenderRect(VREye whichEye);
// hack for testing
void xxxToggleElementVR(Element element);
};
[Pref="dom.vr.enabled" ,
HeaderFile="mozilla/dom/VRDevice.h"]
interface PositionSensorVRDevice : VRDevice {
/*
* Return a VRPositionState dictionary containing the state of this position sensor,
* at an optional past time or predicted for a future time if timeOffset is != 0.
* Return a VRPositionState dictionary containing the state of this position sensor
* for the current frame if within a requestAnimationFrame callback, or for the
* previous frame if not.
*
* The VRPositionState will contain the position, orientation, and velocity
* and acceleration of each of these properties. Use "hasPosition" and "hasOrientation"
* to check if the associated members are valid; if these are false, those members
* will be null.
*/
[NewObject]
VRPositionState getState(optional double timeOffset = 0.0);
[NewObject] VRPositionState getState();
/* Zero this sensor, treating its current position and orientation
/*
* Return the current instantaneous sensor state.
*/
[NewObject] VRPositionState getImmediateState();
/* Reset this sensor, treating its current position and orientation
* as the "origin/zero" values.
*/
void zeroSensor();
void resetSensor();
};