Fixed bug 1565 - some small GL context creation enhancements
authorSam Lantinga <slouken@libsdl.org>
Sun, 12 Aug 2012 11:16:24 -0700
changeset 6393a773384edf20
parent 6392 fa7eb111f994
child 6394 9612bcd79130
Fixed bug 1565 - some small GL context creation enhancements

Matthias Bentrup 2012-08-09 12:53:17 PDT

With OpenGL 4.3 the ARB added a new context flag for context reset isolation
and renamed the existing ES2 profile bit to ES profile bit, as it can be used
to request GLES 3 compatible contexts, too.

This patch adds these changes to SDL on Linux and Windows.

Also SDL lacks the ability to create shared contexts. This patch also adds a
new GL attribute to enable context sharing. As casting a GL context to int is
not portable, I added only a boolean attribute
SDL_GL_SHARE_WITH_CURRENT_CONTEXT, which makes the new context share resources
with the context current on the creating thread.
include/SDL_video.h
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/windows/SDL_windowsopengl.c
src/video/windows/SDL_windowsopengl.h
src/video/x11/SDL_x11opengl.c
     1.1 --- a/include/SDL_video.h	Sat Aug 11 10:15:59 2012 -0700
     1.2 +++ b/include/SDL_video.h	Sun Aug 12 11:16:24 2012 -0700
     1.3 @@ -185,13 +185,15 @@
     1.4      SDL_GL_CONTEXT_MINOR_VERSION,
     1.5      SDL_GL_CONTEXT_EGL,
     1.6      SDL_GL_CONTEXT_FLAGS,
     1.7 -    SDL_GL_CONTEXT_PROFILE_MASK
     1.8 +    SDL_GL_CONTEXT_PROFILE_MASK,
     1.9 +    SDL_GL_SHARE_WITH_CURRENT_CONTEXT
    1.10  } SDL_GLattr;
    1.11  
    1.12  typedef enum
    1.13  {
    1.14      SDL_GL_CONTEXT_PROFILE_CORE           = 0x0001,
    1.15      SDL_GL_CONTEXT_PROFILE_COMPATIBILITY  = 0x0002,
    1.16 +    SDL_GL_CONTEXT_PROFILE_ES             = 0x0004,
    1.17      SDL_GL_CONTEXT_PROFILE_ES2            = 0x0004
    1.18  } SDL_GLprofile;
    1.19  
    1.20 @@ -199,7 +201,8 @@
    1.21  {
    1.22      SDL_GL_CONTEXT_DEBUG_FLAG              = 0x0001,
    1.23      SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002,
    1.24 -    SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG      = 0x0004
    1.25 +    SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG      = 0x0004,
    1.26 +    SDL_GL_CONTEXT_RESET_ISOLATION_FLAG    = 0x0008
    1.27  } SDL_GLcontextFlag;
    1.28  
    1.29  
     2.1 --- a/src/video/SDL_sysvideo.h	Sat Aug 11 10:15:59 2012 -0700
     2.2 +++ b/src/video/SDL_sysvideo.h	Sun Aug 12 11:16:24 2012 -0700
     2.3 @@ -280,6 +280,7 @@
     2.4          int flags;
     2.5          int profile_mask;
     2.6          int use_egl;
     2.7 +        int share_with_current_context;
     2.8          int retained_backing;
     2.9          int driver_loaded;
    2.10          char driver_path[256];
     3.1 --- a/src/video/SDL_video.c	Sat Aug 11 10:15:59 2012 -0700
     3.2 +++ b/src/video/SDL_video.c	Sun Aug 12 11:16:24 2012 -0700
     3.3 @@ -505,6 +505,7 @@
     3.4  #endif
     3.5      _this->gl_config.flags = 0;
     3.6      _this->gl_config.profile_mask = 0;
     3.7 +    _this->gl_config.share_with_current_context = 0;
     3.8  
     3.9      /* Initialize the video subsystem */
    3.10      if (_this->VideoInit(_this) < 0) {
    3.11 @@ -2309,11 +2310,30 @@
    3.12          _this->gl_config.use_egl = value;
    3.13          break;
    3.14      case SDL_GL_CONTEXT_FLAGS:
    3.15 +        if( value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
    3.16 +		      SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG |
    3.17 +		      SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG |
    3.18 +		      SDL_GL_CONTEXT_RESET_ISOLATION_FLAG) ) {
    3.19 +	    SDL_SetError("Unknown OpenGL context flag %d", value);
    3.20 +	    retval = -1;
    3.21 +	    break;
    3.22 +	}
    3.23          _this->gl_config.flags = value;
    3.24          break;
    3.25      case SDL_GL_CONTEXT_PROFILE_MASK:
    3.26 +        if( value != 0 &&
    3.27 +	    value != SDL_GL_CONTEXT_PROFILE_CORE &&
    3.28 +	    value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY &&
    3.29 +	    value != SDL_GL_CONTEXT_PROFILE_ES ) {
    3.30 +	    SDL_SetError("Unknown OpenGL context profile %d", value);
    3.31 +	    retval = -1;
    3.32 +	    break;
    3.33 +	}
    3.34          _this->gl_config.profile_mask = value;
    3.35          break;
    3.36 +    case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
    3.37 +        _this->gl_config.share_with_current_context = value;
    3.38 +	break;
    3.39      default:
    3.40          SDL_SetError("Unknown OpenGL attribute");
    3.41          retval = -1;
    3.42 @@ -2475,6 +2495,11 @@
    3.43              *value = _this->gl_config.profile_mask;
    3.44              return 0;
    3.45          }
    3.46 +    case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
    3.47 +        {
    3.48 +            *value = _this->gl_config.share_with_current_context;
    3.49 +            return 0;
    3.50 +        }
    3.51      default:
    3.52          SDL_SetError("Unknown OpenGL attribute");
    3.53          return -1;
     4.1 --- a/src/video/windows/SDL_windowsopengl.c	Sat Aug 11 10:15:59 2012 -0700
     4.2 +++ b/src/video/windows/SDL_windowsopengl.c	Sun Aug 12 11:16:24 2012 -0700
     4.3 @@ -61,6 +61,11 @@
     4.4  #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT           0x00000004
     4.5  #endif
     4.6  
     4.7 +#ifndef WGL_EXT_create_context_es_profile
     4.8 +#define WGL_EXT_create_context_es_profile
     4.9 +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT            0x00000004
    4.10 +#endif
    4.11 +
    4.12  typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
    4.13                                                              HGLRC
    4.14                                                              hShareContext,
    4.15 @@ -112,6 +117,8 @@
    4.16          GetProcAddress(handle, "wglDeleteContext");
    4.17      _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
    4.18          GetProcAddress(handle, "wglMakeCurrent");
    4.19 +    _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
    4.20 +        GetProcAddress(handle, "wglShareLists");
    4.21  
    4.22      if (!_this->gl_data->wglGetProcAddress ||
    4.23          !_this->gl_data->wglCreateContext ||
    4.24 @@ -519,10 +526,22 @@
    4.25  WIN_GL_CreateContext(_THIS, SDL_Window * window)
    4.26  {
    4.27      HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
    4.28 -    HGLRC context;
    4.29 +    HGLRC context, share_context;
    4.30  
    4.31 -    if (_this->gl_config.major_version < 3) {
    4.32 +    if (_this->gl_config.share_with_current_context) {
    4.33 +        share_context = (HGLRC)(_this->current_glctx);
    4.34 +    } else {
    4.35 +        share_context = 0;
    4.36 +    }
    4.37 +
    4.38 +    if (_this->gl_config.major_version < 3 &&
    4.39 +	_this->gl_config.profile_mask == 0 &&
    4.40 +	_this->gl_config.flags == 0) {
    4.41 +        /* Create legacy context */
    4.42          context = _this->gl_data->wglCreateContext(hdc);
    4.43 +	if( share_context != 0 ) {
    4.44 +            _this->gl_data->wglShareLists(share_context, hdc);
    4.45 +	}
    4.46      } else {
    4.47          PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
    4.48          HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
    4.49 @@ -567,7 +586,7 @@
    4.50  	    attribs[iattr++] = 0;
    4.51  
    4.52              /* Create the GL 3.x context */
    4.53 -            context = wglCreateContextAttribsARB(hdc, 0, attribs);
    4.54 +            context = wglCreateContextAttribsARB(hdc, share_context, attribs);
    4.55              /* Delete the GL 2.x context */
    4.56              _this->gl_data->wglDeleteContext(temp_context);
    4.57          }
     5.1 --- a/src/video/windows/SDL_windowsopengl.h	Sat Aug 11 10:15:59 2012 -0700
     5.2 +++ b/src/video/windows/SDL_windowsopengl.h	Sun Aug 12 11:16:24 2012 -0700
     5.3 @@ -34,6 +34,7 @@
     5.4        HGLRC(WINAPI * wglCreateContext) (HDC hdc);
     5.5        BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
     5.6        BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
     5.7 +      BOOL(WINAPI * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2);
     5.8        BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
     5.9                                                const int *piAttribIList,
    5.10                                                const FLOAT * pfAttribFList,
     6.1 --- a/src/video/x11/SDL_x11opengl.c	Sat Aug 11 10:15:59 2012 -0700
     6.2 +++ b/src/video/x11/SDL_x11opengl.c	Sun Aug 12 11:16:24 2012 -0700
     6.3 @@ -484,7 +484,13 @@
     6.4      XWindowAttributes xattr;
     6.5      XVisualInfo v, *vinfo;
     6.6      int n;
     6.7 -    GLXContext context = NULL;
     6.8 +    GLXContext context = NULL, share_context;
     6.9 +
    6.10 +    if (_this->gl_config.share_with_current_context) {
    6.11 +        share_context = (GLXContext)(_this->current_glctx);
    6.12 +    } else {
    6.13 +        share_context = NULL;
    6.14 +    }
    6.15  
    6.16      /* We do this to create a clean separation between X and GLX errors. */
    6.17      XSync(display, False);
    6.18 @@ -493,9 +499,12 @@
    6.19      v.visualid = XVisualIDFromVisual(xattr.visual);
    6.20      vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
    6.21      if (vinfo) {
    6.22 -        if (_this->gl_config.major_version < 3) {
    6.23 +        if (_this->gl_config.major_version < 3 &&
    6.24 +            _this->gl_config.profile_mask == 0 &&
    6.25 +            _this->gl_config.flags == 0) {
    6.26 +            /* Create legacy context */
    6.27              context =
    6.28 -                _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
    6.29 +                _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
    6.30          } else {
    6.31              /* If we want a GL 3.0 context or later we need to get a temporary
    6.32                 context to grab the new context creation function */
    6.33 @@ -505,7 +514,7 @@
    6.34                  SDL_SetError("Could not create GL context");
    6.35                  return NULL;
    6.36              } else {
    6.37 -	        /* max 8 attributes plus terminator */
    6.38 +                /* max 8 attributes plus terminator */
    6.39                  int attribs[9] = {
    6.40                      GLX_CONTEXT_MAJOR_VERSION_ARB,
    6.41                      _this->gl_config.major_version,
    6.42 @@ -513,21 +522,21 @@
    6.43                      _this->gl_config.minor_version,
    6.44                      0
    6.45                  };
    6.46 -		int iattr = 4;
    6.47 +                int iattr = 4;
    6.48  
    6.49 -		/* SDL profile bits match GLX profile bits */
    6.50 -		if( _this->gl_config.profile_mask != 0 ) {
    6.51 -		    attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
    6.52 -		    attribs[iattr++] = _this->gl_config.profile_mask;
    6.53 -		}
    6.54 +                /* SDL profile bits match GLX profile bits */
    6.55 +                if( _this->gl_config.profile_mask != 0 ) {
    6.56 +                    attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
    6.57 +                    attribs[iattr++] = _this->gl_config.profile_mask;
    6.58 +                }
    6.59  
    6.60 -		/* SDL flags match GLX flags */
    6.61 -		if( _this->gl_config.flags != 0 ) {
    6.62 -		    attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
    6.63 -		    attribs[iattr++] = _this->gl_config.flags;
    6.64 -		}
    6.65 +                /* SDL flags match GLX flags */
    6.66 +                if( _this->gl_config.flags != 0 ) {
    6.67 +                    attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
    6.68 +                    attribs[iattr++] = _this->gl_config.flags;
    6.69 +                }
    6.70  
    6.71 -		attribs[iattr++] = 0;
    6.72 +                attribs[iattr++] = 0;
    6.73  
    6.74                  /* Get a pointer to the context creation function for GL 3.0 */
    6.75                  PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
    6.76 @@ -568,7 +577,7 @@
    6.77                          context =
    6.78                              glXCreateContextAttribs(display,
    6.79                                                      framebuffer_config[0],
    6.80 -                                                    NULL, True, attribs);
    6.81 +                                                    share_context, True, attribs);
    6.82                          _this->gl_data->glXDestroyContext(display,
    6.83                                                            temp_context);
    6.84                      }