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