Sync to vblank, patch by Philip Falkner.
svn path=/branches/work/kwin_composite/; revision=606795
This commit is contained in:
parent
55015eb927
commit
9c4218d4bf
7 changed files with 43 additions and 2 deletions
|
@ -96,10 +96,9 @@ OpenGL TODO
|
|||
one for the root window (or for the window used in the XComposite overlay)
|
||||
and the best one for every depth of drawables
|
||||
|
||||
+ sync to vblank
|
||||
/ sync to vblank
|
||||
- currently the compositing code is run with 20ms timer, i.e. constant 50fps
|
||||
- the GLX_SGI_video_sync extension should be used
|
||||
- compiz uses this, no idea about it though
|
||||
|
||||
+ GL_ARB_texture_rectangle vs GL_ARB_texture_non_power_of_two
|
||||
- code currently uses GL_ARB_texture_rectangle (GL_TEXTURE_RECTANGLE_ARB), using
|
||||
|
|
13
glutils.cpp
13
glutils.cpp
|
@ -33,6 +33,9 @@ glXBindTexImageEXT_func glXBindTexImageEXT;
|
|||
glActiveTexture_func glActiveTexture;
|
||||
// glXCopySubBufferMESA
|
||||
glXCopySubBuffer_func glXCopySubBuffer;
|
||||
// video_sync extension functions
|
||||
glXGetVideoSync_func glXGetVideoSync;
|
||||
glXWaitVideoSync_func glXWaitVideoSync;
|
||||
|
||||
|
||||
// Functions
|
||||
|
@ -74,6 +77,16 @@ void initGLX()
|
|||
glXCopySubBuffer = (glXCopySubBuffer_func) getProcAddress( "glXCopySubBufferMESA" );
|
||||
else
|
||||
glXCopySubBuffer = NULL;
|
||||
if( hasGLExtension( "GLX_SGI_video_sync" ))
|
||||
{
|
||||
glXGetVideoSync = (glXGetVideoSync_func) getProcAddress( "glXGetVideoSyncSGI" );
|
||||
glXWaitVideoSync = (glXWaitVideoSync_func) getProcAddress( "glXWaitVideoSyncSGI" );
|
||||
}
|
||||
else
|
||||
{
|
||||
glXGetVideoSync = NULL;
|
||||
glXWaitVideoSync = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void initGL()
|
||||
|
|
|
@ -85,6 +85,11 @@ extern glActiveTexture_func glActiveTexture;
|
|||
// glXCopySubBufferMESA
|
||||
typedef void (*glXCopySubBuffer_func) ( Display* , GLXDrawable, int, int, int, int );
|
||||
extern glXCopySubBuffer_func glXCopySubBuffer;
|
||||
// video_sync extension functions
|
||||
typedef void (*glXGetVideoSync_func)( unsigned int *count );
|
||||
typedef void (*glXWaitVideoSync_func)( int divisor, int remainder, unsigned int *count );
|
||||
extern glXGetVideoSync_func glXGetVideoSync;
|
||||
extern glXWaitVideoSync_func glXWaitVideoSync;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -203,6 +203,7 @@ unsigned long Options::updateSettings()
|
|||
glMode = GLFallback;
|
||||
glAlwaysRebind = config->readEntry("GLAlwaysRebind", false );
|
||||
glDirect = config->readEntry("GLDirect", true );
|
||||
glVSync = config->readEntry("GLVSync", true );
|
||||
|
||||
config->setGroup( "EffectShowFps" );
|
||||
effectShowFpsAlpha = config->readEntry( "Alpha", 0.5 );
|
||||
|
|
|
@ -304,6 +304,7 @@ class Options : public KDecorationOptions
|
|||
GLMode glMode;
|
||||
bool glAlwaysRebind;
|
||||
bool glDirect;
|
||||
bool glVSync;
|
||||
|
||||
double effectShowFpsAlpha;
|
||||
int effectShowFpsX;
|
||||
|
|
|
@ -450,6 +450,22 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
|||
ungrabXServer();
|
||||
}
|
||||
|
||||
// wait for vblank signal before painting
|
||||
void SceneOpenGL::waitSync()
|
||||
{ // NOTE that vsync has no effect with indirect rendering
|
||||
bool vsync = options->glVSync;
|
||||
unsigned int sync;
|
||||
|
||||
if( !vsync )
|
||||
return;
|
||||
if( glXGetVideoSync )
|
||||
{
|
||||
glFlush();
|
||||
glXGetVideoSync( &sync );
|
||||
glXWaitVideoSync( 2, ( sync + 1 ) % 2, &sync );
|
||||
}
|
||||
}
|
||||
|
||||
// actually paint to the screen (double-buffer swap or copy from pixmap buffer)
|
||||
void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
||||
{
|
||||
|
@ -457,6 +473,7 @@ void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
|||
{
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
{
|
||||
waitSync();
|
||||
if( glXCopySubBuffer )
|
||||
{
|
||||
foreach( QRect r, damage.rects())
|
||||
|
@ -483,7 +500,10 @@ void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
waitSync();
|
||||
glXSwapBuffers( display(), glxbuffer );
|
||||
}
|
||||
glXWaitGL();
|
||||
XFlush( display());
|
||||
}
|
||||
|
@ -491,6 +511,7 @@ void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
|||
{
|
||||
glFlush();
|
||||
glXWaitGL();
|
||||
waitSync();
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
foreach( QRect r, damage.rects())
|
||||
XCopyArea( display(), buffer, rootWindow(), gcroot, r.x(), r.y(), r.width(), r.height(), r.x(), r.y());
|
||||
|
|
|
@ -44,6 +44,7 @@ class SceneOpenGL
|
|||
void initBuffer();
|
||||
void initRenderingContext();
|
||||
bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None );
|
||||
void waitSync();
|
||||
void flushBuffer( int mask, const QRegion& damage );
|
||||
typedef GLuint Texture;
|
||||
GC gcroot;
|
||||
|
|
Loading…
Reference in a new issue