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.
This commit is contained in:
Sam Lantinga 2012-08-12 11:16:24 -07:00
parent bf2304785f
commit 99502c82fd
6 changed files with 80 additions and 22 deletions

View file

@ -185,13 +185,15 @@ typedef enum
SDL_GL_CONTEXT_MINOR_VERSION, SDL_GL_CONTEXT_MINOR_VERSION,
SDL_GL_CONTEXT_EGL, SDL_GL_CONTEXT_EGL,
SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FLAGS,
SDL_GL_CONTEXT_PROFILE_MASK SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_SHARE_WITH_CURRENT_CONTEXT
} SDL_GLattr; } SDL_GLattr;
typedef enum typedef enum
{ {
SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, SDL_GL_CONTEXT_PROFILE_CORE = 0x0001,
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002,
SDL_GL_CONTEXT_PROFILE_ES = 0x0004,
SDL_GL_CONTEXT_PROFILE_ES2 = 0x0004 SDL_GL_CONTEXT_PROFILE_ES2 = 0x0004
} SDL_GLprofile; } SDL_GLprofile;
@ -199,7 +201,8 @@ typedef enum
{ {
SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001,
SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, 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; } SDL_GLcontextFlag;

View file

@ -280,6 +280,7 @@ struct SDL_VideoDevice
int flags; int flags;
int profile_mask; int profile_mask;
int use_egl; int use_egl;
int share_with_current_context;
int retained_backing; int retained_backing;
int driver_loaded; int driver_loaded;
char driver_path[256]; char driver_path[256];

View file

@ -505,6 +505,7 @@ SDL_VideoInit(const char *driver_name)
#endif #endif
_this->gl_config.flags = 0; _this->gl_config.flags = 0;
_this->gl_config.profile_mask = 0; _this->gl_config.profile_mask = 0;
_this->gl_config.share_with_current_context = 0;
/* Initialize the video subsystem */ /* Initialize the video subsystem */
if (_this->VideoInit(_this) < 0) { if (_this->VideoInit(_this) < 0) {
@ -2309,11 +2310,30 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value)
_this->gl_config.use_egl = value; _this->gl_config.use_egl = value;
break; break;
case SDL_GL_CONTEXT_FLAGS: 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; _this->gl_config.flags = value;
break; break;
case SDL_GL_CONTEXT_PROFILE_MASK: 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; _this->gl_config.profile_mask = value;
break; break;
case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
_this->gl_config.share_with_current_context = value;
break;
default: default:
SDL_SetError("Unknown OpenGL attribute"); SDL_SetError("Unknown OpenGL attribute");
retval = -1; retval = -1;
@ -2475,6 +2495,11 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
*value = _this->gl_config.profile_mask; *value = _this->gl_config.profile_mask;
return 0; return 0;
} }
case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
{
*value = _this->gl_config.share_with_current_context;
return 0;
}
default: default:
SDL_SetError("Unknown OpenGL attribute"); SDL_SetError("Unknown OpenGL attribute");
return -1; return -1;

View file

@ -61,6 +61,11 @@
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif #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, typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
HGLRC HGLRC
hShareContext, hShareContext,
@ -112,6 +117,8 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
GetProcAddress(handle, "wglDeleteContext"); GetProcAddress(handle, "wglDeleteContext");
_this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC)) _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
GetProcAddress(handle, "wglMakeCurrent"); GetProcAddress(handle, "wglMakeCurrent");
_this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
GetProcAddress(handle, "wglShareLists");
if (!_this->gl_data->wglGetProcAddress || if (!_this->gl_data->wglGetProcAddress ||
!_this->gl_data->wglCreateContext || !_this->gl_data->wglCreateContext ||
@ -519,10 +526,22 @@ SDL_GLContext
WIN_GL_CreateContext(_THIS, SDL_Window * window) WIN_GL_CreateContext(_THIS, SDL_Window * window)
{ {
HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
HGLRC context; HGLRC context, share_context;
if (_this->gl_config.major_version < 3) { 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 &&
_this->gl_config.profile_mask == 0 &&
_this->gl_config.flags == 0) {
/* Create legacy context */
context = _this->gl_data->wglCreateContext(hdc); context = _this->gl_data->wglCreateContext(hdc);
if( share_context != 0 ) {
_this->gl_data->wglShareLists(share_context, hdc);
}
} else { } else {
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
HGLRC temp_context = _this->gl_data->wglCreateContext(hdc); HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
@ -567,7 +586,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window)
attribs[iattr++] = 0; attribs[iattr++] = 0;
/* Create the GL 3.x context */ /* Create the GL 3.x context */
context = wglCreateContextAttribsARB(hdc, 0, attribs); context = wglCreateContextAttribsARB(hdc, share_context, attribs);
/* Delete the GL 2.x context */ /* Delete the GL 2.x context */
_this->gl_data->wglDeleteContext(temp_context); _this->gl_data->wglDeleteContext(temp_context);
} }

View file

@ -34,6 +34,7 @@ struct SDL_GLDriverData
HGLRC(WINAPI * wglCreateContext) (HDC hdc); HGLRC(WINAPI * wglCreateContext) (HDC hdc);
BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc); BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc); BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
BOOL(WINAPI * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2);
BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc, BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
const int *piAttribIList, const int *piAttribIList,
const FLOAT * pfAttribFList, const FLOAT * pfAttribFList,

View file

@ -484,7 +484,13 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
XWindowAttributes xattr; XWindowAttributes xattr;
XVisualInfo v, *vinfo; XVisualInfo v, *vinfo;
int n; 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. */ /* We do this to create a clean separation between X and GLX errors. */
XSync(display, False); XSync(display, False);
@ -493,9 +499,12 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
v.visualid = XVisualIDFromVisual(xattr.visual); v.visualid = XVisualIDFromVisual(xattr.visual);
vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n); vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
if (vinfo) { 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 = context =
_this->gl_data->glXCreateContext(display, vinfo, NULL, True); _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
} else { } else {
/* If we want a GL 3.0 context or later we need to get a temporary /* If we want a GL 3.0 context or later we need to get a temporary
context to grab the new context creation function */ context to grab the new context creation function */
@ -568,7 +577,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
context = context =
glXCreateContextAttribs(display, glXCreateContextAttribs(display,
framebuffer_config[0], framebuffer_config[0],
NULL, True, attribs); share_context, True, attribs);
_this->gl_data->glXDestroyContext(display, _this->gl_data->glXDestroyContext(display,
temp_context); temp_context);
} }