diff options
author | huangjiahua <jiahua.h@outlook.com> | 2020-05-12 11:28:51 +0800 |
---|---|---|
committer | huangjiahua <jiahua.h@outlook.com> | 2020-05-13 15:41:09 +0800 |
commit | c253ad83990d2435af3e52d7ba9b9148c48cebcf (patch) | |
tree | 61c23ca19c894d9803a3237069a85ba7c58e35be /components/script/dom/xrsession.rs | |
parent | d20b7b96261774a0e841d07a5aa805b6b2ea31a1 (diff) | |
download | servo-c253ad83990d2435af3e52d7ba9b9148c48cebcf.tar.gz servo-c253ad83990d2435af3e52d7ba9b9148c48cebcf.zip |
Handle cancelAnimationFrame() when called within a requestAnimationFrame() callback
Diffstat (limited to 'components/script/dom/xrsession.rs')
-rw-r--r-- | components/script/dom/xrsession.rs | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 2ef47361f92..5460df4fef1 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -74,6 +74,8 @@ pub struct XRSession { next_raf_id: Cell<i32>, #[ignore_malloc_size_of = "closures are hard"] raf_callback_list: DomRefCell<Vec<(i32, Option<Rc<XRFrameRequestCallback>>)>>, + #[ignore_malloc_size_of = "closures are hard"] + current_raf_callback_list: DomRefCell<Vec<(i32, Option<Rc<XRFrameRequestCallback>>)>>, input_sources: Dom<XRInputSourceArray>, // Any promises from calling end() #[ignore_malloc_size_of = "promises are hard"] @@ -110,6 +112,7 @@ impl XRSession { next_raf_id: Cell::new(0), raf_callback_list: DomRefCell::new(vec![]), + current_raf_callback_list: DomRefCell::new(vec![]), input_sources: Dom::from_ref(input_sources), end_promises: DomRefCell::new(vec![]), ended: Cell::new(false), @@ -395,7 +398,11 @@ impl XRSession { // Step 3: XXXManishearth handle inline session // Step 4-5 - let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]); + { + let mut current = self.current_raf_callback_list.borrow_mut(); + assert!(current.is_empty()); + mem::swap(&mut *self.raf_callback_list.borrow_mut(), &mut current); + } let start = self.global().as_window().get_navigation_start(); let time = reduce_timing_resolution((frame.time_ns - start).to_ms()); @@ -406,12 +413,18 @@ impl XRSession { // Step 8 self.outside_raf.set(false); - for (_, callback) in callbacks.drain(..) { + let len = self.current_raf_callback_list.borrow().len(); + for i in 0..len { + let callback = self.current_raf_callback_list.borrow()[i] + .1 + .as_ref() + .map(|callback| Rc::clone(callback)); if let Some(callback) = callback { let _ = callback.Call__(time, &frame, ExceptionHandling::Report); } } self.outside_raf.set(true); + *self.current_raf_callback_list.borrow_mut() = vec![]; frame.set_active(false); if self.is_immersive() { @@ -656,6 +669,11 @@ impl XRSessionMethods for XRSession { if let Some(pair) = list.iter_mut().find(|pair| pair.0 == frame) { pair.1 = None; } + + let mut list = self.current_raf_callback_list.borrow_mut(); + if let Some(pair) = list.iter_mut().find(|pair| pair.0 == frame) { + pair.1 = None; + } } /// https://immersive-web.github.io/webxr/#dom-xrsession-environmentblendmode |