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)
|
one for the root window (or for the window used in the XComposite overlay)
|
||||||
and the best one for every depth of drawables
|
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
|
- currently the compositing code is run with 20ms timer, i.e. constant 50fps
|
||||||
- the GLX_SGI_video_sync extension should be used
|
- 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
|
+ GL_ARB_texture_rectangle vs GL_ARB_texture_non_power_of_two
|
||||||
- code currently uses GL_ARB_texture_rectangle (GL_TEXTURE_RECTANGLE_ARB), using
|
- 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;
|
glActiveTexture_func glActiveTexture;
|
||||||
// glXCopySubBufferMESA
|
// glXCopySubBufferMESA
|
||||||
glXCopySubBuffer_func glXCopySubBuffer;
|
glXCopySubBuffer_func glXCopySubBuffer;
|
||||||
|
// video_sync extension functions
|
||||||
|
glXGetVideoSync_func glXGetVideoSync;
|
||||||
|
glXWaitVideoSync_func glXWaitVideoSync;
|
||||||
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
@ -74,6 +77,16 @@ void initGLX()
|
||||||
glXCopySubBuffer = (glXCopySubBuffer_func) getProcAddress( "glXCopySubBufferMESA" );
|
glXCopySubBuffer = (glXCopySubBuffer_func) getProcAddress( "glXCopySubBufferMESA" );
|
||||||
else
|
else
|
||||||
glXCopySubBuffer = NULL;
|
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()
|
void initGL()
|
||||||
|
|
|
@ -85,6 +85,11 @@ extern glActiveTexture_func glActiveTexture;
|
||||||
// glXCopySubBufferMESA
|
// glXCopySubBufferMESA
|
||||||
typedef void (*glXCopySubBuffer_func) ( Display* , GLXDrawable, int, int, int, int );
|
typedef void (*glXCopySubBuffer_func) ( Display* , GLXDrawable, int, int, int, int );
|
||||||
extern glXCopySubBuffer_func glXCopySubBuffer;
|
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
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,7 @@ unsigned long Options::updateSettings()
|
||||||
glMode = GLFallback;
|
glMode = GLFallback;
|
||||||
glAlwaysRebind = config->readEntry("GLAlwaysRebind", false );
|
glAlwaysRebind = config->readEntry("GLAlwaysRebind", false );
|
||||||
glDirect = config->readEntry("GLDirect", true );
|
glDirect = config->readEntry("GLDirect", true );
|
||||||
|
glVSync = config->readEntry("GLVSync", true );
|
||||||
|
|
||||||
config->setGroup( "EffectShowFps" );
|
config->setGroup( "EffectShowFps" );
|
||||||
effectShowFpsAlpha = config->readEntry( "Alpha", 0.5 );
|
effectShowFpsAlpha = config->readEntry( "Alpha", 0.5 );
|
||||||
|
|
|
@ -304,6 +304,7 @@ class Options : public KDecorationOptions
|
||||||
GLMode glMode;
|
GLMode glMode;
|
||||||
bool glAlwaysRebind;
|
bool glAlwaysRebind;
|
||||||
bool glDirect;
|
bool glDirect;
|
||||||
|
bool glVSync;
|
||||||
|
|
||||||
double effectShowFpsAlpha;
|
double effectShowFpsAlpha;
|
||||||
int effectShowFpsX;
|
int effectShowFpsX;
|
||||||
|
|
|
@ -450,6 +450,22 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
||||||
ungrabXServer();
|
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)
|
// actually paint to the screen (double-buffer swap or copy from pixmap buffer)
|
||||||
void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
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 )
|
if( mask & PAINT_SCREEN_REGION )
|
||||||
{
|
{
|
||||||
|
waitSync();
|
||||||
if( glXCopySubBuffer )
|
if( glXCopySubBuffer )
|
||||||
{
|
{
|
||||||
foreach( QRect r, damage.rects())
|
foreach( QRect r, damage.rects())
|
||||||
|
@ -483,7 +500,10 @@ void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
waitSync();
|
||||||
glXSwapBuffers( display(), glxbuffer );
|
glXSwapBuffers( display(), glxbuffer );
|
||||||
|
}
|
||||||
glXWaitGL();
|
glXWaitGL();
|
||||||
XFlush( display());
|
XFlush( display());
|
||||||
}
|
}
|
||||||
|
@ -491,6 +511,7 @@ void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
||||||
{
|
{
|
||||||
glFlush();
|
glFlush();
|
||||||
glXWaitGL();
|
glXWaitGL();
|
||||||
|
waitSync();
|
||||||
if( mask & PAINT_SCREEN_REGION )
|
if( mask & PAINT_SCREEN_REGION )
|
||||||
foreach( QRect r, damage.rects())
|
foreach( QRect r, damage.rects())
|
||||||
XCopyArea( display(), buffer, rootWindow(), gcroot, r.x(), r.y(), r.width(), r.height(), r.x(), r.y());
|
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 initBuffer();
|
||||||
void initRenderingContext();
|
void initRenderingContext();
|
||||||
bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None );
|
bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None );
|
||||||
|
void waitSync();
|
||||||
void flushBuffer( int mask, const QRegion& damage );
|
void flushBuffer( int mask, const QRegion& damage );
|
||||||
typedef GLuint Texture;
|
typedef GLuint Texture;
|
||||||
GC gcroot;
|
GC gcroot;
|
||||||
|
|
Loading…
Reference in a new issue