Skip to content

Commit c5e5bcb

Browse files
committed
First pass at support for DOM layers
1 parent 400b1ef commit c5e5bcb

File tree

3 files changed

+5915
-1
lines changed

3 files changed

+5915
-1
lines changed

explainer.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,38 @@ const layer = xrMediaBinding.createQuadLayer(video, { layout: 'stereo-top-bottom
299299
```
300300

301301
This will then cause only the top half of the video to show to the left eye and the bottom half of the video to show to the right eye. If more complex layouts are required than are described by the `XRLayerLayout` enum then the video must be manually rendered using an `XRWebGLBinding` layer instead.
302+
303+
## DOM layers
304+
WebXR and WebXR Layers are very flexible because they give you complete control over every pixel.
305+
However, this loses the feature set of HTML which makes it much harder to create 2D UI, provide interactivity and accessible content.
306+
307+
To give developers this ability back, this spec will introduce the notion of `DOM Layers`.
308+
Much like Media and WebGL Layers, these layers are defined as a 2D plane that is composited in the scene by the system Compositor.
309+
However, the content of this layer will be drawn by the browser itself as if it was another browser window. You pass a URL to the layer creation function and the layer will be drawn as if it was a popup window.
310+
311+
To mitigate security concerns the following limitations are applied:
312+
- The URL has to be same origin as the your session
313+
- The layer is not allowed to navigate to a different origin
314+
- The layer is not allowed to create nested context (ie no \<iframe>)
315+
316+
Because layer content is only accessible to the system compositor,
317+
the author will not be able to read any pixel data from the layer
318+
(just like with media layers).
319+
320+
Creating the layer will immediately start its browser session. The session won't be released until the layer's `destroy()` method is called.
321+
322+
Hit testing is done according to the `targetRayMode` of the current session. Layers that do not have a `blendTextureSourceAlpha` will block hit testing of DOM layers.
323+
324+
To create DOM layers, an XRDOMBinding must be created, similar to the XRWebGLBinding:
325+
```js
326+
const xrDOMBinding = new XRMDOMBinding(xrSession);
327+
```
328+
329+
Use this factory object to create DOM Layers:
330+
331+
```js
332+
const domlayer = xrDOMBinding.createCylinderLayer
333+
("https://mysite.html/layercontent.html",
334+
{ referenceSpace: xrReferenceSpace,
335+
transform: new XRRigidTransform({z: -2})});
336+
```

webxrlayers-1.bs

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ spec: html;
5656
type: dfn; text: request the xr permission
5757
spec:webidl;
5858
type:dfn; text:new
59+
spec:dom;
60+
type:dfn; text:origin
5961
</pre>
6062

6163
<pre class="anchors">
@@ -131,6 +133,8 @@ spec: ECMAScript; urlPrefix: https://tc39.github.io/ecma262/#
131133
type: dfn; text: Realm; url: realm
132134
spec: compositing-1; urlPrefix: https://www.w3.org/TR/compositing-1/
133135
type: dfn; text: source-over; url: porterduffcompositingoperators_srcover
136+
spec:fetch; urlPrefix: https://fetch.spec.whatwg.org/
137+
type:dfn; text:cors-protocol; url: cors-protocol
134138
</pre>
135139

136140

@@ -270,6 +274,10 @@ The "[=feature descriptor/layers=]" [=feature descriptor=] has a [=feature requi
270274
NOTE: This means that executing the {{Permissions/request(permissionDesc)}} API with "[=feature descriptor/layers=]" will
271275
not enable layers support for the current active session.
272276

277+
If an application wants to create [[#domlayer|DOM layers]], the session MUST be requested with an appropriate [=feature descriptor=]. The string "<dfn for="feature descriptor">dom-layers</dfn>" is introduced
278+
by this module as a new valid [=feature descriptor=] for the WebXR Layers feature.
279+
280+
273281
Layer types {#xrlayertypes}
274282
===========
275283

@@ -371,6 +379,7 @@ or a {{WebGL2RenderingContext}} |context|, the user agent MUST run the following
371379
<dd> Set [=this=] {{XRCompositionLayer/chromaticAberrationCorrection}} to <code>null</code>.
372380
</dl>
373381

382+
374383
</div>
375384

376385
<div class="algorithm" data-algorithm="calling destroy on a layer">
@@ -1840,6 +1849,133 @@ When this method is invoked, the user agent MUST run the following steps:
18401849

18411850
ISSUE: define how the {{XREquirectLayer}}'s parameters affect the video display.
18421851

1852+
DOM layer creation {#domlayer}
1853+
==================
1854+
1855+
Description {#xrdomlayerdescription}
1856+
-----------
1857+
DOM Layers allow the display of HTML content within an immersive session.
1858+
They are only enabled when the "[=feature descriptor/dom-layers=]" [=feature descriptor=] is granted to the current {{XRSession}}.
1859+
1860+
The [=origin=] of the URL MUST be the same as the [=origin=] of the URL that created the immersive session.
1861+
In addition, the `[=child-src=]` and `[=navigate-to=]` Content Security Policies with the document's [=origin=] MUST be applied to the loaded document.
1862+
1863+
NOTE: this means that the experience can only open pages from the same [=origin=] and these pages can't open iframes to other origins or navigate to other origins.
1864+
1865+
XRDOMLayerInit {#xrdomlayerinittype}
1866+
--------------
1867+
The {{XRDOMLayerInit}} dictionary represents a set of configurable values that describe how an {{XRCompositionLayer}} containing a web page
1868+
is initialized.
1869+
1870+
<pre class="idl">
1871+
dictionary XRDOMLayerInit {
1872+
required XRSpace space;
1873+
XRRigidTransform? transform;
1874+
};
1875+
</pre>
1876+
1877+
The <dfn dict-member for="XRDOMLayerInit">space</dfn> attribute defines the spatial relationship with the user’s physical environment.
1878+
1879+
XRDOMQuadLayerInit {#xrdomquadlayerinittype}
1880+
------------------
1881+
The {{XRDOMQuadLayerInit}} dictionary represents a set of configurable values that describe how an {{XRQuadLayer}} containing a web page
1882+
is initialized.
1883+
1884+
<pre class="idl">
1885+
dictionary XRDOMQuadLayerInit : XRDOMLayerInit {
1886+
float? width;
1887+
float? height;
1888+
};
1889+
</pre>
1890+
1891+
XRDOMCylinderLayerInit {#xrdomcylinderlayerinittype}
1892+
----------------------
1893+
The {{XRDOMCylinderLayerInit}} dictionary represents a set of configurable values that describe how an {{XRCylinderLayer}} containing a web page
1894+
is initialized.
1895+
1896+
<pre class="idl">
1897+
dictionary XRDOMCylinderLayerInit : XRDOMLayerInit {
1898+
float radius = 2.0;
1899+
float centralAngle = 0.78539;
1900+
float? aspectRatio;
1901+
};
1902+
</pre>
1903+
1904+
XRDOMQuadLayerResult {#xrdomquadlayerresulttype}
1905+
--------------------
1906+
The {{XRDOMQuadLayerResult}} class contains the result of calling {{XRDOMBinding/createQuadLayer()}}.
1907+
1908+
<pre class="idl">
1909+
[SecureContext, Exposed=Window]
1910+
interface XRDOMQuadLayerResult {
1911+
[SameObject] readonly attribute XRQuadLayer layer;
1912+
[SameObject] readonly attribute WindowProxy window;
1913+
};
1914+
</pre>
1915+
1916+
{{XRDOMQuadLayerResult/layer}} contains the layer that was created with the {{XRDOMQuadLayerInit}} parameters.
1917+
1918+
{{XRDOMQuadLayerResult/window}} contains the {{WindowProxy}} that is associated with the newly created browsing context in the layer.
1919+
1920+
XRDOMCylinderLayerResult {#xrdomcylinderlayerresulttype}
1921+
--------------------
1922+
The {{XRDOMCylinderLayerResult}} class contains the result of calling {{XRDOMBinding/createCylinderLayer()}}.
1923+
1924+
<pre class="idl">
1925+
[SecureContext, Exposed=Window]
1926+
interface XRDOMCylinderLayerResult {
1927+
[SameObject] readonly attribute XRCylinderLayer layer;
1928+
[SameObject] readonly attribute WindowProxy window;
1929+
};
1930+
</pre>
1931+
1932+
{{XRDOMCylinderLayerResult/layer}} contains the layer that was created with the {{XRDOMQuadLayerInit}} parameters.
1933+
1934+
{{XRDOMCylinderLayerResult/window}} contains the {{WindowProxy}} that is associated with the newly created browsing context in the layer.
1935+
1936+
XRDOMBinding {#xrdombindingtype}
1937+
------------
1938+
The {{XRDOMBinding}} object is used to create layers that display a web page.
1939+
1940+
<pre class="idl">
1941+
[Exposed=Window] interface XRDOMBinding {
1942+
constructor(XRSession session);
1943+
1944+
XRDOMQuadLayerResult createQuadLayer(DOMString url, optional XRDOMQuadLayerInit init = {});
1945+
XRDOMCylinderLayerResult createCylinderLayer(DOMString video, optional XRDOMCylinderLayerInit init = {});
1946+
};
1947+
</pre>
1948+
1949+
ISSUE: the init dictionaries shouldn't be optional. This is bikeshed issue 1566.
1950+
1951+
<!--
1952+
Each {{XRDOMBinding}} has an associated <dfn dfn-for="XRDOMBinding">session</dfn>, which is the
1953+
{{XRSession}} it was created with.
1954+
-->
1955+
1956+
NOTE: It is possible to create more than one {{XRDOMBinding}}. The lifetime of a layer is not tied
1957+
to the lifetime of the {{XRDOMBinding}} that created it.
1958+
1959+
<div class="algorithm" data-algorithm="createDOMQuadLayerAlgo">
1960+
The <dfn method for="XRDOMBinding">createQuadLayer(DOMString |url|, XRQuadLayerInit |init|)</dfn> method creates a new {{XRDOMQuadLayerResult}} |result|.
1961+
1962+
When this method is invoked, the user agent MUST run the following steps:
1963+
1. |url|
1964+
1. |init|
1965+
1. |result|
1966+
1967+
</div>
1968+
1969+
<div class="algorithm" data-algorithm="createDOMCylinderLayerAlgo">
1970+
The <dfn method for="XRDOMBinding">createCylinderLayer(DOMString |url|, XRDOMCylinderLayerInit |init|)</dfn> method creates a new {{XRDOMCylinderLayerResult}} |result|.
1971+
1972+
When this method is invoked, the user agent MUST run the following steps:
1973+
1. |url|
1974+
1. |init|
1975+
1. |result|
1976+
1977+
</div>
1978+
18431979
Events {#events}
18441980
======
18451981

@@ -1939,7 +2075,7 @@ monoscopic devices.
19392075

19402076
XRView changes {#xrviewchanges}
19412077
--------------
1942-
Each [=view=] MUST define a <dfn ignore=''>recommended WebGL texture resolution</dfn> which represents a best estimate of the WebGL texture
2078+
Each [=view=] MUST define a <dfn>recommended WebGL texture resolution</dfn> which represents a best estimate of the WebGL texture
19432079
resolution large enough to contain the view.
19442080

19452081
Animation frames changes {#animationframeschanges}

0 commit comments

Comments
 (0)