You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes#636
This change adds a path for using a single WebGL canvas to drive inline
sessions, rather than needing both a WebGL context and an
XRPresentationContext before the inline session can function. The way to
do this is to create an `XRWebGLLayer` with the `useDefaultFramebuffer`
option set to `true` and set it as the session's `baseLayer`.
In addition to the above, this change removes the XRPresentationContext
entirely, and along with it the ability to do desktop mirroring (and
more advanced inline scenarios.) This is to simplify the core API, and
equivalent functionality will be reconsidered in the future because the
functionality that they represent is valuable.
@@ -457,7 +458,6 @@ When requested, the {{XRSession}} MUST <dfn>apply pending render states</dfn> by
457
458
1. If |newState|'s {{XRRenderStateInit/depthFar}} value is set, set |activeState|'s {{XRRenderState/depthFar}} to |newState|'s {{XRRenderStateInit/depthFar}}.
458
459
1. If |newState|'s {{XRRenderStateInit/inlineVerticalFieldOfView}} is set, set |activeState|'s {{XRRenderState/inlineVerticalFieldOfView}} to |newState|'s {{XRRenderStateInit/inlineVerticalFieldOfView}}.
459
460
1. If |newState|'s {{XRRenderStateInit/baseLayer}} is set, set |activeState|'s {{XRRenderState/baseLayer}} to |newState|'s {{XRRenderStateInit/baseLayer}}.
460
-
1. If |newState|'s {{XRRenderStateInit/outputContext}} is set, set |activeState|'s {{XRRenderState/outputContext}} to |newState|'s {{XRRenderStateInit/outputContext}} and [=update the XRPresentationContext session=] to |session|.
461
461
1. If |activeState|'s {{XRRenderState/inlineVerticalFieldOfView}} is less than |session|'s [=minimum inline field of view=] set |activeState|'s {{XRRenderState/inlineVerticalFieldOfView}} to |session|'s [=minimum inline field of view=].
462
462
1. If |activeState|'s {{XRRenderState/inlineVerticalFieldOfView}} is greater than |session|'s [=maximum inline field of view=] set |activeState|'s {{XRRenderState/inlineVerticalFieldOfView}} to |session|'s [=maximum inline field of view=].
463
463
@@ -537,7 +537,32 @@ The <dfn attribute for="XRSession">environmentBlendMode</dfn> attribute returns
537
537
538
538
NOTE: Most Virtual Reality devices exhibit {{XREnvironmentBlendMode/opaque}} blending behavior. Augmented Reality devices that use transparent optical elements frequently exhibit {{XREnvironmentBlendMode/additive}} blending behavior, and Augmented Reality devices that use passthrough cameras frequently exhibit {{XREnvironmentBlendMode/alpha-blend}} blending behavior.
539
539
540
-
Each {{XRSession}} has a <dfn for="XRSession">viewer reference space</dfn>, which is an {{XRReferenceSpace}} of type {{XRReferenceSpaceType/viewer}} with an [=identity transform=][=XRSpace/origin offset=]. The [=XRSession/viewer reference space=] has a <dfn for="XRSession/viewer reference space">list of views</dfn>, which is a [=/list=] of [=view=]s corresponding to the views provided by the [=/XR device=].
540
+
Each {{XRSession}} has a <dfn for="XRSession">output canvas</dfn>, which is an {{HTMLCanvasElement}}. The [=XRSession/output canvas=] is the DOM element that will display any content rendered for an {{XRSessionMode/inline}}{{XRSession}}.
To determine the [=XRSession/output canvas=] for an {{XRSession}} |session|, the user agent MUST run the following steps:
545
+
546
+
1. Let |baseLayer| be |session|'s {{XRSession/renderState}}'s {{XRRenderState/baseLayer}}.
547
+
1. If |baseLayer| is an instance of an {{XRWebGLLayer}} with a [=XRWebGLLayer/use default framebuffer=] boolean set to <code>true</code>, return |baseLayer|'s {{XRWebGLLayer/context}}'s {{WebGLRenderingContext|canvas}}.
548
+
1. return <code>null</code>.
549
+
550
+
</div>
551
+
552
+
An {{XRSessionMode/inline}}{{XRSession}} is considered a <dfn for="XRSession">direct output session</dfn> if rendering commands performed for the {{XRSession}} are executed in such a way that they are directly displayed on the page, rather than being processed by the [=XR Compositor=].
To determine if an {{XRSession}} |session| is a [=direct output session=], the user agent MUST run the following steps:
557
+
558
+
1. If |session|'s [=XRSession/mode=] is not {{XRSessionMode/inline}}, return <code>false</code>.
559
+
1. Let |baseLayer| be |session|'s {{XRSession/renderState}}'s {{XRRenderState/baseLayer}}.
560
+
1. If |baseLayer| is an instance of an {{XRWebGLLayer}} with a [=XRWebGLLayer/use default framebuffer=] boolean set to <code>true</code>, return <code>true</code>.
561
+
1. return <code>false</code>.
562
+
563
+
</div>
564
+
565
+
Each {{XRSession}} has a <dfn for="XRSession">viewer reference space</dfn>, which is an {{XRReferenceSpace}} of type {{XRReferenceSpaceType/viewer}} with an [=identity transform=][=XRSpace/origin offset=]. The [=XRSession/viewer reference space=] has a <dfn for="XRSession/viewer reference space">list of views</dfn>, which is a [=/list=] of [=view=]s corresponding to the views provided by the [=/XR device=]. If the {{XRSession}} is a [=direct output session=] the [=list of views=] MUST contain a single [=view=].
541
566
542
567
<section class="unstable">
543
568
The <dfn attribute for="XRSession">onblur</dfn> attribute is an [=Event handler IDL attribute=] for the {{blur}} event type.
@@ -596,15 +619,14 @@ When an {{XRRenderState}} object is created for an {{XRSession}} |session|, the
596
619
1. If |session| is an [=immersive session=], initialize |state|'s {{XRRenderState/inlineVerticalFieldOfView}} to <code>null</code>.
597
620
1. Else initialize |state|'s {{XRRenderState/inlineVerticalFieldOfView}} to <code>PI * 0.5</code>.
598
621
1. Initialize |state|'s {{XRRenderState/baseLayer}} to <code>null</code>.
599
-
1. Initialize |state|'s {{XRRenderState/outputContext}} to <code>null</code>.
600
622
601
623
</div>
602
624
603
625
The <dfn attribute for="XRRenderState">depthNear</dfn> attribute defines the distance, in meters, of the near clip plane from the viewer. The <dfn attribute for="XRRenderState">depthFar</dfn> attribute defines the distance, in meters, of the far clip plane from the viewer.
604
626
605
627
{{XRRenderState/depthNear}} and {{XRRenderState/depthFar}} is used in the computation of the {{XRView/projectionMatrix}} of {{XRView}}s and determines how the values of an {{XRWebGLLayer}} depth buffer are interpreted. {{XRRenderState/depthNear}} MAY be greater than {{XRRenderState/depthFar}}.
606
628
607
-
The <dfn attribute for="XRRenderState">inlineVerticalFieldOfView</dfn> attribute defines the default vertical field of view in radians used when computing projection matrices for {{XRSessionMode/inline}}{{XRSession}}s. The projection matrix calculation also takes into account the aspect ratio of the {{XRRenderState/outputContext}}'s {{XRPresentationContext/canvas}}. This value MUST be <code>null</code> for [=immersive sessions=].
629
+
The <dfn attribute for="XRRenderState">inlineVerticalFieldOfView</dfn> attribute defines the default vertical field of view in radians used when computing projection matrices for {{XRSessionMode/inline}}{{XRSession}}s. The projection matrix calculation also takes into account the aspect ratio of the [=XRSession/output canvas=]. This value MUST be <code>null</code> for [=immersive sessions=].
608
630
609
631
Animation Frames {#animation-frames}
610
632
----------------
@@ -646,7 +668,7 @@ When an {{XRSession}} |session| receives updated [=viewer=] state from the [=/XR
646
668
647
669
1. If |session|'s [=list of pending render states=] is not empty, [=apply pending render states=].
648
670
1. If |session|'s {{XRSession/renderState}}'s {{XRRenderState/baseLayer}} is <code>null</code>, abort these steps.
649
-
1. If |session|'s [=XRSession/mode=] is {{XRSessionMode/"inline"}} and |session|'s {{XRSession/renderState}}'s {{XRRenderState/outputContext}} is <code>null</code>, abort these steps.
671
+
1. If |session|'s [=XRSession/mode=] is {{XRSessionMode/"inline"}} and |session|'s [=XRSession/output canvas=] is <code>null</code>, abort these steps.
650
672
1. Let |callbacks| be a list of the entries in |session|'s [=list of animation frame callback=], in the order in which they were added to the list.
651
673
1. Set |session|'s [=list of animation frame callbacks=] to the empty list.
652
674
1. Set |frame|'s [=active=] boolean to <code>true</code>.
@@ -1423,6 +1445,7 @@ typedef (WebGLRenderingContext or
1423
1445
WebGL2RenderingContext) XRWebGLRenderingContext;
1424
1446
1425
1447
dictionary XRWebGLLayerInit {
1448
+
boolean useDefaultFramebuffer = false;
1426
1449
boolean antialias = true;
1427
1450
boolean depth = true;
1428
1451
boolean stencil = false;
@@ -1462,35 +1485,48 @@ The <dfn constructor for="XRWebGLLayer">XRWebGLLayer(|session|, |context|, |laye
1462
1485
1. If |context| is lost, throw an {{InvalidStateError}} and abort these steps.
1463
1486
1. If |context|'s [=XR compatible=] boolean is false, throw an {{InvalidStateError}} and abort these steps.
1464
1487
1. Initialize |layer|'s {{XRWebGLLayer/context}} to |context|.
1465
-
1. Initialize |layer|'s {{XRWebGLLayer/antialias}} to |layerInit|'s {{XRWebGLLayerInit/antialias}} value.
1466
-
1. If |layerInit|'s {{XRWebGLLayerInit/ignoreDepthValues}} value is <code>false</code> and the [=XR Compositor=] will make use of depth values, Initialize |layer|'s {{XRWebGLLayer/ignoreDepthValues}} to <code>false</code>.
1467
-
1. Else Initialize |layer|'s {{XRWebGLLayer/ignoreDepthValues}} to <code>true</code>
1468
-
1. Initialize |layer|'s {{XRWebGLLayer/framebuffer}} to a new [=opaque framebuffer=] created with |context|.
1469
-
1. Initialize the |layer|'s [=swap chain=].
1470
-
1. If |layer|'s [=swap chain=] was unable to be created for any reason, throw an {{OperationError}} and abort these steps.
1488
+
1. Initialize |layer|'s [=XRWebGLLayer/use default framebuffer=] to |layerInit|'s {{XRWebGLLayerInit/useDefaultFramebuffer}}.
1489
+
1. If |layer|'s [=XRWebGLLayer/use default framebuffer=] boolean is <code>false</code>:
1490
+
1. Initialize |layer|'s {{XRWebGLLayer/antialias}} to |layerInit|'s {{XRWebGLLayerInit/antialias}} value.
1491
+
1. If |layerInit|'s {{XRWebGLLayerInit/ignoreDepthValues}} value is <code>false</code> and the [=XR Compositor=] will make use of depth values, Initialize |layer|'s {{XRWebGLLayer/ignoreDepthValues}} to <code>false</code>.
1492
+
1. Else Initialize |layer|'s {{XRWebGLLayer/ignoreDepthValues}} to <code>true</code>
1493
+
1. Initialize |layer|'s {{XRWebGLLayer/framebuffer}} to a new [=opaque framebuffer=] created with |context|.
1494
+
1. Initialize the |layer|'s [=swap chain=].
1495
+
1. If |layer|'s [=swap chain=] was unable to be created for any reason, throw an {{OperationError}} and abort these steps.
1496
+
1. Else if |layer|'s [=XRWebGLLayer/use default framebuffer=] boolean is <code>true</code>:
1497
+
1. If |session|'s [=mode=] is not {{XRSessionMode/inline}}, throw an {{InvalidStateError}} and abort these steps.
1. Initialize |layer|'s {{XRWebGLLayer/ignoreDepthValues}} to <code>true</code>.
1500
+
1. Initialize |layer|'s {{XRWebGLLayer/framebuffer}} to <code>null</code>.
1471
1501
1. Return |layer|.
1472
1502
1473
1503
</div>
1474
1504
1475
1505
The <dfn attribute for="XRWebGLLayer">context</dfn> attribute is the {{WebGLRenderingContext}} the {{XRWebGLLayer}} was created with.
1476
1506
1477
-
The <dfn attribute for="XRWebGLLayer">framebuffer</dfn> attribute of an {{XRWebGLLayer}} is an instance of a {{WebGLFramebuffer}} which has been marked as [=opaque framebuffer|opaque=]. An <dfn>opaque framebuffer</dfn> functions identically to a standard {{WebGLFramebuffer}} with the following changes that make it behave more like the default framebuffer:
1507
+
Each {{XRWebGLLayer}} has a <dfn for="XRWebGLLayer">use default framebuffer</dfn> boolean which is initially set to <code>false</code>. If set to <code>true</code> it indicates that the {{XRWebGLLayer}} MUST NOT allocate its own {{WebGLFramebuffer}}, and all properties of the {{XRWebGLLayer}} that reflect {{XRWebGLLayer/framebuffer}} properties MUST instead reflect the properties of the {{XRWebGLLayer/context}}'s default framebuffer.
1508
+
1509
+
The <dfn attribute for="XRWebGLLayer">framebuffer</dfn> attribute of an {{XRWebGLLayer}} is an instance of a {{WebGLFramebuffer}} which has been marked as [=opaque framebuffer|opaque=] if [=XRWebGLLayer/use default framebuffer=] is <code>false</code>, and <code>null</code> otherwise. The {{framebuffer}} size cannot be adjusted by the developer after the {{XRWebGLLayer}} has been created.
1510
+
1511
+
An <dfn>opaque framebuffer</dfn> functions identically to a standard {{WebGLFramebuffer}} with the following changes that make it behave more like the default framebuffer:
1478
1512
1479
1513
- An [=opaque framebuffer=] MAY support antialiasing, even in WebGL 1.0.
1480
1514
- 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.
1481
1515
- 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.
1482
1516
1483
-
The <dfn attribute for="XRWebGLLayer">framebufferWidth</dfn> and <dfn attribute for="XRWebGLLayer">framebufferHeight</dfn> 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.
1517
+
Each {{XRWebGLLayer}} has a <dfn for="XRWebGLLayer">target framebuffer</dfn>, which is the {{XRWebGLLayer/framebuffer}} if [=XRWebGLLayer/use default framebuffer=] is <code>false</code>, and the {{XRWebGLLayer/context}}'s default framebuffer otherwise.
1484
1518
1485
-
The <dfn attribute for="XRWebGLLayer">antialias</dfn> attribute is <code>true</code> if the {{framebuffer}} supports antialiasing using a technique of the UAs choosing, and <code>false</code> if no antialiasing will be performed.
1519
+
The <dfn attribute for="XRWebGLLayer">framebufferWidth</dfn> and <dfn attribute for="XRWebGLLayer">framebufferHeight</dfn> attributes return the width and height of the [=XRWebGLLayer/target framebuffer=]'s attachments, respectively.
1520
+
1521
+
The <dfn attribute for="XRWebGLLayer">antialias</dfn> attribute is <code>true</code> if the [=XRWebGLLayer/target framebuffer=] supports antialiasing using a technique of the UAs choosing, and <code>false</code> if no antialiasing will be performed.
1486
1522
1487
1523
The <dfn attribute for="XRWebGLLayer">ignoreDepthValues</dfn> attribute, if <code>true</code>, indicates the [=XR Compositor=] MUST NOT make use of values in the depth buffer attachment when rendering. When the attribute is <code>false</code> it indicates that the content of the depth buffer attachment will be used by the [=XR Compositor=] and is expected to be representative of the scene rendered into the layer.
1488
1524
1489
1525
Depth values stored in the buffer are expected to be between <code>0.0</code> and <code>1.0</code>, with <code>0.0</code> representing the distance of {{XRRenderState/depthNear}} and <code>1.0</code> representing the distance of {{XRRenderState/depthFar}}, with intermediate values interpolated linearly. This is the default behavior of WebGL. (See documentation for the <a href="https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glDepthRangef.xml">depthRange function</a> for additional details.))
1490
1526
1491
1527
NOTE: Making the scene's depth buffer available to the compositor allows some platforms to provide quality and comfort improvements such as improved reprojection.
1492
1528
1493
-
Each {{XRWebGLLayer}} MUST have a <dfn>list of viewports</dfn> which contains one [=WebGL viewport=] for each {{XRView}} the {{XRSession}} currently exposes. The viewports MUST NOT be overlapping.
1529
+
Each {{XRWebGLLayer}} MUST have a <dfn>list of viewports</dfn> which is a [=/list=] containing one [=WebGL viewport=] for each {{XRView}} the {{XRSession}} currently exposes. The viewports MUST NOT be overlapping. If [=XRWebGLLayer/use default framebuffer=] is <code>true</code>, the [=list of viewports=] MUST contain a single [=WebGL viewport=] that covers the {{XRWebGLLayer/context}}'s entire default framebuffer.
1494
1530
1495
1531
{{getViewport()}} queries the {{XRViewport}} the given {{XRView}} should use when rendering to the layer.
1496
1532
@@ -1517,7 +1553,7 @@ The [=native WebGL framebuffer resolution=] is determined by running the followi
1517
1553
1518
1554
1. Let |session| be the target {{XRSession}}.
1519
1555
1. If |session|'s [=XRSession/mode=] value is not <code>"inline"</code>, set the [=native WebGL framebuffer resolution=] to the resolution required to have a 1:1 ratio between the pixels of a framebuffer large enough to contain all of the session's {{XRView}}s and the physical screen pixels in the area of the display under the highest magnification and abort these steps. If no method exists to determine the native resolution as described, the [=recommended WebGL framebuffer resolution=] MAY be used.
1520
-
1. If |session|'s [=XRSession/mode=] value is <code>"inline"</code>, set the [=native WebGL framebuffer resolution=] to the size of the |session|'s {{XRSession/renderState}}'s {{XRRenderState/outputContext}}'s {{XRPresentationContext/canvas}} in physical display pixels and reevaluate these steps every time the size of the canvas changes or the {{XRRenderState/outputContext}} is changed.
1556
+
1. Else the set the [=native WebGL framebuffer resolution=] to <code>1 x 1</code>.
1521
1557
1522
1558
</div>
1523
1559
@@ -1646,40 +1682,6 @@ function onXRSessionStarted(xrSession) {
When the {{HTMLCanvasElement/getContext()}} method of an {{HTMLCanvasElement}} |canvas| is to return a new object for the <var ignore>contextId</var><code>present-xr</code>, the user agent must return an {{XRPresentationContext}} with {{XRPresentationContext/canvas}} set to |canvas|.
When another algorithm indicates it will <dfn>update the XRPresentationContext session</dfn> to {{XRSession}} |session|, run the following steps:
1671
-
1672
-
1. Let |context| be the target {{XRPresentationContext}}.
1673
-
1. Let |prevSession| be |context|'s [=XRPresentationContext/session=].
1674
-
1. If |prevSession| is equal to |session| abort these steps.
1675
-
1. If |prevSession| is not <code>null</code>:
1676
-
1. If |prevSession|'s {{XRSession/renderState}}'s {{XRRenderState/outputContext}} is equal to |context| set |prevSession|'s {{XRSession/renderState}}'s {{XRRenderState/outputContext}} to <code>null</code>.
1677
-
1. Set |context|'s [=XRPresentationContext/session=] to |session|.
0 commit comments