opengl: Add support for [GLX|WGL]_ARB_create_context_robustness.

This patch was originally written by Marc Di Luzio for glX and enhanced by
Maximilian Malek for WGL, etc. Thanks to both of you!

Fixes Bugzilla #3643.
Fixes Bugzilla #3735.
This commit is contained in:
Ryan C. Gordon 2017-08-19 15:02:03 -04:00
parent 18a6538507
commit 01e0d8fc85
7 changed files with 47 additions and 6 deletions

View File

@ -201,7 +201,8 @@ typedef enum
SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_SHARE_WITH_CURRENT_CONTEXT, SDL_GL_SHARE_WITH_CURRENT_CONTEXT,
SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, SDL_GL_FRAMEBUFFER_SRGB_CAPABLE,
SDL_GL_CONTEXT_RELEASE_BEHAVIOR SDL_GL_CONTEXT_RELEASE_BEHAVIOR,
SDL_GL_CONTEXT_RESET_NOTIFICATION
} SDL_GLattr; } SDL_GLattr;
typedef enum typedef enum
@ -225,6 +226,12 @@ typedef enum
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001
} SDL_GLcontextReleaseFlag; } SDL_GLcontextReleaseFlag;
typedef enum
{
SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000,
SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001
} SDL_GLContextResetNotification;
/* Function prototypes */ /* Function prototypes */

View File

@ -329,6 +329,7 @@ struct SDL_VideoDevice
int profile_mask; int profile_mask;
int share_with_current_context; int share_with_current_context;
int release_behavior; int release_behavior;
int reset_notification;
int framebuffer_srgb_capable; int framebuffer_srgb_capable;
int retained_backing; int retained_backing;
int driver_loaded; int driver_loaded;

View File

@ -2990,6 +2990,7 @@ SDL_GL_ResetAttributes()
_this->gl_config.flags = 0; _this->gl_config.flags = 0;
_this->gl_config.framebuffer_srgb_capable = 0; _this->gl_config.framebuffer_srgb_capable = 0;
_this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH; _this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
_this->gl_config.reset_notification = SDL_GL_CONTEXT_RESET_NO_NOTIFICATION;
_this->gl_config.share_with_current_context = 0; _this->gl_config.share_with_current_context = 0;
} }
@ -3099,6 +3100,9 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value)
case SDL_GL_CONTEXT_RELEASE_BEHAVIOR: case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
_this->gl_config.release_behavior = value; _this->gl_config.release_behavior = value;
break; break;
case SDL_GL_CONTEXT_RESET_NOTIFICATION:
_this->gl_config.reset_notification = value;
break;
default: default:
retval = SDL_SetError("Unknown OpenGL attribute"); retval = SDL_SetError("Unknown OpenGL attribute");
break; break;

View File

@ -453,11 +453,16 @@ WIN_GL_InitExtensions(_THIS)
); );
} }
/* Check for GLX_ARB_context_flush_control */ /* Check for WGL_ARB_context_flush_control */
if (HasExtension("WGL_ARB_context_flush_control", extensions)) { if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
_this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE; _this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
} }
/* Check for WGL_ARB_create_context_robustness */
if (HasExtension("WGL_ARB_create_context_robustness", extensions)) {
_this->gl_data->HAS_WGL_ARB_create_context_robustness = SDL_TRUE;
}
_this->gl_data->wglMakeCurrent(hdc, NULL); _this->gl_data->wglMakeCurrent(hdc, NULL);
_this->gl_data->wglDeleteContext(hglrc); _this->gl_data->wglDeleteContext(hglrc);
ReleaseDC(hwnd, hdc); ReleaseDC(hwnd, hdc);
@ -713,8 +718,8 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window)
SDL_SetError("GL 3.x is not supported"); SDL_SetError("GL 3.x is not supported");
context = temp_context; context = temp_context;
} else { } else {
/* max 10 attributes plus terminator */ /* max 12 attributes plus terminator */
int attribs[11] = { int attribs[13] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version, WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
0 0
@ -741,6 +746,14 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window)
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
} }
/* only set if wgl extension is available */
if (_this->gl_data->HAS_WGL_ARB_create_context_robustness) {
attribs[iattr++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
attribs[iattr++] = _this->gl_config.reset_notification ?
WGL_LOSE_CONTEXT_ON_RESET_ARB :
WGL_NO_RESET_NOTIFICATION_ARB;
}
attribs[iattr++] = 0; attribs[iattr++] = 0;
/* Create the GL 3.x context */ /* Create the GL 3.x context */

View File

@ -30,6 +30,7 @@ struct SDL_GLDriverData
SDL_bool HAS_WGL_ARB_pixel_format; SDL_bool HAS_WGL_ARB_pixel_format;
SDL_bool HAS_WGL_EXT_swap_control_tear; SDL_bool HAS_WGL_EXT_swap_control_tear;
SDL_bool HAS_WGL_ARB_context_flush_control; SDL_bool HAS_WGL_ARB_context_flush_control;
SDL_bool HAS_WGL_ARB_create_context_robustness;
/* Max version of OpenGL ES context that can be created if the /* Max version of OpenGL ES context that can be created if the
implementation supports WGL_EXT_create_context_es2_profile. implementation supports WGL_EXT_create_context_es2_profile.

View File

@ -394,6 +394,11 @@ X11_GL_InitExtensions(_THIS)
if (HasExtension("GLX_ARB_context_flush_control", extensions)) { if (HasExtension("GLX_ARB_context_flush_control", extensions)) {
_this->gl_data->HAS_GLX_ARB_context_flush_control = SDL_TRUE; _this->gl_data->HAS_GLX_ARB_context_flush_control = SDL_TRUE;
} }
/* Check for GLX_ARB_create_context_robustness */
if (HasExtension("GLX_ARB_create_context_robustness", extensions)) {
_this->gl_data->HAS_GLX_ARB_create_context_robustness = SDL_TRUE;
}
} }
/* glXChooseVisual and glXChooseFBConfig have some small differences in /* glXChooseVisual and glXChooseFBConfig have some small differences in
@ -621,8 +626,8 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
context = context =
_this->gl_data->glXCreateContext(display, vinfo, share_context, True); _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
} else { } else {
/* max 10 attributes plus terminator */ /* max 12 attributes plus terminator */
int attribs[11] = { int attribs[13] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, GLX_CONTEXT_MAJOR_VERSION_ARB,
_this->gl_config.major_version, _this->gl_config.major_version,
GLX_CONTEXT_MINOR_VERSION_ARB, GLX_CONTEXT_MINOR_VERSION_ARB,
@ -652,6 +657,15 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
} }
/* only set if glx extension is available */
if( _this->gl_data->HAS_GLX_ARB_create_context_robustness ) {
attribs[iattr++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
attribs[iattr++] =
_this->gl_config.reset_notification ?
GLX_LOSE_CONTEXT_ON_RESET_ARB :
GLX_NO_RESET_NOTIFICATION_ARB;
}
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 */

View File

@ -35,6 +35,7 @@ struct SDL_GLDriverData
SDL_bool HAS_GLX_EXT_visual_info; SDL_bool HAS_GLX_EXT_visual_info;
SDL_bool HAS_GLX_EXT_swap_control_tear; SDL_bool HAS_GLX_EXT_swap_control_tear;
SDL_bool HAS_GLX_ARB_context_flush_control; SDL_bool HAS_GLX_ARB_context_flush_control;
SDL_bool HAS_GLX_ARB_create_context_robustness;
/* Max version of OpenGL ES context that can be created if the /* Max version of OpenGL ES context that can be created if the
implementation supports GLX_EXT_create_context_es2_profile. implementation supports GLX_EXT_create_context_es2_profile.