diff --git a/src/wrapasvst3.cpp b/src/wrapasvst3.cpp index 4fedd98e..20c1e11d 100644 --- a/src/wrapasvst3.cpp +++ b/src/wrapasvst3.cpp @@ -12,6 +12,10 @@ #include #include +// we need this lock free since we can request a gui resize from any thread in CLAP +static_assert(std::atomic::is_always_lock_free, + "compiler must ensure that std::atomic is lock free"); + #if WIN #include #define S16(x) reinterpret_cast(_T(x)) @@ -1106,6 +1110,16 @@ bool ClapAsVst3::gui_can_resize() bool ClapAsVst3::gui_request_resize(uint32_t width, uint32_t height) { + // UIs with 65kx65k resolution are not supported + if ((width > 0xffff) || (height > 0xffff)) return false; + + if (_main_thread_id != std::this_thread::get_id()) + { + uint32_t newSize = ((width & 0xffff) << 16) | (height & 0xffff); + _gui_resize_request.store(newSize); + return true; + } + if (_wrappedview) return _wrappedview->request_resize(width, height); else @@ -1292,6 +1306,16 @@ void ClapAsVst3::onIdle() _plugin->_plugin->on_main_thread(_plugin->_plugin); } + if (_wrappedview) + { + if (auto const size = _gui_resize_request.exchange(_gui_invalid_size); size != _gui_invalid_size) + { + auto w = (size >> 16) & 0xffff; + auto h = (size & 0xffff); + _wrappedview->request_resize(w, h); + } + } + #if LIN if (!_iRunLoop) // don't process timers if we have a runloop. // (but if we don't have a runloop on linux onIdle isn't called diff --git a/src/wrapasvst3.h b/src/wrapasvst3.h index 6b5c9b2b..5587213e 100644 --- a/src/wrapasvst3.h +++ b/src/wrapasvst3.h @@ -40,6 +40,8 @@ #include "detail/vst3/aravst3.h" #include "detail/shared/spinlock.h" #include +#include +#include using namespace Steinberg; @@ -386,6 +388,10 @@ class ClapAsVst3 : public Steinberg::Vst::SingleComponentEffect, std::atomic_bool _requestUICallback = false; bool _missedLatencyRequest = false; + std::thread::id _main_thread_id{}; + static const uint32_t _gui_invalid_size = 0xffffffff; + std::atomic _gui_resize_request = _gui_invalid_size; + // the queue from audiothread to UI thread ClapWrapper::detail::shared::fixedqueue _queueToUI;