diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index daea6f376..7cdce894b 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2018 Filipe Coelho + * Copyright (C) 2011-2019 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -35,6 +35,12 @@ #include "CarlaNative.hpp" #include "CarlaNativePlugin.h" +#if defined(USING_JUCE) && ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) +# include "AppConfig.h" +# include "juce_events/juce_events.h" +# define USE_JUCE_MESSAGE_THREAD +#endif + #include "water/files/File.h" #include "water/streams/MemoryOutputStream.h" #include "water/xml/XmlDocument.h" @@ -50,6 +56,63 @@ CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- +#ifdef USE_JUCE_MESSAGE_THREAD +static int numScopedInitInstances = 0; + +class SharedJuceMessageThread : public juce::Thread +{ +public: + SharedJuceMessageThread() + : juce::Thread ("SharedJuceMessageThread"), + initialised (false) {} + + ~SharedJuceMessageThread() + { + CARLA_SAFE_ASSERT(numScopedInitInstances == 0); + + // in case something fails + juce::MessageManager::getInstance()->stopDispatchLoop(); + waitForThreadToExit (5000); + } + + void incRef() + { + if (numScopedInitInstances++ == 0) + { + startThread (7); + + while (! initialised) + juce::Thread::sleep (1); + } + } + + void decRef() + { + if (--numScopedInitInstances == 0) + { + juce::MessageManager::getInstance()->stopDispatchLoop(); + waitForThreadToExit (5000); + } + } + +protected: + void run() override + { + const juce::ScopedJuceInitialiser_GUI juceInitialiser; + + juce::MessageManager::getInstance()->setCurrentThreadAsMessageThread(); + initialised = true; + + juce::MessageManager::getInstance()->runDispatchLoop(); + } + +private: + volatile bool initialised; +}; +#endif + +// ----------------------------------------------------------------------- + class CarlaEngineNativeUI : public CarlaExternalUI { public: @@ -584,9 +647,19 @@ public: fIsRunning(false), fUiServer(this), fOptionsForced(false) +#ifdef USE_JUCE_MESSAGE_THREAD + // if not running inside Carla, we will have to run event loop ourselves + , kNeedsJuceMsgThread(host->dispatcher(pHost->handle, + NATIVE_HOST_OPCODE_INTERNAL_PLUGIN, 0, 0, nullptr, 0.0f) == 0) +#endif { carla_debug("CarlaEngineNative::CarlaEngineNative()"); +#ifdef USE_JUCE_MESSAGE_THREAD + if (kNeedsJuceMsgThread) + sJuceMsgThread->incRef(); +#endif + pData->bufferSize = pHost->get_buffer_size(pHost->handle); pData->sampleRate = pHost->get_sample_rate(pHost->handle); pData->initTime(nullptr); @@ -644,6 +717,11 @@ public: pData->graph.destroy(); +#ifdef USE_JUCE_MESSAGE_THREAD + if (kNeedsJuceMsgThread) + sJuceMsgThread->decRef(); +#endif + carla_debug("CarlaEngineNative::~CarlaEngineNative() - END"); } @@ -1990,6 +2068,11 @@ private: bool fOptionsForced; +#ifdef USE_JUCE_MESSAGE_THREAD + const bool kNeedsJuceMsgThread; + const juce::SharedResourcePointer sJuceMsgThread; +#endif + CarlaPlugin* _getFirstPlugin() const noexcept { if (pData->curPluginCount == 0 || pData->plugins == nullptr) diff --git a/source/bridges-plugin/CarlaBridgeSingleLV2.cpp b/source/bridges-plugin/CarlaBridgeSingleLV2.cpp index 9a3700b9d..2607e9b47 100644 --- a/source/bridges-plugin/CarlaBridgeSingleLV2.cpp +++ b/source/bridges-plugin/CarlaBridgeSingleLV2.cpp @@ -1,6 +1,6 @@ /* * Carla LV2 Single Plugin - * Copyright (C) 2017-2018 Filipe Coelho + * Copyright (C) 2017-2019 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,6 +27,11 @@ #include "CarlaLv2Utils.hpp" #include "CarlaUtils.h" +#ifdef USING_JUCE +# include "AppConfig.h" +# include "juce_events/juce_events.h" +#endif + #include "water/files/File.h" template<> @@ -466,6 +471,10 @@ private: CarlaPlugin* fPlugin; CarlaString fUiName; +#ifdef USING_JUCE + juce::SharedResourcePointer sJuceInitialiser; +#endif + void updateParameterOutputs() noexcept { float value;