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:
Imanol Fernandez
2020-07-29 10:00:53 +00:00
parent eb78f029f5
commit 60787e0f88
6 changed files with 33 additions and 12 deletions

View File

@@ -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() {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;