- Revision
- 268820
- Author
- cdu...@apple.com
- Date
- 2020-10-21 13:27:52 -0700 (Wed, 21 Oct 2020)
Log Message
Add addOutput() / removeOutput() utility functions to AudioSummingJunction
https://bugs.webkit.org/show_bug.cgi?id=218045
Reviewed by Eric Carlson.
Add addOutput() / removeOutput() utility functions to AudioSummingJunction to add
or remove outputs from m_outputs and abstract away the call to changedOutputs().
It was awkward that subclasses were modifying m_outputs directly and had to
explicitly call changedOutputs() whenever they did.
No new tests, no web-facing behavior change.
* Modules/webaudio/AudioNode.cpp:
(WebCore::AudioNode::updateChannelsForInputs):
* Modules/webaudio/AudioNodeInput.cpp:
(WebCore::AudioNodeInput::connect):
(WebCore::AudioNodeInput::disconnect):
(WebCore::AudioNodeInput::disable):
(WebCore::AudioNodeInput::enable):
(WebCore::AudioNodeInput::numberOfChannels const):
* Modules/webaudio/AudioParam.cpp:
(WebCore::AudioParam::connect):
(WebCore::AudioParam::disconnect):
* Modules/webaudio/AudioSummingJunction.cpp:
(WebCore::AudioSummingJunction::markRenderingStateAsDirty):
(WebCore::AudioSummingJunction::addOutput):
(WebCore::AudioSummingJunction::removeOutput):
(WebCore::AudioSummingJunction::maximumNumberOfChannels const):
(WebCore::AudioSummingJunction::changedOutputs): Deleted.
* Modules/webaudio/AudioSummingJunction.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (268819 => 268820)
--- trunk/Source/WebCore/ChangeLog 2020-10-21 20:05:56 UTC (rev 268819)
+++ trunk/Source/WebCore/ChangeLog 2020-10-21 20:27:52 UTC (rev 268820)
@@ -1,3 +1,36 @@
+2020-10-21 Chris Dumez <cdu...@apple.com>
+
+ Add addOutput() / removeOutput() utility functions to AudioSummingJunction
+ https://bugs.webkit.org/show_bug.cgi?id=218045
+
+ Reviewed by Eric Carlson.
+
+ Add addOutput() / removeOutput() utility functions to AudioSummingJunction to add
+ or remove outputs from m_outputs and abstract away the call to changedOutputs().
+ It was awkward that subclasses were modifying m_outputs directly and had to
+ explicitly call changedOutputs() whenever they did.
+
+ No new tests, no web-facing behavior change.
+
+ * Modules/webaudio/AudioNode.cpp:
+ (WebCore::AudioNode::updateChannelsForInputs):
+ * Modules/webaudio/AudioNodeInput.cpp:
+ (WebCore::AudioNodeInput::connect):
+ (WebCore::AudioNodeInput::disconnect):
+ (WebCore::AudioNodeInput::disable):
+ (WebCore::AudioNodeInput::enable):
+ (WebCore::AudioNodeInput::numberOfChannels const):
+ * Modules/webaudio/AudioParam.cpp:
+ (WebCore::AudioParam::connect):
+ (WebCore::AudioParam::disconnect):
+ * Modules/webaudio/AudioSummingJunction.cpp:
+ (WebCore::AudioSummingJunction::markRenderingStateAsDirty):
+ (WebCore::AudioSummingJunction::addOutput):
+ (WebCore::AudioSummingJunction::removeOutput):
+ (WebCore::AudioSummingJunction::maximumNumberOfChannels const):
+ (WebCore::AudioSummingJunction::changedOutputs): Deleted.
+ * Modules/webaudio/AudioSummingJunction.h:
+
2020-10-21 Rob Buis <rb...@igalia.com>
Add lazy image loading to feature status page
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp (268819 => 268820)
--- trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp 2020-10-21 20:05:56 UTC (rev 268819)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp 2020-10-21 20:27:52 UTC (rev 268820)
@@ -423,7 +423,7 @@
void AudioNode::updateChannelsForInputs()
{
for (auto& input : m_inputs)
- input->changedOutputs();
+ input->markRenderingStateAsDirty();
}
void AudioNode::initializeDefaultNodeOptions(unsigned count, ChannelCountMode mode, WebCore::ChannelInterpretation interpretation)
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp (268819 => 268820)
--- trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp 2020-10-21 20:05:56 UTC (rev 268819)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp 2020-10-21 20:27:52 UTC (rev 268820)
@@ -53,13 +53,14 @@
if (!output || !node())
return;
- auto& outputsMap = output->isEnabled() ? m_outputs : m_disabledOutputs;
- // Check if we're already connected to this output.
- if (!outputsMap.add(output).isNewEntry)
- return;
+ auto addPotentiallyDisabledOutput = [this](AudioNodeOutput& output) {
+ if (output.isEnabled())
+ return addOutput(output);
+ return m_disabledOutputs.add(&output).isNewEntry;
+ };
- output->addInput(this);
- changedOutputs();
+ if (addPotentiallyDisabledOutput(*output))
+ output->addInput(this);
}
void AudioNodeInput::disconnect(AudioNodeOutput* output)
@@ -71,8 +72,7 @@
return;
// First try to disconnect from "active" connections.
- if (m_outputs.remove(output)) {
- changedOutputs();
+ if (removeOutput(*output)) {
output->removeInput(this); // Note: it's important to return immediately after this since the node may be deleted.
return;
}
@@ -94,11 +94,9 @@
if (!output || !node())
return;
- ASSERT(m_outputs.contains(output));
-
m_disabledOutputs.add(output);
- m_outputs.remove(output);
- changedOutputs();
+ bool wasRemoved = removeOutput(*output);
+ ASSERT_UNUSED(wasRemoved, wasRemoved);
// Propagate disabled state to outputs.
node()->disableOutputsIfNecessary();
@@ -115,9 +113,8 @@
ASSERT(m_disabledOutputs.contains(output));
// Move output from disabled list to active list.
- m_outputs.add(output);
+ addOutput(*output);
m_disabledOutputs.remove(output);
- changedOutputs();
// Propagate enabled state to outputs.
node()->enableOutputsIfNecessary();
@@ -147,14 +144,8 @@
return node()->channelCount();
// Find the number of channels of the connection with the largest number of channels.
- unsigned maxChannels = 1; // one channel is the minimum allowed
+ unsigned maxChannels = std::max(maximumNumberOfChannels(), 1u); // One channel is the minimum allowed.
- for (auto& output : m_outputs) {
- // Use output()->numberOfChannels() instead of output->bus()->numberOfChannels(),
- // because the calling of AudioNodeOutput::bus() is not safe here.
- maxChannels = std::max(maxChannels, output->numberOfChannels());
- }
-
if (mode == ChannelCountMode::ClampedMax)
maxChannels = std::min(maxChannels, static_cast<unsigned>(node()->channelCount()));
Modified: trunk/Source/WebCore/Modules/webaudio/AudioParam.cpp (268819 => 268820)
--- trunk/Source/WebCore/Modules/webaudio/AudioParam.cpp 2020-10-21 20:05:56 UTC (rev 268819)
+++ trunk/Source/WebCore/Modules/webaudio/AudioParam.cpp 2020-10-21 20:27:52 UTC (rev 268820)
@@ -320,13 +320,11 @@
if (!output)
return;
- if (!m_outputs.add(output).isNewEntry)
+ if (!addOutput(*output))
return;
INFO_LOG(LOGIDENTIFIER, output->node()->nodeType());
-
output->addParam(this);
- changedOutputs();
}
void AudioParam::disconnect(AudioNodeOutput* output)
@@ -339,10 +337,8 @@
INFO_LOG(LOGIDENTIFIER, output->node()->nodeType());
- if (m_outputs.remove(output)) {
- changedOutputs();
+ if (removeOutput((*output)))
output->removeParam(this);
- }
}
#if !RELEASE_LOG_DISABLED
Modified: trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp (268819 => 268820)
--- trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp 2020-10-21 20:05:56 UTC (rev 268819)
+++ trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp 2020-10-21 20:27:52 UTC (rev 268820)
@@ -45,7 +45,7 @@
context().removeMarkedSummingJunction(this);
}
-void AudioSummingJunction::changedOutputs()
+void AudioSummingJunction::markRenderingStateAsDirty()
{
ASSERT(context().isGraphOwner());
if (!m_renderingStateNeedUpdating && canUpdateState()) {
@@ -54,6 +54,24 @@
}
}
+bool AudioSummingJunction::addOutput(AudioNodeOutput& output)
+{
+ ASSERT(context().isGraphOwner());
+ if (!m_outputs.add(&output).isNewEntry)
+ return false;
+ markRenderingStateAsDirty();
+ return true;
+}
+
+bool AudioSummingJunction::removeOutput(AudioNodeOutput& output)
+{
+ ASSERT(context().isGraphOwner());
+ if (!m_outputs.remove(&output))
+ return false;
+ markRenderingStateAsDirty();
+ return true;
+}
+
void AudioSummingJunction::updateRenderingState()
{
ASSERT(context().isAudioThread() && context().isGraphOwner());
@@ -73,6 +91,17 @@
}
}
+unsigned AudioSummingJunction::maximumNumberOfChannels() const
+{
+ unsigned maxChannels = 0;
+ std::for_each(m_outputs.begin(), m_outputs.end(), [&](auto* output) {
+ // Use output()->numberOfChannels() instead of output->bus()->numberOfChannels(),
+ // because the calling of AudioNodeOutput::bus() is not safe here.
+ maxChannels = std::max(maxChannels, output->numberOfChannels());
+ });
+ return maxChannels;
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_AUDIO)
Modified: trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.h (268819 => 268820)
--- trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.h 2020-10-21 20:05:56 UTC (rev 268819)
+++ trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.h 2020-10-21 20:27:52 UTC (rev 268820)
@@ -44,9 +44,6 @@
BaseAudioContext& context() { return m_context; }
const BaseAudioContext& context() const { return m_context; }
- // This must be called whenever we modify m_outputs.
- void changedOutputs();
-
// This copies m_outputs to m_renderingOutputs. Please see comments for these lists below.
// This must be called when we own the context's graph lock in the audio thread at the very start or end of the render quantum.
void updateRenderingState();
@@ -60,17 +57,20 @@
virtual bool canUpdateState() = 0;
virtual void didUpdate() = 0;
+ bool addOutput(AudioNodeOutput&);
+ bool removeOutput(AudioNodeOutput&);
+
+ void markRenderingStateAsDirty();
+
protected:
Ref<BaseAudioContext> m_context;
- // m_outputs contains the AudioNodeOutputs representing current connections which are not disabled.
- // The rendering code should never use this directly, but instead uses m_renderingOutputs.
- HashSet<AudioNodeOutput*> m_outputs;
-
// numberOfConnections() should never be called from the audio rendering thread.
// Instead numberOfRenderingConnections() and renderingOutput() should be used.
unsigned numberOfConnections() const { return m_outputs.size(); }
+ unsigned maximumNumberOfChannels() const;
+
// m_renderingOutputs is a copy of m_outputs which will never be modified during the graph rendering on the audio thread.
// This is the list which is used by the rendering code.
// Whenever m_outputs is modified, the context is told so it can later update m_renderingOutputs from m_outputs at a safe time.
@@ -79,6 +79,11 @@
// m_renderingStateNeedUpdating keeps track if m_outputs is modified.
bool m_renderingStateNeedUpdating { false };
+
+private:
+ // m_outputs contains the AudioNodeOutputs representing current connections which are not disabled.
+ // The rendering code should never use this directly, but instead uses m_renderingOutputs.
+ HashSet<AudioNodeOutput*> m_outputs;
};
} // namespace WebCore