Move viewports to being per-session, not per-frame

This commit is contained in:
Manish Goregaokar 2020-05-14 11:18:34 -07:00
parent eaad692c0b
commit 794624b42b
5 changed files with 44 additions and 23 deletions

4
Cargo.lock generated
View file

@ -6471,7 +6471,7 @@ dependencies = [
[[package]]
name = "webxr"
version = "0.0.1"
source = "git+https://github.com/servo/webxr#133663f06f9f0fdffeb046b03ce12205b8515847"
source = "git+https://github.com/servo/webxr#a73b150f1e1a946fd90bd1ccf0056e35c3eef0d2"
dependencies = [
"android_injected_glue",
"bindgen",
@ -6494,7 +6494,7 @@ dependencies = [
[[package]]
name = "webxr-api"
version = "0.0.1"
source = "git+https://github.com/servo/webxr#133663f06f9f0fdffeb046b03ce12205b8515847"
source = "git+https://github.com/servo/webxr#a73b150f1e1a946fd90bd1ccf0056e35c3eef0d2"
dependencies = [
"euclid",
"ipc-channel",

View file

@ -40,7 +40,7 @@ use crate::dom::xrspace::XRSpace;
use crate::realms::InRealm;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use euclid::{Rect, RigidTransform3D, Transform3D, Vector3D};
use euclid::{RigidTransform3D, Transform3D, Vector3D};
use ipc_channel::ipc::IpcReceiver;
use ipc_channel::router::ROUTER;
use metrics::ToMs;
@ -463,17 +463,10 @@ impl XRSession {
/// Constructs a View suitable for inline sessions using the inlineVerticalFieldOfView and canvas size
pub fn inline_view(&self) -> View<Viewer> {
debug_assert!(!self.is_immersive());
let size = self
.active_render_state
.get()
.GetBaseLayer()
.expect("Must never construct views when base layer is not set")
.size();
View {
// Inline views have no offset
transform: RigidTransform3D::identity(),
projection: *self.inline_projection_matrix.borrow(),
viewport: Rect::from_size(size.to_i32()),
}
}

View file

@ -21,6 +21,7 @@ pub struct XRView {
reflector_: Reflector,
session: Dom<XRSession>,
eye: XREye,
viewport_index: usize,
#[ignore_malloc_size_of = "mozjs"]
proj: Heap<*mut JSObject>,
#[ignore_malloc_size_of = "defined in rust-webxr"]
@ -33,27 +34,26 @@ impl XRView {
session: &XRSession,
transform: &XRRigidTransform,
eye: XREye,
viewport_index: usize,
view: View<ApiSpace>,
) -> XRView {
XRView {
reflector_: Reflector::new(),
session: Dom::from_ref(session),
eye,
viewport_index,
proj: Heap::default(),
view,
transform: Dom::from_ref(transform),
}
}
pub fn view(&self) -> &View<ApiSpace> {
&self.view
}
pub fn new<V: Copy>(
global: &GlobalScope,
session: &XRSession,
view: &View<V>,
eye: XREye,
viewport_index: usize,
pose: &ApiViewerPose,
) -> DomRoot<XRView> {
// XXXManishearth compute and cache projection matrices on the Display
@ -70,6 +70,7 @@ impl XRView {
session,
&transform,
eye,
viewport_index,
view.cast_unit(),
)),
global,
@ -79,6 +80,10 @@ impl XRView {
pub fn session(&self) -> &XRSession {
&self.session
}
pub fn viewport_index(&self) -> usize {
self.viewport_index
}
}
impl XRViewMethods for XRView {

View file

@ -49,19 +49,27 @@ impl XRViewerPose {
session,
&session.inline_view(),
XREye::None,
0,
&pose,
)),
Views::Mono(view) => {
views.push(XRView::new(global, session, &view, XREye::None, &pose))
views.push(XRView::new(global, session, &view, XREye::None, 0, &pose))
},
Views::Stereo(left, right) => {
views.push(XRView::new(global, session, &left, XREye::Left, &pose));
views.push(XRView::new(global, session, &right, XREye::Right, &pose));
views.push(XRView::new(global, session, &left, XREye::Left, 0, &pose));
views.push(XRView::new(global, session, &right, XREye::Right, 1, &pose));
},
Views::StereoCapture(left, right, third_eye) => {
views.push(XRView::new(global, session, &left, XREye::Left, &pose));
views.push(XRView::new(global, session, &right, XREye::Right, &pose));
views.push(XRView::new(global, session, &third_eye, XREye::None, &pose));
views.push(XRView::new(global, session, &left, XREye::Left, 0, &pose));
views.push(XRView::new(global, session, &right, XREye::Right, 1, &pose));
views.push(XRView::new(
global,
session,
&third_eye,
XREye::None,
2,
&pose,
));
},
};
let transform = XRRigidTransform::new(global, cast_transform(pose));

View file

@ -21,7 +21,7 @@ use crate::dom::xrview::XRView;
use crate::dom::xrviewport::XRViewport;
use canvas_traits::webgl::WebGLFramebufferId;
use dom_struct::dom_struct;
use euclid::Size2D;
use euclid::{Rect, Size2D};
use std::convert::TryInto;
use webxr_api::SwapChainId as WebXRSwapChainId;
use webxr_api::Viewport;
@ -114,7 +114,11 @@ impl XRWebGLLayer {
// Step 9.2. "Initialize layers framebuffer to a new opaque framebuffer created with context."
let (swap_chain_id, framebuffer) = if session.is_immersive() {
let size = session.with_session(|session| session.recommended_framebuffer_resolution());
let size = session.with_session(|session| {
session
.recommended_framebuffer_resolution()
.expect("immersive session must have viewports")
});
let (swap_chain_id, fb) = WebGLFramebuffer::maybe_new_webxr(session, &context, size)
.ok_or(Error::Operation)?;
framebuffer = fb;
@ -240,6 +244,17 @@ impl XRWebGLLayerMethods for XRWebGLLayer {
return None;
}
Some(XRViewport::new(&self.global(), view.view().viewport))
let index = view.viewport_index();
let viewport = self.session.with_session(|s| {
// Inline sssions
if s.viewports().is_empty() {
Rect::from_size(self.size().to_i32())
} else {
s.viewports()[index]
}
});
Some(XRViewport::new(&self.global(), viewport))
}
}