From 003a33d7088d58a4a6a5aa0946328b3b092b8dd5 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 13 Jan 2024 02:32:42 +0100 Subject: GLX GLES support in sokol_app --- source/saw/_dep.c | 2 +- source/saw/main.c | 31 ++++++++++++++++++++++--------- source/sokol/sokol_app.h | 45 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 63 insertions(+), 15 deletions(-) (limited to 'source') diff --git a/source/saw/_dep.c b/source/saw/_dep.c index c4c20ee..929d3fd 100644 --- a/source/saw/_dep.c +++ b/source/saw/_dep.c @@ -1,4 +1,4 @@ -#ifdef __EMSCRIPTEN__ +#if defined(__EMSCRIPTEN__) || defined(__linux__) # define SOKOL_GLES3 # define NANOVG_GLES3 1 #else diff --git a/source/saw/main.c b/source/saw/main.c index 883e841..1252213 100644 --- a/source/saw/main.c +++ b/source/saw/main.c @@ -5,7 +5,7 @@ #include "../kit/secure_random.h" #include "../kit/file.h" -#ifdef __EMSCRIPTEN__ +#if defined(__EMSCRIPTEN__) || defined(__linux__) # include # define SOKOL_GLES3 # define NANOVG_GLES3 1 @@ -1613,7 +1613,7 @@ static void saw_frame(void) { glViewport(0, 0, frame_width, frame_height); glClearColor(.15f, .12f, .10f, 1.f); -#ifdef __EMSCRIPTEN__ +#if defined(__EMSCRIPTEN__) || defined(__linux__) glClearDepthf(1.f); #else glClearDepth(1.); @@ -1960,6 +1960,16 @@ char const *__lsan_default_suppressions() { return "leak:nvidia"; } +static void log_(const char *tag, uint32_t log_level, + uint32_t log_item_id, const char *message_or_null, + uint32_t line_nr, const char *filename_or_null, + void *user_data) { + if (message_or_null != NULL) + printf("%s", message_or_null); + printf("\n"); + fflush(stdout); +} + sapp_desc sokol_main(i32 argc, char **argv) { i8 print_version = 0; @@ -1987,12 +1997,15 @@ sapp_desc sokol_main(i32 argc, char **argv) { fflush(stdout); return (sapp_desc) { - .window_title = "Saw", - .width = 1280, - .height = 720, - .init_cb = saw_init, - .frame_cb = saw_frame, - .cleanup_cb = saw_cleanup, - .event_cb = saw_event, + .window_title = "Saw", + .width = 1280, + .height = 720, + .init_cb = saw_init, + .frame_cb = saw_frame, + .cleanup_cb = saw_cleanup, + .event_cb = saw_event, + .gl_major_version = 3, + .gl_minor_version = 2, + .logger.func = log_, }; } diff --git a/source/sokol/sokol_app.h b/source/sokol/sokol_app.h index d3cb5a9..fdaed1f 100644 --- a/source/sokol/sokol_app.h +++ b/source/sokol/sokol_app.h @@ -1545,6 +1545,7 @@ typedef struct sapp_allocator { _SAPP_LOGITEM_XMACRO(LINUX_GLX_NO_SUITABLE_GLXFBCONFIG, "failed to find a suitable GLXFBConfig") \ _SAPP_LOGITEM_XMACRO(LINUX_GLX_GET_VISUAL_FROM_FBCONFIG_FAILED, "glXGetVisualFromFBConfig failed") \ _SAPP_LOGITEM_XMACRO(LINUX_GLX_REQUIRED_EXTENSIONS_MISSING, "GLX extensions ARB_create_context and ARB_create_context_profile missing") \ + _SAPP_LOGITEM_XMACRO(LINUX_GLX_ES_REQUIRED_EXTENSIONS_MISSING, "GLX extension EXT_create_context_es_profile missing") \ _SAPP_LOGITEM_XMACRO(LINUX_GLX_CREATE_CONTEXT_FAILED, "Failed to create GL context via glXCreateContextAttribsARB") \ _SAPP_LOGITEM_XMACRO(LINUX_GLX_CREATE_WINDOW_FAILED, "glXCreateWindow() failed") \ _SAPP_LOGITEM_XMACRO(LINUX_X11_CREATE_WINDOW_FAILED, "XCreateWindow() failed") \ @@ -1894,8 +1895,8 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); } // NOTE: the pixel format values *must* be compatible with sg_pixel_format #define _SAPP_PIXELFORMAT_RGBA8 (23) #define _SAPP_PIXELFORMAT_BGRA8 (28) -#define _SAPP_PIXELFORMAT_DEPTH (42) -#define _SAPP_PIXELFORMAT_DEPTH_STENCIL (43) +#define _SAPP_PIXELFORMAT_DEPTH (43) +#define _SAPP_PIXELFORMAT_DEPTH_STENCIL (44) #if defined(_SAPP_MACOS) || defined(_SAPP_IOS) // this is ARC compatible @@ -1955,11 +1956,11 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); } #elif defined(__linux__) || defined(__unix__) /* Linux */ #define _SAPP_LINUX (1) - #if defined(SOKOL_GLCORE33) + #if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3) #if !defined(SOKOL_FORCE_EGL) #define _SAPP_GLX (1) #endif - #elif !defined(SOKOL_GLES3) + #else #error("sokol_app.h: unknown 3D API selected for Linux, must be SOKOL_GLCORE33, SOKOL_GLES3") #endif #else @@ -2606,6 +2607,7 @@ typedef struct { #define GLX_SAMPLES 0x186a1 #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 @@ -2723,6 +2725,8 @@ typedef struct { bool ARB_multisample; bool ARB_create_context; bool ARB_create_context_profile; + bool EXT_create_context_es_profile; + bool EXT_create_context_es2_profile; } _sapp_glx_t; #else @@ -3560,6 +3564,7 @@ _SOKOL_PRIVATE void _sapp_macos_update_dimensions(void) { else { _sapp.dpi_scale = 1.0f; } + _sapp.macos.view.layer.contentsScale = _sapp.dpi_scale; // NOTE: needed because we set layerContentsPlacement to a non-scaling value in windowWillStartLiveResize. const NSRect bounds = [_sapp.macos.view bounds]; _sapp.window_width = (int)roundf(bounds.size.width); _sapp.window_height = (int)roundf(bounds.size.height); @@ -3915,6 +3920,24 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { } } +#if defined(SOKOL_METAL) +- (void)windowWillStartLiveResize:(NSNotification *)notification { + // Work around the MTKView resizing glitch by "anchoring" the layer to the window corner opposite + // to the currently manipulated corner (or edge). This prevents the content stretching back and + // forth during resizing. This is a workaround for this issue: https://github.com/floooh/sokol/issues/700 + // Can be removed if/when migrating to CAMetalLayer: https://github.com/floooh/sokol/issues/727 + bool resizing_from_left = _sapp.mouse.x < _sapp.window_width/2; + bool resizing_from_top = _sapp.mouse.y < _sapp.window_height/2; + NSViewLayerContentsPlacement placement; + if (resizing_from_left) { + placement = resizing_from_top ? NSViewLayerContentsPlacementBottomRight : NSViewLayerContentsPlacementTopRight; + } else { + placement = resizing_from_top ? NSViewLayerContentsPlacementBottomLeft : NSViewLayerContentsPlacementTopLeft; + } + _sapp.macos.view.layerContentsPlacement = placement; +} +#endif + - (void)windowDidResize:(NSNotification*)notification { _SOKOL_UNUSED(notification); _sapp_macos_update_dimensions(); @@ -5873,7 +5896,7 @@ int main(int argc, char* argv[]) { // ██████ ███████ ██ ██ ███████ ███████ ██ ███████ ██ ██ ███████ // // >>gl helpers -#if defined(SOKOL_GLCORE33) +#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3) typedef struct { int red_bits; int green_bits; @@ -9688,6 +9711,8 @@ _SOKOL_PRIVATE void _sapp_glx_init() { _sapp.glx.ARB_create_context = 0 != _sapp.glx.CreateContextAttribsARB; } _sapp.glx.ARB_create_context_profile = _sapp_glx_extsupported("GLX_ARB_create_context_profile", exts); + _sapp.glx.EXT_create_context_es_profile = _sapp_glx_extsupported("GLX_EXT_create_context_es_profile", exts); + _sapp.glx.EXT_create_context_es2_profile = _sapp_glx_extsupported("GLX_EXT_create_context_es2_profile", exts); } _SOKOL_PRIVATE int _sapp_glx_attrib(GLXFBConfig fbconfig, int attrib) { @@ -9791,12 +9816,22 @@ _SOKOL_PRIVATE void _sapp_glx_create_context(void) { if (!(_sapp.glx.ARB_create_context && _sapp.glx.ARB_create_context_profile)) { _SAPP_PANIC(LINUX_GLX_REQUIRED_EXTENSIONS_MISSING); } +#if defined(SOKOL_GLES3) + // At least one of extension strings must be exported + if (!(_sapp.glx.EXT_create_context_es_profile || _sapp.glx.EXT_create_context_es2_profile)) { + _SAPP_PANIC(LINUX_GLX_ES_REQUIRED_EXTENSIONS_MISSING); + } +#endif _sapp_x11_grab_error_handler(); const int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, _sapp.desc.gl_major_version, GLX_CONTEXT_MINOR_VERSION_ARB, _sapp.desc.gl_minor_version, + #if defined(SOKOL_GLES3) + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT, + #else GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + #endif 0, 0 }; _sapp.glx.ctx = _sapp.glx.CreateContextAttribsARB(_sapp.x11.display, native, NULL, True, attribs); -- cgit v1.2.3