From c054398965df99abcea7eaea7ad46d15909a1c1d Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 30 Nov 2021 03:48:08 +0100 Subject: [PATCH] Increase Win32 message limit for JUCE plugins They aggressively use the message loop when parts of a plugin's UI change, sometimes sending as many is 2300 events at once. The old 20 messages per tick limit would cause severe slowdowns in this case. --- CHANGELOG.md | 10 ++++++++++ src/wine-host/bridges/common.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bdeb5d3..ac8db1a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- Fixed sluggish UIs in _Output's Thermal_ and likely a handful of other + JUCE-based plugins. These plugins would emit hundreds to thousands of events + when the GUI changes. Yabridge now detects this, and removes the throttling we + have in place to prevent certain other plugins from getting stuck in infinite + loops. + ## [3.7.0] - 2021-11-21 ### Added diff --git a/src/wine-host/bridges/common.cpp b/src/wine-host/bridges/common.cpp index 2f5a7eb4..b203af9e 100644 --- a/src/wine-host/bridges/common.cpp +++ b/src/wine-host/bridges/common.cpp @@ -31,6 +31,22 @@ */ constexpr int max_win32_messages = 20; +/** + * Some JUCE based plugins however send thousands of `WM_USER+123` events + * at once from the GUI. So while the limit from `win32_message_limit` + * needs to exist, it also causes some other plugins to feel sluggish. + * When we encounter these events, we'll assume we're dealing with a JUCE + * plugin and increase the limit. Examples of affected plugins are: + * + * - Thermal by Output + */ +constexpr int extended_max_win32_messages = 8192; +/** + * The Win32 message ID that needs to trigger the behaviour described for + * `juce_win32_message_limit`. + */ +constexpr unsigned int juce_message_id = WM_USER + 123; + HostBridge::HostBridge(MainContext& main_context, boost::filesystem::path plugin_path, pid_t parent_pid) @@ -45,9 +61,14 @@ HostBridge::~HostBridge() noexcept {} void HostBridge::handle_events() noexcept { MSG msg; - for (int i = 0; - i < max_win32_messages && PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE); + int limit = max_win32_messages; + for (int i = 0; i < limit && PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE); i++) { + // HACK: See the docstring on `juce_win32_message_limit` + if (msg.message == juce_message_id) { + limit = extended_max_win32_messages; + } + TranslateMessage(&msg); DispatchMessage(&msg); }