Give inline sessions the correct projection matrices

This commit is contained in:
Manish Goregaokar 2019-12-05 15:08:09 -08:00
parent a1c1a16e98
commit 8aaa8493a7
4 changed files with 108 additions and 27 deletions

View file

@ -20,10 +20,10 @@ use crate::dom::xrview::XRView;
use crate::dom::xrviewport::XRViewport;
use canvas_traits::webgl::WebGLFramebufferId;
use dom_struct::dom_struct;
use euclid::default::Size2D;
use euclid::Size2D;
use std::convert::TryInto;
use webxr_api::SwapChainId as WebXRSwapChainId;
use webxr_api::Views;
use webxr_api::{Viewport, Views};
#[dom_struct]
pub struct XRWebGLLayer {
@ -33,7 +33,7 @@ pub struct XRWebGLLayer {
stencil: bool,
alpha: bool,
#[ignore_malloc_size_of = "ids don't malloc"]
swap_chain_id: WebXRSwapChainId,
swap_chain_id: Option<WebXRSwapChainId>,
context: Dom<WebGLRenderingContext>,
session: Dom<XRSession>,
/// If none, this is an inline session (the composition disabled flag is true)
@ -42,7 +42,7 @@ pub struct XRWebGLLayer {
impl XRWebGLLayer {
pub fn new_inherited(
swap_chain_id: WebXRSwapChainId,
swap_chain_id: Option<WebXRSwapChainId>,
session: &XRSession,
context: &WebGLRenderingContext,
init: &XRWebGLLayerInit,
@ -63,7 +63,7 @@ impl XRWebGLLayer {
pub fn new(
global: &GlobalScope,
swap_chain_id: WebXRSwapChainId,
swap_chain_id: Option<WebXRSwapChainId>,
session: &XRSession,
context: &WebGLRenderingContext,
init: &XRWebGLLayerInit,
@ -89,6 +89,7 @@ impl XRWebGLLayer {
context: &WebGLRenderingContext,
init: &XRWebGLLayerInit,
) -> Fallible<DomRoot<Self>> {
let framebuffer;
// Step 2
if session.is_ended() {
return Err(Error::InvalidState);
@ -97,9 +98,15 @@ impl XRWebGLLayer {
// XXXManishearth step 4: check XR compat flag for immersive sessions
// Step 9.2. "Initialize layers framebuffer to a new opaque framebuffer created with context."
let size = session.with_session(|session| session.recommended_framebuffer_resolution());
let (swap_chain_id, framebuffer) =
WebGLFramebuffer::maybe_new_webxr(session, context, size).ok_or(Error::Operation)?;
let (swap_chain_id, framebuffer) = if session.is_immersive() {
let size = session.with_session(|session| session.recommended_framebuffer_resolution());
let (swap_chain_id, fb) = WebGLFramebuffer::maybe_new_webxr(session, context, size)
.ok_or(Error::Operation)?;
framebuffer = fb;
(Some(swap_chain_id), Some(&*framebuffer))
} else {
(None, None)
};
// Step 9.3. "Allocate and initialize resources compatible with sessions XR device,
// including GPU accessible memory buffers, as required to support the compositing of layer."
@ -117,12 +124,13 @@ impl XRWebGLLayer {
session,
context,
init,
Some(&framebuffer),
framebuffer,
))
}
pub fn swap_chain_id(&self) -> WebXRSwapChainId {
self.swap_chain_id
.expect("swap_chain_id must not be called for inline sessions")
}
pub fn session(&self) -> &XRSession {
@ -133,19 +141,22 @@ impl XRWebGLLayer {
if let WebGLFramebufferId::Opaque(id) = self
.framebuffer
.as_ref()
.expect("Must have framebuffer")
.expect("swap_buffers must not be called for inline sessions")
.id()
{
self.context.swap_buffers(Some(id));
}
}
fn size(&self) -> Size2D<i32> {
if let Some(framebuffer) = self.framebuffer {
pub fn size(&self) -> Size2D<u32, Viewport> {
if let Some(framebuffer) = self.framebuffer.as_ref() {
let size = framebuffer.size().unwrap_or((0, 0));
Size2D::new(size.0, size.1)
Size2D::new(
size.0.try_into().unwrap_or(0),
size.1.try_into().unwrap_or(0),
)
} else {
self.context.Canvas().get_size()
Size2D::from_untyped(self.context.Canvas().get_size())
}
}
}
@ -183,12 +194,12 @@ impl XRWebGLLayerMethods for XRWebGLLayer {
/// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-framebufferwidth
fn FramebufferWidth(&self) -> u32 {
self.size().width.try_into().unwrap_or(0)
self.size().width
}
/// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-framebufferheight
fn FramebufferHeight(&self) -> u32 {
self.size().height.try_into().unwrap_or(0)
self.size().height
}
/// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport