diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 6d3e324..48d847c 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -43,10 +43,17 @@ #include "DistrhoPluginUtils.hpp" #include "PluginDriver.hpp" -#include "WindowParameters.hpp" #include "extra/Base64.hpp" #include "extra/SharedResourcePointer.hpp" +#ifndef HEADLESS +# include "WindowParameters.hpp" +static const constexpr uint kCardinalStateCount = 2; // patch, windowSize +#else +# define kWindowParameterCount 0 +static const constexpr uint kCardinalStateCount = 1; // patch +#endif + #define REMOTE_HOST_PORT "2228" namespace rack { @@ -54,7 +61,7 @@ namespace plugin { void initStaticPlugins(); void destroyStaticPlugins(); } -#if defined(__MOD_DEVICES__) && !defined(HEADLESS) +#ifndef HEADLESS namespace window { void WindowInit(Window* window, DISTRHO_NAMESPACE::Plugin* plugin); } @@ -342,12 +349,14 @@ class CardinalPlugin : public CardinalBasePlugin uint64_t fPreviousFrame; Mutex fDeviceMutex; + #ifndef HEADLESS // real values, not VCV interpreted ones float fWindowParameters[kWindowParameterCount]; + #endif public: CardinalPlugin() - : CardinalBasePlugin(kModuleParameters + kWindowParameterCount, 0, 2), + : CardinalBasePlugin(kModuleParameters + kWindowParameterCount, 0, kCardinalStateCount), fInitializer(this), fAudioBufferIn(nullptr), fAudioBufferOut(nullptr), @@ -357,6 +366,7 @@ public: fCurrentMidiOutputs(nullptr), fPreviousFrame(0) { + #ifndef HEADLESS fWindowParameters[kWindowParameterShowTooltips] = 1.0f; fWindowParameters[kWindowParameterCableOpacity] = 50.0f; fWindowParameters[kWindowParameterCableTension] = 75.0f; @@ -366,6 +376,7 @@ public: fWindowParameters[kWindowParameterWheelKnobControl] = 0.0f; fWindowParameters[kWindowParameterWheelSensitivity] = 1.0f; fWindowParameters[kWindowParameterLockModulePositions] = 0.0f; + #endif // create unique temporary path for this instance try { @@ -652,6 +663,7 @@ protected: return; } + #ifndef HEADLESS switch (index - kModuleParameters) { case kWindowParameterShowTooltips: @@ -740,6 +752,7 @@ protected: parameter.ranges.max = 1.0f; break; } + #endif } void initState(const uint32_t index, String& stateKey, String& defaultStateValue) override @@ -751,9 +764,11 @@ protected: case 0: stateKey = "patch"; break; + #ifndef HEADLESS case 1: stateKey = "windowSize"; break; + #endif } } @@ -765,10 +780,12 @@ protected: if (index < kModuleParameters) return context->parameters[index]; + #ifndef HEADLESS index -= kModuleParameters; if (index < kWindowParameterCount) return fWindowParameters[index]; + #endif return 0.0f; } @@ -781,6 +798,7 @@ protected: return; } + #ifndef HEADLESS index -= kModuleParameters; if (index < kWindowParameterCount) @@ -788,12 +806,15 @@ protected: fWindowParameters[index] = value; return; } + #endif } String getState(const char* const key) const override { + #ifndef HEADLESS if (std::strcmp(key, "windowSize") == 0) return fWindowSize; + #endif if (std::strcmp(key, "patch") != 0) return String(); @@ -820,11 +841,13 @@ protected: void setState(const char* const key, const char* const value) override { + #ifndef HEADLESS if (std::strcmp(key, "windowSize") == 0) { fWindowSize = value; return; } + #endif if (std::strcmp(key, "patch") != 0) return; diff --git a/src/WindowParameters.hpp b/src/WindowParameters.hpp index 9c30c97..186bd6c 100644 --- a/src/WindowParameters.hpp +++ b/src/WindowParameters.hpp @@ -15,6 +15,10 @@ * For a full copy of the GNU General Public License see the LICENSE file. */ +#ifdef HEADLESS +# error wrong include +#endif + #pragma once #include "DistrhoUtils.hpp" diff --git a/src/override/RemoteWindow.cpp b/src/override/RemoteWindow.cpp index 4c0eff5..724dcdc 100644 --- a/src/override/RemoteWindow.cpp +++ b/src/override/RemoteWindow.cpp @@ -36,29 +36,12 @@ #include #include #include -#include // used in Window::screenshot -#include // used in Window::screenshot +#include #ifdef NDEBUG # undef DEBUG #endif -#include "DistrhoPlugin.hpp" -#include "../WindowParameters.hpp" - -#ifdef WITH_MESA -# include "../src/Rack/dep/glfw/deps/stb_image_write.h" -# include "extra/Thread.hpp" -# include -#endif - - -namespace rack { -namespace app { -widget::Widget* createMenuBar() { return new widget::Widget; } -} -} - namespace rack { namespace window { @@ -112,19 +95,9 @@ struct WindowParams { }; struct Window::Internal -#ifdef WITH_MESA - : public Thread -#endif { - DISTRHO_NAMESPACE::Plugin* plugin = nullptr; - DISTRHO_NAMESPACE::WindowParameters params; - DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr; Context* context = nullptr; Window* self = nullptr; -#ifdef WITH_MESA - OSMesaContext mesa = nullptr; - GLubyte* mesaBuffer = nullptr; -#endif math::Vec size = minWindowSize; std::string lastWindowTitle; @@ -141,28 +114,6 @@ struct Window::Internal bool fbDirtyOnSubpixelChange = true; int fbCount = 0; - -#ifdef WITH_MESA - void run() override { - self->run(); - int i=0; - while (! shouldThreadExit()) { - // d_msleep(500); - d_stdout("thread idle %i - start", i); - contextSet(context); - d_stdout("thread idle %i - context was set", i); - self->step(); - d_stdout("thread idle %i - did step", i); - if (i++ == 0) - { - // render to png - stbi_write_png("testing.png", 1228, 666, 4, mesaBuffer, 666 * 4); - d_stdout("thread idle %i - wrote to png", i); - } - } - d_stdout("thread quit"); - } -#endif }; Window::Window() { @@ -171,142 +122,6 @@ Window::Window() { internal->self = this; } -#ifdef WITH_MESA -static void flipBitmap(uint8_t* pixels, int width, int height, int depth) { - for (int y = 0; y < height / 2; y++) { - int flipY = height - y - 1; - uint8_t tmp[width * depth]; - std::memcpy(tmp, &pixels[y * width * depth], width * depth); - std::memcpy(&pixels[y * width * depth], &pixels[flipY * width * depth], width * depth); - std::memcpy(&pixels[flipY * width * depth], tmp, width * depth); - } -} -#endif - -void WindowInit(Window* const window, DISTRHO_NAMESPACE::Plugin* const plugin) -{ - window->internal->plugin = plugin; - -#ifdef WITH_MESA - window->internal->mesa = OSMesaCreateContextExt(OSMESA_RGBA, 24, 8, 0, nullptr); - DISTRHO_SAFE_ASSERT_RETURN(window->internal->mesa != nullptr,); - - int width = 1228; - int height = 666; - - window->internal->mesaBuffer = new GLubyte[1228 * 666 * 4]; // 4 for RGBA - bool ok = OSMesaMakeCurrent(window->internal->mesa, window->internal->mesaBuffer, GL_UNSIGNED_BYTE, 1228, 666); - - { - int z, s, a; - glGetIntegerv(GL_DEPTH_BITS, &z); - glGetIntegerv(GL_STENCIL_BITS, &s); - glGetIntegerv(GL_ACCUM_RED_BITS, &a); - printf("Depth=%d Stencil=%d Accum=%d\n", z, s, a); - } - - // Set up NanoVG - int nvgFlags = NVG_ANTIALIAS; -// #if defined NANOVG_GL2 - window->vg = nvgCreateGL2(nvgFlags); - window->fbVg = nvgCreateSharedGL2(window->vg, nvgFlags); -// #elif defined NANOVG_GL3 -// window->vg = nvgCreateGL3(nvgFlags); -// #elif defined NANOVG_GLES2 -// window->vg = nvgCreateGLES2(nvgFlags); -// window->fbVg = nvgCreateSharedGLES2(window->vg, nvgFlags); -// #endif -#endif - - // Load default Blendish font - window->uiFont = window->loadFont(asset::system("res/fonts/DejaVuSans.ttf")); - if (window->uiFont != nullptr) - bndSetFont(window->uiFont->handle); - - // Init settings - WindowParametersRestore(window); - - if (APP->scene) { - widget::Widget::ContextCreateEvent e; - APP->scene->onContextCreate(e); - } - -#ifdef WITH_MESA - d_stdout("all good with mesa and GL? %d | %p %p %p", ok, window->internal->mesa, window->vg, window->fbVg); - // window->internal->startThread(); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0, static_cast(width), static_cast(height), 0.0, 0.0, 1.0); - glViewport(0, 0, static_cast(width), static_cast(height)); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - glColor3f(0.5f, 0.2f, 0.9f); - - glBegin(GL_QUADS); - - { - const int x = width / 4; - const int y = height / 4; - const int w = width / 2; - const int h = height / 2; - - glTexCoord2f(0.0f, 0.0f); - glVertex2d(x, y); - - glTexCoord2f(1.0f, 0.0f); - glVertex2d(x+w, y); - - glTexCoord2f(1.0f, 1.0f); - glVertex2d(x+w, y+h); - - glTexCoord2f(0.0f, 1.0f); - glVertex2d(x, y+h); - } - - glEnd(); - - for (int i=0; i<5; ++i) - { - d_stdout("idle %i - before step", i); - window->step(); - d_stdout("idle %i - after step", i); - } - - glFinish(); - - // render to png - d_stdout("idle - before png"); - // flipBitmap(window->internal->mesaBuffer, width, height, 4); - // stbi_write_png("testing.png", 1228, 666, 4, window->internal->mesaBuffer, 666 * 4); - - // Allocate pixel color buffer - uint8_t* pixels = new uint8_t[height * width * 4]; - - // glReadPixels defaults to GL_BACK, but the back-buffer is unstable, so use the front buffer (what the user sees) - glReadBuffer(GL_FRONT); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Write pixels to PNG - flipBitmap(pixels, width, height, 4); - stbi_write_png("testing.png", width, height, 4, pixels, width * 4); - - delete[] pixels; - - d_stdout("idle - after png"); -#endif -} - -void WindowMods(Window* const window, const int mods) -{ - window->internal->mods = mods; -} - Window::~Window() { // internal->stopThread(5000); @@ -319,23 +134,6 @@ Window::~Window() { internal->fontCache.clear(); internal->imageCache.clear(); -#ifdef WITH_MESA -// #if defined NANOVG_GL2 - nvgDeleteGL2(vg); - nvgDeleteGL2(fbVg); -// #elif defined NANOVG_GL3 -// nvgDeleteGL3(vg); -// #elif defined NANOVG_GLES2 -// nvgDeleteGLES2(vg); -// nvgDeleteGLES2(fbVg); -// #endif - - if (internal->mesa != nullptr) - OSMesaDestroyContext(internal->mesa); - - delete[] internal->mesaBuffer; -#endif - delete internal; } @@ -516,99 +314,3 @@ int& Window::fbCount() { } // namespace window } // namespace rack - - -START_NAMESPACE_DISTRHO - -void WindowParametersSave(rack::window::Window* const window) -{ - if (d_isNotEqual(window->internal->params.cableOpacity, rack::settings::cableOpacity)) - { - window->internal->params.cableOpacity = rack::settings::cableOpacity; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterCableOpacity, - rack::settings::cableOpacity); - } - if (d_isNotEqual(window->internal->params.cableTension, rack::settings::cableTension)) - { - window->internal->params.cableTension = rack::settings::cableTension; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterCableTension, - rack::settings::cableTension); - } - if (d_isNotEqual(window->internal->params.rackBrightness, rack::settings::rackBrightness)) - { - window->internal->params.rackBrightness = rack::settings::rackBrightness; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterRackBrightness, - rack::settings::rackBrightness); - } - if (d_isNotEqual(window->internal->params.haloBrightness, rack::settings::haloBrightness)) - { - window->internal->params.haloBrightness = rack::settings::haloBrightness; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterHaloBrightness, - rack::settings::haloBrightness); - } - if (d_isNotEqual(window->internal->params.knobScrollSensitivity, rack::settings::knobScrollSensitivity)) - { - window->internal->params.knobScrollSensitivity = rack::settings::knobScrollSensitivity; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterWheelSensitivity, - rack::settings::knobScrollSensitivity); - } - if (window->internal->params.knobMode != rack::settings::knobMode) - { - window->internal->params.knobMode = rack::settings::knobMode; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterKnobMode, - rack::settings::knobMode); - } - if (window->internal->params.tooltips != rack::settings::tooltips) - { - window->internal->params.tooltips = rack::settings::tooltips; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterShowTooltips, - rack::settings::tooltips); - } - if (window->internal->params.knobScroll != rack::settings::knobScroll) - { - window->internal->params.knobScroll = rack::settings::knobScroll; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterWheelKnobControl, - rack::settings::knobScroll); - } - if (window->internal->params.lockModules != rack::settings::lockModules) - { - window->internal->params.lockModules = rack::settings::lockModules; - if (window->internal->callback != nullptr) - window->internal->callback->WindowParametersChanged(kWindowParameterLockModulePositions, - rack::settings::lockModules); - } -} - -void WindowParametersRestore(rack::window::Window* const window) -{ - rack::settings::cableOpacity = window->internal->params.cableOpacity; - rack::settings::cableTension = window->internal->params.cableTension; - rack::settings::rackBrightness = window->internal->params.rackBrightness; - rack::settings::haloBrightness = window->internal->params.haloBrightness; - rack::settings::knobScrollSensitivity = window->internal->params.knobScrollSensitivity; - rack::settings::knobMode = static_cast(window->internal->params.knobMode); - rack::settings::tooltips = window->internal->params.tooltips; - rack::settings::knobScroll = window->internal->params.knobScroll; - rack::settings::lockModules = window->internal->params.lockModules; -} - -void WindowParametersSetCallback(rack::window::Window* const window, WindowParametersCallback* const callback) -{ - window->internal->callback = callback; -} - -void WindowParametersSetValues(rack::window::Window* const window, const WindowParameters& params) -{ - window->internal->params = params; -} - -END_NAMESPACE_DISTRHO -