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:
parent
bf2304785f
commit
99502c82fd
6 changed files with 80 additions and 22 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 */
|
||||||
|
@ -505,7 +514,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
SDL_SetError("Could not create GL context");
|
SDL_SetError("Could not create GL context");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
/* max 8 attributes plus terminator */
|
/* max 8 attributes plus terminator */
|
||||||
int attribs[9] = {
|
int attribs[9] = {
|
||||||
GLX_CONTEXT_MAJOR_VERSION_ARB,
|
GLX_CONTEXT_MAJOR_VERSION_ARB,
|
||||||
_this->gl_config.major_version,
|
_this->gl_config.major_version,
|
||||||
|
@ -513,21 +522,21 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
_this->gl_config.minor_version,
|
_this->gl_config.minor_version,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
int iattr = 4;
|
int iattr = 4;
|
||||||
|
|
||||||
/* SDL profile bits match GLX profile bits */
|
/* SDL profile bits match GLX profile bits */
|
||||||
if( _this->gl_config.profile_mask != 0 ) {
|
if( _this->gl_config.profile_mask != 0 ) {
|
||||||
attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
|
attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
|
||||||
attribs[iattr++] = _this->gl_config.profile_mask;
|
attribs[iattr++] = _this->gl_config.profile_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SDL flags match GLX flags */
|
/* SDL flags match GLX flags */
|
||||||
if( _this->gl_config.flags != 0 ) {
|
if( _this->gl_config.flags != 0 ) {
|
||||||
attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
|
attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
|
||||||
attribs[iattr++] = _this->gl_config.flags;
|
attribs[iattr++] = _this->gl_config.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs[iattr++] = 0;
|
attribs[iattr++] = 0;
|
||||||
|
|
||||||
/* Get a pointer to the context creation function for GL 3.0 */
|
/* Get a pointer to the context creation function for GL 3.0 */
|
||||||
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
|
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue