From 5e098e3a2a1f73afd245b2dfb707ab81342274da Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 15 Oct 2019 11:17:12 -0700 Subject: [PATCH 1/2] Unconditionally set up rAF loop on initialization --- components/script/dom/xrsession.rs | 51 ++++++++++++++++-------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 3451bb55467..0b47af09c3c 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -119,6 +119,7 @@ impl XRSession { ); input_sources.set_initial_inputs(&ret); ret.attach_event_handler(); + ret.setup_raf_loop(); ret } @@ -131,6 +132,33 @@ impl XRSession { self.ended.get() } + fn setup_raf_loop(&self) { + assert!( + self.raf_sender.borrow().is_none(), + "RAF loop already set up" + ); + let this = Trusted::new(self); + let global = self.global(); + let window = global.as_window(); + let (task_source, canceller) = window + .task_manager() + .dom_manipulation_task_source_with_canceller(); + let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap(); + *self.raf_sender.borrow_mut() = Some(sender); + ROUTER.add_route( + receiver.to_opaque(), + Box::new(move |message| { + let this = this.clone(); + let _ = task_source.queue_with_canceller( + task!(xr_raf_callback: move || { + this.root().raf_callback(message.to().unwrap()); + }), + &canceller, + ); + }), + ); + } + fn attach_event_handler(&self) { let this = Trusted::new(self); let global = self.global(); @@ -378,29 +406,6 @@ impl XRSessionMethods for XRSession { .borrow_mut() .push((raf_id, Some(callback))); - // set up listener for response, if necessary - if self.raf_sender.borrow().is_none() { - let this = Trusted::new(self); - let global = self.global(); - let window = global.as_window(); - let (task_source, canceller) = window - .task_manager() - .dom_manipulation_task_source_with_canceller(); - let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap(); - *self.raf_sender.borrow_mut() = Some(sender); - ROUTER.add_route( - receiver.to_opaque(), - Box::new(move |message| { - let this = this.clone(); - let _ = task_source.queue_with_canceller( - task!(xr_raf_callback: move || { - this.root().raf_callback(message.to().unwrap()); - }), - &canceller, - ); - }), - ); - } if should_send { // If our callback list is empty, it either means this is the first request, From 24bfca9b71642dfc1e5b9371c352b5efaf6f0802 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 15 Oct 2019 11:20:39 -0700 Subject: [PATCH 2/2] Always request new XR frames --- components/script/dom/xrsession.rs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 0b47af09c3c..41f8392acfb 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -157,6 +157,16 @@ impl XRSession { ); }), ); + + self.request_new_xr_frame(); + } + + /// Requests a new https://immersive-web.github.io/webxr/#xr-animation-frame + /// + /// This happens regardless of the presense of rAF callbacks + fn request_new_xr_frame(&self) { + let sender = self.raf_sender.borrow().clone().unwrap(); + self.session.borrow_mut().request_animation_frame(sender); } fn attach_event_handler(&self) { @@ -319,6 +329,7 @@ impl XRSession { frame.set_active(false); self.session.borrow_mut().render_animation_frame(); + self.request_new_xr_frame(); // If the canvas element is attached to the DOM, it is now dirty, // and we need to trigger a reflow. @@ -396,9 +407,6 @@ impl XRSessionMethods for XRSession { /// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe fn RequestAnimationFrame(&self, callback: Rc) -> i32 { - // We only need to send a message once, until a raf callback executes. - let should_send = self.raf_callback_list.borrow().is_empty(); - // queue up RAF callback, obtain ID let raf_id = self.next_raf_id.get(); self.next_raf_id.set(raf_id + 1); @@ -406,22 +414,6 @@ impl XRSessionMethods for XRSession { .borrow_mut() .push((raf_id, Some(callback))); - - if should_send { - // If our callback list is empty, it either means this is the first request, - // or raf_callback executed, in which case we should - // send a message to request an animation frame. - // - // This prevents multiple messages being sent for a single call to raf_callback, - // and multiple message are unnecessary, - // since one call will already deal with multiple potentially enqueued callbacks. - // - // Allowing multiple messages could keep the main-thread, - // where the session thread might be running, looping on incoming messages. - let sender = self.raf_sender.borrow().clone().unwrap(); - self.session.borrow_mut().request_animation_frame(sender); - } - raf_id }