Diff
Modified: trunk/LayoutTests/ChangeLog (269072 => 269073)
--- trunk/LayoutTests/ChangeLog 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/LayoutTests/ChangeLog 2020-10-27 21:46:21 UTC (rev 269073)
@@ -1,3 +1,15 @@
+2020-10-27 Chris Dumez <[email protected]>
+
+ [GPUProcess] Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination
+ https://bugs.webkit.org/show_bug.cgi?id=218251
+
+ Reviewed by Geoffrey Garen.
+
+ * webaudio/audiocontext-state.html:
+ Update existing test which incorrectly expected the AudioContext's state to become "running" synchronously
+ after connecting a source node. The state switches to "running" asynchronously now. It is up to the user
+ agent if and when the audio context starts autoplaying so this should be an acceptable behavior change.
+
2020-10-27 Fujii Hironori <[email protected]>
[TextureMapper][GTK] Test compositing/clipping/border-radius-stacking-context-clip.html is failing
Modified: trunk/LayoutTests/webaudio/audiocontext-state.html (269072 => 269073)
--- trunk/LayoutTests/webaudio/audiocontext-state.html 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/LayoutTests/webaudio/audiocontext-state.html 2020-10-27 21:46:21 UTC (rev 269073)
@@ -16,20 +16,25 @@
var context = null;
var node = null;
+function onAudioContextAutoStart()
+{
+ context._onstatechange_ = null;
+ shouldBeEqualToString('context.state', 'running');
+
+ debug('Calling context.suspend()');
+ context.suspend().then(suspendSucceeded, suspendFailed);
+}
+
function runTest() {
window.jsTestIsAsync = true;
context = new AudioContext();
+ context._onstatechange_ = onAudioContextAutoStart;
- shouldBe('context.state', '"suspended"');
+ shouldBeEqualToString('context.state', 'suspended');
node = context.createBufferSource();
evalAndLog('node.connect(context.destination)');
-
- shouldBe('context.state', '"running"');
-
- debug('Calling context.suspend()');
- context.suspend().then(suspendSucceeded, suspendFailed);
}
function suspendFailed() {
Modified: trunk/Source/WebCore/ChangeLog (269072 => 269073)
--- trunk/Source/WebCore/ChangeLog 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/ChangeLog 2020-10-27 21:46:21 UTC (rev 269073)
@@ -1,3 +1,62 @@
+2020-10-27 Chris Dumez <[email protected]>
+
+ [GPUProcess] Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination
+ https://bugs.webkit.org/show_bug.cgi?id=218251
+
+ Reviewed by Geoffrey Garen.
+
+ DefaultAudioDestinationNode::resume() / suspend() were already asynchronous operations. However, they expected
+ AudioDestination::start() / stop() to finish synchronously and would simply call their completion handler
+ asynchronously. Instead, we now make AudioDestination::start() / stop() asynchronous as well. This allows us
+ to use asynchronous IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination.
+
+ As a result of this change, I had to make AudioDestinationNode::startRendering() asynchronous as well since
+ it uses AudioDestination::start() internally.
+
+ As an improvement, the completion handler to AudioDestinationNode's startRendering() / resume() / suspend()
+ is now provided with an exception in cases where they fail. This allows the call sites to properly deal
+ with such errors instead of assuming things were successsful.
+
+ No new tests, no Web-facing beahvior change.
+
+ * Modules/webaudio/AudioContext.cpp:
+ (WebCore::AudioContext::suspendRendering):
+ (WebCore::AudioContext::resumeRendering):
+ (WebCore::AudioContext::startRendering):
+ (WebCore::AudioContext::mayResumePlayback):
+ (WebCore::AudioContext::suspendPlayback):
+ * Modules/webaudio/AudioDestinationNode.h:
+ (WebCore::AudioDestinationNode::resume):
+ (WebCore::AudioDestinationNode::suspend):
+ (WebCore::AudioDestinationNode::close):
+ * Modules/webaudio/DefaultAudioDestinationNode.cpp:
+ (WebCore::DefaultAudioDestinationNode::startRendering):
+ (WebCore::DefaultAudioDestinationNode::resume):
+ (WebCore::DefaultAudioDestinationNode::suspend):
+ (WebCore::DefaultAudioDestinationNode::close):
+ * Modules/webaudio/DefaultAudioDestinationNode.h:
+ * Modules/webaudio/OfflineAudioContext.cpp:
+ (WebCore::OfflineAudioContext::startOfflineRendering):
+ (WebCore::OfflineAudioContext::resumeOfflineRendering):
+ * Modules/webaudio/OfflineAudioDestinationNode.cpp:
+ (WebCore::OfflineAudioDestinationNode::startRendering):
+ * Modules/webaudio/OfflineAudioDestinationNode.h:
+ * platform/audio/AudioDestination.h:
+ (WebCore::AudioDestination::start):
+ (WebCore::AudioDestination::stop):
+ * platform/audio/cocoa/AudioDestinationCocoa.cpp:
+ (WebCore::AudioDestinationCocoa::start):
+ (WebCore::AudioDestinationCocoa::stop):
+ * platform/audio/cocoa/AudioDestinationCocoa.h:
+ * platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
+ (WebCore::AudioDestinationGStreamer::start):
+ (WebCore::AudioDestinationGStreamer::stop):
+ * platform/audio/gstreamer/AudioDestinationGStreamer.h:
+ * platform/mock/MockAudioDestinationCocoa.cpp:
+ (WebCore::MockAudioDestinationCocoa::start):
+ (WebCore::MockAudioDestinationCocoa::stop):
+ * platform/mock/MockAudioDestinationCocoa.h:
+
2020-10-27 Fujii Hironori <[email protected]>
[TextureMapper][GTK] Test compositing/clipping/border-radius-stacking-context-clip.html is failing
Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -223,7 +223,11 @@
lazyInitialize();
- destinationNode()->suspend([this, protectedThis = makeRef(*this), promise = WTFMove(promise)]() mutable {
+ destinationNode()->suspend([this, protectedThis = makeRef(*this), promise = WTFMove(promise)](Optional<Exception>&& exception) mutable {
+ if (exception) {
+ promise.reject(WTFMove(*exception));
+ return;
+ }
setState(State::Suspended);
promise.resolve();
});
@@ -250,7 +254,12 @@
lazyInitialize();
- destinationNode()->resume([this, protectedThis = makeRef(*this), promise = WTFMove(promise)]() mutable {
+ destinationNode()->resume([this, protectedThis = makeRef(*this), promise = WTFMove(promise)](Optional<Exception>&& exception) mutable {
+ if (exception) {
+ promise.reject(WTFMove(*exception));
+ return;
+ }
+
// Since we update the state asynchronously, we may have been interrupted after the
// call to resume() and before this lambda runs. In this case, we don't want to
// reset the state to running.
@@ -286,10 +295,11 @@
makePendingActivity();
- setState(State::Running);
-
lazyInitialize();
- destination()->startRendering();
+ destination()->startRendering([this, protectedThis = makeRef(*this)](Optional<Exception>&& exception) {
+ if (!exception)
+ setState(State::Running);
+ });
}
void AudioContext::lazyInitialize()
@@ -357,8 +367,8 @@
lazyInitialize();
- destinationNode()->resume([this, protectedThis = makeRef(*this)] {
- setState(State::Running);
+ destinationNode()->resume([this, protectedThis = makeRef(*this)](Optional<Exception>&& exception) {
+ setState(exception ? State::Suspended : State::Running);
});
}
@@ -436,7 +446,10 @@
lazyInitialize();
- destinationNode()->suspend([this, protectedThis = makeRef(*this)] {
+ destinationNode()->suspend([this, protectedThis = makeRef(*this)](Optional<Exception>&& exception) {
+ if (exception)
+ return;
+
bool interrupted = m_mediaSession->state() == PlatformMediaSession::Interrupted;
setState(interrupted ? State::Interrupted : State::Suspended);
});
Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -28,7 +28,7 @@
#include "AudioIOCallback.h"
#include "AudioNode.h"
#include "ExceptionOr.h"
-#include <wtf/Function.h>
+#include <wtf/CompletionHandler.h>
namespace WebCore {
@@ -53,10 +53,10 @@
// Enable local/live input for the specified device.
virtual void enableInput(const String& inputDeviceId) = 0;
- virtual ExceptionOr<void> startRendering() = 0;
- virtual void resume(WTF::Function<void ()>&&) { }
- virtual void suspend(WTF::Function<void ()>&&) { }
- virtual void close(WTF::Function<void ()>&&) { }
+ virtual void startRendering(CompletionHandler<void(Optional<Exception>&&)>&&) = 0;
+ virtual void resume(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler) { completionHandler(WTF::nullopt); }
+ virtual void suspend(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler) { completionHandler(WTF::nullopt); }
+ virtual void close(CompletionHandler<void()>&& completionHandler) { completionHandler(); }
virtual bool isPlaying() { return false; }
void isPlayingDidChange() override;
Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -119,37 +119,53 @@
return { };
}
-ExceptionOr<void> DefaultAudioDestinationNode::startRendering()
+void DefaultAudioDestinationNode::startRendering(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler)
{
ASSERT(isInitialized());
if (!isInitialized())
- return Exception { InvalidStateError, "AudioDestinationNode is not initialized"_s };
+ return completionHandler(Exception { InvalidStateError, "AudioDestinationNode is not initialized"_s });
- m_destination->start(dispatchToRenderThreadFunction());
- return { };
+ auto innerCompletionHandler = [completionHandler = WTFMove(completionHandler)](bool success) mutable {
+ completionHandler(success ? WTF::nullopt : makeOptional(Exception { InvalidStateError, "Failed to start the audio device"_s }));
+ };
+
+ m_destination->start(dispatchToRenderThreadFunction(), WTFMove(innerCompletionHandler));
}
-void DefaultAudioDestinationNode::resume(Function<void ()>&& function)
+void DefaultAudioDestinationNode::resume(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler)
{
ASSERT(isInitialized());
- if (isInitialized())
- m_destination->start(dispatchToRenderThreadFunction());
- context().postTask(WTFMove(function));
+ if (!isInitialized()) {
+ context().postTask([completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(Exception { InvalidStateError, "AudioDestinationNode is not initialized"_s });
+ });
+ return;
+ }
+ m_destination->start(dispatchToRenderThreadFunction(), [completionHandler = WTFMove(completionHandler)](bool success) mutable {
+ completionHandler(success ? WTF::nullopt : makeOptional(Exception { InvalidStateError, "Failed to start the audio device"_s }));
+ });
}
-void DefaultAudioDestinationNode::suspend(Function<void ()>&& function)
+void DefaultAudioDestinationNode::suspend(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler)
{
ASSERT(isInitialized());
- if (isInitialized())
- m_destination->stop();
- context().postTask(WTFMove(function));
+ if (!isInitialized()) {
+ context().postTask([completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(Exception { InvalidStateError, "AudioDestinationNode is not initialized"_s });
+ });
+ return;
+ }
+
+ m_destination->stop([completionHandler = WTFMove(completionHandler)](bool success) mutable {
+ completionHandler(success ? WTF::nullopt : makeOptional(Exception { InvalidStateError, "Failed to stop the audio device"_s }));
+ });
}
-void DefaultAudioDestinationNode::close(Function<void()>&& function)
+void DefaultAudioDestinationNode::close(CompletionHandler<void()>&& completionHandler)
{
ASSERT(isInitialized());
uninitialize();
- context().postTask(WTFMove(function));
+ context().postTask(WTFMove(completionHandler));
}
unsigned DefaultAudioDestinationNode::maxChannelCount() const
Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -43,7 +43,7 @@
unsigned framesPerBuffer() const;
float sampleRate() const final { return m_sampleRate; }
- ExceptionOr<void> startRendering() final;
+ void startRendering(CompletionHandler<void(Optional<Exception>&&)>&&) final;
private:
explicit DefaultAudioDestinationNode(BaseAudioContext&, Optional<float>);
@@ -58,9 +58,9 @@
bool requiresTailProcessing() const final { return false; }
void enableInput(const String& inputDeviceId) final;
- void resume(Function<void ()>&&) final;
- void suspend(Function<void ()>&&) final;
- void close(Function<void ()>&&) final;
+ void resume(CompletionHandler<void(Optional<Exception>&&)>&&) final;
+ void suspend(CompletionHandler<void(Optional<Exception>&&)>&&) final;
+ void close(CompletionHandler<void()>&&) final;
unsigned maxChannelCount() const final;
bool isPlaying() final;
Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -105,16 +105,17 @@
lazyInitialize();
- auto result = destination()->startRendering();
- if (result.hasException()) {
- promise->reject(result.releaseException());
- return;
- }
+ destination()->startRendering([this, promise = WTFMove(promise), pendingActivity = ActiveDOMObject::makePendingActivity(*this)](Optional<Exception>&& exception) mutable {
+ if (exception) {
+ promise->reject(WTFMove(*exception));
+ return;
+ }
- makePendingActivity();
- m_pendingOfflineRenderingPromise = WTFMove(promise);
- m_didStartOfflineRendering = true;
- setState(State::Running);
+ makePendingActivity();
+ m_pendingOfflineRenderingPromise = WTFMove(promise);
+ m_didStartOfflineRendering = true;
+ setState(State::Running);
+ });
}
void OfflineAudioContext::suspendOfflineRendering(double suspendTime, Ref<DeferredPromise>&& promise)
@@ -166,15 +167,16 @@
}
ASSERT(state() == AudioContextState::Suspended);
- auto result = destination()->startRendering();
- if (result.hasException()) {
- promise->reject(result.releaseException());
- return;
- }
+ destination()->startRendering([this, promise = WTFMove(promise), pendingActivity = ActiveDOMObject::makePendingActivity(*this)](Optional<Exception>&& exception) mutable {
+ if (exception) {
+ promise->reject(WTFMove(*exception));
+ return;
+ }
- makePendingActivity();
- setState(State::Running);
- promise->resolve();
+ makePendingActivity();
+ setState(State::Running);
+ promise->resolve();
+ });
}
bool OfflineAudioContext::shouldSuspend()
Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -84,7 +84,7 @@
AudioNode::uninitialize();
}
-ExceptionOr<void> OfflineAudioDestinationNode::startRendering()
+void OfflineAudioDestinationNode::startRendering(CompletionHandler<void(Optional<Exception>&&)>&& completionHandler)
{
ALWAYS_LOG(LOGIDENTIFIER);
@@ -91,10 +91,10 @@
ASSERT(isMainThread());
ASSERT(m_renderTarget.get());
if (!m_renderTarget.get())
- return Exception { InvalidStateError, "OfflineAudioContextNode has no rendering buffer"_s };
+ return completionHandler(Exception { InvalidStateError, "OfflineAudioContextNode has no rendering buffer"_s });
if (m_startedRendering)
- return Exception { InvalidStateError, "Already started rendering"_s };
+ return completionHandler(Exception { InvalidStateError, "Already started rendering"_s });
m_startedRendering = true;
auto protectedThis = makeRef(*this);
@@ -121,12 +121,12 @@
workletProxy->postTaskForModeToWorkletGlobalScope([offThreadRendering = WTFMove(offThreadRendering)](ScriptExecutionContext&) mutable {
offThreadRendering();
}, WorkerRunLoop::defaultMode());
- return { };
+ return completionHandler(WTF::nullopt);
}
// FIXME: We should probably limit the number of threads we create for offline audio.
m_renderThread = Thread::create("offline renderer", WTFMove(offThreadRendering), ThreadType::Audio);
- return { };
+ completionHandler(WTF::nullopt);
}
auto OfflineAudioDestinationNode::offlineRender() -> OfflineRenderResult
Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h (269072 => 269073)
--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -50,7 +50,7 @@
// AudioDestinationNode
void enableInput(const String&) override { }
- ExceptionOr<void> startRendering() final;
+ void startRendering(CompletionHandler<void(Optional<Exception>&&)>&&) final;
float sampleRate() const final { return m_renderTarget->sampleRate(); }
Modified: trunk/Source/WebCore/platform/audio/AudioDestination.h (269072 => 269073)
--- trunk/Source/WebCore/platform/audio/AudioDestination.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/audio/AudioDestination.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -30,6 +30,7 @@
#define AudioDestination_h
#include <memory>
+#include <wtf/CompletionHandler.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/text/WTFString.h>
@@ -50,8 +51,8 @@
virtual ~AudioDestination() = default;
- virtual void start(Function<void(Function<void()>&&)>&& dispatchToRenderThread) = 0;
- virtual void stop() = 0;
+ virtual void start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&& = [](bool) { }) = 0;
+ virtual void stop(CompletionHandler<void(bool)>&& = [](bool) { }) = 0;
virtual bool isPlaying() = 0;
// Sample-rate conversion may happen in AudioDestination to the hardware sample-rate
Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.cpp (269072 => 269073)
--- trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -99,24 +99,30 @@
return m_renderBus->length();
}
-void AudioDestinationCocoa::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread)
+void AudioDestinationCocoa::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&& completionHandler)
{
LOG(Media, "AudioDestinationCocoa::start");
m_dispatchToRenderThread = WTFMove(dispatchToRenderThread);
- OSStatus result = m_audioOutputUnitAdaptor.start();
+ auto success = m_audioOutputUnitAdaptor.start() == noErr;
+ if (success)
+ setIsPlaying(true);
- if (!result)
- setIsPlaying(true);
+ callOnMainThread([completionHandler = WTFMove(completionHandler), success]() mutable {
+ completionHandler(success);
+ });
}
-void AudioDestinationCocoa::stop()
+void AudioDestinationCocoa::stop(CompletionHandler<void(bool)>&& completionHandler)
{
LOG(Media, "AudioDestinationCocoa::stop");
- OSStatus result = m_audioOutputUnitAdaptor.stop();
+ auto success = m_audioOutputUnitAdaptor.stop() == noErr;
m_dispatchToRenderThread = nullptr;
+ if (success)
+ setIsPlaying(false);
- if (!result)
- setIsPlaying(false);
+ callOnMainThread([completionHandler = WTFMove(completionHandler), success]() mutable {
+ completionHandler(success);
+ });
}
void AudioDestinationCocoa::setIsPlaying(bool isPlaying)
Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.h (269072 => 269073)
--- trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioDestinationCocoa.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -70,8 +70,8 @@
private:
friend Ref<AudioDestination> AudioDestination::create(AudioIOCallback&, const String&, unsigned, unsigned, float);
- void start(Function<void(Function<void()>&&)>&&) override;
- void stop() override;
+ void start(Function<void(Function<void()>&&)>&&, CompletionHandler<void(bool)>&&) override;
+ void stop(CompletionHandler<void(bool)>&&) override;
// AudioSourceProvider.
WEBCORE_EXPORT void provideInput(AudioBus*, size_t framesToProcess) final;
Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp (269072 => 269073)
--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -217,33 +217,42 @@
return TRUE;
}
-void AudioDestinationGStreamer::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread)
+void AudioDestinationGStreamer::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&& completionHandler)
{
ASSERT(m_audioSinkAvailable);
- if (!m_audioSinkAvailable)
- return;
+ bool success = false;
+ if (m_audioSinkAvailable) {
+ if (dispatchToRenderThread)
+ webkitWebAudioSourceSetDispatchToRenderThreadCallback(WEBKIT_WEB_AUDIO_SRC(m_src.get()), WTFMove(dispatchToRenderThread));
- if (dispatchToRenderThread)
- webkitWebAudioSourceSetDispatchToRenderThreadCallback(WEBKIT_WEB_AUDIO_SRC(m_src.get()), WTFMove(dispatchToRenderThread));
+ GST_DEBUG("Starting");
+ if (gst_element_set_state(m_pipeline.get(), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+ g_warning("Error: Failed to set pipeline to playing");
+ m_isPlaying = false;
+ } else {
+ m_isPlaying = true;
+ success = true;
+ }
+ }
- GST_DEBUG("Starting");
- if (gst_element_set_state(m_pipeline.get(), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
- g_warning("Error: Failed to set pipeline to playing");
- m_isPlaying = false;
- return;
- }
- m_isPlaying = true;
+ callOnMainThread([completionHandler = WTFMove(completionHandler), success]() mutable {
+ completionHandler(success);
+ });
}
-void AudioDestinationGStreamer::stop()
+void AudioDestinationGStreamer::stop(CompletionHandler<void(bool)>&& completionHandler)
{
ASSERT(m_audioSinkAvailable);
- if (!m_audioSinkAvailable)
- return;
-
- GST_DEBUG("Stopping");
- gst_element_set_state(m_pipeline.get(), GST_STATE_PAUSED);
- m_isPlaying = false;
+ bool success = false;
+ if (m_audioSinkAvailable) {
+ GST_DEBUG("Stopping");
+ gst_element_set_state(m_pipeline.get(), GST_STATE_PAUSED);
+ m_isPlaying = false;
+ success = true;
+ }
+ callOnMainThread([completionHandler = WTFMove(completionHandler), success]() mutable {
+ completionHandler(success);
+ });
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h (269072 => 269073)
--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -34,8 +34,8 @@
AudioDestinationGStreamer(AudioIOCallback&, unsigned long numberOfOutputChannels, float sampleRate);
virtual ~AudioDestinationGStreamer();
- void start(Function<void(Function<void()>&&)>&& dispatchToRenderThread) override;
- void stop() override;
+ void start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&&) override;
+ void stop(CompletionHandler<void(bool)>&&) override;
bool isPlaying() override { return m_isPlaying; }
float sampleRate() const override { return m_sampleRate; }
Modified: trunk/Source/WebCore/platform/mock/MockAudioDestinationCocoa.cpp (269072 => 269073)
--- trunk/Source/WebCore/platform/mock/MockAudioDestinationCocoa.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/mock/MockAudioDestinationCocoa.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -45,23 +45,27 @@
MockAudioDestinationCocoa::~MockAudioDestinationCocoa() = default;
-void MockAudioDestinationCocoa::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread)
+void MockAudioDestinationCocoa::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&& completionHandler)
{
m_dispatchToRenderThread = WTFMove(dispatchToRenderThread);
m_timer.startRepeating(Seconds { m_numberOfFramesToProcess / sampleRate() });
setIsPlaying(true);
+
+ callOnMainThread([completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(true);
+ });
}
-void MockAudioDestinationCocoa::stop()
+void MockAudioDestinationCocoa::stop(CompletionHandler<void(bool)>&& completionHandler)
{
m_timer.stop();
setIsPlaying(false);
- BinarySemaphore semaphore;
- m_workQueue->dispatch([&semaphore] {
- semaphore.signal();
+ m_workQueue->dispatch([completionHandler = WTFMove(completionHandler)]() mutable {
+ callOnMainThread([completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(true);
+ });
});
- semaphore.wait();
}
void MockAudioDestinationCocoa::tick()
Modified: trunk/Source/WebCore/platform/mock/MockAudioDestinationCocoa.h (269072 => 269073)
--- trunk/Source/WebCore/platform/mock/MockAudioDestinationCocoa.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebCore/platform/mock/MockAudioDestinationCocoa.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -47,8 +47,8 @@
WEBCORE_EXPORT virtual ~MockAudioDestinationCocoa();
private:
- void start(Function<void(Function<void()>&&)>&&) final;
- void stop() final;
+ void start(Function<void(Function<void()>&&)>&&, CompletionHandler<void(bool)>&&) final;
+ void stop(CompletionHandler<void(bool)>&&) final;
void tick();
Modified: trunk/Source/WebKit/ChangeLog (269072 => 269073)
--- trunk/Source/WebKit/ChangeLog 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebKit/ChangeLog 2020-10-27 21:46:21 UTC (rev 269073)
@@ -1,3 +1,18 @@
+2020-10-27 Chris Dumez <[email protected]>
+
+ [GPUProcess] Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination
+ https://bugs.webkit.org/show_bug.cgi?id=218251
+
+ Reviewed by Geoffrey Garen.
+
+ Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination.
+
+ * GPUProcess/media/RemoteAudioDestinationManager.messages.in:
+ * WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp:
+ (WebKit::RemoteAudioDestinationProxy::start):
+ (WebKit::RemoteAudioDestinationProxy::stop):
+ * WebProcess/GPU/media/RemoteAudioDestinationProxy.h:
+
2020-10-27 Brian Burg <[email protected]>
[Cocoa] Introduce _WKInspectorConfiguration for customizing local and remote Web Inspectors
Modified: trunk/Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.messages.in (269072 => 269073)
--- trunk/Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.messages.in 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.messages.in 2020-10-27 21:46:21 UTC (rev 269073)
@@ -27,8 +27,8 @@
CreateAudioDestination(String inputDeviceId, uint32_t numberOfInputChannels, uint32_t numberOfOutputChannels, float sampleRate, float hardwareSampleRate) -> (WebKit::RemoteAudioDestinationIdentifier identifier) Synchronous
DeleteAudioDestination(WebKit::RemoteAudioDestinationIdentifier identifier) -> () Async
- StartAudioDestination(WebKit::RemoteAudioDestinationIdentifier identifier) -> (bool isPlaying) Synchronous
- StopAudioDestination(WebKit::RemoteAudioDestinationIdentifier identifier) -> (bool isPlaying) Synchronous
+ StartAudioDestination(WebKit::RemoteAudioDestinationIdentifier identifier) -> (bool isPlaying) Async
+ StopAudioDestination(WebKit::RemoteAudioDestinationIdentifier identifier) -> (bool isPlaying) Async
#if PLATFORM(COCOA)
AudioSamplesStorageChanged(WebKit::RemoteAudioDestinationIdentifier identifier, WebKit::SharedMemory::IPCHandle storageHandle, WebCore::CAAudioStreamDescription description, uint64_t numberOfFrames)
#endif
Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp (269072 => 269073)
--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp 2020-10-27 21:46:21 UTC (rev 269073)
@@ -102,24 +102,22 @@
m_renderThread->waitForCompletion();
}
-void RemoteAudioDestinationProxy::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread)
+void RemoteAudioDestinationProxy::start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&& completionHandler)
{
- m_dispatchToRenderThread = WTFMove(dispatchToRenderThread);
- bool isPlaying;
- WebProcess::singleton().ensureGPUProcessConnection().connection().sendSync(
- Messages::RemoteAudioDestinationManager::StartAudioDestination(m_destinationID),
- Messages::RemoteAudioDestinationManager::StartAudioDestination::Reply(isPlaying), 0);
- setIsPlaying(isPlaying);
+ WebProcess::singleton().ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StartAudioDestination(m_destinationID), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler), dispatchToRenderThread = WTFMove(dispatchToRenderThread)](bool isPlaying) mutable {
+ m_dispatchToRenderThread = WTFMove(dispatchToRenderThread);
+ setIsPlaying(isPlaying);
+ completionHandler(isPlaying);
+ });
}
-void RemoteAudioDestinationProxy::stop()
+void RemoteAudioDestinationProxy::stop(CompletionHandler<void(bool)>&& completionHandler)
{
- bool isPlaying;
- WebProcess::singleton().ensureGPUProcessConnection().connection().sendSync(
- Messages::RemoteAudioDestinationManager::StopAudioDestination(m_destinationID),
- Messages::RemoteAudioDestinationManager::StopAudioDestination::Reply(isPlaying), 0);
- setIsPlaying(isPlaying);
- m_dispatchToRenderThread = nullptr;
+ WebProcess::singleton().ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StopAudioDestination(m_destinationID), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {
+ setIsPlaying(isPlaying);
+ m_dispatchToRenderThread = nullptr;
+ completionHandler(!isPlaying);
+ });
}
#if PLATFORM(COCOA)
Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h (269072 => 269073)
--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h 2020-10-27 21:40:20 UTC (rev 269072)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h 2020-10-27 21:46:21 UTC (rev 269073)
@@ -75,8 +75,8 @@
#endif
private:
- void start(Function<void(Function<void()>&&)>&& dispatchToRenderThread) final;
- void stop() final;
+ void start(Function<void(Function<void()>&&)>&& dispatchToRenderThread, CompletionHandler<void(bool)>&&) final;
+ void stop(CompletionHandler<void(bool)>&&) final;
#if !PLATFORM(COCOA)
bool isPlaying() final { return false; }