aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2022-09-25 17:01:35 +0200
committerAndre Weissflog <floooh@gmail.com>2022-09-25 17:01:35 +0200
commit40eeea226daa8068b38b847c71dccd7c36724c6f (patch)
tree174d7dc4dfa1a2ba2fdc94f9c5a644d7ef53eb73
parent4238be9d53f7a817f7ddf1b8d10560142052c6c7 (diff)
parent0885d519d22c438b0c1d7f02f399db87cf463ecd (diff)
Merge branch 'billzez-egl'
-rw-r--r--.github/workflows/gen_bindings.yml8
-rw-r--r--.github/workflows/main.yml2
-rw-r--r--CHANGELOG.md8
-rw-r--r--README.md3
-rw-r--r--sokol_app.h309
-rw-r--r--tests/CMakeLists.txt11
-rwxr-xr-xtests/analyze_linux.sh3
-rw-r--r--tests/test_common.sh10
-rwxr-xr-xtests/test_linux.sh4
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
diff --git a/README.md b/README.md
index 64412acd..67688396 100644
--- a/README.md
+++ b/README.md
@@ -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)
[![Build](/../../actions/workflows/main.yml/badge.svg)](/../../actions/workflows/main.yml) [![Bindings](/../../actions/workflows/gen_bindings.yml/badge.svg)](/../../actions/workflows/gen_bindings.yml) [![build](https://github.com/floooh/sokol-zig/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-zig/actions/workflows/main.yml) [![build](https://github.com/floooh/sokol-nim/actions/workflows/main.yml/badge.svg)](https://github.com/floooh/sokol-nim/actions/workflows/main.yml) [![Odin](https://github.com/floooh/sokol-odin/actions/workflows/main.yml/badge.svg)](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