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.
--- a/include/SDL_video.h Sat Aug 11 10:15:59 2012 -0700
+++ b/include/SDL_video.h Sun Aug 12 11:16:24 2012 -0700
@@ -185,13 +185,15 @@
SDL_GL_CONTEXT_MINOR_VERSION,
SDL_GL_CONTEXT_EGL,
SDL_GL_CONTEXT_FLAGS,
- SDL_GL_CONTEXT_PROFILE_MASK
+ SDL_GL_CONTEXT_PROFILE_MASK,
+ SDL_GL_SHARE_WITH_CURRENT_CONTEXT
} SDL_GLattr;
typedef enum
{
SDL_GL_CONTEXT_PROFILE_CORE = 0x0001,
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002,
+ SDL_GL_CONTEXT_PROFILE_ES = 0x0004,
SDL_GL_CONTEXT_PROFILE_ES2 = 0x0004
} SDL_GLprofile;
@@ -199,7 +201,8 @@
{
SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001,
SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002,
- SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004
+ SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004,
+ SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
} SDL_GLcontextFlag;
--- a/src/video/SDL_sysvideo.h Sat Aug 11 10:15:59 2012 -0700
+++ b/src/video/SDL_sysvideo.h Sun Aug 12 11:16:24 2012 -0700
@@ -280,6 +280,7 @@
int flags;
int profile_mask;
int use_egl;
+ int share_with_current_context;
int retained_backing;
int driver_loaded;
char driver_path[256];
--- a/src/video/SDL_video.c Sat Aug 11 10:15:59 2012 -0700
+++ b/src/video/SDL_video.c Sun Aug 12 11:16:24 2012 -0700
@@ -505,6 +505,7 @@
#endif
_this->gl_config.flags = 0;
_this->gl_config.profile_mask = 0;
+ _this->gl_config.share_with_current_context = 0;
/* Initialize the video subsystem */
if (_this->VideoInit(_this) < 0) {
@@ -2309,11 +2310,30 @@
_this->gl_config.use_egl = value;
break;
case SDL_GL_CONTEXT_FLAGS:
+ if( value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
+ SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG |
+ SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG |
+ SDL_GL_CONTEXT_RESET_ISOLATION_FLAG) ) {
+ SDL_SetError("Unknown OpenGL context flag %d", value);
+ retval = -1;
+ break;
+ }
_this->gl_config.flags = value;
break;
case SDL_GL_CONTEXT_PROFILE_MASK:
+ if( value != 0 &&
+ value != SDL_GL_CONTEXT_PROFILE_CORE &&
+ value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY &&
+ value != SDL_GL_CONTEXT_PROFILE_ES ) {
+ SDL_SetError("Unknown OpenGL context profile %d", value);
+ retval = -1;
+ break;
+ }
_this->gl_config.profile_mask = value;
break;
+ case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
+ _this->gl_config.share_with_current_context = value;
+ break;
default:
SDL_SetError("Unknown OpenGL attribute");
retval = -1;
@@ -2475,6 +2495,11 @@
*value = _this->gl_config.profile_mask;
return 0;
}
+ case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
+ {
+ *value = _this->gl_config.share_with_current_context;
+ return 0;
+ }
default:
SDL_SetError("Unknown OpenGL attribute");
return -1;
--- a/src/video/windows/SDL_windowsopengl.c Sat Aug 11 10:15:59 2012 -0700
+++ b/src/video/windows/SDL_windowsopengl.c Sun Aug 12 11:16:24 2012 -0700
@@ -61,6 +61,11 @@
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif
+#ifndef WGL_EXT_create_context_es_profile
+#define WGL_EXT_create_context_es_profile
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#endif
+
typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
HGLRC
hShareContext,
@@ -112,6 +117,8 @@
GetProcAddress(handle, "wglDeleteContext");
_this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
GetProcAddress(handle, "wglMakeCurrent");
+ _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
+ GetProcAddress(handle, "wglShareLists");
if (!_this->gl_data->wglGetProcAddress ||
!_this->gl_data->wglCreateContext ||
@@ -519,10 +526,22 @@
WIN_GL_CreateContext(_THIS, SDL_Window * window)
{
HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
- HGLRC context;
+ HGLRC context, share_context;
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (HGLRC)(_this->current_glctx);
+ } else {
+ share_context = 0;
+ }
- if (_this->gl_config.major_version < 3) {
+ if (_this->gl_config.major_version < 3 &&
+ _this->gl_config.profile_mask == 0 &&
+ _this->gl_config.flags == 0) {
+ /* Create legacy context */
context = _this->gl_data->wglCreateContext(hdc);
+ if( share_context != 0 ) {
+ _this->gl_data->wglShareLists(share_context, hdc);
+ }
} else {
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
@@ -567,7 +586,7 @@
attribs[iattr++] = 0;
/* Create the GL 3.x context */
- context = wglCreateContextAttribsARB(hdc, 0, attribs);
+ context = wglCreateContextAttribsARB(hdc, share_context, attribs);
/* Delete the GL 2.x context */
_this->gl_data->wglDeleteContext(temp_context);
}
--- a/src/video/windows/SDL_windowsopengl.h Sat Aug 11 10:15:59 2012 -0700
+++ b/src/video/windows/SDL_windowsopengl.h Sun Aug 12 11:16:24 2012 -0700
@@ -34,6 +34,7 @@
HGLRC(WINAPI * wglCreateContext) (HDC hdc);
BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
+ BOOL(WINAPI * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2);
BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
const int *piAttribIList,
const FLOAT * pfAttribFList,
--- a/src/video/x11/SDL_x11opengl.c Sat Aug 11 10:15:59 2012 -0700
+++ b/src/video/x11/SDL_x11opengl.c Sun Aug 12 11:16:24 2012 -0700
@@ -484,7 +484,13 @@
XWindowAttributes xattr;
XVisualInfo v, *vinfo;
int n;
- GLXContext context = NULL;
+ GLXContext context = NULL, share_context;
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (GLXContext)(_this->current_glctx);
+ } else {
+ share_context = NULL;
+ }
/* We do this to create a clean separation between X and GLX errors. */
XSync(display, False);
@@ -493,9 +499,12 @@
v.visualid = XVisualIDFromVisual(xattr.visual);
vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
if (vinfo) {
- if (_this->gl_config.major_version < 3) {
+ if (_this->gl_config.major_version < 3 &&
+ _this->gl_config.profile_mask == 0 &&
+ _this->gl_config.flags == 0) {
+ /* Create legacy context */
context =
- _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
+ _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
} else {
/* If we want a GL 3.0 context or later we need to get a temporary
context to grab the new context creation function */
@@ -505,7 +514,7 @@
SDL_SetError("Could not create GL context");
return NULL;
} else {
- /* max 8 attributes plus terminator */
+ /* max 8 attributes plus terminator */
int attribs[9] = {
GLX_CONTEXT_MAJOR_VERSION_ARB,
_this->gl_config.major_version,
@@ -513,21 +522,21 @@
_this->gl_config.minor_version,
0
};
- int iattr = 4;
+ int iattr = 4;
- /* SDL profile bits match GLX profile bits */
- if( _this->gl_config.profile_mask != 0 ) {
- attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
- attribs[iattr++] = _this->gl_config.profile_mask;
- }
+ /* SDL profile bits match GLX profile bits */
+ if( _this->gl_config.profile_mask != 0 ) {
+ attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
+ attribs[iattr++] = _this->gl_config.profile_mask;
+ }
- /* SDL flags match GLX flags */
- if( _this->gl_config.flags != 0 ) {
- attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
- attribs[iattr++] = _this->gl_config.flags;
- }
+ /* SDL flags match GLX flags */
+ if( _this->gl_config.flags != 0 ) {
+ attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
+ attribs[iattr++] = _this->gl_config.flags;
+ }
- attribs[iattr++] = 0;
+ attribs[iattr++] = 0;
/* Get a pointer to the context creation function for GL 3.0 */
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
@@ -568,7 +577,7 @@
context =
glXCreateContextAttribs(display,
framebuffer_config[0],
- NULL, True, attribs);
+ share_context, True, attribs);
_this->gl_data->glXDestroyContext(display,
temp_context);
}