diff --git a/WhatsNew b/WhatsNew index f64ec2e5..e6444926 100644 --- a/WhatsNew +++ b/WhatsNew @@ -6,6 +6,8 @@ Version 1.0: 1.2.10: Added SDL_GL_SWAP_CONTROL to wait for vsync in OpenGL applications. + Added SDL_GL_ACCELERATED_VISUAL to guarantee hardware acceleration. + Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set. diff --git a/include/SDL_video.h b/include/SDL_video.h index bfdbad64..720022e3 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -214,6 +214,7 @@ typedef enum { SDL_GL_STEREO, SDL_GL_MULTISAMPLEBUFFERS, SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, SDL_GL_SWAP_CONTROL } SDL_GLattr; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index df09815d..e1568a7d 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -292,6 +292,7 @@ struct SDL_VideoDevice { int stereo; int multisamplebuffers; int multisamplesamples; + int accelerated; int swap_control; int driver_loaded; char driver_path[256]; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index df8cdf68..322b2f0e 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -233,6 +233,7 @@ int SDL_VideoInit (const char *driver_name, Uint32 flags) video->gl_config.stereo = 0; video->gl_config.multisamplebuffers = 0; video->gl_config.multisamplesamples = 0; + video->gl_config.accelerated = -1; /* not known, don't set */ video->gl_config.swap_control = -1; /* not known, don't set */ /* Initialize the video subsystem */ @@ -1475,6 +1476,9 @@ int SDL_GL_SetAttribute( SDL_GLattr attr, int value ) case SDL_GL_MULTISAMPLESAMPLES: video->gl_config.multisamplesamples = value; break; + case SDL_GL_ACCELERATED_VISUAL: + video->gl_config.accelerated = value; + break; case SDL_GL_SWAP_CONTROL: video->gl_config.swap_control = value; break; diff --git a/src/video/maccommon/SDL_macgl.c b/src/video/maccommon/SDL_macgl.c index 27bf4ad8..063ab417 100644 --- a/src/video/maccommon/SDL_macgl.c +++ b/src/video/maccommon/SDL_macgl.c @@ -34,7 +34,7 @@ int Mac_GL_Init(_THIS) #if SDL_VIDEO_OPENGL AGLPixelFormat format; int i = 0; - GLint attributes [ 24 ]; /* 24 is max possible in this setup */ + GLint attributes [ 26 ]; /* 26 is max possible in this setup */ GLboolean noerr; /* load the gl driver from a default path */ @@ -95,6 +95,11 @@ int Mac_GL_Init(_THIS) attributes[i++] = this->gl_config.multisamplesamples; } #endif + if ( this->gl_config.accelerated > 0 ) { + attributes[i++] = AGL_ACCELERATED; + attributes[i++] = AGL_NO_RECOVERY; + } + attributes[i++] = AGL_ALL_RENDERERS; attributes[i] = AGL_NONE; diff --git a/src/video/quartz/SDL_QuartzGL.m b/src/video/quartz/SDL_QuartzGL.m index b9e77fa5..d2a4f526 100644 --- a/src/video/quartz/SDL_QuartzGL.m +++ b/src/video/quartz/SDL_QuartzGL.m @@ -112,6 +112,10 @@ int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) { attr[i++] = NSOpenGLPFANoRecovery; } + if ( this->gl_config.accelerated > 0 ) { + attr[i++] = NSOpenGLPFAAccelerated; + } + attr[i++] = NSOpenGLPFAScreenMask; attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id); attr[i] = 0; @@ -242,8 +246,22 @@ int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value) { glGetIntegerv (GL_ALPHA_BITS, &component); bits += component; *value = bits; + return 0; + } + case SDL_GL_ACCELERATED_VISUAL: + { + long val; + [fmt getValues: &val forAttribute: NSOpenGLPFAAccelerated attr forVirtualScreen: 0]; + *value = val; + return 0; + } + case SDL_GL_SWAP_CONTROL: + { + long val; + [ gl_context getValues: &val forParameter: NSOpenGLCPSwapInterval ]; + *value = val; + return 0; } - return 0; } glGetIntegerv (attr, (GLint *)value); diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c index da521228..9de5b010 100644 --- a/src/video/wincommon/SDL_wingl.c +++ b/src/video/wincommon/SDL_wingl.c @@ -290,6 +290,11 @@ int WIN_GL_SetupWindow(_THIS) *iAttr++ = this->gl_config.multisamplesamples; } + if ( this->gl_config.accelerated >= 0 ) { + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB); + } + *iAttr = 0; /* Choose and set the closest available pixel format */ @@ -442,6 +447,16 @@ int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) case SDL_GL_MULTISAMPLESAMPLES: wgl_attrib = WGL_SAMPLES_ARB; break; + case SDL_GL_ACCELERATED_VISUAL: + wgl_attrib = WGL_ACCELERATION_ARB; + this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); + if ( *value == WGL_NO_ACCELERATION_ARB ) { + *value = SDL_FALSE; + } else { + *value = SDL_TRUE; + } + return 0; + break; case SDL_GL_SWAP_CONTROL: if ( this->gl_data->wglGetSwapIntervalEXT ) { return this->gl_data->wglGetSwapIntervalEXT(); diff --git a/src/video/x11/SDL_x11gl.c b/src/video/x11/SDL_x11gl.c index 6a8082ec..99ffbc88 100644 --- a/src/video/x11/SDL_x11gl.c +++ b/src/video/x11/SDL_x11gl.c @@ -43,6 +43,47 @@ #define GLX_SAMPLES_ARB 100001 #endif +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#endif + +#if SDL_VIDEO_OPENGL_GLX +static int glXExtensionSupported(_THIS, const char *extension) +{ + const char *extensions; + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = SDL_strchr(extension, ' '); + if ( where || *extension == '\0' ) { + return 0; + } + + extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen); + /* It takes a bit of care to be fool-proof about parsing the + * OpenGL extensions string. Don't be fooled by sub-strings, etc. + */ + + start = extensions; + + for (;;) { + where = SDL_strstr(start, extension); + if (!where) break; + + terminator = where + strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') return 1; + + start = terminator; + } + return 0; +} +#endif /* SDL_VIDEO_OPENGL_GLX */ + XVisualInfo *X11_GL_GetVisual(_THIS) { #if SDL_VIDEO_OPENGL_GLX @@ -138,6 +179,12 @@ XVisualInfo *X11_GL_GetVisual(_THIS) attribs[i++] = this->gl_config.multisamplesamples; } + if( this->gl_config.accelerated >= 0 && + glXExtensionSupported(this, "GLX_EXT_visual_rating") ) { + attribs[i++] = GLX_VISUAL_CAVEAT_EXT; + attribs[i++] = this->gl_config.accelerated ? GLX_NONE : GLX_DONT_CARE; + } + #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */ if ( !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { attribs[i++] = GLX_X_VISUAL_TYPE; @@ -205,7 +252,6 @@ int X11_GL_CreateContext(_THIS) { int retval; #if SDL_VIDEO_OPENGL_GLX - const char *glXext; /* We do this to create a clean separation between X and GLX errors. */ XSync( SDL_Display, False ); @@ -222,12 +268,10 @@ int X11_GL_CreateContext(_THIS) } gl_active = 1; - /* The use of strstr here should be safe */ - glXext = this->gl_data->glXQueryExtensionsString(GFX_Display, DefaultScreen(GFX_Display)); - if ( !SDL_strstr(glXext, "SGI_swap_control") ) { + if ( !glXExtensionSupported(this, "SGI_swap_control") ) { this->gl_data->glXSwapIntervalSGI = NULL; } - if ( !SDL_strstr(glXext, "GLX_MESA_swap_control") ) { + if ( !glXExtensionSupported(this, "GLX_MESA_swap_control") ) { this->gl_data->glXSwapIntervalMESA = NULL; this->gl_data->glXGetSwapIntervalMESA = NULL; } @@ -340,11 +384,25 @@ int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) case SDL_GL_MULTISAMPLESAMPLES: glx_attrib = GLX_SAMPLES_ARB; break; + case SDL_GL_ACCELERATED_VISUAL: + if ( glXExtensionSupported(this, "GLX_EXT_visual_rating") ) { + glx_attrib = GLX_VISUAL_CAVEAT_EXT; + retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value); + if ( *value == GLX_SLOW_VISUAL_EXT ) { + *value = SDL_FALSE; + } else { + *value = SDL_TRUE; + } + return retval; + } else { + return(-1); + } + break; case SDL_GL_SWAP_CONTROL: if ( this->gl_data->glXGetSwapIntervalMESA ) { return this->gl_data->glXGetSwapIntervalMESA(); } else { - return -1 /*(this->gl_config.swap_control > 0)*/; + return(-1)/*(this->gl_config.swap_control > 0)*/; } break; default: diff --git a/test/testgl.c b/test/testgl.c index 26ea43df..5ce1c2fa 100644 --- a/test/testgl.c +++ b/test/testgl.c @@ -445,7 +445,7 @@ void DrawLogoBlit(void) } int RunGLTest( int argc, char* argv[], - int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync ) + int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync, int accel ) { int i; int rgb_size[3]; @@ -531,6 +531,9 @@ int RunGLTest( int argc, char* argv[], SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa ); } + if ( accel ) { + SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ); + } if ( sync ) { SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 ); } else { @@ -566,6 +569,10 @@ int RunGLTest( int argc, char* argv[], SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &value ); printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value ); } + if ( accel ) { + SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL, &value ); + printf( "SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value ); + } if ( sync ) { SDL_GL_GetAttribute( SDL_GL_SWAP_CONTROL, &value ); printf( "SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value ); @@ -779,6 +786,7 @@ int main(int argc, char *argv[]) float gamma = 0.0; int noframe = 0; int fsaa = 0; + int accel = 0; int sync = 0; logo = 0; @@ -814,6 +822,9 @@ int main(int argc, char *argv[]) if ( strcmp(argv[i], "-fsaa") == 0 ) { ++fsaa; } + if ( strcmp(argv[i], "-accel") == 0 ) { + ++accel; + } if ( strcmp(argv[i], "-sync") == 0 ) { ++sync; } @@ -825,7 +836,7 @@ int main(int argc, char *argv[]) } } for ( i=0; i