Bug 1655006 - Implement WebXR nativeFramebufferScaleFactor. r=jgilbert,kip,daoshengmu
Clamp the requested XRWebGLLayer framebuffer size to ensure it's not too small to see or larger than the max native resolution. Differential Revision: https://phabricator.services.mozilla.com/D84799
This commit is contained in:
@@ -24,6 +24,8 @@ using namespace mozilla::gl;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static constexpr float XR_FRAMEBUFFER_MIN_SCALE = 0.2f;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(XRWebGLLayer, mParent, mSession, mWebGL,
|
||||
mFramebuffer, mLeftViewport,
|
||||
mRightViewport)
|
||||
@@ -136,12 +138,19 @@ already_AddRefed<XRWebGLLayer> XRWebGLLayer::Constructor(
|
||||
options.depthStencil =
|
||||
aXRWebGLLayerInitDict.mDepth || aXRWebGLLayerInitDict.mStencil;
|
||||
|
||||
// Clamp the requested framebuffer size to ensure it's not too
|
||||
// small to see or larger than the max native resolution.
|
||||
const float maxScale =
|
||||
std::max(displayState.nativeFramebufferScaleFactor, 1.0f);
|
||||
const float scaleFactor =
|
||||
fmin(aXRWebGLLayerInitDict.mFramebufferScaleFactor, 1.0f);
|
||||
std::max(XR_FRAMEBUFFER_MIN_SCALE,
|
||||
std::min((float)aXRWebGLLayerInitDict.mFramebufferScaleFactor,
|
||||
maxScale));
|
||||
|
||||
options.width =
|
||||
(int32_t)(2.0f * displayState.eyeResolution.width * scaleFactor);
|
||||
options.height = (int32_t)(displayState.eyeResolution.height * scaleFactor);
|
||||
(int32_t)ceilf(2.0f * displayState.eyeResolution.width * scaleFactor);
|
||||
options.height =
|
||||
(int32_t)ceilf(displayState.eyeResolution.height * scaleFactor);
|
||||
framebuffer = gl->CreateOpaqueFramebuffer(options);
|
||||
|
||||
if (!framebuffer) {
|
||||
@@ -233,14 +242,19 @@ already_AddRefed<XRViewport> XRWebGLLayer::GetViewport(const XRView& aView) {
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/webxr/#dom-xrwebgllayer-getnativeframebufferscalefactor
|
||||
/* static */ double XRWebGLLayer::GetNativeFramebufferScaleFactor(
|
||||
const GlobalObject& aGlobal, const XRSession& aSession) {
|
||||
if (aSession.IsEnded()) {
|
||||
return 0.0f;
|
||||
}
|
||||
// TODO: Get the maximum framebuffer size from each display.
|
||||
// Right now we assume that the recommended size is the maximum one.
|
||||
return 1.0f;
|
||||
if (!aSession.IsImmersive()) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const gfx::VRDisplayInfo& displayInfo =
|
||||
aSession.GetDisplayClient()->GetDisplayInfo();
|
||||
return displayInfo.mDisplayState.nativeFramebufferScaleFactor;
|
||||
}
|
||||
|
||||
void XRWebGLLayer::StartAnimationFrame() {
|
||||
|
||||
@@ -143,7 +143,9 @@ XRSession::XRSession(
|
||||
|
||||
XRSession::~XRSession() { MOZ_ASSERT(mShutdown); }
|
||||
|
||||
gfx::VRDisplayClient* XRSession::GetDisplayClient() { return mDisplayClient; }
|
||||
gfx::VRDisplayClient* XRSession::GetDisplayClient() const {
|
||||
return mDisplayClient;
|
||||
}
|
||||
|
||||
JSObject* XRSession::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
@@ -382,7 +384,9 @@ already_AddRefed<Promise> XRSession::RequestReferenceSpace(
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
XRRenderState* XRSession::GetActiveRenderState() { return mActiveRenderState; }
|
||||
XRRenderState* XRSession::GetActiveRenderState() const {
|
||||
return mActiveRenderState;
|
||||
}
|
||||
|
||||
void XRSession::XRFrameRequest::Call(const DOMHighResTimeStamp& aTimeStamp,
|
||||
XRFrame& aFrame) {
|
||||
|
||||
@@ -87,8 +87,8 @@ class XRSession final : public DOMEventTargetHelper, public nsARefreshObserver {
|
||||
IMPL_EVENT_HANDLER(visibilitychange);
|
||||
|
||||
// Non WebIDL Members
|
||||
gfx::VRDisplayClient* GetDisplayClient();
|
||||
XRRenderState* GetActiveRenderState();
|
||||
gfx::VRDisplayClient* GetDisplayClient() const;
|
||||
XRRenderState* GetActiveRenderState() const;
|
||||
bool IsEnded() const;
|
||||
bool IsImmersive() const;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace gfx {
|
||||
// and mapped files if we have both release and nightlies
|
||||
// running at the same time? Or...what if we have multiple
|
||||
// release builds running on same machine? (Bug 1563232)
|
||||
#define SHMEM_VERSION "0.0.10"
|
||||
static const int32_t kVRExternalVersion = 17;
|
||||
#define SHMEM_VERSION "0.0.11"
|
||||
static const int32_t kVRExternalVersion = 18;
|
||||
|
||||
// We assign VR presentations to groups with a bitmask.
|
||||
// Currently, we will only display either content or chrome.
|
||||
@@ -345,6 +345,7 @@ struct VRDisplayState {
|
||||
VRFieldOfView eyeFOV[VRDisplayState::NumEyes];
|
||||
Point3D_POD eyeTranslation[VRDisplayState::NumEyes];
|
||||
IntSize_POD eyeResolution;
|
||||
float nativeFramebufferScaleFactor;
|
||||
bool suppressFrames;
|
||||
bool isConnected;
|
||||
bool isMounted;
|
||||
|
||||
@@ -1054,6 +1054,7 @@ bool OculusSession::InitState(VRSystemState& aSystemState) {
|
||||
texSize[VRDisplayState::Eye_Right].w);
|
||||
state.eyeResolution.height = std::max(texSize[VRDisplayState::Eye_Left].h,
|
||||
texSize[VRDisplayState::Eye_Right].h);
|
||||
state.nativeFramebufferScaleFactor = 1.0f;
|
||||
|
||||
// default to an identity quaternion
|
||||
aSystemState.sensorState.pose.orientation[3] = 1.0f;
|
||||
|
||||
@@ -740,6 +740,7 @@ bool OpenVRSession::InitState(VRSystemState& aSystemState) {
|
||||
mVRSystem->GetRecommendedRenderTargetSize(&w, &h);
|
||||
state.eyeResolution.width = w;
|
||||
state.eyeResolution.height = h;
|
||||
state.nativeFramebufferScaleFactor = 1.0f;
|
||||
|
||||
// default to an identity quaternion
|
||||
aSystemState.sensorState.pose.orientation[3] = 1.0f;
|
||||
|
||||
Reference in New Issue
Block a user