From d13e3547288e516792f5435d33f99f3155ac3c9e Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 13 Nov 2021 12:56:08 +0000 Subject: [PATCH] Use host idle call to give idle to Carla and Ildaeil, fixes GL UIs Signed-off-by: falkTX --- plugins/Cardinal/src/Carla.cpp | 97 +++++++++++++++++--------- plugins/Cardinal/src/Ildaeil.cpp | 78 +++++++++++++++------ plugins/Cardinal/src/plugincontext.hpp | 8 +++ src/CardinalUI.cpp | 19 +++++ src/PluginContext.hpp | 21 +++++- 5 files changed, 167 insertions(+), 56 deletions(-) diff --git a/plugins/Cardinal/src/Carla.cpp b/plugins/Cardinal/src/Carla.cpp index dd47ce0..31503f3 100644 --- a/plugins/Cardinal/src/Carla.cpp +++ b/plugins/Cardinal/src/Carla.cpp @@ -366,7 +366,7 @@ static intptr_t host_dispatcher(const NativeHostHandle handle, const NativeHostD // -------------------------------------------------------------------------------------------------------------------- -struct CarlaModuleWidget : ModuleWidget { +struct CarlaModuleWidget : ModuleWidget, IdleCallback { static constexpr const float startX_In = 14.0f; static constexpr const float startX_Out = 96.0f; static constexpr const float startY = 74.0f; @@ -374,6 +374,7 @@ struct CarlaModuleWidget : ModuleWidget { static constexpr const float middleX = startX_In + (startX_Out - startX_In) * 0.5f + padding * 0.25f; CarlaModule* const module; + bool idleCallbackActive = false; bool visible = false; CarlaModuleWidget(CarlaModule* const m) @@ -393,21 +394,6 @@ struct CarlaModuleWidget : ModuleWidget { for (uint i=0; i(Vec(startX_Out, startY + padding * i), module, i)); - - if (module != nullptr && module->fCarlaHostHandle != nullptr) - { - const CarlaHostHandle handle = module->fCarlaHostHandle; - - char winIdStr[24]; - std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); - carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); - module->fCarlaHostDescriptor.uiParentId = module->pcontext->nativeWindowId; - /* - carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, getScaleFactor()*1000, nullptr); - */ - - module->fUI = this; - } } ~CarlaModuleWidget() override @@ -427,25 +413,80 @@ struct CarlaModuleWidget : ModuleWidget { void onContextCreate(const ContextCreateEvent& e) override { ModuleWidget::onContextCreate(e); + widgetCreated(); + } + + void onContextDestroy(const ContextDestroyEvent& e) override + { + widgetDestroyed(); + ModuleWidget::onContextDestroy(e); + } + void onAdd(const AddEvent& e) override + { + ModuleWidget::onAdd(e); + widgetCreated(); + } + + void onRemove(const RemoveEvent& e) override + { + widgetDestroyed(); + ModuleWidget::onRemove(e); + } + + void widgetCreated() + { if (module == nullptr || module->pcontext == nullptr || module->fCarlaHostHandle == nullptr) return; + const CarlaHostHandle handle = module->fCarlaHostHandle; + CardinalPluginContext* const pcontext = module->pcontext; + char winIdStr[24]; - std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); - carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); - module->fCarlaHostDescriptor.uiParentId = module->pcontext->nativeWindowId; + std::snprintf(winIdStr, sizeof(winIdStr), "%llx", (ulonglong)pcontext->nativeWindowId); + + module->fCarlaHostDescriptor.uiParentId = pcontext->nativeWindowId; + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); + + if (pcontext->window != nullptr) + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, pcontext->window->pixelRatio*1000, nullptr); + + if (! idleCallbackActive) + idleCallbackActive = pcontext->addIdleCallback(this); + + module->fUI = this; } - void onContextDestroy(const ContextDestroyEvent& e) override + void widgetDestroyed() { - if (module != nullptr && module->fCarlaHostHandle != nullptr) + if (module == nullptr || module->pcontext == nullptr || module->fCarlaHostHandle == nullptr) + return; + + const CarlaHostHandle handle = module->fCarlaHostHandle; + CardinalPluginContext* const pcontext = module->pcontext; + + module->fUI = nullptr; + + if (visible) { - module->fCarlaHostDescriptor.uiParentId = 0; - carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); + visible = false; + module->fCarlaPluginDescriptor->ui_show(module->fCarlaPluginHandle, false); } - ModuleWidget::onContextDestroy(e); + if (idleCallbackActive) + { + idleCallbackActive = false; + pcontext->removeIdleCallback(this); + } + + module->fCarlaHostDescriptor.uiParentId = 0; + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); + } + + void idleCallback() override + { + if (module != nullptr && module->fCarlaHostHandle != nullptr && visible) + module->fCarlaPluginDescriptor->ui_idle(module->fCarlaPluginHandle); } void drawTextLine(NVGcontext* const vg, const uint offset, const char* const text) @@ -488,14 +529,6 @@ struct CarlaModuleWidget : ModuleWidget { ModuleWidget::draw(args); } - void step() override - { - if (module != nullptr && module->fCarlaHostHandle != nullptr && visible) - module->fCarlaPluginDescriptor->ui_idle(module->fCarlaPluginHandle); - - ModuleWidget::step(); - } - void showUI() { visible = true; diff --git a/plugins/Cardinal/src/Ildaeil.cpp b/plugins/Cardinal/src/Ildaeil.cpp index 4d1912e..1f69bcc 100644 --- a/plugins/Cardinal/src/Ildaeil.cpp +++ b/plugins/Cardinal/src/Ildaeil.cpp @@ -357,7 +357,7 @@ static intptr_t host_dispatcher(const NativeHostHandle handle, const NativeHostD // -------------------------------------------------------------------------------------------------------------------- #ifndef HEADLESS -struct IldaeilWidget : ImGuiWidget, Thread { +struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { static constexpr const uint kButtonHeight = 20; struct PluginInfoCache { @@ -440,13 +440,14 @@ struct IldaeilWidget : ImGuiWidget, Thread { String fPopupError; + bool idleCallbackActive = false; IldaeilModule* const module; IldaeilWidget(IldaeilModule* const m) : ImGuiWidget(), module(m) { - if (module == nullptr || module->fCarlaHostHandle == nullptr) + if (module->fCarlaHostHandle == nullptr) { fDrawingState = kDrawingErrorInit; fPopupError = "Ildaeil backend failed to init properly, cannot continue."; @@ -460,13 +461,6 @@ struct IldaeilWidget : ImGuiWidget, Thread { const CarlaHostHandle handle = module->fCarlaHostHandle; - char winIdStr[24]; - std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); - carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); - /* - carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, getScaleFactor()*1000, nullptr); - */ - if (carla_get_current_plugin_count(handle) != 0) { const uint hints = carla_get_plugin_info(handle, 0)->hints; @@ -479,10 +473,12 @@ struct IldaeilWidget : ImGuiWidget, Thread { ~IldaeilWidget() override { - if (module != nullptr && module->fCarlaHostHandle != nullptr) + if (module->fCarlaHostHandle != nullptr) { module->fUI = nullptr; carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); + + module->pcontext->removeIdleCallback(this); } if (isThreadRunning()) @@ -661,28 +657,66 @@ struct IldaeilWidget : ImGuiWidget, Thread { void onContextCreate(const ContextCreateEvent& e) override { ImGuiWidget::onContextCreate(e); + widgetCreated(); + } - if (module == nullptr || module->pcontext == nullptr || module->fCarlaHostHandle == nullptr) - return; + void onContextDestroy(const ContextDestroyEvent& e) override + { + widgetDestroyed(); + ImGuiWidget::onContextDestroy(e); + } - char winIdStr[24]; - std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); - carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); + void onAdd(const AddEvent& e) override + { + ImGuiWidget::onAdd(e); + widgetCreated(); } - void onContextDestroy(const ContextDestroyEvent& e) override + void onRemove(const RemoveEvent& e) override { - if (module != nullptr && module->fCarlaHostHandle != nullptr) - carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); + widgetDestroyed(); + ImGuiWidget::onRemove(e); + } - ImGuiWidget::onContextDestroy(e); + void widgetCreated() + { + if (const CarlaHostHandle handle = module->fCarlaHostHandle) + { + CardinalPluginContext* const pcontext = module->pcontext; + + char winIdStr[24]; + std::snprintf(winIdStr, sizeof(winIdStr), "%llx", (ulonglong)pcontext->nativeWindowId); + + module->fCarlaHostDescriptor.uiParentId = pcontext->nativeWindowId; + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); + + if (pcontext->window != nullptr) + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, pcontext->window->pixelRatio*1000, nullptr); + + if (! idleCallbackActive) + idleCallbackActive = pcontext->addIdleCallback(this); + } } - void step() override + void widgetDestroyed() { - ImGuiWidget::step(); - setDirty(true); + if (const CarlaHostHandle handle = module->fCarlaHostHandle) + { + CardinalPluginContext* const pcontext = module->pcontext; + + module->fCarlaHostDescriptor.uiParentId = 0; + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); + + if (idleCallbackActive) + { + idleCallbackActive = false; + pcontext->removeIdleCallback(this); + } + } + } + void idleCallback() override + { switch (fDrawingState) { case kDrawingInit: diff --git a/plugins/Cardinal/src/plugincontext.hpp b/plugins/Cardinal/src/plugincontext.hpp index cc952e0..736c496 100644 --- a/plugins/Cardinal/src/plugincontext.hpp +++ b/plugins/Cardinal/src/plugincontext.hpp @@ -20,6 +20,10 @@ #include "plugin.hpp" #include "DistrhoUtils.hpp" +#ifndef HEADLESS +# include "dgl/Base.hpp" +#endif + // ----------------------------------------------------------------------------------------------------------- // from PluginContext.hpp @@ -44,6 +48,10 @@ struct CardinalPluginContext : rack::Context { float** dataOuts; Plugin* const plugin; CardinalPluginContext(Plugin* const p); +#ifndef HEADLESS + bool addIdleCallback(IdleCallback* cb); + void removeIdleCallback(IdleCallback* cb); +#endif }; END_NAMESPACE_DISTRHO diff --git a/src/CardinalUI.cpp b/src/CardinalUI.cpp index 6c720b6..d83e41e 100644 --- a/src/CardinalUI.cpp +++ b/src/CardinalUI.cpp @@ -56,6 +56,25 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------------------------------------------- +bool CardinalPluginContext::addIdleCallback(IdleCallback* const cb) +{ + if (ui == nullptr) + return false; + + ui->addIdleCallback(cb); + return true; +} + +void CardinalPluginContext::removeIdleCallback(IdleCallback* const cb) +{ + if (ui == nullptr) + return; + + ui->removeIdleCallback(cb); +} + +// ----------------------------------------------------------------------------------------------------------- + class CardinalUI : public CardinalBaseUI, public WindowParametersCallback { diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp index 57764d7..83073db 100644 --- a/src/PluginContext.hpp +++ b/src/PluginContext.hpp @@ -54,6 +54,9 @@ struct CardinalPluginContext : rack::Context { const float** dataIns; float** dataOuts; Plugin* const plugin; +#ifndef HEADLESS + UI* ui; +#endif CardinalPluginContext(Plugin* const p) : bufferSize(p->getBufferSize()), @@ -79,9 +82,17 @@ struct CardinalPluginContext : rack::Context { dataIns(nullptr), dataOuts(nullptr), plugin(p) +#ifndef HEADLESS + , ui(nullptr) +#endif { std::memset(parameters, 0, sizeof(parameters)); } + +#ifndef HEADLESS + bool addIdleCallback(IdleCallback* cb); + void removeIdleCallback(IdleCallback* cb); +#endif }; // ----------------------------------------------------------------------------------------------------------- @@ -121,8 +132,14 @@ public: CardinalBaseUI(const uint width, const uint height) : UI(width, height), context(getRackContextFromPlugin(getPluginInstancePointer())), - saving(false) {} - ~CardinalBaseUI() override {} + saving(false) + { + context->ui = this; + } + ~CardinalBaseUI() override + { + context->ui = nullptr; + } }; #endif