aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/xrsession.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/xrsession.rs')
-rw-r--r--components/script/dom/xrsession.rs81
1 files changed, 39 insertions, 42 deletions
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs
index 3451bb55467..41f8392acfb 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,43 @@ 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,
+ );
+ }),
+ );
+
+ 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) {
let this = Trusted::new(self);
let global = self.global();
@@ -291,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.
@@ -368,9 +407,6 @@ impl XRSessionMethods for XRSession {
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe
fn RequestAnimationFrame(&self, callback: Rc<XRFrameRequestCallback>) -> 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);
@@ -378,45 +414,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,
- // 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
}