Skip to content

Commit

Permalink
Move viewports to being per-session, not per-frame
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed May 18, 2020
1 parent eaad692 commit 794624b
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 1 addition & 8 deletions components/script/dom/xrsession.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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()),
}
}

Expand Down
13 changes: 9 additions & 4 deletions components/script/dom/xrview.rs
Expand Up @@ -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"]
Expand All @@ -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
Expand All @@ -70,6 +70,7 @@ impl XRView {
session,
&transform,
eye,
viewport_index,
view.cast_unit(),
)),
global,
Expand All @@ -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 {
Expand Down
20 changes: 14 additions & 6 deletions components/script/dom/xrviewerpose.rs
Expand Up @@ -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));
Expand Down
21 changes: 18 additions & 3 deletions components/script/dom/xrwebgllayer.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -114,7 +114,11 @@ impl XRWebGLLayer {

// Step 9.2. "Initialize layer’s 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;
Expand Down Expand Up @@ -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))
}
}

0 comments on commit 794624b

Please sign in to comment.