Merge lp:~vanvugt/compiz/fix-763005-trunk into lp:~compiz/compiz/ubuntu

Proposed by Daniel van Vugt
Status: Superseded
Proposed branch: lp:~vanvugt/compiz/fix-763005-trunk
Merge into: lp:~compiz/compiz/ubuntu
Diff against target: 187 lines (+176/-0)
2 files modified
debian/patches/fix_slow_vsync_lp763005.patch (+175/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~vanvugt/compiz/fix-763005-trunk
Reviewer Review Type Date Requested Status
Sam Spilsbury Approve
compiz packagers Pending
Review via email: mp+71307@code.launchpad.net

This proposal has been superseded by a proposal from 2011-09-01.

Description of the change

Fix slow/stuttering display when sync to Vblank is enabled. (LP: #763005)

For fglrx the cause appears to be an ATI/AMD driver bug where glXGetVideoSyncSGI and glXWaitVideoSyncSGI are particularly slow, so we can't afford to call both on every redraw or we end up with 1/3-1/2 framerate. For intel and really all drivers, another cause appears to be excessive waiting in the compiz architecture not allowing enough CPU time to draw the full frame before the next vertical refresh.

This patch addresses both possible problems, providing optimal framerates with sync-to-vblank support, most of the time.

It is possible this might also fix similar nvidia issues where DynamicTwinView reduces the framerate; bug 762749 and maybe bug 92599...

To post a comment you must log in.
Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

Sam, can you look at this? Thanks!

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Sorry I got to this so late.

This looks good. Could you possibly retarget this against lp:compiz-core and make sure comments are on a new line ?

review: Approve

Unmerged revisions

648. By Daniel van Vugt

Fix slow/stuttering display when sync to Vblank is enabled. (LP: #763005)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'debian/patches/fix_slow_vsync_lp763005.patch'
2--- debian/patches/fix_slow_vsync_lp763005.patch 1970-01-01 00:00:00 +0000
3+++ debian/patches/fix_slow_vsync_lp763005.patch 2011-08-12 07:46:22 +0000
4@@ -0,0 +1,175 @@
5+Description: Fix slow/stuttering display when sync to Vblank is enabled.
6+ For fglrx the cause appears to be an ATI/AMD driver bug where
7+ glXGetVideoSyncSGI and glXWaitVideoSyncSGI are particularly slow, so we
8+ can't afford to call both on every redraw or we end up with 1/3-1/2 framerate.
9+ For intel and really all drivers, another cause appears to be excessive
10+ waiting in the compiz architecture not allowing enough CPU time to draw the
11+ full frame before the next vertical refresh.
12+ This patch addresses both possible problems, providing optimal framerates
13+ with sync-to-vblank support, most of the time.
14+Author: Daniel van Vugt <vanvugt@gmail.com>
15+Bug-Ubuntu: https://launchpad.net/bugs/763005
16+
17+===================================================================
18+--- old/plugins/opengl/include/opengl/opengl.h 2011-08-12 15:00:38.809906000 +0800
19++++ new/plugins/opengl/include/opengl/opengl.h 2011-08-12 15:09:05.000000000 +0800
20+@@ -98,11 +98,13 @@
21+ int width,
22+ int height);
23+
24+- typedef int (*GLXGetVideoSyncProc) (unsigned int *count);
25+ typedef int (*GLXWaitVideoSyncProc) (int divisor,
26+ int remainder,
27+ unsigned int *count);
28+
29++ // http://www.opengl.org/registry/specs/SGI/swap_control.txt
30++ typedef int (*GLXSwapIntervalProc) (int interval);
31++
32+ #ifndef GLX_VERSION_1_3
33+ typedef struct __GLXFBConfigRec *GLXFBConfig;
34+ #endif
35+@@ -163,8 +165,8 @@
36+ extern GLXReleaseTexImageProc releaseTexImage;
37+ extern GLXQueryDrawableProc queryDrawable;
38+ extern GLXCopySubBufferProc copySubBuffer;
39+- extern GLXGetVideoSyncProc getVideoSync;
40+ extern GLXWaitVideoSyncProc waitVideoSync;
41++ extern GLXSwapIntervalProc swapInterval;
42+ extern GLXGetFBConfigsProc getFBConfigs;
43+ extern GLXGetFBConfigAttribProc getFBConfigAttrib;
44+ extern GLXCreatePixmapProc createPixmap;
45+===================================================================
46+--- old/plugins/opengl/src/screen.cpp 2011-08-12 15:00:38.809906000 +0800
47++++ new/plugins/opengl/src/screen.cpp 2011-08-12 15:09:05.000000000 +0800
48+@@ -36,8 +36,8 @@
49+ GLXReleaseTexImageProc releaseTexImage = NULL;
50+ GLXQueryDrawableProc queryDrawable = NULL;
51+ GLXCopySubBufferProc copySubBuffer = NULL;
52+- GLXGetVideoSyncProc getVideoSync = NULL;
53+ GLXWaitVideoSyncProc waitVideoSync = NULL;
54++ GLXSwapIntervalProc swapInterval = NULL;
55+ GLXGetFBConfigsProc getFBConfigs = NULL;
56+ GLXGetFBConfigAttribProc getFBConfigAttrib = NULL;
57+ GLXCreatePixmapProc createPixmap = NULL;
58+@@ -227,13 +227,16 @@
59+
60+ if (strstr (glxExtensions, "GLX_SGI_video_sync"))
61+ {
62+- GL::getVideoSync = (GL::GLXGetVideoSyncProc)
63+- getProcAddress ("glXGetVideoSyncSGI");
64+-
65+ GL::waitVideoSync = (GL::GLXWaitVideoSyncProc)
66+ getProcAddress ("glXWaitVideoSyncSGI");
67+ }
68+
69++ if (strstr (glxExtensions, "GLX_SGI_swap_control"))
70++ {
71++ GL::swapInterval = (GL::GLXSwapIntervalProc)
72++ getProcAddress ("glXSwapIntervalSGI");
73++ }
74++
75+ glXMakeCurrent (dpy, CompositeScreen::get (s)->output (), priv->ctx);
76+
77+ glExtensions = (const char *) glGetString (GL_EXTENSIONS);
78+@@ -1002,19 +1005,30 @@
79+ }
80+
81+ void
82+-PrivateGLScreen::waitForVideoSync ()
83++PrivateGLScreen::controlSwapVideoSync ()
84+ {
85+- unsigned int sync;
86+-
87+- if (!optionGetSyncToVblank ())
88+- return;
89++ bool sync = optionGetSyncToVblank ();
90++ if (GL::swapInterval)
91++ { // Docs: http://www.opengl.org/registry/specs/SGI/swap_control.txt
92++ (*GL::swapInterval) (sync ? 1 : 0);
93++ }
94++ else if (sync)
95++ { // ugly fallback - blocks the CPU.
96++ waitForVideoSync ();
97++ }
98++}
99+
100+- if (GL::getVideoSync)
101++void
102++PrivateGLScreen::waitForVideoSync ()
103++{
104++ if (optionGetSyncToVblank () && GL::waitVideoSync)
105+ {
106+- glFlush ();
107++ if (GL::swapInterval)
108++ (*GL::swapInterval) (0); // Don't wait twice. Just in case.
109+
110+- (*GL::getVideoSync) (&sync);
111+- (*GL::waitVideoSync) (2, (sync + 1) % 2, &sync);
112++ // Docs: http://www.opengl.org/registry/specs/SGI/video_sync.txt
113++ unsigned int frameno;
114++ (*GL::waitVideoSync) (1, 0, &frameno);
115+ }
116+ }
117+
118+@@ -1087,10 +1101,23 @@
119+
120+ targetOutput = &screen->outputDevs ()[0];
121+
122+- waitForVideoSync ();
123++ glFlush (); // used to be called from waitForVideoSync
124+
125++ //
126++ // FIXME: Actually fix the composite plugin to be more efficient;
127++ // If GL::swapInterval == NULL && GL::waitVideoSync != NULL then the
128++ // composite plugin should not be imposing any framerate restriction
129++ // (ie. blocking the CPU) at all. Because the framerate will be controlled
130++ // and optimized here:
131++ //
132+ if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
133+ {
134++ //
135++ // controlSwapVideoSync is much faster than waitForVideoSync because
136++ // it won't block the CPU. The waiting is offloaded to the GPU.
137++ // Unfortunately it only works with glXSwapBuffers in most drivers.
138++ //
139++ controlSwapVideoSync ();
140+ glXSwapBuffers (screen->dpy (), cScreen->output ());
141+ }
142+ else
143+@@ -1098,6 +1125,7 @@
144+ BoxPtr pBox;
145+ int nBox, y;
146+
147++ waitForVideoSync ();
148+ pBox = const_cast <Region> (tmpRegion.handle ())->rects;
149+ nBox = const_cast <Region> (tmpRegion.handle ())->numRects;
150+
151+@@ -1153,7 +1181,7 @@
152+ bool
153+ PrivateGLScreen::hasVSync ()
154+ {
155+- return (GL::getVideoSync && optionGetSyncToVblank ());
156++ return (GL::waitVideoSync && optionGetSyncToVblank ());
157+ }
158+
159+ void
160+@@ -1161,7 +1189,7 @@
161+ {
162+ if (pendingCommands)
163+ {
164+- glFinish ();
165++ glFlush (); // glFlush! glFinish would block the CPU, which is bad.
166+ pendingCommands = false;
167+ }
168+ }
169+===================================================================
170+--- old/plugins/opengl/src/privates.h 2011-08-12 15:10:58.007681085 +0800
171++++ new/plugins/opengl/src/privates.h 2011-08-12 15:13:02.617681069 +0800
172+@@ -70,6 +70,7 @@
173+
174+ void prepareDrawing ();
175+
176++ void controlSwapVideoSync ();
177+ void waitForVideoSync ();
178+
179+ void paintBackground (const CompRegion &region,
180
181=== modified file 'debian/patches/series'
182--- debian/patches/series 2011-08-12 07:07:23 +0000
183+++ debian/patches/series 2011-08-12 07:46:22 +0000
184@@ -1,2 +1,3 @@
185 01_don_t_init_a11y.patch
186 091_no_use_gnome_but_desktop_file.patch
187+fix_slow_vsync_lp763005.patch

Subscribers

People subscribed via source and target branches

to all changes: