aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/xrsession.rs
diff options
context:
space:
mode:
authorhuangjiahua <jiahua.h@outlook.com>2020-05-12 11:28:51 +0800
committerhuangjiahua <jiahua.h@outlook.com>2020-05-13 15:41:09 +0800
commitc253ad83990d2435af3e52d7ba9b9148c48cebcf (patch)
tree61c23ca19c894d9803a3237069a85ba7c58e35be /components/script/dom/xrsession.rs
parentd20b7b96261774a0e841d07a5aa805b6b2ea31a1 (diff)
downloadservo-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.rs22
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