diff --git a/Makefile.base.mk b/Makefile.base.mk index efec11d35..55dd9a9b1 100644 --- a/Makefile.base.mk +++ b/Makefile.base.mk @@ -25,30 +25,36 @@ ifneq ($(HAIKU),true) ifneq ($(HURD),true) ifneq ($(LINUX),true) ifneq ($(MACOS),true) +ifneq ($(WASM),true) ifneq ($(WINDOWS),true) ifneq (,$(findstring bsd,$(TARGET_MACHINE))) -BSD=true +BSD = true else ifneq (,$(findstring haiku,$(TARGET_MACHINE))) -HAIKU=true +HAIKU = true else ifneq (,$(findstring linux,$(TARGET_MACHINE))) -LINUX=true +LINUX = true else ifneq (,$(findstring gnu,$(TARGET_MACHINE))) -HURD=true +HURD = true else ifneq (,$(findstring apple,$(TARGET_MACHINE))) -MACOS=true +MACOS = true else ifneq (,$(findstring mingw,$(TARGET_MACHINE))) -WINDOWS=true +WINDOWS = true +else ifneq (,$(findstring msys,$(TARGET_MACHINE))) +WINDOWS = true +else ifneq (,$(findstring wasm,$(TARGET_MACHINE))) +WASM = true else ifneq (,$(findstring windows,$(TARGET_MACHINE))) -WINDOWS=true +WINDOWS = true endif -endif -endif -endif -endif -endif -endif +endif # WINDOWS +endif # WASM +endif # MACOS +endif # LINUX +endif # HURD +endif # HAIKU +endif # BSD # --------------------------------------------------------------------------------------------------------------------- # Auto-detect the processor @@ -56,24 +62,28 @@ endif TARGET_PROCESSOR := $(firstword $(subst -, ,$(TARGET_MACHINE))) ifneq (,$(filter i%86,$(TARGET_PROCESSOR))) -CPU_I386=true -CPU_I386_OR_X86_64=true +CPU_I386 = true +CPU_I386_OR_X86_64 = true +endif +ifneq (,$(filter wasm32,$(TARGET_PROCESSOR))) +CPU_I386 = true +CPU_I386_OR_X86_64 = true endif ifneq (,$(filter x86_64,$(TARGET_PROCESSOR))) -CPU_X86_64=true -CPU_I386_OR_X86_64=true +CPU_X86_64 = true +CPU_I386_OR_X86_64 = true endif ifneq (,$(filter arm%,$(TARGET_PROCESSOR))) -CPU_ARM=true -CPU_ARM_OR_AARCH64=true +CPU_ARM = true +CPU_ARM_OR_AARCH64 = true endif ifneq (,$(filter arm64%,$(TARGET_PROCESSOR))) -CPU_ARM64=true -CPU_ARM_OR_AARCH64=true +CPU_ARM64 = true +CPU_ARM_OR_AARCH64 = true endif ifneq (,$(filter aarch64%,$(TARGET_PROCESSOR))) -CPU_AARCH64=true -CPU_ARM_OR_AARCH64=true +CPU_AARCH64 = true +CPU_ARM_OR_AARCH64 = true endif # --------------------------------------------------------------------------------------------------------------------- @@ -90,47 +100,57 @@ endif # Set LINUX_OR_MACOS ifeq ($(LINUX),true) -LINUX_OR_MACOS=true +LINUX_OR_MACOS = true endif ifeq ($(MACOS),true) -LINUX_OR_MACOS=true +LINUX_OR_MACOS = true endif # --------------------------------------------------------------------------------------------------------------------- -# Set MACOS_OR_WINDOWS and HAIKU_OR_MACOS_OR_WINDOWS +# Set MACOS_OR_WINDOWS, MACOS_OR_WASM_OR_WINDOWS, HAIKU_OR_MACOS_OR_WINDOWS and HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS ifeq ($(HAIKU),true) -HAIKU_OR_MACOS_OR_WINDOWS=true +HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS = true +HAIKU_OR_MACOS_OR_WINDOWS = true endif ifeq ($(MACOS),true) -MACOS_OR_WINDOWS=true -HAIKU_OR_MACOS_OR_WINDOWS=true +HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS = true +HAIKU_OR_MACOS_OR_WINDOWS = true +MACOS_OR_WASM_OR_WINDOWS = true +MACOS_OR_WINDOWS = true +endif + +ifeq ($(WASM),true) +HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS = true +MACOS_OR_WASM_OR_WINDOWS = true endif ifeq ($(WINDOWS),true) -MACOS_OR_WINDOWS=true -HAIKU_OR_MACOS_OR_WINDOWS=true +HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS = true +HAIKU_OR_MACOS_OR_WINDOWS = true +MACOS_OR_WASM_OR_WINDOWS = true +MACOS_OR_WINDOWS = true endif # --------------------------------------------------------------------------------------------------------------------- # Set UNIX ifeq ($(BSD),true) -UNIX=true +UNIX = true endif ifeq ($(HURD),true) -UNIX=true +UNIX = true endif ifeq ($(LINUX),true) -UNIX=true +UNIX = true endif ifeq ($(MACOS),true) -UNIX=true +UNIX = true endif # --------------------------------------------------------------------------------------------------------------------- @@ -140,7 +160,12 @@ BASE_FLAGS = -Wall -Wextra -pipe -MD -MP BASE_OPTS = -O3 -ffast-math -fdata-sections -ffunction-sections ifeq ($(CPU_I386_OR_X86_64),true) -BASE_OPTS += -mtune=generic -msse -msse2 -mfpmath=sse +BASE_OPTS += -mtune=generic -msse -msse2 +ifeq ($(WASM),true) +BASE_OPTS += -msse3 -msimd128 +else +BASE_OPTS += -mfpmath=sse +endif endif ifeq ($(CPU_ARM),true) @@ -151,16 +176,19 @@ endif ifeq ($(MACOS),true) # MacOS linker flags -LINK_OPTS = -fdata-sections -ffunction-sections -Wl,-dead_strip -Wl,-dead_strip_dylibs +LINK_OPTS = -fdata-sections -ffunction-sections -Wl,-dead_strip,-dead_strip_dylibs ifneq ($(SKIP_STRIPPING),true) LINK_OPTS += -Wl,-x endif else # Common linker flags -LINK_OPTS = -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed +LINK_OPTS = -fdata-sections -ffunction-sections -Wl,-O1,--gc-sections ifneq ($(SKIP_STRIPPING),true) LINK_OPTS += -Wl,--strip-all endif +ifneq ($(WASM),true) +LINK_OPTS += -Wl,--as-needed +endif endif ifeq ($(SKIP_STRIPPING),true) @@ -172,7 +200,7 @@ ifeq ($(NOOPT),true) BASE_OPTS = -O2 -ffast-math -fdata-sections -ffunction-sections endif -ifneq ($(MACOS_OR_WINDOWS),true) +ifneq ($(MACOS_OR_WASM_OR_WINDOWS),true) ifneq ($(BSD),true) BASE_FLAGS += -fno-gnu-unique endif @@ -191,6 +219,9 @@ endif ifeq ($(DEBUG),true) BASE_FLAGS += -DDEBUG -O0 -g LINK_OPTS = +ifeq ($(WASM),true) +LINK_OPTS += -sASSERTIONS=1 +endif else BASE_FLAGS += -DNDEBUG $(BASE_OPTS) -fvisibility=hidden CXXFLAGS += -fvisibility-inlines-hidden @@ -210,9 +241,12 @@ BUILD_C_FLAGS = $(BASE_FLAGS) -std=gnu99 $(CFLAGS) BUILD_CXX_FLAGS = $(BASE_FLAGS) -std=gnu++11 $(CXXFLAGS) LINK_FLAGS = $(LINK_OPTS) $(LDFLAGS) -ifneq ($(MACOS),true) +ifeq ($(WASM),true) +# Special flag for emscripten +LINK_FLAGS += -sLLD_REPORT_UNDEFINED +else ifneq ($(MACOS),true) # Not available on MacOS -LINK_FLAGS += -Wl,--no-undefined +LINK_FLAGS += -Wl,--no-undefined endif ifeq ($(MACOS_OLD),true) @@ -252,7 +286,7 @@ endif HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true) -ifeq ($(MACOS_OR_WINDOWS),true) +ifeq ($(MACOS_OR_WASM_OR_WINDOWS),true) HAVE_OPENGL = true else HAVE_OPENGL = $(shell $(PKG_CONFIG) --exists gl && echo true) @@ -297,18 +331,13 @@ HAVE_JACK = true ifeq ($(HAIKU),true) DGL_SYSTEM_LIBS += -lbe -endif - -ifeq ($(MACOS),true) +else ifeq ($(MACOS),true) DGL_SYSTEM_LIBS += -framework Cocoa -framework CoreVideo -endif - -ifeq ($(WINDOWS),true) +else ifeq ($(WASM),true) +else ifeq ($(WINDOWS),true) DGL_SYSTEM_LIBS += -lgdi32 -lcomdlg32 # -lole32 -endif - -ifneq ($(MACOS_OR_WINDOWS),true) +else ifeq ($(HAVE_DBUS),true) DGL_FLAGS += $(shell $(PKG_CONFIG) --cflags dbus-1) -DHAVE_DBUS DGL_SYSTEM_LIBS += $(shell $(PKG_CONFIG) --libs dbus-1) @@ -355,18 +384,18 @@ DGL_FLAGS += -DHAVE_OPENGL ifeq ($(HAIKU),true) OPENGL_FLAGS = $(shell $(PKG_CONFIG) --cflags gl) OPENGL_LIBS = $(shell $(PKG_CONFIG) --libs gl) -endif - -ifeq ($(MACOS),true) +else ifeq ($(MACOS),true) OPENGL_FLAGS = -DGL_SILENCE_DEPRECATION=1 -Wno-deprecated-declarations OPENGL_LIBS = -framework OpenGL +else ifeq ($(WASM),true) +ifneq ($(USE_GLES2),true) +ifneq ($(USE_GLES3),true) +OPENGL_LIBS = -sLEGACY_GL_EMULATION -sGL_UNSAFE_OPTS=0 endif - -ifeq ($(WINDOWS),true) -OPENGL_LIBS = -lopengl32 endif - -ifneq ($(MACOS_OR_WINDOWS),true) +else ifeq ($(WINDOWS),true) +OPENGL_LIBS = -lopengl32 +else OPENGL_FLAGS = $(shell $(PKG_CONFIG) --cflags gl x11) OPENGL_LIBS = $(shell $(PKG_CONFIG) --libs gl x11) endif @@ -378,7 +407,7 @@ endif # --------------------------------------------------------------------------------------------------------------------- # Set Stub specific stuff -ifeq ($(MACOS_OR_WINDOWS),true) +ifeq ($(MACOS_OR_WASM_OR_WINDOWS),true) HAVE_STUB = true else HAVE_STUB = $(HAVE_X11) @@ -425,7 +454,7 @@ JACK_LIBS = $(shell $(PKG_CONFIG) --libs jack) endif endif -ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true) +ifneq ($(HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS),true) SHARED_MEMORY_LIBS = -lrt endif @@ -468,6 +497,14 @@ ifneq ($(WINDOWS_ICON_ID),) BUILD_CXX_FLAGS += -DDGL_WINDOWS_ICON_ID=$(WINDOWS_ICON_ID) endif +ifeq ($(USE_GLES2),true) +BUILD_CXX_FLAGS += -DDGL_USE_GLES -DDGL_USE_GLES2 +endif + +ifeq ($(USE_GLES3),true) +BUILD_CXX_FLAGS += -DDGL_USE_GLES -DDGL_USE_GLES3 +endif + ifeq ($(USE_OPENGL3),true) BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3 endif @@ -487,21 +524,21 @@ endif # --------------------------------------------------------------------------------------------------------------------- # Set app extension -ifeq ($(WINDOWS),true) +ifeq ($(WASM),true) +APP_EXT = .html +else ifeq ($(WINDOWS),true) APP_EXT = .exe endif # --------------------------------------------------------------------------------------------------------------------- # Set shared lib extension -LIB_EXT = .so - ifeq ($(MACOS),true) LIB_EXT = .dylib -endif - -ifeq ($(WINDOWS),true) +else ifeq ($(WINDOWS),true) LIB_EXT = .dll +else +LIB_EXT = .so endif # --------------------------------------------------------------------------------------------------------------------- @@ -550,9 +587,12 @@ features: $(call print_available,HURD) $(call print_available,LINUX) $(call print_available,MACOS) + $(call print_available,WASM) $(call print_available,WINDOWS) + $(call print_available,HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS) $(call print_available,HAIKU_OR_MACOS_OR_WINDOWS) $(call print_available,LINUX_OR_MACOS) + $(call print_available,MACOS_OR_WASM_OR_WINDOWS) $(call print_available,MACOS_OR_WINDOWS) $(call print_available,UNIX) @echo === Detected features diff --git a/Makefile.plugins.mk b/Makefile.plugins.mk index 0aeea9110..147b20688 100644 --- a/Makefile.plugins.mk +++ b/Makefile.plugins.mk @@ -51,7 +51,7 @@ BASE_FLAGS += -DHAVE_PULSEAUDIO endif # always needed -ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true) +ifneq ($(HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS),true) ifneq ($(STATIC_BUILD),true) LINK_FLAGS += -ldl endif @@ -162,6 +162,15 @@ SYMBOLS_LV2 = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/lv2.exp SYMBOLS_VST2 = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/vst2.exp SYMBOLS_VST3 = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/vst3.exp SYMBOLS_SHARED = -Wl,-exported_symbols_list,$(DPF_PATH)/utils/symbols/shared.exp +else ifeq ($(WASM),true) +SYMBOLS_LADSPA = -sEXPORTED_FUNCTIONS="['ladspa_descriptor']" +SYMBOLS_DSSI = -sEXPORTED_FUNCTIONS="['ladspa_descriptor','dssi_descriptor']" +SYMBOLS_LV2DSP = -sEXPORTED_FUNCTIONS="['lv2_descriptor']" +SYMBOLS_LV2UI = -sEXPORTED_FUNCTIONS="['lv2ui_descriptor']" +SYMBOLS_LV2 = -sEXPORTED_FUNCTIONS="['lv2_descriptor','lv2ui_descriptor']" +SYMBOLS_VST2 = -sEXPORTED_FUNCTIONS="['VSTPluginMain']" +SYMBOLS_VST3 = -sEXPORTED_FUNCTIONS="['GetPluginFactory','ModuleEntry','ModuleExit']" +SYMBOLS_SHARED = -sEXPORTED_FUNCTIONS="['createSharedPlugin']" else ifeq ($(WINDOWS),true) SYMBOLS_LADSPA = $(DPF_PATH)/utils/symbols/ladspa.def SYMBOLS_DSSI = $(DPF_PATH)/utils/symbols/dssi.def diff --git a/dgl/src/Application.cpp b/dgl/src/Application.cpp index 5d6529a93..0ec4de820 100644 --- a/dgl/src/Application.cpp +++ b/dgl/src/Application.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2021 Filipe Coelho + * Copyright (C) 2012-2022 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -16,10 +16,21 @@ #include "ApplicationPrivateData.hpp" +#ifdef __EMSCRIPTEN__ +# include +#endif + START_NAMESPACE_DGL // -------------------------------------------------------------------------------------------------------------------- +#ifdef __EMSCRIPTEN__ +static void app_idle(void* const app) +{ + static_cast(app)->idle(); +} +#endif + Application::Application(const bool isStandalone) : pData(new PrivateData(isStandalone)) {} @@ -37,8 +48,12 @@ void Application::exec(const uint idleTimeInMs) { DISTRHO_SAFE_ASSERT_RETURN(pData->isStandalone,); +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop_arg(app_idle, this, 0, true); +#else while (! pData->isQuitting) pData->idle(idleTimeInMs); +#endif } void Application::quit() diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp index 590ae3b57..7bf488360 100644 --- a/dgl/src/ApplicationPrivateData.cpp +++ b/dgl/src/ApplicationPrivateData.cpp @@ -60,7 +60,9 @@ Application::PrivateData::PrivateData(const bool standalone) DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); puglSetWorldHandle(world, this); +#ifndef __EMSCRIPTEN__ puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); +#endif } Application::PrivateData::~PrivateData() diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp index cb78fade9..15c1b6a25 100644 --- a/dgl/src/NanoVG.cpp +++ b/dgl/src/NanoVG.cpp @@ -82,7 +82,9 @@ DGL_EXT(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding) // Include NanoVG OpenGL implementation //#define STB_IMAGE_STATIC -#ifdef DGL_USE_OPENGL3 +#if defined(DGL_USE_GLES2) +# define NANOVG_GLES2_IMPLEMENTATION +#elif defined(DGL_USE_OPENGL3) # define NANOVG_GL3_IMPLEMENTATION #else # define NANOVG_GL2_IMPLEMENTATION @@ -314,7 +316,10 @@ NanoVG::Paint::operator NVGpaint() const noexcept NanoVG::NanoVG(int flags) : fContext(nvgCreateGL(flags)), fInFrame(false), - fIsSubWidget(false) {} + fIsSubWidget(false) +{ + DISTRHO_SAFE_ASSERT(fContext); +} NanoVG::~NanoVG() { diff --git a/dgl/src/OpenGL.cpp b/dgl/src/OpenGL.cpp index 0992cc32c..b74263701 100644 --- a/dgl/src/OpenGL.cpp +++ b/dgl/src/OpenGL.cpp @@ -35,11 +35,23 @@ START_NAMESPACE_DGL // ----------------------------------------------------------------------- -#ifdef DGL_USE_OPENGL3 +#if defined(DGL_USE_GLES2) +static void notImplemented(const char* const name) +{ +// d_stderr2("GLES2 function not implemented: %s", name); +} +#elif defined(DGL_USE_GLES3) +static void notImplemented(const char* const name) +{ + d_stderr2("GLES3 function not implemented: %s", name); +} +#elif defined(DGL_USE_OPENGL3) static void notImplemented(const char* const name) { d_stderr2("OpenGL3 function not implemented: %s", name); } +#else +# define DGL_USE_COMPAT_OPENGL #endif // ----------------------------------------------------------------------- @@ -47,7 +59,7 @@ static void notImplemented(const char* const name) void Color::setFor(const GraphicsContext&, const bool includeAlpha) { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL if (includeAlpha) glColor4f(red, green, blue, alpha); else @@ -62,7 +74,7 @@ void Color::setFor(const GraphicsContext&, const bool includeAlpha) // ----------------------------------------------------------------------- // Line -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL template static void drawLine(const Point& posStart, const Point& posEnd) { @@ -82,7 +94,7 @@ static void drawLine(const Point& posStart, const Point& posEnd) template void Line::draw(const GraphicsContext&, const T width) { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL DISTRHO_SAFE_ASSERT_RETURN(width != 0,); glLineWidth(static_cast(width)); @@ -96,7 +108,7 @@ void Line::draw(const GraphicsContext&, const T width) template void Line::draw() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawLine(posStart, posEnd); #else notImplemented("Line::draw"); @@ -113,7 +125,7 @@ template class Line; // ----------------------------------------------------------------------- // Circle -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL template static void drawCircle(const Point& pos, const uint numSegments, @@ -146,7 +158,7 @@ static void drawCircle(const Point& pos, template void Circle::draw(const GraphicsContext&) { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawCircle(fPos, fNumSegments, fSize, fSin, fCos, false); #else notImplemented("Circle::draw"); @@ -159,7 +171,7 @@ void Circle::drawOutline(const GraphicsContext&, const T lineWidth) DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); glLineWidth(static_cast(lineWidth)); -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawCircle(fPos, fNumSegments, fSize, fSin, fCos, true); #else notImplemented("Circle::drawOutline"); @@ -170,7 +182,7 @@ void Circle::drawOutline(const GraphicsContext&, const T lineWidth) template void Circle::draw() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawCircle(fPos, fNumSegments, fSize, fSin, fCos, false); #else notImplemented("Circle::draw"); @@ -180,7 +192,7 @@ void Circle::draw() template void Circle::drawOutline() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawCircle(fPos, fNumSegments, fSize, fSin, fCos, true); #else notImplemented("Circle::drawOutline"); @@ -197,7 +209,7 @@ template class Circle; // ----------------------------------------------------------------------- // Triangle -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL template static void drawTriangle(const Point& pos1, const Point& pos2, @@ -221,7 +233,7 @@ static void drawTriangle(const Point& pos1, template void Triangle::draw(const GraphicsContext&) { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawTriangle(pos1, pos2, pos3, false); #else notImplemented("Triangle::draw"); @@ -234,7 +246,7 @@ void Triangle::drawOutline(const GraphicsContext&, const T lineWidth) DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); glLineWidth(static_cast(lineWidth)); -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawTriangle(pos1, pos2, pos3, true); #else notImplemented("Triangle::drawOutline"); @@ -245,7 +257,7 @@ void Triangle::drawOutline(const GraphicsContext&, const T lineWidth) template void Triangle::draw() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawTriangle(pos1, pos2, pos3, false); #else notImplemented("Triangle::draw"); @@ -255,7 +267,7 @@ void Triangle::draw() template void Triangle::drawOutline() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawTriangle(pos1, pos2, pos3, true); #else notImplemented("Triangle::drawOutline"); @@ -272,7 +284,7 @@ template class Triangle; // ----------------------------------------------------------------------- // Rectangle -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL template static void drawRectangle(const Rectangle& rect, const bool outline) { @@ -306,7 +318,7 @@ static void drawRectangle(const Rectangle& rect, const bool outline) template void Rectangle::draw(const GraphicsContext&) { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawRectangle(*this, false); #else notImplemented("Rectangle::draw"); @@ -319,7 +331,7 @@ void Rectangle::drawOutline(const GraphicsContext&, const T lineWidth) DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); glLineWidth(static_cast(lineWidth)); -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawRectangle(*this, true); #else notImplemented("Rectangle::drawOutline"); @@ -330,7 +342,7 @@ void Rectangle::drawOutline(const GraphicsContext&, const T lineWidth) template void Rectangle::draw() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawRectangle(*this, false); #else notImplemented("Rectangle::draw"); @@ -340,7 +352,7 @@ void Rectangle::draw() template void Rectangle::drawOutline() { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL drawRectangle(*this, true); #else notImplemented("Rectangle::drawOutline"); @@ -395,14 +407,14 @@ static void drawOpenGLImage(const OpenGLImage& image, const Point& pos, con setupCalled = true; } -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL glColor4f(1.0f, 1.0f, 1.0f, 1.0f); #endif glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textureId); -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL glBegin(GL_QUADS); { @@ -616,21 +628,21 @@ void ImageBaseKnob::onDisplay() if (pData->rotationAngle != 0) { -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL glPushMatrix(); #endif const int w2 = w/2; const int h2 = h/2; -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL glTranslatef(static_cast(w2), static_cast(h2), 0.0f); glRotatef(normValue*static_cast(pData->rotationAngle), 0.0f, 0.0f, 1.0f); #endif Rectangle(-w2, -h2, w, h).draw(context); -#ifndef DGL_USE_OPENGL3 +#ifdef DGL_USE_COMPAT_OPENGL glPopMatrix(); #endif } diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index 963bf83f9..92d90fc7b 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -253,9 +253,6 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo puglSetMatchingBackendForCurrentBuild(view); puglSetHandle(view, this); - // FIXME? - // puglClearMinSize(view); - puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); #if DGL_USE_RGBA diff --git a/dgl/src/nanovg/nanovg_gl.h b/dgl/src/nanovg/nanovg_gl.h index dc541ff24..5894ba42b 100644 --- a/dgl/src/nanovg/nanovg_gl.h +++ b/dgl/src/nanovg/nanovg_gl.h @@ -151,6 +151,9 @@ struct GLNVGtexture { int width, height; int type; int flags; +#if defined NANOVG_GLES2 + unsigned char* data; +#endif }; typedef struct GLNVGtexture GLNVGtexture; @@ -399,7 +402,10 @@ static int glnvg__deleteTexture(GLNVGcontext* gl, int id) for (i = 0; i < gl->textureContext->ntextures; i++) { if (gl->textureContext->textures[i].id == id) { if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0) + { glDeleteTextures(1, &gl->textureContext->textures[i].tex); + free(gl->textureContext->textures[i].data); + } memset(&gl->textureContext->textures[i], 0, sizeof(gl->textureContext->textures[i])); return 1; } @@ -753,7 +759,7 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im } // No mips. if (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) { - printf("Mip-maps is not support for non power-of-two textures (%d x %d)\n", w, h); + printf("Mip-maps is not supported for non power-of-two textures (%d x %d)\n", w, h); imageFlags &= ~NVG_IMAGE_GENERATE_MIPMAPS; } } @@ -783,10 +789,37 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int im switch (type) { case NVG_TEXTURE_BGR: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, data); +#if NANOVG_GLES2 + // GLES2 cannot handle GL_BGR, do local conversion to GL_RGB + tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 3 * w * h); + for (uint32_t i=0; idata[i*3+0] = data[i*3+2]; + tex->data[i*3+1] = data[i*3+1]; + tex->data[i*3+2] = data[i*3+0]; + } + data = tex->data; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, data); +#endif break; case NVG_TEXTURE_BGRA: +#if NANOVG_GLES2 + // GLES2 cannot handle GL_BGRA, do local conversion to GL_RGBA + tex->data = (uint8_t*)malloc(sizeof(uint8_t) * 4 * w * h); + for (uint32_t i=0; idata[i*3+0] = data[i*3+3]; + tex->data[i*3+1] = data[i*3+2]; + tex->data[i*3+2] = data[i*3+1]; + tex->data[i*3+3] = data[i*3+0]; + } + data = tex->data; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data); +#endif break; case NVG_TEXTURE_RGB: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data); diff --git a/dgl/src/pugl-upstream b/dgl/src/pugl-upstream index 6731c86f3..0ea278e7c 160000 --- a/dgl/src/pugl-upstream +++ b/dgl/src/pugl-upstream @@ -1 +1 @@ -Subproject commit 6731c86f3f17712c396316321fffcb415593ff69 +Subproject commit 0ea278e7c911fe83805e58e0d0b002c952e909b1 diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp index 3f63905aa..da7f498cd 100644 --- a/dgl/src/pugl.cpp +++ b/dgl/src/pugl.cpp @@ -51,6 +51,12 @@ # import # include # endif +#elif defined(DISTRHO_OS_WASM) +# include +# include +# ifdef DGL_OPENGL +# include +# endif #elif defined(DISTRHO_OS_WINDOWS) # include # include @@ -66,7 +72,7 @@ # include # include # endif -#else +#elif defined(HAVE_X11) # include # include # include @@ -141,6 +147,12 @@ START_NAMESPACE_DGL # import "pugl-upstream/src/mac_vulkan.m" # endif # pragma clang diagnostic pop +#elif defined(DISTRHO_OS_WASM) +# include "pugl-upstream/src/wasm.c" +# include "pugl-upstream/src/wasm_stub.c" +# ifdef DGL_OPENGL +# include "pugl-upstream/src/wasm_gl.c" +# endif #elif defined(DISTRHO_OS_WINDOWS) # include "pugl-upstream/src/win.c" # include "pugl-upstream/src/win_stub.c" @@ -153,7 +165,7 @@ START_NAMESPACE_DGL # ifdef DGL_VULKAN # include "pugl-upstream/src/win_vulkan.c" # endif -#else +#elif defined(HAVE_X11) # include "pugl-upstream/src/x11.c" # include "pugl-upstream/src/x11_stub.c" # ifdef DGL_CAIRO @@ -204,15 +216,6 @@ void puglSetMatchingBackendForCurrentBuild(PuglView* const view) puglSetBackend(view, puglStubBackend()); } -// -------------------------------------------------------------------------------------------------------------------- -// clear minimum size to 0 - -// void puglClearMinSize(PuglView* const view) -// { -// view->sizeHints[PUGL_MIN_SIZE].width = 0; -// view->sizeHints[PUGL_MIN_SIZE].height = 0; -// } - // -------------------------------------------------------------------------------------------------------------------- // bring view window into the foreground, aka "raise" window @@ -225,7 +228,7 @@ void puglRaiseWindow(PuglView* const view) #elif defined(DISTRHO_OS_WINDOWS) SetForegroundWindow(view->impl->hwnd); SetActiveWindow(view->impl->hwnd); -#else +#elif defined(HAVE_X11) XRaiseWindow(view->world->impl->display, view->impl->win); #endif } @@ -288,7 +291,7 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co } #elif defined(DISTRHO_OS_WINDOWS) // nothing -#else +#elif defined(HAVE_X11) if (const PuglStatus status = updateSizeHints(view)) return status; @@ -320,7 +323,7 @@ void puglSetResizable(PuglView* const view, const bool resizable) : GetWindowLong(hwnd, GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX); SetWindowLong(hwnd, GWL_STYLE, winFlags); } -#else +#elif defined(HAVE_X11) updateSizeHints(view); #endif } @@ -355,6 +358,9 @@ PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height) const NSSize sizePt = [impl->drawView convertSizeFromBacking:sizePx]; [impl->wrapperView setFrameSize:sizePt]; [impl->drawView setFrameSize:sizePt]; +#elif defined(DISTRHO_OS_WASM) + d_stdout("className is %s", view->world->className); + emscripten_set_canvas_element_size(view->world->className, width, height); #elif defined(DISTRHO_OS_WINDOWS) // matches upstream pugl, except we re-enter context after resize if (const HWND hwnd = view->impl->hwnd) @@ -369,7 +375,7 @@ PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height) // make sure to return context back to ourselves puglBackendEnter(view); } -#else +#elif defined(HAVE_X11) // matches upstream pugl, all in one if (const Window window = view->impl->win) { @@ -395,7 +401,9 @@ void puglOnDisplayPrepare(PuglView*) { #ifdef DGL_OPENGL glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +# ifndef DGL_USE_GLES glLoadIdentity(); +# endif #endif } @@ -407,12 +415,16 @@ void puglFallbackOnResize(PuglView* const view) #ifdef DGL_OPENGL glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +# ifndef DGL_USE_GLES glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, static_cast(view->frame.width), static_cast(view->frame.height), 0.0, 0.0, 1.0); glViewport(0, 0, static_cast(view->frame.width), static_cast(view->frame.height)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); +# else + glViewport(0, 0, static_cast(view->frame.width), static_cast(view->frame.height)); +# endif #else return; // unused diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp index 1241e1966..23b62e54f 100644 --- a/dgl/src/pugl.hpp +++ b/dgl/src/pugl.hpp @@ -52,9 +52,6 @@ bool puglBackendLeave(PuglView* view); // DGL specific, assigns backend that matches current DGL build void puglSetMatchingBackendForCurrentBuild(PuglView* view); -// clear minimum size to 0 -void puglClearMinSize(PuglView* view); - // bring view window into the foreground, aka "raise" window void puglRaiseWindow(PuglView* view); diff --git a/distrho/src/DistrhoDefines.h b/distrho/src/DistrhoDefines.h index 94c6a2a4e..e42eec2c0 100644 --- a/distrho/src/DistrhoDefines.h +++ b/distrho/src/DistrhoDefines.h @@ -45,6 +45,8 @@ # define DISTRHO_OS_BSD 1 # elif defined(__GNU__) # define DISTRHO_OS_GNU_HURD 1 +# elif defined(__EMSCRIPTEN__) +# define DISTRHO_OS_WASM 1 # endif #endif diff --git a/pugl-updates-notes.txt b/pugl-updates-notes.txt deleted file mode 100644 index 254e15896..000000000 --- a/pugl-updates-notes.txt +++ /dev/null @@ -1,3 +0,0 @@ - -puglClearMinSize needed? -puglSetWindowSize was used on first show, still needed? diff --git a/tests/Makefile b/tests/Makefile index 9b652ea50..8ddd754fc 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -22,17 +22,25 @@ endif # --------------------------------------------------------------------------------------------------------------------- MANUAL_TESTS = -UNIT_TESTS = Application Color Point +UNIT_TESTS = Color Point ifeq ($(HAVE_CAIRO),true) MANUAL_TESTS += Demo.cairo -UNIT_TESTS += Window.cairo endif + ifeq ($(HAVE_OPENGL),true) MANUAL_TESTS += Demo.opengl MANUAL_TESTS += FileBrowserDialog MANUAL_TESTS += NanoImage MANUAL_TESTS += NanoSubWidgets +endif + +ifneq ($(WASM),true) +UNIT_TESTS += Application +ifeq ($(HAVE_CAIRO),true) +UNIT_TESTS += Window.cairo +endif +ifeq ($(HAVE_OPENGL),true) UNIT_TESTS += Window.opengl endif ifeq ($(HAVE_STUB),true) @@ -41,6 +49,7 @@ endif ifeq ($(HAVE_VULKAN),true) UNIT_TESTS += Window.vulkan endif +endif MANUAL_TARGETS = $(MANUAL_TESTS:%=../build/tests/%$(APP_EXT)) UNIT_TARGET = $(UNIT_TESTS:%=../build/tests/%$(APP_EXT)) @@ -54,6 +63,13 @@ all: $(MANUAL_TARGETS) $(UNIT_TARGET) # --------------------------------------------------------------------------------------------------------------------- +Demo.opengl: ../build/tests/Demo.opengl$(APP_EXT) +FileBrowserDialog: ../build/tests/FileBrowserDialog$(APP_EXT) +NanoImage: ../build/tests/NanoImage$(APP_EXT) +NanoSubWidgets: ../build/tests/NanoSubWidgets$(APP_EXT) + +# --------------------------------------------------------------------------------------------------------------------- + define RUN_TEST ${1} @@ -154,6 +170,8 @@ clean: # --------------------------------------------------------------------------------------------------------------------- +.PHONY: Demo.opengl FileBrowserDialog NanoImage NanoSubWidgets + -include $(ALL_OBJS:%.o=%.d) # --------------------------------------------------------------------------------------------------------------------- diff --git a/tests/NanoImage.cpp b/tests/NanoImage.cpp index 9b719d1f0..bd6bbb404 100644 --- a/tests/NanoImage.cpp +++ b/tests/NanoImage.cpp @@ -38,8 +38,6 @@ class NanoImageExample : public NanoStandaloneWindow, static const int kImg2max = 500-CatPics::cat2Width; static const int kImg3max = 400-CatPics::cat3Height; - static const int kImgFlags = IMAGE_GENERATE_MIPMAPS | IMAGE_REPEAT_X; - int imgTop1st, imgTop2nd, imgTop3rd; int img1x, img2x, img3y; bool img1rev, img2rev, img3rev; @@ -57,9 +55,9 @@ class NanoImageExample : public NanoStandaloneWindow, img1rev(false), img2rev(true), img3rev(true), - img1(createImageFromRawMemory(CatPics::cat1Width, CatPics::cat1Height, (uchar*)CatPics::cat1Data, kImgFlags, kImageFormatBGR)), - img2(createImageFromRawMemory(CatPics::cat2Width, CatPics::cat2Height, (uchar*)CatPics::cat2Data, kImgFlags, kImageFormatBGR)), - img3(createImageFromRawMemory(CatPics::cat3Width, CatPics::cat3Height, (uchar*)CatPics::cat3Data, kImgFlags, kImageFormatBGR)) + img1(createImageFromRawMemory(CatPics::cat1Width, CatPics::cat1Height, (uchar*)CatPics::cat1Data, 0, kImageFormatBGR)), + img2(createImageFromRawMemory(CatPics::cat2Width, CatPics::cat2Height, (uchar*)CatPics::cat2Data, 0, kImageFormatBGR)), + img3(createImageFromRawMemory(CatPics::cat3Width, CatPics::cat3Height, (uchar*)CatPics::cat3Data, 0, kImageFormatBGR)) { DISTRHO_SAFE_ASSERT(img1.isValid()); DISTRHO_SAFE_ASSERT(img2.isValid()); diff --git a/tests/widgets/ResizeHandle.hpp b/tests/widgets/ResizeHandle.hpp index 99a164a15..a4067d159 100644 --- a/tests/widgets/ResizeHandle.hpp +++ b/tests/widgets/ResizeHandle.hpp @@ -62,7 +62,7 @@ class ResizeHandle : public TopLevelWidget const double lineWidth = 1.0 * getScaleFactor(); #if defined(DGL_OPENGL) && !defined(DGL_USE_OPENGL3) - glMatrixMode(GL_MODELVIEW); +// glMatrixMode(GL_MODELVIEW); #endif // draw white lines, 1px wide