Title: [274527] trunk/Source/WebCore
Revision
274527
Author
cdu...@apple.com
Date
2021-03-16 15:52:14 -0700 (Tue, 16 Mar 2021)

Log Message

Avoid heap allocation under AudioDestinationCocoa::render()
https://bugs.webkit.org/show_bug.cgi?id=223272

Reviewed by Sam Weinig.

In the common case where no AudioWorklet is used, AudioDestinationCocoa::render()
would unnecessarily create a WTF::Function to dispatch to the render thread, even
though we are already on the render thread. Constructing a WTF::Function does a
heap allocation so we really want to avoid constructing one on the high priority
audio thread.

In the AudioWorklet case, we still construct a WTF::Function for now. I will follow
up if I find a way to avoid it in this case too.

* Modules/webaudio/DefaultAudioDestinationNode.cpp:
(WebCore::Function<void):
* platform/audio/cocoa/AudioDestinationCocoa.cpp:
(WebCore::AudioDestinationCocoa::render):
(WebCore::AudioDestinationCocoa::renderOnRenderingTheadIfPlaying):
* platform/audio/cocoa/AudioDestinationCocoa.h:
* platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
(webKitWebAudioSrcRenderIteration):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (274526 => 274527)


--- trunk/Source/WebCore/ChangeLog	2021-03-16 22:45:00 UTC (rev 274526)
+++ trunk/Source/WebCore/ChangeLog	2021-03-16 22:52:14 UTC (rev 274527)
@@ -1,3 +1,28 @@
+2021-03-16  Chris Dumez  <cdu...@apple.com>
+
+        Avoid heap allocation under AudioDestinationCocoa::render()
+        https://bugs.webkit.org/show_bug.cgi?id=223272
+
+        Reviewed by Sam Weinig.
+
+        In the common case where no AudioWorklet is used, AudioDestinationCocoa::render()
+        would unnecessarily create a WTF::Function to dispatch to the render thread, even
+        though we are already on the render thread. Constructing a WTF::Function does a
+        heap allocation so we really want to avoid constructing one on the high priority
+        audio thread.
+
+        In the AudioWorklet case, we still construct a WTF::Function for now. I will follow
+        up if I find a way to avoid it in this case too.
+
+        * Modules/webaudio/DefaultAudioDestinationNode.cpp:
+        (WebCore::Function<void):
+        * platform/audio/cocoa/AudioDestinationCocoa.cpp:
+        (WebCore::AudioDestinationCocoa::render):
+        (WebCore::AudioDestinationCocoa::renderOnRenderingTheadIfPlaying):
+        * platform/audio/cocoa/AudioDestinationCocoa.h:
+        * platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
+        (webKitWebAudioSrcRenderIteration):
+
 2021-03-16  Julian Gonzalez  <julian_a_gonza...@apple.com>
 
         ASSERTION FAILED: m_state == State::Committed in WebKit::FrameLoadState::didFailLoad()

Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp (274526 => 274527)


--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp	2021-03-16 22:45:00 UTC (rev 274526)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp	2021-03-16 22:52:14 UTC (rev 274527)
@@ -134,7 +134,7 @@
             }, WorkerRunLoop::defaultMode());
         };
     }
-    return [](Function<void()>&& function) { function(); };
+    return nullptr;
 }
 
 void DefaultAudioDestinationNode::startRendering(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler)

Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.cpp (274526 => 274527)


--- trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.cpp	2021-03-16 22:45:00 UTC (rev 274526)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.cpp	2021-03-16 22:52:14 UTC (rev 274527)
@@ -222,18 +222,27 @@
 
     // When there is a AudioWorklet, we do rendering on the AudioWorkletThread.
     auto locker = tryHoldLock(m_dispatchToRenderThreadLock);
-    if (!locker || !m_dispatchToRenderThread)
+    if (!locker)
         return -1;
 
-    m_dispatchToRenderThread([this, protectedThis = makeRef(*this), framesToRender]() mutable {
-        auto locker = tryHoldLock(m_isPlayingLock);
-        if (locker && m_isPlaying)
-            renderOnRenderingThead(framesToRender);
-    });
+    if (!m_dispatchToRenderThread)
+        renderOnRenderingTheadIfPlaying(framesToRender);
+    else {
+        m_dispatchToRenderThread([protectedThis = makeRef(*this), framesToRender]() mutable {
+            protectedThis->renderOnRenderingTheadIfPlaying(framesToRender);
+        });
+    }
 
     return noErr;
 }
 
+void AudioDestinationCocoa::renderOnRenderingTheadIfPlaying(size_t framesToRender)
+{
+    auto locker = tryHoldLock(m_isPlayingLock);
+    if (locker && m_isPlaying)
+        renderOnRenderingThead(framesToRender);
+}
+
 // This runs on the AudioWorkletThread when AudioWorklet is enabled, on the audio device's rendering thread otherwise.
 void AudioDestinationCocoa::renderOnRenderingThead(size_t framesToRender)
 {

Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.h (274526 => 274527)


--- trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.h	2021-03-16 22:45:00 UTC (rev 274526)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.h	2021-03-16 22:52:14 UTC (rev 274527)
@@ -71,6 +71,7 @@
     virtual void startRendering(CompletionHandler<void(bool)>&&);
     virtual void stopRendering(CompletionHandler<void(bool)>&&);
 
+    void renderOnRenderingTheadIfPlaying(size_t framesToRender);
     void renderOnRenderingThead(size_t framesToRender);
 
     AudioOutputUnitAdaptor m_audioOutputUnitAdaptor;

Modified: trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp (274526 => 274527)


--- trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp	2021-03-16 22:45:00 UTC (rev 274526)
+++ trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp	2021-03-16 22:52:14 UTC (rev 274527)
@@ -404,12 +404,16 @@
     }
 
     auto locker = tryHoldLock(priv->dispatchToRenderThreadLock);
-    if (!locker || !priv->dispatchToRenderThreadFunction)
+    if (!locker)
         return;
 
-    priv->dispatchToRenderThreadFunction([channels = WTFMove(*channelBufferList), protectedThis = GRefPtr<GstElement>(GST_ELEMENT_CAST(src))]() mutable {
-        webKitWebAudioSrcRenderAndPushFrames(WTFMove(protectedThis), WTFMove(channels));
-    });
+    if (!priv->dispatchToRenderThreadFunction)
+        webKitWebAudioSrcRenderAndPushFrames(GRefPtr<GstElement>(GST_ELEMENT_CAST(src)), WTFMove(*channelBufferList));
+    else {
+        priv->dispatchToRenderThreadFunction([channels = WTFMove(*channelBufferList), protectedThis = GRefPtr<GstElement>(GST_ELEMENT_CAST(src))]() mutable {
+            webKitWebAudioSrcRenderAndPushFrames(WTFMove(protectedThis), WTFMove(channels));
+        });
+    }
 
     {
         LockHolder lock(priv->dispatchLock);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to