x11: Make a sacrificial glX context to check for extensions during init.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 01 Sep 2017 13:27:53 -0400
changeset 114381717e5011161
parent 11437 d53f2dddf6ee
child 11439 37688701d4ce
x11: Make a sacrificial glX context to check for extensions during init.

This is necessary because we need to see if GLES compat extensions exist.

All of this code (including ShouldUseTextureFramebuffer()) should be
revisited after 2.0.6 ships; ideally we don't make throwaway contexts if
we can avoid it...but maybe we can't. I hear Vulkan is pretty cool.

Fixes Bugzilla #3725.
src/video/SDL_video.c
src/video/x11/SDL_x11opengl.c
     1.1 --- a/src/video/SDL_video.c	Thu Aug 31 22:07:28 2017 -0300
     1.2 +++ b/src/video/SDL_video.c	Fri Sep 01 13:27:53 2017 -0400
     1.3 @@ -2941,8 +2941,8 @@
     1.4  void
     1.5  SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor)
     1.6  {
     1.7 -/* This function breaks games because OpenGL functions are being called before a context is current - see bug 3725 */
     1.8 -#if 0
     1.9 +/* THIS REQUIRES AN EXISTING GL CONTEXT THAT HAS BEEN MADE CURRENT. */
    1.10 +/*  Please refer to https://bugzilla.libsdl.org/show_bug.cgi?id=3725 for discussion. */
    1.11  #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
    1.12  	/* XXX This is fragile; it will break in the event of release of
    1.13  	 * new versions of OpenGL ES.
    1.14 @@ -2961,10 +2961,6 @@
    1.15          *minor = 0;
    1.16      }
    1.17  #endif
    1.18 -#else
    1.19 -        *major = 2;
    1.20 -        *minor = 0;
    1.21 -#endif /* 0 */
    1.22  }
    1.23  
    1.24  void
     2.1 --- a/src/video/x11/SDL_x11opengl.c	Thu Aug 31 22:07:28 2017 -0300
     2.2 +++ b/src/video/x11/SDL_x11opengl.c	Fri Sep 01 13:27:53 2017 -0400
     2.3 @@ -331,9 +331,32 @@
     2.4  {
     2.5      Display *display = ((SDL_VideoData *) _this->driverdata)->display;
     2.6      const int screen = DefaultScreen(display);
     2.7 +    XVisualInfo *vinfo;
     2.8 +    XSetWindowAttributes xattr;
     2.9 +    Window w;
    2.10 +    GLXContext context;
    2.11      const char *(*glXQueryExtensionsStringFunc) (Display *, int);
    2.12      const char *extensions;
    2.13  
    2.14 +    vinfo = X11_GL_GetVisual(_this, display, screen);
    2.15 +    if (!vinfo) {
    2.16 +        return;
    2.17 +    }
    2.18 +
    2.19 +    xattr.background_pixel = 0;
    2.20 +    xattr.border_pixel = 0;
    2.21 +    xattr.colormap =
    2.22 +        X11_XCreateColormap(display, RootWindow(display, screen), vinfo->visual,
    2.23 +                        AllocNone);
    2.24 +    w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0,
    2.25 +                      vinfo->depth, InputOutput, vinfo->visual,
    2.26 +                      (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
    2.27 +    context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
    2.28 +    if (context) {
    2.29 +        _this->gl_data->glXMakeCurrent(display, w, context);
    2.30 +    }
    2.31 +    X11_XFree(vinfo);
    2.32 +
    2.33      glXQueryExtensionsStringFunc =
    2.34          (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this,
    2.35                                                                  "glXQueryExtensionsString");
    2.36 @@ -391,10 +414,14 @@
    2.37      
    2.38      /* Check for GLX_EXT_create_context_es2_profile */
    2.39      if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) {
    2.40 -        SDL_GL_DeduceMaxSupportedESProfile(
    2.41 -            &_this->gl_data->es_profile_max_supported_version.major,
    2.42 -            &_this->gl_data->es_profile_max_supported_version.minor
    2.43 -        );
    2.44 +        /* this wants to call glGetString(), so it needs a context. */
    2.45 +        /* !!! FIXME: it would be nice not to make a context here though! */
    2.46 +        if (context) {
    2.47 +            SDL_GL_DeduceMaxSupportedESProfile(
    2.48 +                &_this->gl_data->es_profile_max_supported_version.major,
    2.49 +                &_this->gl_data->es_profile_max_supported_version.minor
    2.50 +            );
    2.51 +        }
    2.52      }
    2.53  
    2.54      /* Check for GLX_ARB_context_flush_control */
    2.55 @@ -411,6 +438,14 @@
    2.56      if (HasExtension("GLX_ARB_create_context_no_error", extensions)) {
    2.57          _this->gl_data->HAS_GLX_ARB_create_context_no_error = SDL_TRUE;
    2.58      }
    2.59 +
    2.60 +    if (context) {
    2.61 +        _this->gl_data->glXMakeCurrent(display, None, NULL);
    2.62 +        _this->gl_data->glXDestroyContext(display, context);
    2.63 +    }
    2.64 +
    2.65 +    X11_XDestroyWindow(display, w);
    2.66 +    X11_PumpEvents(_this);
    2.67  }
    2.68  
    2.69  /* glXChooseVisual and glXChooseFBConfig have some small differences in