electron/patches/chromium/cherry-pick-cc07a95bc309.patch

166 lines
8.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Fri, 19 Jan 2024 19:17:18 +0000
Subject: Update rendering state of automatic pull nodes before graph rendering
In rare cases, the rendering fan out count of automatic pull node
does not match the main thread fan out count after recreating
a platform destination followed by disconnection.
This CL forces the update of the rendering state of automatic
pull nodes before graph rendering to make sure that fan out counts
are synchronized before executing the audio processing function call.
NOTE: This change makes 2 WPTs fail. The follow-up work is planned
to address them once this patch is merged.
(cherry picked from commit f4bffa09b46c21147431179e1e6dd2b27bc35fbc)
Bug: 1505080
Test: Locally confirmed that ASAN doesn't crash on all repro cases.
Change-Id: I6768cd8bc64525ea9d56a19b9c58439e9cdab9a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5131958
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1246718}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5214669
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1833}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
index b2f3242426930b06694a12296206da1e7a7abfb7..490143f710dc51a93dd89fdc85035519db5e292b 100644
--- a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
@@ -40,9 +40,14 @@ AnalyserHandler::~AnalyserHandler() {
}
void AnalyserHandler::Process(uint32_t frames_to_process) {
- AudioBus* output_bus = Output(0).Bus();
+ DCHECK(Context()->IsAudioThread());
+
+ // It's possible that output is not connected. Assign nullptr to indicate
+ // such case.
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0
+ ? Output(0).Bus() : nullptr;
- if (!IsInitialized()) {
+ if (!IsInitialized() && output_bus) {
output_bus->Zero();
return;
}
@@ -54,6 +59,11 @@ void AnalyserHandler::Process(uint32_t frames_to_process) {
// Analyser reflects the current input.
analyser_.WriteInput(input_bus.get(), frames_to_process);
+ // Subsequent steps require `output_bus` to be valid.
+ if (!output_bus) {
+ return;
+ }
+
if (!Input(0).IsConnected()) {
// No inputs, so clear the output, and propagate the silence hint.
output_bus->Zero();
@@ -178,8 +188,12 @@ double AnalyserHandler::TailTime() const {
}
void AnalyserHandler::PullInputs(uint32_t frames_to_process) {
- // Render directly into the output bus
- Input(0).Pull(Output(0).Bus(), frames_to_process);
+ DCHECK(Context()->IsAudioThread());
+
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0
+ ? Output(0).Bus() : nullptr;
+
+ Input(0).Pull(output_bus, frames_to_process);
}
void AnalyserHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
index 0bf86b7d659533e0acd9cd0c902c6dd68b51e1e6..903e8172d7c381da2e2cb8e9962ea601c76b375a 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
@@ -119,12 +119,14 @@ void AudioWorkletHandler::Process(uint32_t frames_to_process) {
return;
}
- // If the input is not connected, inform the processor with nullptr.
+ // If the input or the output is not connected, inform the processor with
+ // nullptr.
for (unsigned i = 0; i < NumberOfInputs(); ++i) {
inputs_[i] = Input(i).IsConnected() ? Input(i).Bus() : nullptr;
}
for (unsigned i = 0; i < NumberOfOutputs(); ++i) {
- outputs_[i] = WrapRefCounted(Output(i).Bus());
+ outputs_[i] = Output(i).RenderingFanOutCount() > 0
+ ? WrapRefCounted(Output(i).Bus()) : nullptr;
}
for (const auto& param_name : param_value_map_.Keys()) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
index 181dfa92723843d5ce9ae3e7399215870ac1dc80..c3c53d7a7099d67a6bb76df55a6c71965ca3bf02 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
@@ -376,6 +376,12 @@ void AudioWorkletProcessor::CopyArrayBuffersToPort(
for (uint32_t bus_index = 0; bus_index < audio_port.size(); ++bus_index) {
const scoped_refptr<AudioBus>& audio_bus = audio_port[bus_index];
+
+ // nullptr indicates the output bus is not connected. Do not proceed.
+ if (!audio_bus) {
+ break;
+ }
+
for (uint32_t channel_index = 0;
channel_index < audio_bus->NumberOfChannels(); ++channel_index) {
auto backing_store = array_buffers[bus_index][channel_index]
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
index fa1de8f37b9be681f7ac447bc3e3859e8909216d..4730383dafa957c2e84c009387d15d6fe479e5ba 100644
--- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
@@ -172,6 +172,16 @@ void DeferredTaskHandler::UpdateAutomaticPullNodes() {
base::AutoTryLock try_locker(automatic_pull_handlers_lock_);
if (try_locker.is_acquired()) {
rendering_automatic_pull_handlers_.assign(automatic_pull_handlers_);
+
+ // In rare cases, it is possible for automatic pull nodes' output bus
+ // to become stale. Make sure update their rendering output counts.
+ // crbug.com/1505080.
+ for (auto& handler : rendering_automatic_pull_handlers_) {
+ for (unsigned i = 0; i < handler->NumberOfOutputs(); ++i) {
+ handler->Output(i).UpdateRenderingState();
+ }
+ }
+
automatic_pull_handlers_need_updating_ = false;
}
}
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
index 33627204a6f538eba77bd8346952404814e4affa..ce0cfa40b691d859d372c9e6da7ff54fe64bbbe1 100644
--- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
@@ -43,7 +43,10 @@
if (actual.done)
task.done();
};
- sourceNode.connect(workletNode);
+ // To have valid ArrayBuffers for both input and output, we need
+ // both connections.
+ // See: https://github.com/WebAudio/web-audio-api/issues/2566
+ sourceNode.connect(workletNode).connect(context.destination);
sourceNode.start();
});
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fbac76d9b865bfdec552bf280e4a19ae1743ef4a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+[PASS] 3 inputs; 0 outputs
+[FAIL] 0 inputs; 3 outputs
+ assert_equals: outputs[0].length expected 1 but got 0
+Harness: the test ran to completion.
+