From 1c2d872e33adfaab5c06f54904b523d0ba23e948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 28 Jun 2018 10:24:59 +0200 Subject: [PATCH] Workaround resume issues --- components/script/dom/audiocontext.rs | 19 +++++++++++++------ components/script/dom/audionode.rs | 6 ++++-- components/script/dom/baseaudiocontext.rs | 22 ++++++++++------------ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 2dd357ca2ec..6eb9cc781a9 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -46,11 +46,8 @@ impl AudioContext { // servo-media takes care of setting the default sample rate of the output device // and of resampling the audio output if needed. - // Step 5. - if context.is_allowed_to_start() { - // Step 6. - context.resume(); - } + // Steps 5 and 6 of the construction algorithm will happen in `resume`, + // after reflecting dom object. AudioContext { context, @@ -64,7 +61,9 @@ impl AudioContext { pub fn new(global: &GlobalScope, options: &AudioContextOptions) -> DomRoot { let context = AudioContext::new_inherited(global, options); - reflect_dom_object(Box::new(context), global, AudioContextBinding::Wrap) + let context = reflect_dom_object(Box::new(context), global, AudioContextBinding::Wrap); + context.resume(); + context } // https://webaudio.github.io/web-audio-api/#AudioContext-constructors @@ -73,6 +72,14 @@ impl AudioContext { let global = window.upcast::(); Ok(AudioContext::new(global, options)) } + + fn resume(&self) { + // Step 5. + if self.context.is_allowed_to_start() { + // Step 6. + self.context.resume(); + } + } } impl AudioContextMethods for AudioContext { diff --git a/components/script/dom/audionode.rs b/components/script/dom/audionode.rs index f31c2808716..c0c6668106b 100644 --- a/components/script/dom/audionode.rs +++ b/components/script/dom/audionode.rs @@ -65,8 +65,8 @@ impl AudioNodeMethods for AudioNode { destination: &AudioNode, output: u32, input: u32) -> Fallible> { - if self.context != destination.Context() { - return Err(Error::InvalidAccess); + if *(self.context) != *(destination.Context()) { + //XXX return Err(Error::InvalidAccess); } if output >= self.NumberOfOutputs() || @@ -74,6 +74,8 @@ impl AudioNodeMethods for AudioNode { return Err(Error::IndexSize); } + // XXX Check previous connections. + self.context.audio_context_impl().connect_ports( self.node().output(output), destination.node().input(input) ); diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 2a0ea434dd9..50092b81ebd 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -15,6 +15,7 @@ use dom::bindings::num::Finite; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{DomObject, Reflector}; use dom::bindings::root::DomRoot; +use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::oscillatornode::OscillatorNode; use dom::promise::Promise; @@ -100,6 +101,11 @@ impl BaseAudioContext { self.state.get() == AudioContextState::Suspended } + #[allow(unrooted_must_root)] + fn push_pending_resume_promise(&self, promise: &Rc) { + self.pending_resume_promises.borrow_mut().push(promise.clone()); + } + /// Takes the pending resume promises. /// /// The result with which these promises will be fulfilled is passed here @@ -162,7 +168,6 @@ impl BaseAudioContext { let window = DomRoot::downcast::(self.global()).unwrap(); let task_source = window.dom_manipulation_task_source(); let this = Trusted::new(self); - // Set the rendering thread state to 'running' and start // rendering the audio graph. match self.audio_context_impl.resume() { @@ -173,21 +178,16 @@ impl BaseAudioContext { this.fulfill_in_flight_resume_promises(|| { if this.state.get() != AudioContextState::Running { this.state.set(AudioContextState::Running); - let window = DomRoot::downcast::(this.global()).unwrap(); - window.dom_manipulation_task_source().queue_simple_event( - this.upcast(), - atom!("statechange"), - &window - ); + //XXX this.upcast::().fire_event(atom!("statechange")); } + }); }), window.upcast()); }, Err(()) => { self.take_pending_resume_promises(Err(Error::Type("Something went wrong".to_owned()))); let _ = task_source.queue(task!(resume_error: move || { - let this = this.root(); - this.fulfill_in_flight_resume_promises(|| {}); + this.root().fulfill_in_flight_resume_promises(|| {}) }), window.upcast()); } } @@ -229,9 +229,7 @@ impl BaseAudioContextMethods for BaseAudioContext { return promise; } - // Push the promise into the queue to avoid passing a reference to - // `resume()`. This way we limit the usage of #[allow(unrooted_must_root)] - self.pending_resume_promises.borrow_mut().push(promise.clone()); + self.push_pending_resume_promise(&promise); // Step 4. if !self.is_allowed_to_start() {