Commit 3626b1f1 authored by Raymond Toy's avatar Raymond Toy Committed by Commit Bot

When suspending context, don't clear handlers

AudioContext.suspend() would call StopRendering().  This stops the audio
thread from pulling the graph (eventually) but it also clears out any
handlers, including those associated with automatic pull nodes for any
AnalyserNode that isn't connected to the destination.  When the context
is resumed, the AnalyserNode isn't pulled anymore, so the output never
changes.

Add a SuspendRendering() method to handle AudioContext.suspend() which
doesn't clear the handlers.  Then when the context is resumed,
AnalyserNodes will get pulled again.  Then StopRendering() is used only
for AudioContext.close() where it is ok to clear out the handlers since
we can't resume a closed context.

Bug: 1018499
Change-Id: I4b4ccf688b37e6b81d310d2596cfff9603048876
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1903894Reviewed-by: default avatarHongchan Choi <hongchan@chromium.org>
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723609}
parent 211b705e
...@@ -214,7 +214,7 @@ ScriptPromise AudioContext::suspendContext(ScriptState* script_state) { ...@@ -214,7 +214,7 @@ ScriptPromise AudioContext::suspendContext(ScriptState* script_state) {
// Stop rendering now. // Stop rendering now.
if (destination()) if (destination())
StopRendering(); SuspendRendering();
// Since we don't have any way of knowing when the hardware actually stops, // Since we don't have any way of knowing when the hardware actually stops,
// we'll just resolve the promise now. // we'll just resolve the promise now.
...@@ -364,11 +364,21 @@ void AudioContext::StopRendering() { ...@@ -364,11 +364,21 @@ void AudioContext::StopRendering() {
if (ContextState() == kRunning) { if (ContextState() == kRunning) {
destination()->GetAudioDestinationHandler().StopRendering(); destination()->GetAudioDestinationHandler().StopRendering();
SetContextState(kSuspended); SetContextState(kClosed);
GetDeferredTaskHandler().ClearHandlersToBeDeleted(); GetDeferredTaskHandler().ClearHandlersToBeDeleted();
} }
} }
void AudioContext::SuspendRendering() {
DCHECK(IsMainThread());
DCHECK(destination());
if (ContextState() == kRunning) {
destination()->GetAudioDestinationHandler().StopRendering();
SetContextState(kSuspended);
}
}
double AudioContext::baseLatency() const { double AudioContext::baseLatency() const {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
DCHECK(destination()); DCHECK(destination());
......
...@@ -133,8 +133,14 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext { ...@@ -133,8 +133,14 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// Record the current autoplay metrics. // Record the current autoplay metrics.
void RecordAutoplayMetrics(); void RecordAutoplayMetrics();
// Called when the context is being closed to stop rendering audio and clean
// up handlers.
void StopRendering(); void StopRendering();
// Called when suspending the context to stop reundering audio, but don't
// clean up handlers because we expect to be resuming where we left off.
void SuspendRendering();
void DidClose(); void DidClose();
// Called by the audio thread to handle Promises for resume() and suspend(), // Called by the audio thread to handle Promises for resume() and suspend(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment