diff --git a/VisualC/tests/testgles2/testgles2.vcxproj b/VisualC/tests/testgles2/testgles2.vcxproj index 186f6affd..f1c633a43 100644 --- a/VisualC/tests/testgles2/testgles2.vcxproj +++ b/VisualC/tests/testgles2/testgles2.vcxproj @@ -189,6 +189,12 @@ false true + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + @@ -196,4 +202,4 @@ - \ No newline at end of file + diff --git a/VisualC/tests/testgles2/testgles2_VS2008.vcproj b/VisualC/tests/testgles2/testgles2_VS2008.vcproj index b70a13715..efe5355b8 100644 --- a/VisualC/tests/testgles2/testgles2_VS2008.vcproj +++ b/VisualC/tests/testgles2/testgles2_VS2008.vcproj @@ -336,6 +336,10 @@ CopyLocalSatelliteAssemblies="false" RelativePathToProject=".\SDLmain\SDLmain_VS2008.vcproj" /> + 0. To avoid this + test failing, increment driver_loaded around the call to + WIN_GLInitExtensions. + + Successful loading of the library is normally indicated by + SDL_GL_LoadLibrary incrementing driver_loaded immediately after + this function returns 0 to it. + + Alternatives to this are: + - moving SDL_GL_DeduceMaxSupportedESProfile to both the WIN and + X11 platforms while adding a function equivalent to + SDL_GL_ExtensionSupported but which directly calls + glGetProcAddress(). Having 3 copies of the + SDL_GL_ExtensionSupported makes this alternative unattractive. + - moving SDL_GL_DeduceMaxSupportedESProfile to a new file shared + by the WIN and X11 platforms while adding a function equivalent + to SDL_GL_ExtensionSupported. This is unattractive due to the + number of project files that will need updating, plus there + will be 2 copies of the SDL_GL_ExtensionSupported code. + - Add a private equivalent of SDL_GL_ExtensionSupported to + SDL_video.c. + - Move the call to WIN_GL_InitExtensions back to WIN_CreateWindow + and add a flag to gl_data to avoid multiple calls to this + expensive function. This is probably the least objectionable + alternative if this increment/decrement trick is unacceptable. + + Note that the driver_loaded > 0 check needs to remain in + SDL_GL_ExtensionSupported and SDL_GL_GetProcAddress as they are + public API functions. + */ + ++_this->gl_config.driver_loaded; + WIN_GL_InitExtensions(_this); + --_this->gl_config.driver_loaded; + return 0; } @@ -407,9 +446,11 @@ WIN_GL_InitExtensions(_THIS) } /* Check for WGL_EXT_create_context_es2_profile */ - _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_FALSE; if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) { - _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_TRUE; + SDL_GL_DeduceMaxSupportedESProfile( + &_this->gl_data->es_profile_max_supported_version.major, + &_this->gl_data->es_profile_max_supported_version.minor + ); } /* Check for GLX_ARB_context_flush_control */ @@ -593,14 +634,26 @@ WIN_GL_SetupWindow(_THIS, SDL_Window * window) return retval; } +SDL_bool +WIN_GL_UseEGL(_THIS) +{ + SDL_assert(_this->gl_data != NULL); + SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES); + + return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) + || _this->gl_config.major_version == 1 /* No WGL extension for OpenGL ES 1.x profiles. */ + || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major + || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major + && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor)); +} + SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window) { HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; HGLRC context, share_context; - if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && - !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile) { + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) { #if SDL_VIDEO_OPENGL_EGL /* Switch to EGL based functions */ WIN_GL_UnloadLibrary(_this); diff --git a/src/video/windows/SDL_windowsopengl.h b/src/video/windows/SDL_windowsopengl.h index b01f96bc7..de0a1c76b 100644 --- a/src/video/windows/SDL_windowsopengl.h +++ b/src/video/windows/SDL_windowsopengl.h @@ -29,10 +29,18 @@ struct SDL_GLDriverData { SDL_bool HAS_WGL_ARB_pixel_format; SDL_bool HAS_WGL_EXT_swap_control_tear; - SDL_bool HAS_WGL_EXT_create_context_es2_profile; SDL_bool HAS_WGL_ARB_context_flush_control; - void *(WINAPI * wglGetProcAddress) (const char *proc); + /* Max version of OpenGL ES context that can be created if the + implementation supports WGL_EXT_create_context_es2_profile. + major = minor = 0 when unsupported. + */ + struct { + int major; + int minor; + } es_profile_max_supported_version; + + void *(WINAPI * wglGetProcAddress) (const char *proc); HGLRC(WINAPI * wglCreateContext) (HDC hdc); BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc); BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc); @@ -56,6 +64,7 @@ struct SDL_GLDriverData extern int WIN_GL_LoadLibrary(_THIS, const char *path); extern void *WIN_GL_GetProcAddress(_THIS, const char *proc); extern void WIN_GL_UnloadLibrary(_THIS); +extern SDL_bool WIN_GL_UseEGL(_THIS); extern int WIN_GL_SetupWindow(_THIS, SDL_Window * window); extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window); extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window, diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index f1eeb2819..531010e0e 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -263,6 +263,8 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) return 0; } + + int WIN_CreateWindow(_THIS, SDL_Window * window) { @@ -299,38 +301,36 @@ WIN_CreateWindow(_THIS, SDL_Window * window) return -1; } -#if SDL_VIDEO_OPENGL_WGL - /* We need to initialize the extensions before deciding how to create ES profiles */ - if (window->flags & SDL_WINDOW_OPENGL) { - WIN_GL_InitExtensions(_this); + if (!(window->flags & SDL_WINDOW_OPENGL)) { + return 0; } -#endif + /* The rest of this macro mess is for OpenGL or OpenGL ES windows */ #if SDL_VIDEO_OPENGL_ES2 - if ((window->flags & SDL_WINDOW_OPENGL) && - _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES -#if SDL_VIDEO_OPENGL_WGL - && (!_this->gl_data || !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile) -#endif - ) { -#if SDL_VIDEO_OPENGL_EGL + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES +#if SDL_VIDEO_OPENGL_WGL + && (!_this->gl_data || WIN_GL_UseEGL(_this)) +#endif /* SDL_VIDEO_OPENGL_WGL */ + ) { +#if SDL_VIDEO_OPENGL_EGL if (WIN_GLES_SetupWindow(_this, window) < 0) { WIN_DestroyWindow(_this, window); return -1; } + return 0; #else - return SDL_SetError("Could not create GLES window surface (no EGL support available)"); -#endif /* SDL_VIDEO_OPENGL_EGL */ - } else + return SDL_SetError("Could not create GLES window surface (EGL support not configured)"); +#endif /* SDL_VIDEO_OPENGL_EGL */ + } #endif /* SDL_VIDEO_OPENGL_ES2 */ #if SDL_VIDEO_OPENGL_WGL - if (window->flags & SDL_WINDOW_OPENGL) { - if (WIN_GL_SetupWindow(_this, window) < 0) { - WIN_DestroyWindow(_this, window); - return -1; - } + if (WIN_GL_SetupWindow(_this, window) < 0) { + WIN_DestroyWindow(_this, window); + return -1; } +#else + return SDL_SetError("Could not create GL window (WGL support not configured)"); #endif return 0; diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index e407c2922..a16bdc268 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -24,6 +24,7 @@ #include "SDL_x11video.h" #include "SDL_assert.h" +#include "SDL_hints.h" /* GLX implementation of SDL OpenGL support */ @@ -143,7 +144,6 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, static void X11_GL_InitExtensions(_THIS); - int X11_GL_LoadLibrary(_THIS, const char *path) { @@ -222,13 +222,17 @@ X11_GL_LoadLibrary(_THIS, const char *path) } /* Initialize extensions */ + /* See lengthy comment about the inc/dec in + ../windows/SDL_windowsopengl.c. */ + ++_this->gl_config.driver_loaded; X11_GL_InitExtensions(_this); + --_this->gl_config.driver_loaded; /* If we need a GL ES context and there's no * GLX_EXT_create_context_es2_profile extension, switch over to X11_GLES functions */ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && - ! _this->gl_data->HAS_GLX_EXT_create_context_es2_profile ) { + X11_GL_UseEGL(_this) ) { #if SDL_VIDEO_OPENGL_EGL X11_GL_UnloadLibrary(_this); /* Better avoid conflicts! */ @@ -380,7 +384,10 @@ X11_GL_InitExtensions(_THIS) /* Check for GLX_EXT_create_context_es2_profile */ if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) { - _this->gl_data->HAS_GLX_EXT_create_context_es2_profile = SDL_TRUE; + SDL_GL_DeduceMaxSupportedESProfile( + &_this->gl_data->es_profile_max_supported_version.major, + &_this->gl_data->es_profile_max_supported_version.minor + ); } /* Check for GLX_ARB_context_flush_control */ @@ -565,6 +572,19 @@ X11_GL_ErrorHandler(Display * d, XErrorEvent * e) return (0); } +SDL_bool +X11_GL_UseEGL(_THIS) +{ + SDL_assert(_this->gl_data != NULL); + SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES); + + return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) + || _this->gl_config.major_version == 1 /* No GLX extension for OpenGL ES 1.x profiles. */ + || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major + || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major + && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor)); +} + SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window) { diff --git a/src/video/x11/SDL_x11opengl.h b/src/video/x11/SDL_x11opengl.h index 0f81e2160..5d781c3e1 100644 --- a/src/video/x11/SDL_x11opengl.h +++ b/src/video/x11/SDL_x11opengl.h @@ -34,9 +34,17 @@ struct SDL_GLDriverData SDL_bool HAS_GLX_EXT_visual_rating; SDL_bool HAS_GLX_EXT_visual_info; SDL_bool HAS_GLX_EXT_swap_control_tear; - SDL_bool HAS_GLX_EXT_create_context_es2_profile; SDL_bool HAS_GLX_ARB_context_flush_control; + /* Max version of OpenGL ES context that can be created if the + implementation supports WGL_EXT_create_context_es2_profile. + major = minor = 0 when unsupported. + */ + struct { + int major; + int minor; + } es_profile_max_supported_version; + Bool (*glXQueryExtension) (Display*,int*,int*); void *(*glXGetProcAddress) (const GLubyte*); XVisualInfo *(*glXChooseVisual) (Display*,int,int*); @@ -57,6 +65,7 @@ struct SDL_GLDriverData extern int X11_GL_LoadLibrary(_THIS, const char *path); extern void *X11_GL_GetProcAddress(_THIS, const char *proc); extern void X11_GL_UnloadLibrary(_THIS); +extern SDL_bool X11_GL_UseEGL(_THIS); extern XVisualInfo *X11_GL_GetVisual(_THIS, Display * display, int screen); extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window); extern int X11_GL_MakeCurrent(_THIS, SDL_Window * window, diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index a6042af68..908244854 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -389,7 +389,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) #if SDL_VIDEO_OPENGL_EGL if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES #if SDL_VIDEO_OPENGL_GLX - && ( !_this->gl_data || ! _this->gl_data->HAS_GLX_EXT_create_context_es2_profile ) + && ( !_this->gl_data || X11_GL_UseEGL(_this) ) #endif ) { vinfo = X11_GLES_GetVisual(_this, display, screen); @@ -600,7 +600,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) if ((window->flags & SDL_WINDOW_OPENGL) && _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES #if SDL_VIDEO_OPENGL_GLX - && ( !_this->gl_data || ! _this->gl_data->HAS_GLX_EXT_create_context_es2_profile ) + && ( !_this->gl_data || X11_GL_UseEGL(_this) ) #endif ) { #if SDL_VIDEO_OPENGL_EGL @@ -617,7 +617,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) return SDL_SetError("Could not create GLES window surface"); } #else - return SDL_SetError("Could not create GLES window surface (no EGL support available)"); + return SDL_SetError("Could not create GLES window surface (EGL support not configured)"); #endif /* SDL_VIDEO_OPENGL_EGL */ } #endif diff --git a/test/testgles2.c b/test/testgles2.c index d6261cba6..58a46ac02 100644 --- a/test/testgles2.c +++ b/test/testgles2.c @@ -20,7 +20,8 @@ #include "SDL_test_common.h" -#if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) +#if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \ + || defined(__WINDOWS__) || defined(__LINUX__) #define HAVE_OPENGLES2 #endif