Title: [268728] trunk/Source/WebCore
Revision
268728
Author
cdu...@apple.com
Date
2020-10-20 08:02:18 -0700 (Tue, 20 Oct 2020)

Log Message

Drop explicit calls to BaseAudioContext::refNode()
https://bugs.webkit.org/show_bug.cgi?id=217926

Reviewed by Eric Carlson.

Drop explicit calls to BaseAudioContext::refNode(). Instead we now rely on the
sourceNodeWillBeginPlayback() signal to ref the source AudioNode. This simplifies
the code a bit. I also did some renaming for clarity, so be explicit about the
fact we are dealing with *source* nodes here.

No new tests, no Web-facing behavior change.

* Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore::AudioBufferSourceNode::create):
(WebCore::AudioBufferSourceNode::startPlaying):
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::sourceNodeWillBeginPlayback):
* Modules/webaudio/AudioContext.h:
* Modules/webaudio/AudioScheduledSourceNode.cpp:
(WebCore::AudioScheduledSourceNode::startLater):
(WebCore::AudioScheduledSourceNode::finish):

* Modules/webaudio/AudioWorkletNode.cpp:
(WebCore::AudioWorkletNode::create):
(WebCore::AudioWorkletNode::didFinishProcessingOnRenderingThread):
Only call sourceNodeWillBeginPlayback() / sourceNodeDidFinishPlayback()
when the AudioWorklet is actually a *source* node, meaning that it has
outputs. This behavior is consistent with Blink.

* Modules/webaudio/BaseAudioContext.cpp:
(WebCore::BaseAudioContext::~BaseAudioContext):
(WebCore::BaseAudioContext::uninitialize):
(WebCore::BaseAudioContext::createScriptProcessor):
(WebCore::BaseAudioContext::derefFinishedSourceNodes):
(WebCore::BaseAudioContext::refSourceNode):
(WebCore::BaseAudioContext::derefSourceNode):
(WebCore::BaseAudioContext::derefUnfinishedSourceNodes):
(WebCore::BaseAudioContext::sourceNodeWillBeginPlayback):
(WebCore::BaseAudioContext::sourceNodeDidFinishPlayback):
* Modules/webaudio/BaseAudioContext.h:
* Modules/webaudio/ConstantSourceNode.cpp:
(WebCore::ConstantSourceNode::create):
* Modules/webaudio/MediaElementAudioSourceNode.cpp:
(WebCore::MediaElementAudioSourceNode::create):
* Modules/webaudio/MediaStreamAudioSourceNode.cpp:
(WebCore::MediaStreamAudioSourceNode::create):
* Modules/webaudio/OscillatorNode.cpp:
(WebCore::OscillatorNode::create):

* Modules/webaudio/ScriptProcessorNode.cpp:
(WebCore::ScriptProcessorNode::eventListenersDidChange):
(WebCore::ScriptProcessorNode::virtualHasPendingActivity const):
* Modules/webaudio/ScriptProcessorNode.h:
Use ActiveDOMObject logic to keep the script wrapper alive instead of relying on the
AudioContext to do so. We keep the wrapper alive as long as the context's state is
not closed and as long as there is an audioprocess event listener registered. This
behavior is consistent with what Blink does.

* Modules/webaudio/WebKitAudioContext.cpp:
(WebCore::WebKitAudioContext::createWebKitOscillator):
(WebCore::WebKitAudioContext::createWebKitBufferSource):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (268727 => 268728)


--- trunk/Source/WebCore/ChangeLog	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/ChangeLog	2020-10-20 15:02:18 UTC (rev 268728)
@@ -1,3 +1,67 @@
+2020-10-20  Chris Dumez  <cdu...@apple.com>
+
+        Drop explicit calls to BaseAudioContext::refNode()
+        https://bugs.webkit.org/show_bug.cgi?id=217926
+
+        Reviewed by Eric Carlson.
+
+        Drop explicit calls to BaseAudioContext::refNode(). Instead we now rely on the
+        sourceNodeWillBeginPlayback() signal to ref the source AudioNode. This simplifies
+        the code a bit. I also did some renaming for clarity, so be explicit about the
+        fact we are dealing with *source* nodes here.
+
+        No new tests, no Web-facing behavior change.
+
+        * Modules/webaudio/AudioBufferSourceNode.cpp:
+        (WebCore::AudioBufferSourceNode::create):
+        (WebCore::AudioBufferSourceNode::startPlaying):
+        * Modules/webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::sourceNodeWillBeginPlayback):
+        * Modules/webaudio/AudioContext.h:
+        * Modules/webaudio/AudioScheduledSourceNode.cpp:
+        (WebCore::AudioScheduledSourceNode::startLater):
+        (WebCore::AudioScheduledSourceNode::finish):
+
+        * Modules/webaudio/AudioWorkletNode.cpp:
+        (WebCore::AudioWorkletNode::create):
+        (WebCore::AudioWorkletNode::didFinishProcessingOnRenderingThread):
+        Only call sourceNodeWillBeginPlayback() / sourceNodeDidFinishPlayback()
+        when the AudioWorklet is actually a *source* node, meaning that it has
+        outputs. This behavior is consistent with Blink.
+
+        * Modules/webaudio/BaseAudioContext.cpp:
+        (WebCore::BaseAudioContext::~BaseAudioContext):
+        (WebCore::BaseAudioContext::uninitialize):
+        (WebCore::BaseAudioContext::createScriptProcessor):
+        (WebCore::BaseAudioContext::derefFinishedSourceNodes):
+        (WebCore::BaseAudioContext::refSourceNode):
+        (WebCore::BaseAudioContext::derefSourceNode):
+        (WebCore::BaseAudioContext::derefUnfinishedSourceNodes):
+        (WebCore::BaseAudioContext::sourceNodeWillBeginPlayback):
+        (WebCore::BaseAudioContext::sourceNodeDidFinishPlayback):
+        * Modules/webaudio/BaseAudioContext.h:
+        * Modules/webaudio/ConstantSourceNode.cpp:
+        (WebCore::ConstantSourceNode::create):
+        * Modules/webaudio/MediaElementAudioSourceNode.cpp:
+        (WebCore::MediaElementAudioSourceNode::create):
+        * Modules/webaudio/MediaStreamAudioSourceNode.cpp:
+        (WebCore::MediaStreamAudioSourceNode::create):
+        * Modules/webaudio/OscillatorNode.cpp:
+        (WebCore::OscillatorNode::create):
+
+        * Modules/webaudio/ScriptProcessorNode.cpp:
+        (WebCore::ScriptProcessorNode::eventListenersDidChange):
+        (WebCore::ScriptProcessorNode::virtualHasPendingActivity const):
+        * Modules/webaudio/ScriptProcessorNode.h:
+        Use ActiveDOMObject logic to keep the script wrapper alive instead of relying on the
+        AudioContext to do so. We keep the wrapper alive as long as the context's state is
+        not closed and as long as there is an audioprocess event listener registered. This
+        behavior is consistent with what Blink does.
+
+        * Modules/webaudio/WebKitAudioContext.cpp:
+        (WebCore::WebKitAudioContext::createWebKitOscillator):
+        (WebCore::WebKitAudioContext::createWebKitBufferSource):
+
 2020-10-20  Philippe Normand  <pnorm...@igalia.com>
 
         [GStreamer] REGRESSION(r266559): imported/w3c/web-platform-tests/webaudio/the-audio-api/the-destinationnode-interface/destination.html is failing

Modified: trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -76,10 +76,6 @@
     node->setLoopStart(options.loopStart);
     node->playbackRate().setValue(options.playbackRate);
 
-    // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
-    // When this happens, AudioScheduledSourceNode::finish() calls BaseAudioContext::notifyNodeFinishedProcessing().
-    context.refNode(node);
-
     return node;
 }
 
@@ -473,8 +469,6 @@
     ASSERT(isMainThread());
     ALWAYS_LOG(LOGIDENTIFIER, "when = ", when, ", offset = ", grainOffset, ", duration = ", grainDuration.valueOr(0));
 
-    context().nodeWillBeginPlayback();
-
     if (m_playbackState != UNSCHEDULED_STATE)
         return Exception { InvalidStateError, "Cannot call start more than once."_s };
 
@@ -487,6 +481,8 @@
     if (grainDuration && (!std::isfinite(*grainDuration) || (*grainDuration < 0)))
         return Exception { RangeError, "duration value should be positive"_s };
 
+    context().sourceNodeWillBeginPlayback(*this);
+
     // This synchronizes with process().
     auto locker = holdLock(m_processLock);
 

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -252,8 +252,10 @@
     });
 }
 
-void AudioContext::nodeWillBeginPlayback()
+void AudioContext::sourceNodeWillBeginPlayback(AudioNode& audioNode)
 {
+    BaseAudioContext::sourceNodeWillBeginPlayback(audioNode);
+
     // Called by scheduled AudioNodes when clients schedule their start times.
     // Prior to the introduction of suspend(), resume(), and stop(), starting
     // a scheduled AudioNode would remove the user-gesture restriction, if present,

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.h (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2020-10-20 15:02:18 UTC (rev 268728)
@@ -71,7 +71,7 @@
     void suspendRendering(DOMPromiseDeferred<void>&&);
     void resumeRendering(DOMPromiseDeferred<void>&&);
 
-    void nodeWillBeginPlayback() final;
+    void sourceNodeWillBeginPlayback(AudioNode&) final;
     void lazyInitialize() final;
 
     void startRendering();

Modified: trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -152,8 +152,6 @@
     ASSERT(isMainThread());
     ALWAYS_LOG(LOGIDENTIFIER, when);
 
-    context().nodeWillBeginPlayback();
-
     if (m_playbackState != UNSCHEDULED_STATE)
         return Exception { InvalidStateError };
 
@@ -160,6 +158,8 @@
     if (!std::isfinite(when) || when < 0)
         return Exception { RangeError, "when value should be positive"_s };
 
+    context().sourceNodeWillBeginPlayback(*this);
+
     m_startTime = when;
     m_playbackState = SCHEDULED_STATE;
 
@@ -193,7 +193,7 @@
 {
     ASSERT(!hasFinished());
     // Let the context dereference this AudioNode.
-    context().notifyNodeFinishedProcessing(this);
+    context().sourceNodeDidFinishPlayback(*this);
     m_playbackState = FINISHED_STATE;
     context().decrementActiveSourceCount();
 

Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -105,7 +105,9 @@
     node->initializeAudioParameters(parameterDescriptors, parameterData);
 
     // Will cause the context to ref the node until playback has finished.
-    context.refNode(node);
+    // Note that a node with zero outputs cannot be a source node.
+    if (node->numberOfOutputs() > 0)
+        context.sourceNodeWillBeginPlayback(node);
 
     context.audioWorklet().createProcessor(name, processorMessagePort->disentangle(), serializedOptions.releaseNonNull(), node);
 
@@ -228,7 +230,9 @@
 
     m_processor = nullptr;
     m_tailTime = 0;
-    context().notifyNodeFinishedProcessing(this);
+
+    if (numberOfOutputs() > 0)
+        context().sourceNodeDidFinishPlayback(*this);
 }
 
 void AudioWorkletNode::updatePullStatus()

Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -170,8 +170,8 @@
     ASSERT(!m_isInitialized);
     ASSERT(m_isStopScheduled);
     ASSERT(m_nodesToDelete.isEmpty());
-    ASSERT(m_referencedNodes.isEmpty());
-    ASSERT(m_finishedNodes.isEmpty()); // FIXME (bug 105870): This assertion fails on tests sometimes.
+    ASSERT(m_referencedSourceNodes.isEmpty());
+    ASSERT(m_finishedSourceNodes.isEmpty());
     ASSERT(m_automaticPullNodes.isEmpty());
     if (m_automaticPullNodesNeedUpdating)
         m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size());
@@ -244,7 +244,7 @@
         AutoLocker locker(*this);
         // This should have been called from handlePostRenderTasks() at the end of rendering.
         // However, in case of lock contention, the tryLock() call could have failed in handlePostRenderTasks(),
-        // leaving nodes in m_finishedNodes. Now that the audio thread is gone, make sure we deref those nodes
+        // leaving nodes in m_finishedSourceNodes. Now that the audio thread is gone, make sure we deref those nodes
         // before the BaseAudioContext gets destroyed.
         derefFinishedSourceNodes();
     }
@@ -436,10 +436,7 @@
     if (numberOfOutputChannels > maxNumberOfChannels())
         return Exception { NotSupportedError };
 
-    auto node = ScriptProcessorNode::create(*this, bufferSize, numberOfInputChannels, numberOfOutputChannels);
-
-    refNode(node); // context keeps reference until we stop making _javascript_ rendering callbacks
-    return node;
+    return ScriptProcessorNode::create(*this, bufferSize, numberOfInputChannels, numberOfOutputChannels);
 }
 
 ExceptionOr<Ref<BiquadFilterNode>> BaseAudioContext::createBiquadFilter()
@@ -578,42 +575,38 @@
     return IIRFilterNode::create(scriptExecutionContext, *this, WTFMove(options));
 }
 
-void BaseAudioContext::notifyNodeFinishedProcessing(AudioNode* node)
-{
-    ASSERT(isAudioThread());
-    m_finishedNodes.append(node);
-}
-
 void BaseAudioContext::derefFinishedSourceNodes()
 {
     ASSERT(isGraphOwner());
     ASSERT(isAudioThread() || isAudioThreadFinished());
-    for (auto& node : m_finishedNodes)
-        derefNode(*node);
+    for (auto& node : m_finishedSourceNodes)
+        derefSourceNode(*node);
 
-    m_finishedNodes.clear();
+    m_finishedSourceNodes.clear();
 }
 
-void BaseAudioContext::refNode(AudioNode& node)
+void BaseAudioContext::refSourceNode(AudioNode& node)
 {
     ASSERT(isMainThread());
     AutoLocker locker(*this);
-    
-    m_referencedNodes.append(&node);
+
+    ASSERT(!m_referencedSourceNodes.contains(&node));
+    // Reference source node to keep it alive and playing even if its JS wrapper gets garbage collected.
+    m_referencedSourceNodes.append(&node);
 }
 
-void BaseAudioContext::derefNode(AudioNode& node)
+void BaseAudioContext::derefSourceNode(AudioNode& node)
 {
     ASSERT(isGraphOwner());
     
-    ASSERT(m_referencedNodes.contains(&node));
-    m_referencedNodes.removeFirst(&node);
+    ASSERT(m_referencedSourceNodes.contains(&node));
+    m_referencedSourceNodes.removeFirst(&node);
 }
 
 void BaseAudioContext::derefUnfinishedSourceNodes()
 {
     ASSERT(isMainThread() && isAudioThreadFinished());
-    m_referencedNodes.clear();
+    m_referencedSourceNodes.clear();
 }
 
 void BaseAudioContext::lock(bool& mustReleaseLock)
@@ -1050,6 +1043,18 @@
     m_parameterDescriptorMap.add(processorName, WTFMove(descriptors));
 }
 
+void BaseAudioContext::sourceNodeWillBeginPlayback(AudioNode& node)
+{
+    refSourceNode(node);
+}
+
+void BaseAudioContext::sourceNodeDidFinishPlayback(AudioNode& node)
+{
+    ASSERT(isAudioThread());
+
+    m_finishedSourceNodes.append(&node);
+}
+
 #if !RELEASE_LOG_DISABLED
 WTFLogChannel& BaseAudioContext::logChannel() const
 {

Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h	2020-10-20 15:02:18 UTC (rev 268728)
@@ -163,9 +163,6 @@
     ExceptionOr<Ref<StereoPannerNode>> createStereoPanner();
     ExceptionOr<Ref<IIRFilterNode>> createIIRFilter(ScriptExecutionContext&, Vector<double>&& feedforward, Vector<double>&& feedback);
 
-    // When a source node has no more processing to do (has finished playing), then it tells the context to dereference it.
-    void notifyNodeFinishedProcessing(AudioNode*);
-
     // Called at the start of each render quantum.
     void handlePreRenderTasks(const AudioIOPosition& outputPosition);
 
@@ -249,7 +246,9 @@
 
     void isPlayingAudioDidChange();
 
-    virtual void nodeWillBeginPlayback() { }
+    virtual void sourceNodeWillBeginPlayback(AudioNode&);
+    // When a source node has no more processing to do (has finished playing), then it tells the context to dereference it.
+    void sourceNodeDidFinishPlayback(AudioNode&);
 
 #if !RELEASE_LOG_DISABLED
     const Logger& logger() const override { return m_logger.get(); }
@@ -283,13 +282,6 @@
         bool m_mustReleaseLock;
     };
 
-    // The context itself keeps a reference to all source nodes. The source nodes, then reference all nodes they're connected to.
-    // In turn, these nodes reference all nodes they're connected to. All nodes are ultimately connected to the AudioDestinationNode.
-    // When the context dereferences a source node, it will be deactivated from the rendering graph along with all other nodes it is
-    // uniquely connected to. See the AudioNode::ref() and AudioNode::deref() methods for more details.
-    void refNode(AudioNode&);
-    void derefNode(AudioNode&);
-
     virtual void lazyInitialize();
 
     static bool isSupportedSampleRate(float sampleRate);
@@ -326,6 +318,13 @@
 
     void scheduleNodeDeletion();
 
+    // When source nodes begin playing, the BaseAudioContext keeps them alive inside m_referencedSourceNodes.
+    // When the nodes stop playing, they get added to m_finishedSourceNodes. After each rendering quantum,
+    // we call derefSourceNode() on every node in m_finishedSourceNodes since we no longer need to keep them
+    // alive.
+    void refSourceNode(AudioNode&);
+    void derefSourceNode(AudioNode&);
+
     // EventTarget
     void dispatchEvent(Event&) final;
 
@@ -352,10 +351,10 @@
     Ref<AudioWorklet> m_worklet;
 
     // Only accessed in the audio thread.
-    Vector<AudioNode*> m_finishedNodes;
+    Vector<AudioNode*> m_finishedSourceNodes;
 
     // Either accessed when the graph lock is held, or on the main thread when the audio thread has finished.
-    Vector<AudioConnectionRefPtr<AudioNode>> m_referencedNodes;
+    Vector<AudioConnectionRefPtr<AudioNode>> m_referencedSourceNodes;
 
     // Accumulate nodes which need to be deleted here.
     // This is copied to m_nodesToDelete at the end of a render cycle in handlePostRenderTasks(), where we're assured of a stable graph

Modified: trunk/Source/WebCore/Modules/webaudio/ConstantSourceNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/ConstantSourceNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/ConstantSourceNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -41,11 +41,7 @@
 
 ExceptionOr<Ref<ConstantSourceNode>> ConstantSourceNode::create(BaseAudioContext& context, const ConstantSourceOptions& options)
 {
-    auto node = adoptRef(*new ConstantSourceNode(context, options.offset));
-    
-    context.refNode(node);
-    
-    return node;
+    return adoptRef(*new ConstantSourceNode(context, options.offset));
 }
 
 ConstantSourceNode::ConstantSourceNode(BaseAudioContext& context, float offset)

Modified: trunk/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -55,8 +55,10 @@
     auto node = adoptRef(*new MediaElementAudioSourceNode(context, *options.mediaElement));
 
     options.mediaElement->setAudioSourceNode(node.ptr());
-    context.refNode(node.get()); // context keeps reference until node is disconnected
 
+    // context keeps reference until node is disconnected.
+    context.sourceNodeWillBeginPlayback(node);
+
     return node;
 }
 

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -60,7 +60,8 @@
     auto node = adoptRef(*new MediaStreamAudioSourceNode(context, *options.mediaStream, *providerTrack));
     node->setFormat(2, context.sampleRate());
 
-    context.refNode(node); // context keeps reference until node is disconnected
+    // Context keeps reference until node is disconnected.
+    context.sourceNodeWillBeginPlayback(node);
 
     return node;
 }

Modified: trunk/Source/WebCore/Modules/webaudio/OscillatorNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/OscillatorNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/OscillatorNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -77,10 +77,6 @@
             return result.releaseException();
     }
 
-    // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
-    // When this happens, AudioScheduledSourceNode::finish() calls BaseAudioContext::notifyNodeFinishedProcessing().
-    context.refNode(oscillator);
-
     return oscillator;
 }
 

Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -270,6 +270,19 @@
     return true;
 }
 
+void ScriptProcessorNode::eventListenersDidChange()
+{
+    m_hasAudioProcessEventListener = hasEventListeners(eventNames().audioprocessEvent);
+}
+
+bool ScriptProcessorNode::virtualHasPendingActivity() const
+{
+    if (context().isClosed())
+        return false;
+
+    return m_hasAudioProcessEventListener;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_AUDIO)

Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.h (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.h	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.h	2020-10-20 15:02:18 UTC (rev 268728)
@@ -76,6 +76,8 @@
 
     ScriptProcessorNode(BaseAudioContext&, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels);
 
+    bool virtualHasPendingActivity() const final;
+    void eventListenersDidChange() final;
     void fireProcessEvent(unsigned doubleBufferIndex);
 
     // Double buffering
@@ -94,6 +96,7 @@
     RefPtr<AudioBus> m_internalInputBus;
     RefPtr<PendingActivity<ScriptProcessorNode>> m_pendingActivity;
     Lock m_processLock;
+    bool m_hasAudioProcessEventListener { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webaudio/WebKitAudioContext.cpp (268727 => 268728)


--- trunk/Source/WebCore/Modules/webaudio/WebKitAudioContext.cpp	2020-10-20 13:19:42 UTC (rev 268727)
+++ trunk/Source/WebCore/Modules/webaudio/WebKitAudioContext.cpp	2020-10-20 15:02:18 UTC (rev 268728)
@@ -145,15 +145,7 @@
 
     lazyInitialize();
 
-    auto node = WebKitOscillatorNode::create(*this);
-    if (node.hasException())
-        return node.releaseException();
-
-    // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
-    // When this happens, AudioScheduledSourceNode::finish() calls BaseAudioContext::notifyNodeFinishedProcessing().
-    auto nodeValue = node.releaseReturnValue();
-    refNode(nodeValue);
-    return nodeValue;
+    return WebKitOscillatorNode::create(*this);
 }
 
 ExceptionOr<Ref<PeriodicWave>> WebKitAudioContext::createPeriodicWave(Float32Array& real, Float32Array& imaginary)
@@ -180,13 +172,7 @@
 
     lazyInitialize();
 
-    auto node = WebKitAudioBufferSourceNode::create(*this);
-
-    // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
-    // When this happens, AudioScheduledSourceNode::finish() calls BaseAudioContext::notifyNodeFinishedProcessing().
-    refNode(node);
-
-    return node;
+    return WebKitAudioBufferSourceNode::create(*this);
 }
 
 ExceptionOr<Ref<WebKitDynamicsCompressorNode>> WebKitAudioContext::createWebKitDynamicsCompressor()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to