diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 43fb5bf36..cdd7414d3 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -1652,6 +1652,18 @@ extern "C" { */ #define SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY "SDL_VIDEO_EGL_ALLOW_TRANSPARENCY" +/** + * \brief If eglGetPlatformDisplay fails, fall back to calling eglGetDisplay. + * + * This variable can be set to one of the following values: + * "0" - Do not fall back to eglGetDisplay + * "1" - Fall back to eglGetDisplay if eglGetPlatformDisplay fails. + * + * By default, SDL will fall back to eglGetDisplay if eglGetPlatformDisplay + * fails. + */ +#define SDL_HINT_VIDEO_EGL_ALLOW_GETDISPLAY_FALLBACK "SDL_VIDEO_EGL_GETDISPLAY_FALLBACK" + /** * \brief A variable controlling whether the graphics context is externally managed. * @@ -1811,6 +1823,18 @@ extern "C" { */ #define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" +/** + * \brief A variable controlling whether the OpenGL context should be created + * with EGL by default + * + * This variable can be set to the following values: + * "0" - Use platform-specific GL context creation API (GLX, WGL, CGL, etc) + * "1" - Use EGL + * + * By default SDL will use the platform-specific GL context API when both are present. + */ +#define SDL_HINT_VIDEO_FORCE_EGL "SDL_VIDEO_FORCE_EGL" + /** * \brief A variable controlling whether X11 should use GLX or EGL by default * @@ -1819,6 +1843,9 @@ extern "C" { * "1" - Use EGL * * By default SDL will use GLX when both are present. + * + * \deprecated Use the platform-agnostic SDL_HINT_VIDEO_FORCE_EGL hint instead. + * */ #define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" diff --git a/include/SDL_video.h b/include/SDL_video.h index ccd43394e..fd63fd9bc 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -217,6 +217,21 @@ typedef enum */ typedef void *SDL_GLContext; +/** + * \brief Opaque EGL types. + */ +typedef void *SDL_EGLDisplay; +typedef void *SDL_EGLConfig; +typedef void *SDL_EGLSurface; +typedef intptr_t SDL_EGLAttrib; +typedef int SDL_EGLint; + +/** + * \brief EGL attribute initialization callback types. + */ +typedef SDL_EGLAttrib *(SDLCALL *SDL_EGLAttribArrayCallback)(void); +typedef SDL_EGLint *(SDLCALL *SDL_EGLIntArrayCallback)(void); + /** * \brief OpenGL configuration attributes */ @@ -249,7 +264,8 @@ typedef enum SDL_GL_CONTEXT_RELEASE_BEHAVIOR, SDL_GL_CONTEXT_RESET_NOTIFICATION, SDL_GL_CONTEXT_NO_ERROR, - SDL_GL_FLOATBUFFERS + SDL_GL_FLOATBUFFERS, + SDL_GL_EGL_PLATFORM } SDL_GLattr; typedef enum @@ -1902,6 +1918,21 @@ extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); */ extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); +/** + * Get an EGL library function by name. + * + * If an EGL library is loaded, this function allows applications to get entry + * points for EGL functions. This is useful to provide to an EGL API and + * extension loader. + * + * \param proc the name of an EGL function + * \returns a pointer to the named EGL function. The returned pointer should be + * cast to the appropriate function signature. + * + * \sa SDL_GL_GetCurrentEGLDisplay + */ +extern DECLSPEC void *SDLCALL SDL_EGL_GetProcAddress(const char *proc); + /** * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary(). * @@ -2040,6 +2071,56 @@ extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); */ extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); +/** + * Get the currently active EGL display. + * + * \returns the currently active EGL display or NULL on failure; call + * SDL_GetError() for more information. + * + */ +extern DECLSPEC SDL_EGLDisplay SDLCALL SDL_EGL_GetCurrentEGLDisplay(void); + +/** + * Get the currently active EGL config. + * + * \returns the currently active EGL config or NULL on failure; call + * SDL_GetError() for more information. + * + */ +extern DECLSPEC SDL_EGLConfig SDLCALL SDL_EGL_GetCurrentEGLConfig(void); + +/** + * Get the EGL surface associated with the window. + * + * \returns the EGLSurface pointer associated with the window, or NULL on + * failure. + */ +extern DECLSPEC SDL_EGLSurface SDLCALL SDL_EGL_GetWindowEGLSurface(SDL_Window * window); + +/** + * Sets the callbacks for defining custom EGLAttrib arrays for EGL + * initialization. + * + * Each callback should return a pointer to an EGL attribute array terminated + * with EGL_NONE. Callbacks may return NULL pointers to signal an error, which + * will cause the SDL_CreateWindow process to fail gracefully. + * + * The arrays returned by each callback will be appended to the existing + * attribute arrays defined by SDL. + * + * NOTE: These callback pointers will be reset after SDL_GL_ResetAttributes. + * + * \param platformAttribCallback Callback for attributes to pass to + * eglGetPlatformDisplay. + * \param surfaceAttribCallback Callback for attributes to pass to + * eglCreateSurface. + * \param contextAttribCallback Callback for attributes to pass to + * eglCreateContext. + */ +extern DECLSPEC void SDLCALL SDL_EGL_SetEGLAttributeCallbacks(SDL_EGLAttribArrayCallback platformAttribCallback, + SDL_EGLIntArrayCallback surfaceAttribCallback, + SDL_EGLIntArrayCallback contextAttribCallback); + /** * Get the size of a window's underlying drawable in pixels. * diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 41ae6ec01..bdd99ff75 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -76,6 +76,7 @@ #elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT /* EGL AND OpenGL ES support via ANGLE */ #define DEFAULT_EGL "libEGL.dll" +#define DEFAULT_OGL "opengl32.dll" #define DEFAULT_OGL_ES2 "libGLESv2.dll" #define DEFAULT_OGL_ES_PVR "libGLES_CM.dll" #define DEFAULT_OGL_ES "libGLESv1_CM.dll" @@ -242,7 +243,7 @@ SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext } void * -SDL_EGL_GetProcAddress(_THIS, const char *proc) +SDL_EGL_GetProcAddressInternal(_THIS, const char *proc) { void *retval = NULL; if (_this->egl_data != NULL) { @@ -518,7 +519,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa * Khronos doc: "EGL_BAD_DISPLAY is generated if display is not an EGL display connection, unless display is EGL_NO_DISPLAY and name is EGL_EXTENSIONS." * Therefore SDL_EGL_GetVersion() shouldn't work with uninitialized display. * - it actually doesn't work on Android that has 1.5 egl client - * - it works on desktop X11 (using SDL_VIDEO_X11_FORCE_EGL=1) */ + * - it works on desktop X11 (using SDL_VIDEO_FORCE_EGL=1) */ SDL_EGL_GetVersion(_this); if (_this->egl_data->egl_version_major == 1 && _this->egl_data->egl_version_minor == 5) { @@ -526,10 +527,19 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa } if (_this->egl_data->eglGetPlatformDisplay) { - _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, NULL); + EGLAttrib *attribs = NULL; + if (_this->egl_platformattrib_callback) { + attribs = _this->egl_platformattrib_callback(); + if (!attribs) { + _this->gl_config.driver_loaded = 0; + *_this->gl_config.driver_path = '\0'; + return SDL_SetError("EGL platform attribute callback returned NULL pointer"); + } + } + _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, attribs); } else { if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) { - _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT"); + _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddressInternal(_this, "eglGetPlatformDisplayEXT"); if (_this->egl_data->eglGetPlatformDisplayEXT) { _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(uintptr_t)native_display, NULL); } @@ -538,7 +548,9 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa } #endif /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */ - if ((_this->egl_data->egl_display == EGL_NO_DISPLAY) && (_this->egl_data->eglGetDisplay != NULL)) { + if ((_this->egl_data->egl_display == EGL_NO_DISPLAY) && + (_this->egl_data->eglGetDisplay != NULL) && + SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_GETDISPLAY_FALLBACK, SDL_TRUE)) { _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display); } if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { @@ -944,8 +956,8 @@ SDL_EGL_ChooseConfig(_THIS) SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) { - /* max 14 values plus terminator. */ - EGLint attribs[15]; + /* max 16 key+value pairs plus terminator. */ + EGLint attribs[33]; int attr = 0; EGLContext egl_context, share_context = EGL_NO_CONTEXT; @@ -1034,6 +1046,29 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) } #endif + if (_this->egl_contextattrib_callback) { + const int maxAttribs = sizeof(attribs) / sizeof(attribs[0]); + EGLint *userAttribs, *userAttribP; + userAttribs = _this->egl_contextattrib_callback(); + if (!userAttribs) { + _this->gl_config.driver_loaded = 0; + *_this->gl_config.driver_path = '\0'; + SDL_SetError("EGL context attribute callback returned NULL pointer"); + return NULL; + } + + for (userAttribP = userAttribs; *userAttribP != EGL_NONE; ) { + if (attr + 3 >= maxAttribs) { + _this->gl_config.driver_loaded = 0; + *_this->gl_config.driver_path = '\0'; + SDL_SetError("EGL context attribute callback returned too many attributes"); + return NULL; + } + attribs[attr++] = *userAttribP++; + attribs[attr++] = *userAttribP++; + } + } + attribs[attr++] = EGL_NONE; /* Bind the API */ @@ -1200,8 +1235,8 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) EGLint format_wanted; EGLint format_got; #endif - /* max 2 key+value pairs, plus terminator. */ - EGLint attribs[5]; + /* max 16 key+value pairs, plus terminator. */ + EGLint attribs[33]; int attr = 0; EGLSurface * surface; @@ -1242,6 +1277,29 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) } #endif + if (_this->egl_surfaceattrib_callback) { + const int maxAttribs = sizeof(attribs) / sizeof(attribs[0]); + EGLint *userAttribs, *userAttribP; + userAttribs = _this->egl_surfaceattrib_callback(); + if (!userAttribs) { + _this->gl_config.driver_loaded = 0; + *_this->gl_config.driver_path = '\0'; + SDL_SetError("EGL surface attribute callback returned NULL pointer"); + return EGL_NO_SURFACE; + } + + for (userAttribP = userAttribs; *userAttribP != EGL_NONE; ) { + if (attr + 3 >= maxAttribs) { + _this->gl_config.driver_loaded = 0; + *_this->gl_config.driver_path = '\0'; + SDL_SetError("EGL surface attribute callback returned too many attributes"); + return EGL_NO_SURFACE; + } + attribs[attr++] = *userAttribP++; + attribs[attr++] = *userAttribP++; + } + } + attribs[attr++] = EGL_NONE; surface = _this->egl_data->eglCreateWindowSurface( diff --git a/src/video/SDL_egl_c.h b/src/video/SDL_egl_c.h index 76d26f93b..3cf3cbb57 100644 --- a/src/video/SDL_egl_c.h +++ b/src/video/SDL_egl_c.h @@ -46,7 +46,7 @@ typedef struct SDL_EGL_VideoData EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display); EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplay) (EGLenum platform, void *native_display, - const EGLint *attrib_list); + const EGLAttrib *attrib_list); EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplayEXT) (EGLenum platform, void *native_display, const EGLint *attrib_list); @@ -132,7 +132,7 @@ extern int SDL_EGL_GetAttribute(_THIS, SDL_GLattr attrib, int *value); */ extern int SDL_EGL_LoadLibraryOnly(_THIS, const char *path); extern int SDL_EGL_LoadLibrary(_THIS, const char *path, NativeDisplayType native_display, EGLenum platform); -extern void *SDL_EGL_GetProcAddress(_THIS, const char *proc); +extern void *SDL_EGL_GetProcAddressInternal(_THIS, const char *proc); extern void SDL_EGL_UnloadLibrary(_THIS); extern void SDL_EGL_SetRequiredVisualId(_THIS, int visual_id); extern int SDL_EGL_ChooseConfig(_THIS); diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 5a0c24d62..b0ac1efb5 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -275,6 +275,7 @@ struct SDL_VideoDevice SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window); int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context); void (*GL_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h); + SDL_EGLSurface (*GL_GetEGLSurface) (_THIS, SDL_Window * window); int (*GL_SetSwapInterval) (_THIS, int interval); int (*GL_GetSwapInterval) (_THIS); int (*GL_SwapWindow) (_THIS, SDL_Window * window); @@ -391,11 +392,16 @@ struct SDL_VideoDevice int framebuffer_srgb_capable; int no_error; int retained_backing; + int egl_platform; int driver_loaded; char driver_path[256]; void *dll_handle; } gl_config; + SDL_EGLAttribArrayCallback egl_platformattrib_callback; + SDL_EGLIntArrayCallback egl_surfaceattrib_callback; + SDL_EGLIntArrayCallback egl_contextattrib_callback; + /* * * */ /* Cache current GL context; don't call the OS when it hasn't changed. */ /* We have the global pointers here so Cocoa continues to work the way diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index e25cb2dab..36f0cc13f 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -25,6 +25,7 @@ #include "SDL.h" #include "SDL_video.h" #include "SDL_sysvideo.h" +#include "SDL_egl_c.h" #include "SDL_blit.h" #include "SDL_pixels_c.h" #include "SDL_rect_c.h" @@ -1902,16 +1903,6 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) window->surface_valid = SDL_FALSE; } - if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } - } - - if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { - _this->DestroyWindow(_this, window); - } - if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) { if (flags & SDL_WINDOW_OPENGL) { need_gl_load = SDL_TRUE; @@ -1942,6 +1933,16 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) SDL_Vulkan_UnloadLibrary(); } + if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } + } + + if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { + _this->DestroyWindow(_this, window); + } + if (need_gl_load) { if (SDL_GL_LoadLibrary(NULL) < 0) { return -1; @@ -3283,6 +3284,12 @@ SDL_DestroyWindow(SDL_Window * window) window->surface = NULL; window->surface_valid = SDL_FALSE; } + if (window->flags & SDL_WINDOW_OPENGL) { + SDL_GL_UnloadLibrary(); + } + if (window->flags & SDL_WINDOW_VULKAN) { + SDL_Vulkan_UnloadLibrary(); + } if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ if (_this->DestroyWindowFramebuffer) { _this->DestroyWindowFramebuffer(_this, window); @@ -3291,12 +3298,6 @@ SDL_DestroyWindow(SDL_Window * window) if (_this->DestroyWindow) { _this->DestroyWindow(_this, window); } - if (window->flags & SDL_WINDOW_OPENGL) { - SDL_GL_UnloadLibrary(); - } - if (window->flags & SDL_WINDOW_VULKAN) { - SDL_Vulkan_UnloadLibrary(); - } display = SDL_GetDisplayForWindow(window); if (display->fullscreen_window == window) { @@ -3466,6 +3467,31 @@ SDL_GL_GetProcAddress(const char *proc) return func; } +void * +SDL_EGL_GetProcAddress(const char *proc) +{ +#if SDL_VIDEO_OPENGL_EGL + void *func; + + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + func = NULL; + + if (_this->egl_data) { + func = SDL_EGL_GetProcAddressInternal(_this, proc); + } else { + SDL_SetError("No EGL library has been loaded"); + } + + return func; +#else + SDL_SetError("SDL was not built with EGL support"); + return NULL; +#endif +} + void SDL_GL_UnloadLibrary(void) { @@ -3606,6 +3632,18 @@ SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor) #endif } +void SDL_EGL_SetEGLAttributeCallbacks(SDL_EGLAttribArrayCallback platformAttribCallback, + SDL_EGLIntArrayCallback surfaceAttribCallback, + SDL_EGLIntArrayCallback contextAttribCallback) +{ + if (!_this) { + return; + } + _this->egl_platformattrib_callback = platformAttribCallback; + _this->egl_surfaceattrib_callback = surfaceAttribCallback; + _this->egl_contextattrib_callback = contextAttribCallback; +} + void SDL_GL_ResetAttributes() { @@ -3613,6 +3651,10 @@ SDL_GL_ResetAttributes() return; } + _this->egl_platformattrib_callback = NULL; + _this->egl_surfaceattrib_callback = NULL; + _this->egl_contextattrib_callback = NULL; + _this->gl_config.red_size = 3; _this->gl_config.green_size = 3; _this->gl_config.blue_size = 2; @@ -3659,6 +3701,8 @@ SDL_GL_ResetAttributes() _this->gl_config.reset_notification = SDL_GL_CONTEXT_RESET_NO_NOTIFICATION; _this->gl_config.share_with_current_context = 0; + + _this->gl_config.egl_platform = 0; } int @@ -3775,6 +3819,9 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) case SDL_GL_CONTEXT_NO_ERROR: _this->gl_config.no_error = value; break; + case SDL_GL_EGL_PLATFORM: + _this->gl_config.egl_platform = value; + break; default: retval = SDL_SetError("Unknown OpenGL attribute"); break; @@ -3984,6 +4031,12 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) *value = _this->gl_config.no_error; return 0; } + case SDL_GL_EGL_PLATFORM: + { + *value = _this->gl_config.egl_platform; + return 0; + } + break; default: return SDL_SetError("Unknown OpenGL attribute"); } @@ -4129,6 +4182,66 @@ SDL_GL_GetCurrentContext(void) return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls); } +SDL_EGLDisplay +SDL_EGL_GetCurrentEGLDisplay(void) +{ +#if SDL_VIDEO_OPENGL_EGL + if (!_this) { + SDL_UninitializedVideo(); + return EGL_NO_DISPLAY; + } + if (!_this->egl_data) { + SDL_SetError("There is no current EGL display"); + return EGL_NO_DISPLAY; + } + return _this->egl_data->egl_display; +#else + SDL_SetError("SDL was not built with EGL support"); + return NULL; +#endif +} + +SDL_EGLConfig +SDL_EGL_GetCurrentEGLConfig(void) +{ +#if SDL_VIDEO_OPENGL_EGL + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + if (!_this->egl_data) { + SDL_SetError("There is no current EGL display"); + return NULL; + } + return _this->egl_data->egl_config; +#else + SDL_SetError("SDL was not built with EGL support"); + return NULL; +#endif +} + +SDL_EGLConfig +SDL_EGL_GetWindowEGLSurface(SDL_Window * window) +{ +#if SDL_VIDEO_OPENGL_EGL + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + if (!_this->egl_data) { + SDL_SetError("There is no current EGL display"); + return NULL; + } + if (_this->GL_GetEGLSurface) { + return _this->GL_GetEGLSurface(_this, window); + } + return NULL; +#else + SDL_SetError("SDL was not built with EGL support"); + return NULL; +#endif +} + void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h) { CHECK_WINDOW_MAGIC(window,); diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index 3ed828fde..d405e7004 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/src/video/android/SDL_androidvideo.c @@ -50,7 +50,7 @@ static void Android_VideoQuit(_THIS); int Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi); #include "../SDL_egl_c.h" -#define Android_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define Android_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval diff --git a/src/video/cocoa/SDL_cocoaopengles.h b/src/video/cocoa/SDL_cocoaopengles.h index bfabb6d57..4b3b53cc6 100644 --- a/src/video/cocoa/SDL_cocoaopengles.h +++ b/src/video/cocoa/SDL_cocoaopengles.h @@ -30,7 +30,7 @@ /* OpenGLES functions */ #define Cocoa_GLES_GetAttribute SDL_EGL_GetAttribute -#define Cocoa_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define Cocoa_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define Cocoa_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define Cocoa_GLES_GetSwapInterval SDL_EGL_GetSwapInterval #define Cocoa_GLES_SetSwapInterval SDL_EGL_SetSwapInterval @@ -39,8 +39,11 @@ extern int Cocoa_GLES_LoadLibrary(_THIS, const char *path); extern SDL_GLContext Cocoa_GLES_CreateContext(_THIS, SDL_Window * window); extern int Cocoa_GLES_SwapWindow(_THIS, SDL_Window * window); extern int Cocoa_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern void Cocoa_GLES_GetDrawableSize(_THIS, SDL_Window * window, + int * w, int * h); extern void Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context); extern int Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window); +extern SDL_EGLSurface Cocoa_GLES_GetEGLSurface(_THIS, SDL_Window * window); #endif /* SDL_VIDEO_OPENGL_EGL */ diff --git a/src/video/cocoa/SDL_cocoaopengles.m b/src/video/cocoa/SDL_cocoaopengles.m index bdf2e9a08..6df958f1d 100644 --- a/src/video/cocoa/SDL_cocoaopengles.m +++ b/src/video/cocoa/SDL_cocoaopengles.m @@ -44,6 +44,7 @@ Cocoa_GLES_LoadLibrary(_THIS, const char *path) _this->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval; _this->GL_SwapWindow = Cocoa_GL_SwapWindow; _this->GL_DeleteContext = Cocoa_GL_DeleteContext; + _this->GL_GetEGLSurface = NULL; return Cocoa_GL_LoadLibrary(_this, path); #else return SDL_SetError("SDL not configured with OpenGL/CGL support"); @@ -51,7 +52,7 @@ Cocoa_GLES_LoadLibrary(_THIS, const char *path) } if (_this->egl_data == NULL) { - return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0); + return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform); } return 0; @@ -77,6 +78,7 @@ Cocoa_GLES_CreateContext(_THIS, SDL_Window * window) _this->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval; _this->GL_SwapWindow = Cocoa_GL_SwapWindow; _this->GL_DeleteContext = Cocoa_GL_DeleteContext; + _this->GL_GetEGLSurface = NULL; if (Cocoa_GL_LoadLibrary(_this, NULL) != 0) { return NULL; @@ -112,8 +114,29 @@ Cocoa_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) return SDL_EGL_MakeCurrent(_this, window ? ((__bridge SDL_WindowData *) window->driverdata).egl_surface : EGL_NO_SURFACE, context); }} +void +Cocoa_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) +{ @autoreleasepool +{ + SDL_WindowData *windata = (__bridge SDL_WindowData *)window->driverdata; + NSView *contentView = windata.nswindow.contentView; + CALayer *layer = [contentView layer]; + + int width = layer.bounds.size.width * layer.contentsScale; + int height = layer.bounds.size.height * layer.contentsScale; + + if (w) { + *w = width; + } + + if (h) { + *h = height; + } +}} + int Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) +{ @autoreleasepool { NSView* v; /* The current context is lost in here; save it and reset it. */ @@ -127,7 +150,7 @@ Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) #if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */ SDL_assert(!_this->gl_config.driver_loaded); #endif - if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) { + if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform) < 0) { SDL_EGL_UnloadLibrary(_this); return -1; } @@ -143,7 +166,14 @@ Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) } return Cocoa_GLES_MakeCurrent(_this, current_win, current_ctx); -} +}} + +SDL_EGLSurface +Cocoa_GLES_GetEGLSurface(_THIS, SDL_Window * window) +{ @autoreleasepool +{ + return ((__bridge SDL_WindowData *) window->driverdata).egl_surface; +}} #endif /* SDL_VIDEO_DRIVER_COCOA && SDL_VIDEO_OPENGL_EGL */ diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 6c3d44efa..da43da732 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -139,16 +139,26 @@ Cocoa_CreateDevice(void) device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval; device->GL_SwapWindow = Cocoa_GL_SwapWindow; device->GL_DeleteContext = Cocoa_GL_DeleteContext; -#elif SDL_VIDEO_OPENGL_EGL - device->GL_LoadLibrary = Cocoa_GLES_LoadLibrary; - device->GL_GetProcAddress = Cocoa_GLES_GetProcAddress; - device->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary; - device->GL_CreateContext = Cocoa_GLES_CreateContext; - device->GL_MakeCurrent = Cocoa_GLES_MakeCurrent; - device->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval; - device->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval; - device->GL_SwapWindow = Cocoa_GLES_SwapWindow; - device->GL_DeleteContext = Cocoa_GLES_DeleteContext; + device->GL_GetEGLSurface = NULL; +#endif +#if SDL_VIDEO_OPENGL_EGL +#if SDL_VIDEO_OPENGL_CGL + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) { +#endif + device->GL_LoadLibrary = Cocoa_GLES_LoadLibrary; + device->GL_GetProcAddress = Cocoa_GLES_GetProcAddress; + device->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary; + device->GL_CreateContext = Cocoa_GLES_CreateContext; + device->GL_MakeCurrent = Cocoa_GLES_MakeCurrent; + device->GL_GetDrawableSize = Cocoa_GLES_GetDrawableSize; + device->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval; + device->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval; + device->GL_SwapWindow = Cocoa_GLES_SwapWindow; + device->GL_DeleteContext = Cocoa_GLES_DeleteContext; + device->GL_GetEGLSurface = Cocoa_GLES_GetEGLSurface; +#if SDL_VIDEO_OPENGL_CGL + } +#endif #endif #if SDL_VIDEO_VULKAN diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index c73827656..6bd3ad1ce 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1799,6 +1799,13 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) if ((window->flags & SDL_WINDOW_OPENGL) && _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { [contentView setWantsLayer:TRUE]; + if (!(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + contentView.layer.contentsScale = 1; + } else { + if ([nswindow.screen respondsToSelector:@selector(backingScaleFactor)]) { + contentView.layer.contentsScale = nswindow.screen.backingScaleFactor; + } + } } #endif /* SDL_VIDEO_OPENGL_EGL */ #endif /* SDL_VIDEO_OPENGL_ES2 */ diff --git a/src/video/emscripten/SDL_emscriptenopengles.h b/src/video/emscripten/SDL_emscriptenopengles.h index 6d58ac10d..c8fef84ec 100644 --- a/src/video/emscripten/SDL_emscriptenopengles.h +++ b/src/video/emscripten/SDL_emscriptenopengles.h @@ -28,7 +28,6 @@ #include "../SDL_sysvideo.h" /* OpenGLES functions */ - extern int Emscripten_GLES_LoadLibrary(_THIS, const char *path); extern void Emscripten_GLES_UnloadLibrary(_THIS); extern void * Emscripten_GLES_GetProcAddress(_THIS, const char *proc); diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.h b/src/video/kmsdrm/SDL_kmsdrmopengles.h index a762ab0f3..1f3eb3631 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.h +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.h @@ -30,7 +30,7 @@ /* OpenGLES functions */ #define KMSDRM_GLES_GetAttribute SDL_EGL_GetAttribute -#define KMSDRM_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define KMSDRM_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define KMSDRM_GLES_DeleteContext SDL_EGL_DeleteContext #define KMSDRM_GLES_GetSwapInterval SDL_EGL_GetSwapInterval diff --git a/src/video/offscreen/SDL_offscreenopengles.h b/src/video/offscreen/SDL_offscreenopengles.h index 6c9e51820..deafd09cc 100644 --- a/src/video/offscreen/SDL_offscreenopengles.h +++ b/src/video/offscreen/SDL_offscreenopengles.h @@ -28,7 +28,7 @@ #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" -#define OFFSCREEN_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define OFFSCREEN_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define OFFSCREEN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define OFFSCREEN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval #define OFFSCREEN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval diff --git a/src/video/raspberry/SDL_rpiopengles.h b/src/video/raspberry/SDL_rpiopengles.h index 2cdf0fdcf..59b7e5720 100644 --- a/src/video/raspberry/SDL_rpiopengles.h +++ b/src/video/raspberry/SDL_rpiopengles.h @@ -30,7 +30,7 @@ /* OpenGLES functions */ #define RPI_GLES_GetAttribute SDL_EGL_GetAttribute -#define RPI_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define RPI_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define RPI_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define RPI_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define RPI_GLES_GetSwapInterval SDL_EGL_GetSwapInterval diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c index 33758d691..b7f452303 100644 --- a/src/video/vita/SDL_vitavideo.c +++ b/src/video/vita/SDL_vitavideo.c @@ -47,7 +47,7 @@ #if defined(SDL_VIDEO_VITA_PVR_OGL) #include "SDL_vitagl_pvr_c.h" #endif - #define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddress + #define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define VITA_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define VITA_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define VITA_GLES_GetSwapInterval SDL_EGL_GetSwapInterval diff --git a/src/video/vivante/SDL_vivanteopengles.h b/src/video/vivante/SDL_vivanteopengles.h index dce74ae6b..2484f413e 100644 --- a/src/video/vivante/SDL_vivanteopengles.h +++ b/src/video/vivante/SDL_vivanteopengles.h @@ -30,7 +30,7 @@ /* OpenGLES functions */ #define VIVANTE_GLES_GetAttribute SDL_EGL_GetAttribute -#define VIVANTE_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define VIVANTE_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define VIVANTE_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define VIVANTE_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define VIVANTE_GLES_GetSwapInterval SDL_EGL_GetSwapInterval diff --git a/src/video/wayland/SDL_waylandopengles.c b/src/video/wayland/SDL_waylandopengles.c index a0af3f5a4..f90d7ac00 100644 --- a/src/video/wayland/SDL_waylandopengles.c +++ b/src/video/wayland/SDL_waylandopengles.c @@ -40,7 +40,7 @@ Wayland_GLES_LoadLibrary(_THIS, const char *path) { int ret; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0); + ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, _this->gl_config.egl_platform); Wayland_PumpEvents(_this); WAYLAND_wl_display_flush(data->display); @@ -204,6 +204,14 @@ Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context) WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); } +EGLSurface +Wayland_GLES_GetEGLSurface(_THIS, SDL_Window * window) +{ + SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + + return windowdata->egl_surface; +} + #endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandopengles.h b/src/video/wayland/SDL_waylandopengles.h index b9500b9f1..39e6cdf58 100644 --- a/src/video/wayland/SDL_waylandopengles.h +++ b/src/video/wayland/SDL_waylandopengles.h @@ -33,7 +33,7 @@ typedef struct SDL_PrivateGLESData /* OpenGLES functions */ #define Wayland_GLES_GetAttribute SDL_EGL_GetAttribute -#define Wayland_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define Wayland_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define Wayland_GLES_UnloadLibrary SDL_EGL_UnloadLibrary extern int Wayland_GLES_LoadLibrary(_THIS, const char *path); @@ -43,6 +43,7 @@ extern int Wayland_GLES_GetSwapInterval(_THIS); extern int Wayland_GLES_SwapWindow(_THIS, SDL_Window * window); extern int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); extern void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context); +extern SDL_EGLSurface Wayland_GLES_GetEGLSurface(_THIS, SDL_Window * window); #endif /* SDL_waylandopengles_h_ */ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 76b93cd09..38e1b2810 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -237,6 +237,7 @@ Wayland_CreateDevice(void) device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary; device->GL_GetProcAddress = Wayland_GLES_GetProcAddress; device->GL_DeleteContext = Wayland_GLES_DeleteContext; + device->GL_GetEGLSurface = Wayland_GLES_GetEGLSurface; #endif device->CreateSDLWindow = Wayland_CreateWindow; diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c index c1df7f6b9..ffb0d040f 100644 --- a/src/video/windows/SDL_windowsopengl.c +++ b/src/video/windows/SDL_windowsopengl.c @@ -689,6 +689,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; _this->GL_SwapWindow = WIN_GLES_SwapWindow; _this->GL_DeleteContext = WIN_GLES_DeleteContext; + _this->GL_GetEGLSurface = WIN_GLES_GetEGLSurface; if (WIN_GLES_LoadLibrary(_this, NULL) != 0) { return NULL; diff --git a/src/video/windows/SDL_windowsopengles.c b/src/video/windows/SDL_windowsopengles.c index 1e2a4f620..4ba30ba4f 100644 --- a/src/video/windows/SDL_windowsopengles.c +++ b/src/video/windows/SDL_windowsopengles.c @@ -22,6 +22,7 @@ #if SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#include "SDL_hints.h" #include "SDL_windowsvideo.h" #include "SDL_windowsopengles.h" #include "SDL_windowsopengl.h" @@ -33,7 +34,8 @@ int WIN_GLES_LoadLibrary(_THIS, const char *path) { /* If the profile requested is not GL ES, switch over to WIN_GL functions */ - if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { + if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES && + !SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) { #if SDL_VIDEO_OPENGL_WGL WIN_GLES_UnloadLibrary(_this); _this->GL_LoadLibrary = WIN_GL_LoadLibrary; @@ -45,6 +47,7 @@ WIN_GLES_LoadLibrary(_THIS, const char *path) { _this->GL_GetSwapInterval = WIN_GL_GetSwapInterval; _this->GL_SwapWindow = WIN_GL_SwapWindow; _this->GL_DeleteContext = WIN_GL_DeleteContext; + _this->GL_GetEGLSurface = NULL; return WIN_GL_LoadLibrary(_this, path); #else return SDL_SetError("SDL not configured with OpenGL/WGL support"); @@ -52,7 +55,7 @@ WIN_GLES_LoadLibrary(_THIS, const char *path) { } if (_this->egl_data == NULL) { - return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0); + return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform); } return 0; @@ -65,7 +68,8 @@ WIN_GLES_CreateContext(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *)window->driverdata; #if SDL_VIDEO_OPENGL_WGL - if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { + if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES && + !SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) { /* Switch to WGL based functions */ WIN_GLES_UnloadLibrary(_this); _this->GL_LoadLibrary = WIN_GL_LoadLibrary; @@ -77,6 +81,7 @@ WIN_GLES_CreateContext(_THIS, SDL_Window * window) _this->GL_GetSwapInterval = WIN_GL_GetSwapInterval; _this->GL_SwapWindow = WIN_GL_SwapWindow; _this->GL_DeleteContext = WIN_GL_DeleteContext; + _this->GL_GetEGLSurface = NULL; if (WIN_GL_LoadLibrary(_this, NULL) != 0) { return NULL; @@ -113,7 +118,7 @@ WIN_GLES_SetupWindow(_THIS, SDL_Window * window) #if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */ SDL_assert(!_this->gl_config.driver_loaded); #endif - if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) { + if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, _this->gl_config.egl_platform) < 0) { SDL_EGL_UnloadLibrary(_this); return -1; } @@ -130,6 +135,14 @@ WIN_GLES_SetupWindow(_THIS, SDL_Window * window) return WIN_GLES_MakeCurrent(_this, current_win, current_ctx); } +EGLSurface +WIN_GLES_GetEGLSurface(_THIS, SDL_Window * window) +{ + SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + + return windowdata->egl_surface; +} + #endif /* SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windows/SDL_windowsopengles.h b/src/video/windows/SDL_windowsopengles.h index b21c56f4f..84171ec07 100644 --- a/src/video/windows/SDL_windowsopengles.h +++ b/src/video/windows/SDL_windowsopengles.h @@ -30,7 +30,7 @@ /* OpenGLES functions */ #define WIN_GLES_GetAttribute SDL_EGL_GetAttribute -#define WIN_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WIN_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define WIN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define WIN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval #define WIN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval @@ -41,6 +41,7 @@ extern int WIN_GLES_SwapWindow(_THIS, SDL_Window * window); extern int WIN_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); extern void WIN_GLES_DeleteContext(_THIS, SDL_GLContext context); extern int WIN_GLES_SetupWindow(_THIS, SDL_Window * window); +extern SDL_EGLSurface WIN_GLES_GetEGLSurface(_THIS, SDL_Window * window); #endif /* SDL_VIDEO_OPENGL_EGL */ diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 0dc107bdf..2c30fd230 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -226,17 +226,26 @@ WIN_CreateDevice(void) device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; device->GL_SwapWindow = WIN_GL_SwapWindow; device->GL_DeleteContext = WIN_GL_DeleteContext; -#elif SDL_VIDEO_OPENGL_EGL - /* Use EGL based functions */ - device->GL_LoadLibrary = WIN_GLES_LoadLibrary; - device->GL_GetProcAddress = WIN_GLES_GetProcAddress; - device->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; - device->GL_CreateContext = WIN_GLES_CreateContext; - device->GL_MakeCurrent = WIN_GLES_MakeCurrent; - device->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; - device->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; - device->GL_SwapWindow = WIN_GLES_SwapWindow; - device->GL_DeleteContext = WIN_GLES_DeleteContext; + device->GL_GetEGLSurface = NULL; +#endif +#if SDL_VIDEO_OPENGL_EGL +#if SDL_VIDEO_OPENGL_WGL + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) { +#endif + /* Use EGL based functions */ + device->GL_LoadLibrary = WIN_GLES_LoadLibrary; + device->GL_GetProcAddress = WIN_GLES_GetProcAddress; + device->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; + device->GL_CreateContext = WIN_GLES_CreateContext; + device->GL_MakeCurrent = WIN_GLES_MakeCurrent; + device->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; + device->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; + device->GL_SwapWindow = WIN_GLES_SwapWindow; + device->GL_DeleteContext = WIN_GLES_DeleteContext; + device->GL_GetEGLSurface = WIN_GLES_GetEGLSurface; +#if SDL_VIDEO_OPENGL_WGL + } +#endif #endif #if SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = WIN_Vulkan_LoadLibrary; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 600f92af2..9d8afee63 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -543,9 +543,10 @@ WIN_CreateWindow(_THIS, SDL_Window * window) /* The rest of this macro mess is for OpenGL or OpenGL ES windows */ #if SDL_VIDEO_OPENGL_ES2 - if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES + if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES || + SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE)) && #if SDL_VIDEO_OPENGL_WGL - && (!_this->gl_data || WIN_GL_UseEGL(_this)) + (!_this->gl_data || WIN_GL_UseEGL(_this)) #endif /* SDL_VIDEO_OPENGL_WGL */ ) { #if SDL_VIDEO_OPENGL_EGL diff --git a/src/video/winrt/SDL_winrtopengles.h b/src/video/winrt/SDL_winrtopengles.h index c702c8b69..c56d66524 100644 --- a/src/video/winrt/SDL_winrtopengles.h +++ b/src/video/winrt/SDL_winrtopengles.h @@ -30,7 +30,7 @@ /* OpenGLES functions */ #define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute -#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval #define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 3a1485698..5068c6ae7 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -251,6 +251,7 @@ X11_GL_LoadLibrary(_THIS, const char *path) * GLX_EXT_create_context_es2_profile extension, switch over to X11_GLES functions */ if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || + SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE) || SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) && X11_GL_UseEGL(_this) ) { #if SDL_VIDEO_OPENGL_EGL @@ -689,7 +690,8 @@ SDL_bool X11_GL_UseEGL(_THIS) { SDL_assert(_this->gl_data != NULL); - if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE) || + SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) { /* use of EGL has been requested, even for desktop GL */ return SDL_TRUE; diff --git a/src/video/x11/SDL_x11opengles.c b/src/video/x11/SDL_x11opengles.c index e1ec4e4d2..8e7ffb0a0 100644 --- a/src/video/x11/SDL_x11opengles.c +++ b/src/video/x11/SDL_x11opengles.c @@ -36,6 +36,7 @@ X11_GLES_LoadLibrary(_THIS, const char *path) /* If the profile requested is not GL ES, switch over to X11_GL functions */ if ((_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) && + !SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE) && !SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) { #if SDL_VIDEO_OPENGL_GLX X11_GLES_UnloadLibrary(_this); @@ -54,7 +55,7 @@ X11_GLES_LoadLibrary(_THIS, const char *path) #endif } - return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0); + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, _this->gl_config.egl_platform); } XVisualInfo * @@ -103,6 +104,13 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window) return context; } +SDL_EGLSurface +X11_GLES_GetEGLSurface(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + return data->egl_surface; +} + SDL_EGL_SwapWindow_impl(X11) SDL_EGL_MakeCurrent_impl(X11) diff --git a/src/video/x11/SDL_x11opengles.h b/src/video/x11/SDL_x11opengles.h index 5219553ca..6d4df5ef2 100644 --- a/src/video/x11/SDL_x11opengles.h +++ b/src/video/x11/SDL_x11opengles.h @@ -37,7 +37,7 @@ typedef struct SDL_PrivateGLESData /* OpenGLES functions */ #define X11_GLES_GetAttribute SDL_EGL_GetAttribute -#define X11_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define X11_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal #define X11_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define X11_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define X11_GLES_GetSwapInterval SDL_EGL_GetSwapInterval @@ -48,6 +48,7 @@ extern XVisualInfo *X11_GLES_GetVisual(_THIS, Display * display, int screen); extern SDL_GLContext X11_GLES_CreateContext(_THIS, SDL_Window * window); extern int X11_GLES_SwapWindow(_THIS, SDL_Window * window); extern int X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern SDL_EGLSurface X11_GLES_GetEGLSurface(_THIS, SDL_Window * window); #endif /* SDL_VIDEO_OPENGL_EGL */ diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 59f2cf545..2d042e0c1 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -284,10 +284,12 @@ X11_CreateDevice(void) device->GL_GetSwapInterval = X11_GL_GetSwapInterval; device->GL_SwapWindow = X11_GL_SwapWindow; device->GL_DeleteContext = X11_GL_DeleteContext; + device->GL_GetEGLSurface = NULL; #endif #if SDL_VIDEO_OPENGL_EGL #if SDL_VIDEO_OPENGL_GLX - if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) { + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE) || + SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) { #endif device->GL_LoadLibrary = X11_GLES_LoadLibrary; device->GL_GetProcAddress = X11_GLES_GetProcAddress; @@ -298,6 +300,7 @@ X11_CreateDevice(void) device->GL_GetSwapInterval = X11_GLES_GetSwapInterval; device->GL_SwapWindow = X11_GLES_SwapWindow; device->GL_DeleteContext = X11_GLES_DeleteContext; + device->GL_GetEGLSurface = X11_GLES_GetEGLSurface; #if SDL_VIDEO_OPENGL_GLX } #endif diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 6d4e53f20..c0114b56e 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -429,6 +429,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) #if SDL_VIDEO_OPENGL_EGL if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || + SDL_GetHintBoolean(SDL_HINT_VIDEO_FORCE_EGL, SDL_FALSE) || SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) #if SDL_VIDEO_OPENGL_GLX && ( !_this->gl_data || X11_GL_UseEGL(_this) )