diff --git a/explainer.md b/explainer.md index 26847d40..e2791463 100644 --- a/explainer.md +++ b/explainer.md @@ -458,9 +458,9 @@ Beyond the core APIs described above, the WebXR Device API also exposes several ### Controlling rendering quality -While in immersive sessions, the UA is responsible for providing a framebuffer that is correctly optimized for presentation to the `XRSession` in each `XRFrame`. Developers can optionally request either the buffer size or viewport size be scaled, though the UA may not respect the request. Even when the UA honors the scaling requests, the result is not guaranteed to be the exact percentage requested. +While in immersive sessions, the UA is responsible for providing a framebuffer that is correctly optimized for presentation to the `XRSession` in each `XRFrame`. Developers can optionally request the framebuffer size be scaled, though the UA may not respect the request. Even when the UA honors the scaling requests, the result is not guaranteed to be the exact percentage requested. -The first scaling mechanism is done by specifying a `framebufferScaleFactor` at `XRWebGLLayer` creation time. Each XR device has a default framebuffer size, which corresponds to a `framebufferScaleFactor` of `1.0`. This default size is determined by the UA and should represent a reasonable balance between rendering quality and performance. It may not be the 'native' size for the device (that is, a buffer which would match the native screen resolution 1:1 at point of highest magnification). For example, mobile platforms such as GearVR or Daydream frequently suggest using lower resolutions than their screens are capable of to ensure consistent performance. +Framebuffer scaling is done by specifying a `framebufferScaleFactor` at `XRWebGLLayer` creation time. Each XR device has a default framebuffer size, which corresponds to a `framebufferScaleFactor` of `1.0`. This default size is determined by the UA and should represent a reasonable balance between rendering quality and performance. It may not be the 'native' size for the device (that is, a buffer which would match the native screen resolution 1:1 at point of highest magnification). For example, mobile platforms such as GearVR or Daydream frequently suggest using lower resolutions than their screens are capable of to ensure consistent performance. If the `framebufferScaleFactor` is set to a number higher or lower than `1.0` the UA should create a framebuffer that is the default resolution multiplied by the given scale factor. So a `framebufferScaleFactor` of `0.5` would specify a framebuffer with 50% the default height and width, and so on. The UA may clamp the scale factor however it sees fit, or may round it to a desired increment if needed (for example, fitting the buffer dimensions to powers of two if that is known to increase performance.) @@ -485,23 +485,7 @@ function setupNativeScaleWebGLLayer() { }); ``` -This technique should be used carefully, since the native resolution on some headsets may be higher than the system is capable of rendering at a stable framerate without use of additional techniques such as foveated rendering. Also note that the UA's scale clamping is allowed to prevent the allocation of native resoltion framebuffers if it deems it necessary to maintain acceptable performance. - -The second scaling mechanism is to request a scaled viewport into the `XRWebGLLayer`'s `framebuffer`. For example, under times of heavy load the developer may choose to temporarily render fewer pixels. To do so, developers should call `XRWebGLLayer.requestViewportScaling()` and supply a value between 0.0 and 1.0. The UA may then respond by changing the `XRWebGLLayer`'s `framebuffer` and/or the `XRViewport` values in future XR frames. It is worth noting that the UA may change the viewports for reasons other than developer request, and that not all UAs will respect requested viewport changes; as such, developers must always query the viewport values on each XR frame. - -```js -function onDrawFrame() { - // Draw the current frame - - // In response to a performance dip, request the viewport be restricted - // to a percentage (ex: 50%) of the layer's actual buffer. This change - // will apply to subsequent rendering frames - layer.requestViewportScaling(0.5); - - // Register for next frame callback - xrSession.requestAnimationFrame(onDrawFrame); -} -``` +This technique should be used carefully, since the native resolution on some headsets may be higher than the system is capable of rendering at a stable framerate without use of additional techniques such as foveated rendering. Also note that the UA's scale clamping is allowed to prevent the allocation of native resolution framebuffers if it deems it necessary to maintain acceptable performance. ### Controlling depth precision @@ -738,7 +722,6 @@ interface XRWebGLLayer : XRLayer { readonly attribute WebGLFramebuffer framebuffer; XRViewport? getViewport(XRView view); - Promise requestViewportScaling(double viewportScaleFactor); static double getNativeFramebufferScaleFactor(XRSession session); }; diff --git a/index.bs b/index.bs index 0177d6a0..7c76641b 100644 --- a/index.bs +++ b/index.bs @@ -1324,7 +1324,6 @@ interface XRWebGLLayer : XRLayer { // Methods XRViewport? getViewport(XRView view); - void requestViewportScaling(double viewportScaleFactor); // Static Methods static double getNativeFramebufferScaleFactor(XRSession session); @@ -1358,7 +1357,7 @@ The framebuffer attribute of an {{XRWebG - An [=opaque framebuffer=]'s attachments cannot be inspected or changed. Calling {{framebufferTexture2D}}, {{framebufferRenderbuffer}}, {{getFramebufferAttachmentParameter}}, or {{getRenderbufferParameter}} with an [=opaque framebuffer=] MUST generate an {{INVALID_OPERATION}} error. - An [=opaque framebuffer=] is considered incomplete outside of an {{XRSession/requestAnimationFrame()}} callback. When not in a {{XRSession/requestAnimationFrame()}} callback calls to {{checkFramebufferStatus}} outside of an {{XRSession/requestAnimationFrame()}} callback MUST generate a {{FRAMEBUFFER_UNSUPPORTED}} error and attempts to clear, draw to, or read from the [=opaque framebuffer=] MUST generate an {{INVALID_FRAMEBUFFER_OPERATION}} error. -The framebufferWidth and framebufferHeight attributes return the width and height of the {{framebuffer}}'s attachments, respectively. +The framebufferWidth and framebufferHeight attributes return the width and height of the {{framebuffer}}'s attachments, respectively. The {{framebuffer}} size cannot be adjusted by the developer after the {{XRWebGLLayer}} has been created. The antialias attribute is true if the {{framebuffer}} supports antialiasing using a technique of the UAs choosing, and false if no antialiasing will be performed. @@ -1368,7 +1367,7 @@ Depth values stored in the buffer are expected to be between 0.0 an NOTE: Making the scene's depth buffer available to the compositor allows some platforms to provide quality and comfort improvements such as improved reprojection. -Each {{XRWebGLLayer}} MUST have a list of viewports which contains one [=WebGL viewport=] for each {{XRView}} the {{XRSession}} currently exposes. The viewports MUST NOT be overlapping. The {{XRWebGLLayer}} MUST also have a viewport scale factor, initially set to 1.0, and a minimum viewport scale factor set to a UA-determined value between 0 and 1. +Each {{XRWebGLLayer}} MUST have a list of viewports which contains one [=WebGL viewport=] for each {{XRView}} the {{XRSession}} currently exposes. The viewports MUST NOT be overlapping. {{getViewport()}} queries the {{XRViewport}} the given {{XRView}} should use when rendering to the layer. @@ -1381,27 +1380,12 @@ The getViewport(|view|) method, when invoke 1. Let |viewport| be a new {{XRViewport}} instance. 1. Initialize |viewport|'s {{XRViewport/x}} to |glViewport|'s x component. 1. Initialize |viewport|'s {{XRViewport/y}} to |glViewport|'s y component. - 1. Initialize |viewport|'s {{XRViewport/width}} to |glViewport|'s width component multiplied by the [=viewport scale factor=]. - 1. Initialize |viewport|'s {{XRViewport/height}} to |glViewport|'s height component multiplied by the [=viewport scale factor=]. + 1. Initialize |viewport|'s {{XRViewport/width}} to |glViewport|'s width. + 1. Initialize |viewport|'s {{XRViewport/height}} to |glViewport|'s height. 1. Return |viewport|. -
-The {{framebuffer}} size cannot be adjusted by the developer after the {{XRWebGLLayer}} has been created, but it can be useful to adjust the resolution content is rendered at at runtime to aid application performance. To do so, developers can request that the size of the viewports in the [=list of viewports=] be changed using the {{requestViewportScaling()}} method. - -
- -The requestViewportScaling(|scaleFactor|) method, when invoked, MUST run the following steps: - - 1. If |scaleFactor| is greater than 1.0 set |scaleFactor| to 1.0. - 1. If |scaleFactor| is less than the [=minimum viewport scale factor=] set |scaleFactor| to the [=minimum viewport scale factor=]. - 1. If the [=XR/XR device=] places additional device-specific restrictions on viewport size, adjust |scaleFactor| accordingly. - 1. Set the [=viewport scale factor=] to |scaleFactor|. - -
-
- Each {{XRSession}} MUST identify a native WebGL framebuffer resolution, which is the pixel resolution of a WebGL framebuffer required to match the physical pixel resolution of the [=/XR device=].