diff options
| author | Andre Weissflog <floooh@gmail.com> | 2022-09-25 17:01:35 +0200 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2022-09-25 17:01:35 +0200 |
| commit | 40eeea226daa8068b38b847c71dccd7c36724c6f (patch) | |
| tree | 174d7dc4dfa1a2ba2fdc94f9c5a644d7ef53eb73 | |
| parent | 4238be9d53f7a817f7ddf1b8d10560142052c6c7 (diff) | |
| parent | 0885d519d22c438b0c1d7f02f399db87cf463ecd (diff) | |
Merge branch 'billzez-egl'
| -rw-r--r-- | .github/workflows/gen_bindings.yml | 8 | ||||
| -rw-r--r-- | .github/workflows/main.yml | 2 | ||||
| -rw-r--r-- | CHANGELOG.md | 8 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | sokol_app.h | 309 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 11 | ||||
| -rwxr-xr-x | tests/analyze_linux.sh | 3 | ||||
| -rw-r--r-- | tests/test_common.sh | 10 | ||||
| -rwxr-xr-x | tests/test_linux.sh | 4 |
9 files changed, 301 insertions, 57 deletions
diff --git a/.github/workflows/gen_bindings.yml b/.github/workflows/gen_bindings.yml index 8ec29779..746b9baf 100644 --- a/.github/workflows/gen_bindings.yml +++ b/.github/workflows/gen_bindings.yml @@ -31,7 +31,7 @@ jobs: - name: prepare run: | sudo apt-get update - sudo apt-get install libglu1-mesa-dev mesa-common-dev xorg-dev libasound-dev + sudo apt-get install libgl1-mesa-dev libegl1-mesa-dev mesa-common-dev xorg-dev libasound-dev - name: test_linux run: | cd tests @@ -99,7 +99,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install libglu1-mesa-dev mesa-common-dev xorg-dev libasound-dev + sudo apt-get install libgl1-mesa-dev libegl1-mesa-dev mesa-common-dev xorg-dev libasound-dev - name: build run: zig build @@ -122,7 +122,7 @@ jobs: name: prepare run: | sudo apt-get update - sudo apt-get install libglu1-mesa-dev mesa-common-dev xorg-dev libasound-dev + sudo apt-get install libgl1-mesa-dev libegl1-mesa-dev mesa-common-dev xorg-dev libasound-dev - name: build run: | nimble install -Y @@ -148,7 +148,7 @@ jobs: name: prepare-linux run: | sudo apt-get update - sudo apt-get install libglu1-mesa-dev mesa-common-dev xorg-dev libasound-dev + sudo apt-get install libgl1-mesa-dev libegl1-mesa-dev mesa-common-dev xorg-dev libasound-dev curl -L https://github.com/odin-lang/Odin/releases/download/dev-2022-08/odin-ubuntu-amd64-dev-2022-08.zip --output odin.zip unzip odin.zip chmod a+x odin diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1081dd5a..d344aba3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,7 +37,7 @@ jobs: - name: prepare run: | sudo apt-get update - sudo apt-get install libglu1-mesa-dev mesa-common-dev xorg-dev libasound-dev + sudo apt-get install libgl1-mesa-dev libegl1-mesa-dev mesa-common-dev xorg-dev libasound-dev - name: test_linux run: | cd tests diff --git a/CHANGELOG.md b/CHANGELOG.md index e566dcf8..356af8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ## Updates +- **25-Sep-2022**: sokol_app.h on Linux now optionally supports EGL instead of + GLX for the window system glue code and can create a GLES2 or GLES3 context + instead of a 'desktop GL' context. + To get EGL+GLES2/GLES3, just define SOKOL_GLES2 or SOKOL_GLES3 to compile the + implementation. To get EGL+GL, define SOKOL_GLCORE33 *and* SOKOL_FORCE_EGL. + By default, defining just SOKOL_GLCORE33 uses GLX for the window system glue + (just as before). + - **10-Sep-2022**: sokol_app.h and sokol_args.h has been fixed for Emscripten 3.21, those headers used the Emscripten Javascript helper function ```ccall()``` which is now part of the 'legacy runtime' and causes linker errors. Instead of ```ccall()``` sokol_app.h and sokol_args.h @@ -4,7 +4,8 @@ Simple [STB-style](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt) cross-platform libraries for C and C++, written in C. -[**See what's new**](https://github.com/floooh/sokol/blob/master/CHANGELOG.md) (**10-Sep-2022** an important compatibility fix for Emscripten 3.21 in sokol_app.h and sokol_args.h) +[**See what's new**](https://github.com/floooh/sokol/blob/master/CHANGELOG.md) (**25-Sep-2022** sokol_app.h: EGL/GLES2/GLES3 +support on Linux) [](/../../actions/workflows/main.yml) [](/../../actions/workflows/gen_bindings.yml) [](https://github.com/floooh/sokol-zig/actions/workflows/main.yml) [](https://github.com/floooh/sokol-nim/actions/workflows/main.yml) [](https://github.com/floooh/sokol-odin/actions/workflows/main.yml) diff --git a/sokol_app.h b/sokol_app.h index 201acfc6..97b98714 100644 --- a/sokol_app.h +++ b/sokol_app.h @@ -50,6 +50,9 @@ On Windows, SOKOL_DLL will define SOKOL_APP_API_DECL as __declspec(dllexport) or __declspec(dllimport) as needed. + On Linux, SOKOL_GLCORE33 can use either GLX or EGL. + GLX is default, set SOKOL_FORCE_EGL to override. + For example code, see https://github.com/floooh/sokol-samples/tree/master/sapp Portions of the Windows and Linux GL initialization, event-, icon- etc... code @@ -63,7 +66,8 @@ - on macOS with GL: Cocoa, QuartzCore, OpenGL - on iOS with Metal: Foundation, UIKit, Metal, MetalKit - on iOS with GL: Foundation, UIKit, OpenGLES, GLKit - - on Linux: X11, Xi, Xcursor, GL, dl, pthread, m(?) + - on Linux with EGL: X11, Xi, Xcursor, EGL, GL (or GLESv2), dl, pthread, m(?) + - on Linux with GLX: X11, Xi, Xcursor, GL, dl, pthread, m(?) - on Android: GLESv3, EGL, log, android - on Windows with the MSVC or Clang toolchains: no action needed, libs are defined in-source via pragma-comment-lib - on Windows with MINGW/MSYS2 gcc: compile with '-mwin32' so that _WIN32 is defined @@ -89,55 +93,56 @@ - creates a window and 3D-API context/device with a 'default framebuffer' - makes the rendered frame visible - provides keyboard-, mouse- and low-level touch-events - - platforms: MacOS, iOS, HTML5, Win32, Linux, Android (TODO: RaspberryPi) + - platforms: MacOS, iOS, HTML5, Win32, Linux/RaspberryPi, Android - 3D-APIs: Metal, D3D11, GL3.2, GLES2, GLES3, WebGL, WebGL2 FEATURE/PLATFORM MATRIX ======================= - | Windows | macOS | Linux | iOS | Android | UWP | Raspi | HTML5 - --------------------+---------+-------+-------+-------+---------+------+-------+------- - gl 3.x | YES | YES | YES | --- | --- | --- | --- | --- - gles2/webgl | --- | --- | --- | YES | YES | --- | TODO | YES - gles3/webgl2 | --- | --- | --- | YES | YES | --- | --- | YES - metal | --- | YES | --- | YES | --- | --- | --- | --- - d3d11 | YES | --- | --- | --- | --- | YES | --- | --- - KEY_DOWN | YES | YES | YES | SOME | TODO | YES | TODO | YES - KEY_UP | YES | YES | YES | SOME | TODO | YES | TODO | YES - CHAR | YES | YES | YES | YES | TODO | YES | TODO | YES - MOUSE_DOWN | YES | YES | YES | --- | --- | YES | TODO | YES - MOUSE_UP | YES | YES | YES | --- | --- | YES | TODO | YES - MOUSE_SCROLL | YES | YES | YES | --- | --- | YES | TODO | YES - MOUSE_MOVE | YES | YES | YES | --- | --- | YES | TODO | YES - MOUSE_ENTER | YES | YES | YES | --- | --- | YES | TODO | YES - MOUSE_LEAVE | YES | YES | YES | --- | --- | YES | TODO | YES - TOUCHES_BEGAN | --- | --- | --- | YES | YES | TODO | --- | YES - TOUCHES_MOVED | --- | --- | --- | YES | YES | TODO | --- | YES - TOUCHES_ENDED | --- | --- | --- | YES | YES | TODO | --- | YES - TOUCHES_CANCELLED | --- | --- | --- | YES | YES | TODO | --- | YES - RESIZED | YES | YES | YES | YES | YES | YES | --- | YES - ICONIFIED | YES | YES | YES | --- | --- | YES | --- | --- - RESTORED | YES | YES | YES | --- | --- | YES | --- | --- - FOCUSED | YES | YES | YES | --- | --- | --- | --- | YES - UNFOCUSED | YES | YES | YES | --- | --- | --- | --- | YES - SUSPENDED | --- | --- | --- | YES | YES | YES | --- | TODO - RESUMED | --- | --- | --- | YES | YES | YES | --- | TODO - QUIT_REQUESTED | YES | YES | YES | --- | --- | --- | TODO | YES - IME | TODO | TODO? | TODO | ??? | TODO | --- | ??? | ??? - key repeat flag | YES | YES | YES | --- | --- | YES | TODO | YES - windowed | YES | YES | YES | --- | --- | YES | TODO | YES - fullscreen | YES | YES | YES | YES | YES | YES | TODO | --- - mouse hide | YES | YES | YES | --- | --- | YES | TODO | YES - mouse lock | YES | YES | YES | --- | --- | TODO | TODO | YES - set cursor type | YES | YES | YES | --- | --- | YES | TODO | YES - screen keyboard | --- | --- | --- | YES | TODO | TODO | --- | YES - swap interval | YES | YES | YES | YES | TODO | --- | TODO | YES - high-dpi | YES | YES | TODO | YES | YES | YES | TODO | YES - clipboard | YES | YES | TODO | --- | --- | TODO | --- | YES - MSAA | YES | YES | YES | YES | YES | TODO | TODO | YES - drag'n'drop | YES | YES | YES | --- | --- | TODO | TODO | YES - window icon | YES | YES(1)| YES | --- | --- | TODO | TODO | YES + | Windows | macOS | Linux | iOS | Android | UWP | HTML5 + --------------------+---------+-------+-------+-------+---------+------+------- + gl 3.x | YES | YES | YES | --- | --- | --- | --- + gles2/webgl | --- | --- | YES(2)| YES | YES | --- | YES + gles3/webgl2 | --- | --- | YES(2)| YES | YES | --- | YES + metal | --- | YES | --- | YES | --- | --- | --- + d3d11 | YES | --- | --- | --- | --- | YES | --- + KEY_DOWN | YES | YES | YES | SOME | TODO | YES | YES + KEY_UP | YES | YES | YES | SOME | TODO | YES | YES + CHAR | YES | YES | YES | YES | TODO | YES | YES + MOUSE_DOWN | YES | YES | YES | --- | --- | YES | YES + MOUSE_UP | YES | YES | YES | --- | --- | YES | YES + MOUSE_SCROLL | YES | YES | YES | --- | --- | YES | YES + MOUSE_MOVE | YES | YES | YES | --- | --- | YES | YES + MOUSE_ENTER | YES | YES | YES | --- | --- | YES | YES + MOUSE_LEAVE | YES | YES | YES | --- | --- | YES | YES + TOUCHES_BEGAN | --- | --- | --- | YES | YES | TODO | YES + TOUCHES_MOVED | --- | --- | --- | YES | YES | TODO | YES + TOUCHES_ENDED | --- | --- | --- | YES | YES | TODO | YES + TOUCHES_CANCELLED | --- | --- | --- | YES | YES | TODO | YES + RESIZED | YES | YES | YES | YES | YES | YES | YES + ICONIFIED | YES | YES | YES | --- | --- | YES | --- + RESTORED | YES | YES | YES | --- | --- | YES | --- + FOCUSED | YES | YES | YES | --- | --- | --- | YES + UNFOCUSED | YES | YES | YES | --- | --- | --- | YES + SUSPENDED | --- | --- | --- | YES | YES | YES | TODO + RESUMED | --- | --- | --- | YES | YES | YES | TODO + QUIT_REQUESTED | YES | YES | YES | --- | --- | --- | YES + IME | TODO | TODO? | TODO | ??? | TODO | --- | ??? + key repeat flag | YES | YES | YES | --- | --- | YES | YES + windowed | YES | YES | YES | --- | --- | YES | YES + fullscreen | YES | YES | YES | YES | YES | YES | --- + mouse hide | YES | YES | YES | --- | --- | YES | YES + mouse lock | YES | YES | YES | --- | --- | TODO | YES + set cursor type | YES | YES | YES | --- | --- | YES | YES + screen keyboard | --- | --- | --- | YES | TODO | TODO | YES + swap interval | YES | YES | YES | YES | TODO | --- | YES + high-dpi | YES | YES | TODO | YES | YES | YES | YES + clipboard | YES | YES | TODO | --- | --- | TODO | YES + MSAA | YES | YES | YES | YES | YES | TODO | YES + drag'n'drop | YES | YES | YES | --- | --- | TODO | YES + window icon | YES | YES(1)| YES | --- | --- | TODO | YES (1) macOS has no regular window icons, instead the dock icon is changed + (2) supported with EGL only (not GLX) STEP BY STEP ============ @@ -1586,6 +1591,11 @@ SOKOL_APP_API_DECL const char* sapp_get_dropped_file_path(int index); /* special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub) */ SOKOL_APP_API_DECL void sapp_run(const sapp_desc* desc); +/* EGL: get EGLDisplay object */ +SOKOL_APP_API_DECL const void* sapp_egl_get_display(void); +/* EGL: get EGLContext object */ +SOKOL_APP_API_DECL const void* sapp_egl_get_context(void); + /* GL: return true when GLES2 fallback is active (to detect fallback from GLES3) */ SOKOL_APP_API_DECL bool sapp_gles2(void); @@ -1721,8 +1731,12 @@ 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) - #error("sokol_app.h: unknown 3D API selected for Linux, must be SOKOL_GLCORE33") + #if defined(SOKOL_GLCORE33) + #if !defined(SOKOL_FORCE_EGL) + #define _SAPP_GLX (1) + #endif + #elif !defined(SOKOL_GLES3) && !defined(SOKOL_GLES2) + #error("sokol_app.h: unknown 3D API selected for Linux, must be SOKOL_GLCORE33, SOKOL_GLES3 or SOKOL_GLES2") #endif #else #error "sokol_app.h: Unknown platform" @@ -1899,6 +1913,9 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); } #include <X11/Xcursor/Xcursor.h> #include <X11/cursorfont.h> /* XC_* font cursors */ #include <X11/Xmd.h> /* CARD32 */ + #if !defined(_SAPP_GLX) + #include <EGL/egl.h> + #endif #include <dlfcn.h> /* dlopen, dlsym, dlclose */ #include <limits.h> /* LONG_MAX */ #include <pthread.h> /* only used a linker-guard, search for _sapp_linux_run() and see first comment */ @@ -2503,6 +2520,8 @@ typedef struct { _sapp_xdnd_t xdnd; } _sapp_x11_t; +#if defined(_SAPP_GLX) + typedef struct { void* libgl; int major; @@ -2541,6 +2560,16 @@ typedef struct { bool ARB_create_context_profile; } _sapp_glx_t; +#else + +typedef struct { + EGLDisplay display; + EGLContext context; + EGLSurface surface; +} _sapp_egl_t; + +#endif // _SAPP_GLX + #endif // _SAPP_LINUX /*== COMMON DECLARATIONS =====================================================*/ @@ -2643,7 +2672,11 @@ typedef struct { _sapp_android_t android; #elif defined(_SAPP_LINUX) _sapp_x11_t x11; - _sapp_glx_t glx; + #if defined(_SAPP_GLX) + _sapp_glx_t glx; + #else + _sapp_egl_t egl; + #endif #endif char html5_canvas_selector[_SAPP_MAX_TITLE_LENGTH]; char window_title[_SAPP_MAX_TITLE_LENGTH]; /* UTF-8 */ @@ -10183,6 +10216,8 @@ _SOKOL_PRIVATE void _sapp_x11_query_system_dpi(void) { } } +#if defined(_SAPP_GLX) + _SOKOL_PRIVATE bool _sapp_glx_has_ext(const char* ext, const char* extensions) { SOKOL_ASSERT(ext); const char* start = extensions; @@ -10442,6 +10477,8 @@ _SOKOL_PRIVATE void _sapp_glx_swapinterval(int interval) { } } +#endif /* _SAPP_GLX */ + _SOKOL_PRIVATE void _sapp_x11_send_event(Atom type, int a, int b, int c, int d, int e) { XEvent event; _sapp_clear(&event, sizeof(event)); @@ -11463,6 +11500,147 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) { } } +#if !defined(_SAPP_GLX) + +_SOKOL_PRIVATE void _sapp_egl_init(void) { +#if defined(SOKOL_GLCORE33) + if (!eglBindAPI(EGL_OPENGL_API)) { + _sapp_fail("EGL: failed to bind API"); + } +#else + if (!eglBindAPI(EGL_OPENGL_ES_API)) { + _sapp_fail("EGL: failed to bind API"); + } +#endif + + _sapp.egl.display = eglGetDisplay((EGLNativeDisplayType)_sapp.x11.display); + if (EGL_NO_DISPLAY == _sapp.egl.display) { + _sapp_fail("EGL: failed to get display"); + } + + EGLint major, minor; + if (!eglInitialize(_sapp.egl.display, &major, &minor)) { + _sapp_fail("EGL: failed to initialize"); + } + + EGLint sample_count = _sapp.desc.sample_count > 1 ? _sapp.desc.sample_count : 0; + EGLint alpha_size = _sapp.desc.alpha ? 8 : 0; + const EGLint config_attrs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + #if defined(SOKOL_GLCORE33) + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + #elif defined(SOKOL_GLES3) + EGL_RENDERABLE_TYPE, _sapp.desc.gl_force_gles2 ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_ES3_BIT, + #else + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + #endif + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, alpha_size, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, _sapp.desc.sample_count > 1 ? 1 : 0, + EGL_SAMPLES, sample_count, + EGL_NONE, + }; + + EGLConfig egl_configs[32]; + EGLint config_count; + if (!eglChooseConfig(_sapp.egl.display, config_attrs, egl_configs, 32, &config_count) || config_count == 0) { + _sapp_fail("EGL: no available configs"); + } + + EGLConfig config = egl_configs[0]; + for (int i = 0; i < config_count; ++i) { + EGLConfig c = egl_configs[i]; + EGLint r, g, b, a, d, s, n; + if (eglGetConfigAttrib(_sapp.egl.display, c, EGL_RED_SIZE, &r) && + eglGetConfigAttrib(_sapp.egl.display, c, EGL_GREEN_SIZE, &g) && + eglGetConfigAttrib(_sapp.egl.display, c, EGL_BLUE_SIZE, &b) && + eglGetConfigAttrib(_sapp.egl.display, c, EGL_ALPHA_SIZE, &a) && + eglGetConfigAttrib(_sapp.egl.display, c, EGL_DEPTH_SIZE, &d) && + eglGetConfigAttrib(_sapp.egl.display, c, EGL_STENCIL_SIZE, &s) && + eglGetConfigAttrib(_sapp.egl.display, c, EGL_SAMPLES, &n) && + (r == 8) && (g == 8) && (b == 8) && (a == alpha_size) && (d == 24) && (s == 8) && (n == sample_count)) { + config = c; + break; + } + } + + EGLint visual_id; + if (!eglGetConfigAttrib(_sapp.egl.display, config, EGL_NATIVE_VISUAL_ID, &visual_id)) { + _sapp_fail("EGL: failed to get native visual"); + } + + XVisualInfo visual_info_template; + _sapp_clear(&visual_info_template, sizeof(visual_info_template)); + visual_info_template.visualid = (VisualID)visual_id; + + int num_visuals; + XVisualInfo* visual_info = XGetVisualInfo(_sapp.x11.display, VisualIDMask, &visual_info_template, &num_visuals); + if (!visual_info) { + _sapp_fail("EGL: failed to get x11 visual"); + } + + _sapp_x11_create_window(visual_info->visual, visual_info->depth); + XFree(visual_info); + + _sapp.egl.surface = eglCreateWindowSurface(_sapp.egl.display, config, (EGLNativeWindowType)_sapp.x11.window, NULL); + if (EGL_NO_SURFACE == _sapp.egl.surface) { + _sapp_fail("EGL: failed to create EGL surface"); + } + + EGLint ctx_attrs[] = { + #if defined(SOKOL_GLCORE33) + EGL_CONTEXT_MAJOR_VERSION, _sapp.desc.gl_major_version, + EGL_CONTEXT_MINOR_VERSION, _sapp.desc.gl_minor_version, + EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + #elif defined(SOKOL_GLES3) + EGL_CONTEXT_CLIENT_VERSION, _sapp.desc.gl_force_gles2 ? 2 : 3, + #else + EGL_CONTEXT_CLIENT_VERSION, 2, + #endif + EGL_NONE, + }; + + _sapp.egl.context = eglCreateContext(_sapp.egl.display, config, EGL_NO_CONTEXT, ctx_attrs); + if (EGL_NO_CONTEXT == _sapp.egl.context) { + _sapp_fail("EGL: failed to create GL context"); + } + + if (!eglMakeCurrent(_sapp.egl.display, _sapp.egl.surface, _sapp.egl.surface, _sapp.egl.context)) { + _sapp_fail("EGL: failed to set current context"); + } + + eglSwapInterval(_sapp.egl.display, _sapp.swap_interval); + +#if defined(SOKOL_GLES3) + _sapp.gles2_fallback = _sapp.desc.gl_force_gles2; +#endif +} + +_SOKOL_PRIVATE void _sapp_egl_destroy(void) { + if (_sapp.egl.display != EGL_NO_DISPLAY) { + eglMakeCurrent(_sapp.egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (_sapp.egl.context != EGL_NO_CONTEXT) { + eglDestroyContext(_sapp.egl.display, _sapp.egl.context); + _sapp.egl.context = EGL_NO_CONTEXT; + } + + if (_sapp.egl.surface != EGL_NO_SURFACE) { + eglDestroySurface(_sapp.egl.display, _sapp.egl.surface); + _sapp.egl.surface = EGL_NO_SURFACE; + } + + eglTerminate(_sapp.egl.display); + _sapp.egl.display = EGL_NO_DISPLAY; + } +} + +#endif /* _SAPP_GLX */ + _SOKOL_PRIVATE void _sapp_linux_run(const sapp_desc* desc) { /* The following lines are here to trigger a linker error instead of an obscure runtime error if the user has forgotten to add -pthread to @@ -11488,24 +11666,27 @@ _SOKOL_PRIVATE void _sapp_linux_run(const sapp_desc* desc) { _sapp.dpi_scale = _sapp.x11.dpi / 96.0f; _sapp_x11_init_extensions(); _sapp_x11_create_cursors(); +#if defined(_SAPP_GLX) _sapp_glx_init(); Visual* visual = 0; int depth = 0; _sapp_glx_choose_visual(&visual, &depth); _sapp_x11_create_window(visual, depth); _sapp_glx_create_context(); + _sapp_glx_swapinterval(_sapp.swap_interval); +#else + _sapp_egl_init(); +#endif sapp_set_icon(&desc->icon); _sapp.valid = true; _sapp_x11_show_window(); if (_sapp.fullscreen) { _sapp_x11_set_fullscreen(true); } - _sapp_glx_swapinterval(_sapp.swap_interval); XFlush(_sapp.x11.display); while (!_sapp.quit_ordered) { _sapp_timing_measure(&_sapp.timing); - _sapp_glx_make_current(); int count = XPending(_sapp.x11.display); while (count--) { XEvent event; @@ -11513,7 +11694,11 @@ _SOKOL_PRIVATE void _sapp_linux_run(const sapp_desc* desc) { _sapp_x11_process_event(&event); } _sapp_frame(); +#if defined(_SAPP_GLX) _sapp_glx_swap_buffers(); +#else + eglSwapBuffers(_sapp.egl.display, _sapp.egl.surface); +#endif XFlush(_sapp.x11.display); /* handle quit-requested, either from window or from sapp_request_quit() */ if (_sapp.quit_requested && !_sapp.quit_ordered) { @@ -11526,7 +11711,11 @@ _SOKOL_PRIVATE void _sapp_linux_run(const sapp_desc* desc) { } } _sapp_call_cleanup(); +#if defined(_SAPP_GLX) _sapp_glx_destroy_context(); +#else + _sapp_egl_destroy(); +#endif _sapp_x11_destroy_window(); _sapp_x11_destroy_cursors(); XCloseDisplay(_sapp.x11.display); @@ -11649,6 +11838,28 @@ SOKOL_API_IMPL float sapp_dpi_scale(void) { return _sapp.dpi_scale; } +SOKOL_APP_IMPL const void* sapp_egl_get_display(void) { + SOKOL_ASSERT(_sapp.valid); + #if defined(_SAPP_ANDROID) + return _sapp.android.display; + #elif defined(_SAPP_LINUX) && !defined(_SAPP_GLX) + return _sapp.egl.display; + #else + return 0; + #endif +} + +SOKOL_APP_IMPL const void* sapp_egl_get_context(void) { + SOKOL_ASSERT(_sapp.valid); + #if defined(_SAPP_ANDROID) + return _sapp.android.context; + #elif defined(_SAPP_LINUX) && !defined(_SAPP_GLX) + return _sapp.egl.context; + #else + return 0; + #endif +} + SOKOL_API_IMPL bool sapp_gles2(void) { return _sapp.gles2_fallback; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fe923218..8d3c2492 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 17) # needed for UWP # SOKOL_GLCORE33, SOKOL_GLES2, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL, SOKOL_WGPU, SOKOL_DUMMY option(SOKOL_BACKEND "Select 3D backend API" SOKOL_GLCORE33) +option(SOKOL_FORCE_EGL "Force EGL with GLCORE33 backend" OFF) option(USE_ARC "Enable/disable ARC" OFF) if (CMAKE_SYSTEM_NAME STREQUAL Emscripten) @@ -27,6 +28,7 @@ else() endif() message(">> SOKOL_BACKEND: ${SOKOL_BACKEND}") +message(">> SOKOL_FORCE_EGL: ${SOKOL_FORCE_EGL}") if (OSX_IOS OR OSX_MACOS) if (USE_ARC) message(">> ObjC ARC ENABLED") @@ -83,7 +85,11 @@ elseif (ANDROID) elseif (LINUX) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) - set(system_libs ${system_libs} X11 Xi Xcursor GL asound dl m Threads::Threads) + if ((SOKOL_BACKEND STREQUAL SOKOL_GLES3) OR SOKOL_FORCE_EGL) + set(system_libs ${system_libs} X11 Xi Xcursor EGL GL asound dl m Threads::Threads) + else() + set(system_libs ${system_libs} X11 Xi Xcursor GL asound dl m Threads::Threads) + endif() elseif (OSX_MACOS) set(exe_type MACOSX_BUNDLE) if (USE_ARC) @@ -103,6 +109,9 @@ elseif (WINDOWS) endif() macro(configure_common target) + if (SOKOL_FORCE_EGL) + target_compile_definitions(${target} PRIVATE SOKOL_FORCE_EGL) + endif() target_compile_definitions(${target} PRIVATE ${SOKOL_BACKEND}) target_link_options(${target} PRIVATE ${link_flags}) target_link_libraries(${target} PRIVATE ${system_libs}) diff --git a/tests/analyze_linux.sh b/tests/analyze_linux.sh index 35b408f4..229e272a 100755 --- a/tests/analyze_linux.sh +++ b/tests/analyze_linux.sh @@ -3,4 +3,5 @@ set -e source test_common.sh prepare -analyze linux_gl_analyze SOKOL_GLCORE33 Debug
\ No newline at end of file +analyze linux_gl_analyze SOKOL_GLCORE33 Debug +analyze linux_gles3_analyze SOKOL_GLES3 Debug
\ No newline at end of file diff --git a/tests/test_common.sh b/tests/test_common.sh index 1fe5dd73..046f40e3 100644 --- a/tests/test_common.sh +++ b/tests/test_common.sh @@ -41,6 +41,16 @@ build() { cd ../.. } +build_force_egl() { + cfg=$1 + backend=$2 + mode=$3 + mkdir -p build/$cfg && cd build/$cfg + cmake -GNinja -DSOKOL_BACKEND=$backend -DSOKOL_FORCE_EGL=ON -DCMAKE_BUILD_TYPE=$mode ../.. + cmake --build . + cd ../.. +} + analyze() { cfg=$1 backend=$2 diff --git a/tests/test_linux.sh b/tests/test_linux.sh index e157ec2c..5cd86e70 100755 --- a/tests/test_linux.sh +++ b/tests/test_linux.sh @@ -4,5 +4,9 @@ source test_common.sh prepare build linux_gl_debug SOKOL_GLCORE33 Debug build linux_gl_release SOKOL_GLCORE33 Release +build linux_gles3_debug SOKOL_GLES3 Debug +build linux_gles3_release SOKOL_GLES3 Release +build_force_egl linux_gl_egl_debug SOKOL_GLCORE33 Debug +build_force_egl linux_gl_egl_release SOKOL_GLCORE33 Release runtest linux_gl_debug |