Avoid accessing DOM global from VRDisplay's destructor.

This commit is contained in:
Josh Matthews 2019-12-19 18:14:05 -05:00
parent 2e6252f256
commit fda0572a93
6 changed files with 27 additions and 28 deletions

View file

@ -23,7 +23,6 @@ use crate::dom::bindings::root::{DomRoot, MutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::vrdisplaycapabilities::VRDisplayCapabilities;
use crate::dom::vrdisplayevent::VRDisplayEvent;
@ -32,6 +31,7 @@ use crate::dom::vrframedata::VRFrameData;
use crate::dom::vrpose::VRPose;
use crate::dom::vrstageparameters::VRStageParameters;
use crate::dom::webglrenderingcontext::{WebGLMessageSender, WebGLRenderingContext};
use crate::dom::window::Window;
use crate::realms::InRealm;
use crate::script_runtime::CommonScriptMsg;
use crate::script_runtime::ScriptThreadEventCategory::WebVREvent;
@ -40,6 +40,7 @@ use canvas_traits::webgl::{webgl_channel, WebGLReceiver, WebVRCommand};
use crossbeam_channel::{unbounded, Sender};
use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use profile_traits::ipc;
use std::cell::Cell;
use std::mem;
@ -82,6 +83,9 @@ pub struct VRDisplay {
running_display_raf: Cell<bool>,
paused: Cell<bool>,
stopped_on_pause: Cell<bool>,
#[ignore_malloc_size_of = "channels are hard"]
webvr_thread: IpcSender<WebVRMsg>,
pipeline: PipelineId,
}
unsafe_no_jsmanaged_fields!(WebVRDisplayData);
@ -110,7 +114,7 @@ struct VRRAFUpdate {
type VRRAFUpdateSender = Sender<Result<VRRAFUpdate, ()>>;
impl VRDisplay {
fn new_inherited(global: &GlobalScope, display: WebVRDisplayData) -> VRDisplay {
fn new_inherited(global: &Window, display: WebVRDisplayData) -> VRDisplay {
let stage = match display.stage_parameters {
Some(ref params) => Some(VRStageParameters::new(params.clone(), &global)),
None => None,
@ -152,10 +156,12 @@ impl VRDisplay {
// This flag is set when the Display was presenting when it received a VR Pause event.
// When the VR Resume event is received and the flag is set, VR presentation automatically restarts.
stopped_on_pause: Cell::new(false),
webvr_thread: global.webvr_thread().expect("webvr is disabled"),
pipeline: global.pipeline_id(),
}
}
pub fn new(global: &GlobalScope, display: WebVRDisplayData) -> DomRoot<VRDisplay> {
pub fn new(global: &Window, display: WebVRDisplayData) -> DomRoot<VRDisplay> {
reflect_dom_object(
Box::new(VRDisplay::new_inherited(&global, display)),
global,
@ -229,7 +235,7 @@ impl VRDisplayMethods for VRDisplay {
// If not presenting we fetch inmediante VRFrameData
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
self.webvr_thread()
self.webvr_thread
.send(WebVRMsg::GetFrameData(
self.global().pipeline_id(),
self.DisplayId(),
@ -258,7 +264,7 @@ impl VRDisplayMethods for VRDisplay {
// https://w3c.github.io/webvr/#dom-vrdisplay-resetpose
fn ResetPose(&self) {
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
self.webvr_thread()
self.webvr_thread
.send(WebVRMsg::ResetPose(
self.global().pipeline_id(),
self.DisplayId(),
@ -398,7 +404,7 @@ impl VRDisplayMethods for VRDisplay {
// Exit present
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
self.webvr_thread()
self.webvr_thread
.send(WebVRMsg::ExitPresent(
self.global().pipeline_id(),
self.display.borrow().display_id,
@ -452,18 +458,14 @@ impl VRDisplayMethods for VRDisplay {
}
impl VRDisplay {
fn webvr_thread(&self) -> IpcSender<WebVRMsg> {
self.global()
.as_window()
.webvr_thread()
.expect("Shouldn't arrive here with WebVR disabled")
}
pub fn update_display(&self, display: &WebVRDisplayData) {
*self.display.borrow_mut() = display.clone();
if let Some(ref stage) = display.stage_parameters {
if self.stage_params.get().is_none() {
let params = Some(VRStageParameters::new(stage.clone(), &self.global()));
let params = Some(VRStageParameters::new(
stage.clone(),
&self.global().as_window(),
));
self.stage_params.set(params.as_deref());
} else {
self.stage_params.get().unwrap().update(&stage);
@ -484,7 +486,7 @@ impl VRDisplay {
{
// Request Present
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
self.webvr_thread()
self.webvr_thread
.send(WebVRMsg::RequestPresent(
self.global().pipeline_id(),
self.display.borrow().display_id,
@ -730,7 +732,7 @@ impl VRDisplay {
// Only called when the JSContext is destroyed while presenting.
// In this case we don't want to wait for WebVR Thread response.
fn force_stop_present(&self) {
self.webvr_thread()
self.webvr_thread
.send(WebVRMsg::ExitPresent(
self.global().pipeline_id(),
self.display.borrow().display_id,

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::VRDisplayCapabilitiesBinding;
use crate::dom::bindings::codegen::Bindings::VRDisplayCapabilitiesBinding::VRDisplayCapabilitiesMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use webvr_traits::WebVRDisplayCapabilities;
@ -30,7 +30,7 @@ impl VRDisplayCapabilities {
pub fn new(
capabilities: WebVRDisplayCapabilities,
global: &GlobalScope,
global: &Window,
) -> DomRoot<VRDisplayCapabilities> {
reflect_dom_object(
Box::new(VRDisplayCapabilities::new_inherited(capabilities)),

View file

@ -7,8 +7,8 @@ use crate::dom::bindings::codegen::Bindings::VREyeParametersBinding;
use crate::dom::bindings::codegen::Bindings::VREyeParametersBinding::VREyeParametersMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::globalscope::GlobalScope;
use crate::dom::vrfieldofview::VRFieldOfView;
use crate::dom::window::Window;
use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject};
@ -41,7 +41,7 @@ impl VREyeParameters {
}
#[allow(unsafe_code)]
pub fn new(parameters: WebVREyeParameters, global: &GlobalScope) -> DomRoot<VREyeParameters> {
pub fn new(parameters: WebVREyeParameters, global: &Window) -> DomRoot<VREyeParameters> {
let fov = VRFieldOfView::new(&global, parameters.field_of_view.clone());
let cx = global.get_cx();

View file

@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::Bindings::VRFieldOfViewBinding::VRFieldOfView
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use webvr_traits::WebVRFieldOfView;
@ -29,7 +29,7 @@ impl VRFieldOfView {
}
}
pub fn new(global: &GlobalScope, fov: WebVRFieldOfView) -> DomRoot<VRFieldOfView> {
pub fn new(global: &Window, fov: WebVRFieldOfView) -> DomRoot<VRFieldOfView> {
reflect_dom_object(
Box::new(VRFieldOfView::new_inherited(fov)),
global,

View file

@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::Bindings::VRStageParametersBinding::VRStagePa
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject};
@ -38,10 +38,7 @@ impl VRStageParameters {
}
#[allow(unsafe_code)]
pub fn new(
parameters: WebVRStageParameters,
global: &GlobalScope,
) -> DomRoot<VRStageParameters> {
pub fn new(parameters: WebVRStageParameters, global: &Window) -> DomRoot<VRStageParameters> {
let cx = global.get_cx();
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
unsafe {

View file

@ -364,7 +364,7 @@ impl XRSystem {
existing.update_display(&display);
existing
} else {
let root = VRDisplay::new(&self.global(), display.clone());
let root = VRDisplay::new(&self.global().as_window(), display.clone());
self.displays.borrow_mut().push(Dom::from_ref(&*root));
root
}