mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-20 22:16:49 +01:00
opengl: Allow SDL_GL_MakeCurrent() to accept a NULL window (thanks, Martin!).
This allows you to bind surfaceless contexts on a background thread to, for example, load assets in a separate context, for platforms that have different requirements about sharing surfaces, etc. Martin's notes on the matter: "Here's a patch that enables passing NULL windows to SDL_GL_MakeCurrent, if the involved APIs allow it. Currently, this is only the case for EGL, and even then only if some specific extensions are present (which they usually are). If "surfaceless" contexts are not supported, SDL_GL_MakeCurrent continues to generate an error (albeit with a more specific error message than it used to), so this should not break anything that wasn't broken before." (Please see https://bugzilla.libsdl.org/show_bug.cgi?id=3695 for more discussion.) Fixes Bugzilla #3695.
This commit is contained in:
parent
e6c640f314
commit
389c8995d2
@ -81,6 +81,10 @@
|
|||||||
#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
|
#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
|
||||||
#endif /* SDL_VIDEO_DRIVER_RPI */
|
#endif /* SDL_VIDEO_DRIVER_RPI */
|
||||||
|
|
||||||
|
#if SDL_VIDEO_OPENGL
|
||||||
|
#include "SDL_opengl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/** If we happen to not have this defined because of an older EGL version, just define it 0x0
|
/** If we happen to not have this defined because of an older EGL version, just define it 0x0
|
||||||
as eglGetPlatformDisplayEXT will most likely be NULL if this is missing
|
as eglGetPlatformDisplayEXT will most likely be NULL if this is missing
|
||||||
*/
|
*/
|
||||||
@ -943,6 +947,34 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether making contexts current without a surface is supported.
|
||||||
|
* First condition: EGL must support it. That's the case for EGL 1.5
|
||||||
|
* or later, or if the EGL_KHR_surfaceless_context extension is present. */
|
||||||
|
if ((_this->egl_data->egl_version_major > 1) ||
|
||||||
|
((_this->egl_data->egl_version_major == 1) && (_this->egl_data->egl_version_minor >= 5)) ||
|
||||||
|
SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_surfaceless_context"))
|
||||||
|
{
|
||||||
|
/* Secondary condition: The client API must support it. */
|
||||||
|
if (profile_es) {
|
||||||
|
/* On OpenGL ES, the GL_OES_surfaceless_context extension must be
|
||||||
|
* present. */
|
||||||
|
if (SDL_GL_ExtensionSupported("GL_OES_surfaceless_context")) {
|
||||||
|
_this->gl_allow_no_surface = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Desktop OpenGL supports it by default from version 3.0 on. */
|
||||||
|
void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
|
||||||
|
glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
|
||||||
|
if (glGetIntegervFunc) {
|
||||||
|
GLint v = 0;
|
||||||
|
glGetIntegervFunc(GL_MAJOR_VERSION, &v);
|
||||||
|
if (v >= 3) {
|
||||||
|
_this->gl_allow_no_surface = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (SDL_GLContext) egl_context;
|
return (SDL_GLContext) egl_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,7 +990,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
|
|||||||
/* The android emulator crashes badly if you try to eglMakeCurrent
|
/* The android emulator crashes badly if you try to eglMakeCurrent
|
||||||
* with a valid context and invalid surface, so we have to check for both here.
|
* with a valid context and invalid surface, so we have to check for both here.
|
||||||
*/
|
*/
|
||||||
if (!egl_context || !egl_surface) {
|
if (!egl_context || (!egl_surface && !_this->gl_allow_no_surface)) {
|
||||||
_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
} else {
|
} else {
|
||||||
if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
|
if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
|
||||||
|
@ -147,12 +147,7 @@ BACKEND ## _GLES_SwapWindow(_THIS, SDL_Window * window) \
|
|||||||
#define SDL_EGL_MakeCurrent_impl(BACKEND) int \
|
#define SDL_EGL_MakeCurrent_impl(BACKEND) int \
|
||||||
BACKEND ## _GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) \
|
BACKEND ## _GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) \
|
||||||
{\
|
{\
|
||||||
if (window && context) { \
|
return SDL_EGL_MakeCurrent(_this, window ? ((SDL_WindowData *) window->driverdata)->egl_surface : EGL_NO_SURFACE, context);\
|
||||||
return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); \
|
|
||||||
}\
|
|
||||||
else {\
|
|
||||||
return SDL_EGL_MakeCurrent(_this, NULL, NULL);\
|
|
||||||
}\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SDL_EGL_CreateContext_impl(BACKEND) SDL_GLContext \
|
#define SDL_EGL_CreateContext_impl(BACKEND) SDL_GLContext \
|
||||||
|
@ -375,6 +375,11 @@ struct SDL_VideoDevice
|
|||||||
SDL_TLSID current_glwin_tls;
|
SDL_TLSID current_glwin_tls;
|
||||||
SDL_TLSID current_glctx_tls;
|
SDL_TLSID current_glctx_tls;
|
||||||
|
|
||||||
|
/* Flag that stores whether it's allowed to call SDL_GL_MakeCurrent()
|
||||||
|
* with a NULL window, but a non-NULL context. (Not allowed in most cases,
|
||||||
|
* except on EGL under some circumstances.) */
|
||||||
|
int gl_allow_no_surface;
|
||||||
|
|
||||||
/* * * */
|
/* * * */
|
||||||
/* Data used by the Vulkan drivers */
|
/* Data used by the Vulkan drivers */
|
||||||
struct
|
struct
|
||||||
|
@ -3585,12 +3585,14 @@ SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
|
|||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
window = NULL;
|
window = NULL;
|
||||||
} else {
|
} else if (window) {
|
||||||
CHECK_WINDOW_MAGIC(window, -1);
|
CHECK_WINDOW_MAGIC(window, -1);
|
||||||
|
|
||||||
if (!(window->flags & SDL_WINDOW_OPENGL)) {
|
if (!(window->flags & SDL_WINDOW_OPENGL)) {
|
||||||
return SDL_SetError("The specified window isn't an OpenGL window");
|
return SDL_SetError("The specified window isn't an OpenGL window");
|
||||||
}
|
}
|
||||||
|
} else if (!_this->gl_allow_no_surface) {
|
||||||
|
return SDL_SetError("Use of OpenGL without a window is not supported on this platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = _this->GL_MakeCurrent(_this, window, ctx);
|
retval = _this->GL_MakeCurrent(_this, window, ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user