[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kwin
Subject:    Video sync
From:       Philip Falkner <philip.falkner () gmail ! com>
Date:       2006-11-21 19:55:32
Message-ID: 200611211455.32251.philip.falkner () gmail ! com
[Download RAW message or body]

Attached is a patch which adds support for syncing to video retrace when using 
direct rendering (enabled by default).

Note that this WILL increase time between repaints (since that's the point) 
but prevent flickering/tearing.  The speed difference is not that large here, 
and the improved appearance is more than worth it.

This doesn't change the default 50fps refresh rate.  We could detect the 
screen's refresh rate with RandR, but do we want to?  If we do, should it be 
for all compositing engines, or just OpenGL?

-- 
Philip Falkner

["vsync.patch" (text/x-diff)]

Index: options.h
===================================================================
--- options.h	(revision 606773)
+++ options.h	(working copy)
@@ -304,6 +304,7 @@
         GLMode glMode;
         bool glAlwaysRebind;
         bool glDirect;
+        bool glVSync;
 
         double effectShowFpsAlpha;
         int effectShowFpsX;
Index: scene_opengl.h
===================================================================
--- scene_opengl.h	(revision 606773)
+++ scene_opengl.h	(working copy)
@@ -44,6 +44,7 @@
         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;
Index: options.cpp
===================================================================
--- options.cpp	(revision 606773)
+++ options.cpp	(working copy)
@@ -203,6 +203,7 @@
         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 );
Index: scene_opengl.cpp
===================================================================
--- scene_opengl.cpp	(revision 606773)
+++ scene_opengl.cpp	(working copy)
@@ -450,6 +450,22 @@
     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 @@
         {
         if( mask & PAINT_SCREEN_REGION )
             {
+            waitSync();
             if( glXCopySubBuffer )
                 {
                 foreach( QRect r, damage.rects())
@@ -483,7 +500,10 @@
                 }
             }
         else
+            {
+            waitSync();
             glXSwapBuffers( display(), glxbuffer );
+            }
         glXWaitGL();
         XFlush( display());
         }
Index: glutils.h
===================================================================
--- glutils.h	(revision 606773)
+++ glutils.h	(working copy)
@@ -85,6 +85,11 @@
 // 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
 
Index: glutils.cpp
===================================================================
--- glutils.cpp	(revision 606773)
+++ glutils.cpp	(working copy)
@@ -33,6 +33,9 @@
 glActiveTexture_func glActiveTexture;
 // glXCopySubBufferMESA
 glXCopySubBuffer_func glXCopySubBuffer;
+// video_sync extension functions
+glXGetVideoSync_func glXGetVideoSync;
+glXWaitVideoSync_func glXWaitVideoSync;
 
 
 // Functions
@@ -74,6 +77,16 @@
         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()


_______________________________________________
Kwin mailing list
Kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic