From 21ff906bf8b2a031f308296b1fb85b7112a29d08 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 24 Jan 2021 15:42:25 +0100 Subject: [PATCH] Handle connection point proxy from GUI thread FabFilter plugins will exchange messages that have to be handled from the GUI thread, or they'll get stuck waiting on a synchronisation object. This probably hurts GUI performance significantly but luckily it only affects Ardour. --- .../bridges/vst3-impls/connection-point-proxy.cpp | 6 +++++- src/wine-host/bridges/vst3.cpp | 14 +++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp b/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp index 39b547d2..f4ef6ff0 100644 --- a/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp @@ -52,7 +52,11 @@ Vst3ConnectionPointProxyImpl::disconnect(IConnectionPoint* /*other*/) { tresult PLUGIN_API Vst3ConnectionPointProxyImpl::notify(Steinberg::Vst::IMessage* message) { if (message) { - return bridge.send_message( + // FabFilter plugins require this to be done from the GUI thread so we + // need to use our mutual recursion mechanism. Luckily only Ardour uses + // connection proxies, so if this ends up breaking something it will + // only affect Ardour. + return bridge.send_mutually_recursive_message( YaConnectionPoint::Notify{.instance_id = owner_instance_id(), .message_ptr = YaMessagePtr(*message)}); } else { diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index dc4e8420..1d553e9d 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -280,9 +280,17 @@ void Vst3Bridge::run() { // We should thus be passing a (raw) pointer to the // original object so we can pretend none of this wrapping // and serializing has ever happened. - return object_instances[request.instance_id] - .connection_point->notify( - request.message_ptr.get_original()); + // NOTE: FabFilter plugins require some of their messages to be + // handled from the GUI thread. This could make the GUI + // much slower in Ardour, but there's no other non-hacky + // solution for this (and bypassing Ardour's connection + // proxies sort of goes against the idea behind yabridge) + return do_mutual_recursion_or_handle_in_main_context( + [&]() { + return object_instances[request.instance_id] + .connection_point->notify( + request.message_ptr.get_original()); + }); }, [&](YaContextMenuTarget::ExecuteMenuItem& request) -> YaContextMenuTarget::ExecuteMenuItem::Response {