Merge lp:~bregma/compiz/lp-269904-trusty into lp:compiz/0.9.11
- lp-269904-trusty
- Merge into 0.9.11
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Christopher Townsend | ||||
Approved revision: | 3871 | ||||
Merged at revision: | 3871 | ||||
Proposed branch: | lp:~bregma/compiz/lp-269904-trusty | ||||
Merge into: | lp:compiz/0.9.11 | ||||
Diff against target: |
819 lines (+622/-5) 8 files modified
debian/changelog (+24/-0) debian/patches/100_workaround_virtualbox_hang.patch (+4/-4) plugins/opengl/include/opengl/opengl.h (+64/-0) plugins/opengl/include/opengl/xtoglsync.h (+99/-0) plugins/opengl/opengl.xml.in (+5/-0) plugins/opengl/src/privates.h (+13/-0) plugins/opengl/src/screen.cpp (+219/-1) plugins/opengl/src/xtoglsync.cpp (+194/-0) |
||||
To merge this branch: | bzr merge lp:~bregma/compiz/lp-269904-trusty | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Christopher Townsend | Approve | ||
Review via email: mp+245866@code.launchpad.net |
Commit message
Use the GL_EXT_
Description of the change
Use the GL_EXT_
Cherry-picked for backport from COmpiz 0.9.12.
Stephen M. Webb (bregma) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3867
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3870. By Stephen M. Webb
-
Use the GL_EXT_
x11_sync_ object OpenGL extension to synchronize updates with X11 to avoid unrefreshed parts of the screen on Nvidia hardware.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3870
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Stephen M. Webb (bregma) wrote : | # |
C'mon Jenkins, you can do better than that.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3870
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Christopher Townsend (townsend) wrote : | # |
Changelog version should be 1:0.9.11.3-0ubuntu2 instead of 1:0.9.12.
- 3871. By Stephen M. Webb
-
debian/changelog: fixed Ubuntu package versaion
Christopher Townsend (townsend) wrote : | # |
Ok, looks good now.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3871
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-11-04 19:42:46 +0000 |
3 | +++ debian/changelog 2015-01-13 14:32:13 +0000 |
4 | @@ -1,3 +1,27 @@ |
5 | +compiz (1:0.9.11.3-0ubuntu2) UNRELEASED; urgency=medium |
6 | + |
7 | + [ James Jones ] |
8 | + * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia |
9 | + based GPUs to avoid screen refresh issues. (LP: #269904) |
10 | + |
11 | + [ Kyle Brenneman ] |
12 | + * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia |
13 | + based GPUs to avoid screen refresh issues. (LP: #269904) |
14 | + |
15 | + [ Viktor A. Danilov ] |
16 | + * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia |
17 | + based GPUs to avoid screen refresh issues. (LP: #269904) |
18 | + |
19 | + [ Chris Townsend ] |
20 | + * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia |
21 | + based GPUs to avoid screen refresh issues. (LP: #269904) |
22 | + |
23 | + [ Stephen M. Webb ] |
24 | + * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia |
25 | + based GPUs to avoid screen refresh issues. (LP: #269904) |
26 | + |
27 | + -- Chris Townsend <christopher.townsend@canonical.com> Wed, 10 Dec 2014 08:19:58 -0500 |
28 | + |
29 | compiz (1:0.9.11.3+14.04.20141104-0ubuntu1) trusty; urgency=medium |
30 | |
31 | [ Chris Townsend ] |
32 | |
33 | === modified file 'debian/patches/100_workaround_virtualbox_hang.patch' |
34 | --- debian/patches/100_workaround_virtualbox_hang.patch 2014-03-03 14:32:56 +0000 |
35 | +++ debian/patches/100_workaround_virtualbox_hang.patch 2015-01-13 14:32:13 +0000 |
36 | @@ -79,10 +79,10 @@ |
37 | bool incorrectRefreshRate; // hack for NVIDIA specifying an incorrect |
38 | // refresh rate, causing us to miss vblanks |
39 | |
40 | -@@ -253,6 +273,10 @@ |
41 | - bool postprocessingRequired; |
42 | - mutable CompString prevRegex; |
43 | - mutable bool prevBlacklisted; |
44 | +@@ -266,6 +266,10 @@ |
45 | + std::vector<XToGLSync*>::size_type currentSyncNum; |
46 | + XToGLSync *currentSync; |
47 | + std::vector<XToGLSync*>::size_type warmupSyncs; |
48 | + |
49 | + private: |
50 | + |
51 | |
52 | === modified file 'plugins/opengl/include/opengl/opengl.h' |
53 | --- plugins/opengl/include/opengl/opengl.h 2013-04-27 23:30:28 +0000 |
54 | +++ plugins/opengl/include/opengl/opengl.h 2015-01-13 14:32:13 +0000 |
55 | @@ -36,7 +36,9 @@ |
56 | #include <EGL/eglext.h> |
57 | #else |
58 | #include <GL/gl.h> |
59 | +#include <GL/glext.h> |
60 | #include <GL/glx.h> |
61 | +#include <inttypes.h> |
62 | |
63 | /* Some implementations have not yet given a definition |
64 | * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined |
65 | @@ -117,6 +119,39 @@ |
66 | #define GLX_FRONT_LEFT_EXT 0x20DE |
67 | #endif |
68 | |
69 | +#ifndef GL_ARB_sync |
70 | +# ifndef GL_ES_VERSION_2_0 |
71 | +typedef struct __GLsync *GLsync; |
72 | +typedef int64_t GLint64; |
73 | +typedef uint64_t GLuint64; |
74 | +typedef intptr_t GLintptr; |
75 | +# endif |
76 | + |
77 | +# ifdef GL_APPLE_sync |
78 | +# define GL_TIMEOUT_IGNORED GL_TIMEOUT_IGNORED_APPLE |
79 | +# define GL_ALREADY_SIGNALED GL_ALREADY_SIGNALED_APPLE |
80 | +# define GL_TIMEOUT_EXPIRED GL_TIMEOUT_EXPIRED_APPLE |
81 | +# define GL_CONDITION_SATISFIED GL_CONDITION_SATISFIED_APPLE |
82 | +# define GL_WAIT_FAILED GL_WAIT_FAILED_APPLE |
83 | +# define GL_SYNC_GPU_COMMANDS_COMPLETE GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE |
84 | +# define GL_SYNC_STATUS GL_SYNC_STATUS _APPLE |
85 | +# define GL_SIGNALED GL_SIGNALED_APPLE |
86 | +# else |
87 | +# define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull |
88 | +# define GL_ALREADY_SIGNALED 0x911A |
89 | +# define GL_TIMEOUT_EXPIRED 0x911B |
90 | +# define GL_CONDITION_SATISFIED 0x911C |
91 | +# define GL_WAIT_FAILED 0x911D |
92 | +# define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 |
93 | +# define GL_SYNC_STATUS 0x9114 |
94 | +# define GL_SIGNALED 0x9119 |
95 | +# endif |
96 | +#endif |
97 | + |
98 | +#ifndef GL_EXT_x11_sync_object |
99 | +#define GL_SYNC_X11_FENCE_EXT 0x90E1 |
100 | +#endif |
101 | + |
102 | namespace GL { |
103 | #ifdef USE_GLES |
104 | typedef EGLImageKHR (*EGLCreateImageKHRProc) (EGLDisplay dpy, |
105 | @@ -320,6 +355,24 @@ |
106 | GLsizei width, |
107 | GLsizei height); |
108 | |
109 | + typedef GLsync (*GLFenceSyncProc) (GLenum condition, GLbitfield flags); |
110 | + typedef void (*GLDeleteSyncProc) (GLsync sync); |
111 | + typedef GLenum (*GLClientWaitSyncProc) (GLsync sync, |
112 | + GLbitfield flags, |
113 | + GLuint64 timeout); |
114 | + typedef void (*GLWaitSyncProc) (GLsync sync, |
115 | + GLbitfield flags, |
116 | + GLuint64 timeout); |
117 | + typedef void (*GLGetSyncivProc) (GLsync sync, |
118 | + GLenum pname, |
119 | + GLsizei bufSize, |
120 | + GLsizei *length, |
121 | + GLint *values); |
122 | + |
123 | + typedef GLsync (*GLImportSyncProc) (GLenum external_sync_type, |
124 | + GLintptr external_sync, |
125 | + GLbitfield flags); |
126 | + |
127 | |
128 | /* GL_ARB_shader_objects */ |
129 | #ifndef USE_GLES |
130 | @@ -519,6 +572,14 @@ |
131 | |
132 | #endif |
133 | |
134 | + extern GLFenceSyncProc fenceSync; |
135 | + extern GLDeleteSyncProc deleteSync; |
136 | + extern GLClientWaitSyncProc clientWaitSync; |
137 | + extern GLWaitSyncProc waitSync; |
138 | + extern GLGetSyncivProc getSynciv; |
139 | + |
140 | + extern GLImportSyncProc importSync; |
141 | + |
142 | extern bool textureFromPixmap; |
143 | extern bool textureRectangle; |
144 | extern bool textureNonPowerOfTwo; |
145 | @@ -538,6 +599,9 @@ |
146 | extern GLint maxTextureUnits; |
147 | extern bool bufferAge; |
148 | |
149 | + extern bool sync; |
150 | + extern bool xToGLSync; |
151 | + |
152 | extern bool canDoSaturated; |
153 | extern bool canDoSlightlySaturated; |
154 | |
155 | |
156 | === added file 'plugins/opengl/include/opengl/xtoglsync.h' |
157 | --- plugins/opengl/include/opengl/xtoglsync.h 1970-01-01 00:00:00 +0000 |
158 | +++ plugins/opengl/include/opengl/xtoglsync.h 2015-01-13 14:32:13 +0000 |
159 | @@ -0,0 +1,99 @@ |
160 | +/* |
161 | + * Copyright © 2011 NVIDIA Corporation |
162 | + * |
163 | + * Permission to use, copy, modify, distribute, and sell this software |
164 | + * and its documentation for any purpose is hereby granted without |
165 | + * fee, provided that the above copyright notice appear in all copies |
166 | + * and that both that copyright notice and this permission notice |
167 | + * appear in supporting documentation, and that the name of |
168 | + * NVIDIA Corporation not be used in advertising or publicity pertaining to |
169 | + * distribution of the software without specific, written prior permission. |
170 | + * NVIDIA Corporation makes no representations about the suitability of this |
171 | + * software for any purpose. It is provided "as is" without express or |
172 | + * implied warranty. |
173 | + * |
174 | + * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
175 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
176 | + * NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
177 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
178 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
179 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
180 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
181 | + * |
182 | + * Authors: James Jones <jajones@nvidia.com> |
183 | + */ |
184 | + |
185 | +#ifndef _GLXTOGLSYNC_H |
186 | +#define _GLXTOGLSYNC_H |
187 | + |
188 | +#include <composite/composite.h> |
189 | +#include <opengl/opengl.h> |
190 | +#include <X11/extensions/sync.h> |
191 | + |
192 | +#include "opengl/opengl.h" |
193 | + |
194 | +/** |
195 | + * Class that manages an XFenceSync wrapped in a GLsync object. |
196 | + * |
197 | + * Can be used to synchronize operations in the GL command stream |
198 | + * with operations in the X command stream. |
199 | + */ |
200 | +class XToGLSync { |
201 | + public: |
202 | + XToGLSync (); |
203 | + ~XToGLSync (); |
204 | + |
205 | + XSyncAlarm alarm (void) const { return a; } |
206 | + bool isReady (void) const { return state == XTOGLS_READY; } |
207 | + |
208 | + /** |
209 | + * Sends the trigger request to the server. The fence will be signaled |
210 | + * after all rendering has completed. |
211 | + */ |
212 | + void trigger (void); |
213 | + |
214 | + /** |
215 | + * Calls glWaitSync. Any OpenGL commands after this will wait for the |
216 | + * fence to be signaled. |
217 | + */ |
218 | + void insertWait (void); |
219 | + |
220 | + /** |
221 | + * Blocks until the fence is signaled, or until a timeout expires. |
222 | + * |
223 | + * \param The maximum time to wait, in nanoseconds. |
224 | + * \return One of \c GL_ALREADY_SIGNALED, \c GL_CONDITION_SATISFIED, |
225 | + * \c GL_TIMEOUT_EXPIRED, or \c GL_WAIT_FAILED. |
226 | + */ |
227 | + GLenum checkUpdateFinished (GLuint64 timeout); |
228 | + |
229 | + /** |
230 | + * Resets the fence. |
231 | + */ |
232 | + void reset (void); |
233 | + void handleEvent (XSyncAlarmNotifyEvent *ev); |
234 | + |
235 | + private: |
236 | + XSyncFence f; |
237 | + GLsync fGL; |
238 | + |
239 | + XSyncCounter c; |
240 | + XSyncAlarm a; |
241 | + XSyncValue nextCounterValue; |
242 | + |
243 | + enum { |
244 | + XTOGLS_READY, |
245 | + XTOGLS_TRIGGER_SENT, |
246 | + XTOGLS_WAITING, |
247 | + XTOGLS_DONE, |
248 | + XTOGLS_RESET_PENDING, |
249 | + } state; |
250 | + |
251 | + static bool syncValuesInitialized; |
252 | + static XSyncValue zero; |
253 | + static XSyncValue one; |
254 | + |
255 | + static Bool alarmEventPredicate (Display *dpy, XEvent *ev, XPointer arg); |
256 | +}; |
257 | + |
258 | +#endif |
259 | |
260 | === modified file 'plugins/opengl/opengl.xml.in' |
261 | --- plugins/opengl/opengl.xml.in 2012-12-17 10:53:59 +0000 |
262 | +++ plugins/opengl/opengl.xml.in 2015-01-13 14:32:13 +0000 |
263 | @@ -59,6 +59,11 @@ |
264 | <_long>Use glXSwapBuffers to display every frame. This eliminates visible tearing with most drivers and dramatically improves visual smoothness. Automatically enabled when framebuffer_object is on.</_long> |
265 | <default>true</default> |
266 | </option> |
267 | + <option name="enable_x11_sync" type="bool"> |
268 | + <_short>X11 Sync objects</_short> |
269 | + <_long>Use X11 Sync fences to synchronize rendering between X11 and OpenGL (GL_EXT_x11_sync_object). Without this, the contents of windows may not be completely redrawn.</_long> |
270 | + <default>true</default> |
271 | + </option> |
272 | <option name="unredirect_driver_blacklist" type="string"> |
273 | <_short>Unredirect Driver Blacklist</_short> |
274 | <_long>If non-empty, specifies a POSIX (extended) regular expression to match against the OpenGL driver strings (newline separated): "GL_VENDOR\nGL_RENDERER\nGL_VERSION". If the regular expression matches a substring of that concatenation then no windows will ever be unredirected while using that particular graphics driver.</_long> |
275 | |
276 | === modified file 'plugins/opengl/src/privates.h' |
277 | --- plugins/opengl/src/privates.h 2013-04-25 17:01:46 +0000 |
278 | +++ plugins/opengl/src/privates.h 2015-01-13 14:32:13 +0000 |
279 | @@ -35,6 +35,7 @@ |
280 | |
281 | #include <composite/composite.h> |
282 | #include <opengl/opengl.h> |
283 | +#include <opengl/xtoglsync.h> |
284 | #include <core/atoms.h> |
285 | #include <core/configurerequestbuffer.h> |
286 | |
287 | @@ -184,6 +185,12 @@ |
288 | |
289 | void updateView (); |
290 | |
291 | + bool syncObjectsInitialized () const; |
292 | + bool syncObjectsEnabled (); |
293 | + void initXToGLSyncs (); |
294 | + void destroyXToGLSyncs (); |
295 | + void updateXToGLSyncs (); |
296 | + |
297 | bool driverIsBlacklisted (const char *regex) const; |
298 | |
299 | bool postprocessRequiredForCurrentFrame (); |
300 | @@ -253,6 +260,12 @@ |
301 | bool postprocessingRequired; |
302 | mutable CompString prevRegex; |
303 | mutable bool prevBlacklisted; |
304 | + |
305 | + std::vector<XToGLSync*> xToGLSyncs; |
306 | + std::map<XSyncAlarm, XToGLSync*> alarmToSync; |
307 | + std::vector<XToGLSync*>::size_type currentSyncNum; |
308 | + XToGLSync *currentSync; |
309 | + std::vector<XToGLSync*>::size_type warmupSyncs; |
310 | }; |
311 | |
312 | class PrivateGLWindow : |
313 | |
314 | === modified file 'plugins/opengl/src/screen.cpp' |
315 | --- plugins/opengl/src/screen.cpp 2013-10-30 20:31:20 +0000 |
316 | +++ plugins/opengl/src/screen.cpp 2015-01-13 14:32:13 +0000 |
317 | @@ -68,6 +68,16 @@ |
318 | |
319 | using namespace compiz::opengl; |
320 | |
321 | +/** |
322 | + * The number of X11 sync objects to create. |
323 | + */ |
324 | +static const size_t NUM_X11_SYNCS = 16; |
325 | + |
326 | +/** |
327 | + * The maximum time to wait for a sync object, in nanoseconds. |
328 | + */ |
329 | +static const GLuint64 MAX_SYNC_WAIT_TIME = 1000000000ull; // One second |
330 | + |
331 | namespace GL { |
332 | #ifdef USE_GLES |
333 | EGLCreateImageKHRProc createImage; |
334 | @@ -170,6 +180,14 @@ |
335 | GLBindRenderbufferProc bindRenderbuffer = NULL; |
336 | GLRenderbufferStorageProc renderbufferStorage = NULL; |
337 | |
338 | + GLFenceSyncProc fenceSync = NULL; |
339 | + GLDeleteSyncProc deleteSync = NULL; |
340 | + GLClientWaitSyncProc clientWaitSync = NULL; |
341 | + GLWaitSyncProc waitSync = NULL; |
342 | + GLGetSyncivProc getSynciv = NULL; |
343 | + |
344 | + GLImportSyncProc importSync = NULL; |
345 | + |
346 | bool textureFromPixmap = true; |
347 | bool textureRectangle = false; |
348 | bool textureNonPowerOfTwo = false; |
349 | @@ -188,6 +206,9 @@ |
350 | GLint maxTextureUnits = 1; |
351 | bool bufferAge = false; |
352 | |
353 | + bool sync = false; |
354 | + bool xToGLSync = false; |
355 | + |
356 | bool canDoSaturated = false; |
357 | bool canDoSlightlySaturated = false; |
358 | |
359 | @@ -1054,6 +1075,36 @@ |
360 | if (strstr (glExtensions, "GL_ARB_texture_compression")) |
361 | GL::textureCompression = true; |
362 | |
363 | + if (strstr (glExtensions, "GL_ARB_sync")) |
364 | + { |
365 | + GL::fenceSync = (GL::GLFenceSyncProc) |
366 | + getProcAddress ("glFenceSync"); |
367 | + GL::deleteSync = (GL::GLDeleteSyncProc) |
368 | + getProcAddress ("glDeleteSync"); |
369 | + GL::clientWaitSync = (GL::GLClientWaitSyncProc) |
370 | + getProcAddress ("glClientWaitSync"); |
371 | + GL::waitSync = (GL::GLWaitSyncProc) |
372 | + getProcAddress ("glWaitSync"); |
373 | + GL::getSynciv = (GL::GLGetSyncivProc) |
374 | + getProcAddress ("glGetSynciv"); |
375 | + |
376 | + if (GL::fenceSync && |
377 | + GL::deleteSync && |
378 | + GL::clientWaitSync && |
379 | + GL::waitSync && |
380 | + GL::getSynciv) |
381 | + GL::sync = true; |
382 | + } |
383 | + |
384 | + if (strstr (glExtensions, "GL_EXT_x11_sync_object")) |
385 | + { |
386 | + GL::importSync = (GL::GLImportSyncProc) |
387 | + getProcAddress ("glImportSyncEXT"); |
388 | + |
389 | + if (GL::importSync) |
390 | + GL::xToGLSync = true; |
391 | + } |
392 | + |
393 | glClearColor (0.0, 0.0, 0.0, 1.0); |
394 | glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
395 | glEnable (GL_CULL_FACE); |
396 | @@ -1257,6 +1308,8 @@ |
397 | getProcAddress ("glXSwapIntervalSGI"); |
398 | } |
399 | |
400 | + priv->initXToGLSyncs (); |
401 | + |
402 | fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements); |
403 | |
404 | GL::stencilBuffer = false; |
405 | @@ -1411,6 +1464,9 @@ |
406 | |
407 | GLScreen::~GLScreen () |
408 | { |
409 | + // Must occur before context is destroyed. |
410 | + priv->destroyXToGLSyncs (); |
411 | + |
412 | if (priv->hasCompositing) |
413 | CompositeScreen::get (screen)->unregisterPaintHandler (); |
414 | |
415 | @@ -1471,7 +1527,10 @@ |
416 | glVersion (NULL), |
417 | postprocessingRequired (false), |
418 | prevRegex (), |
419 | - prevBlacklisted (false) |
420 | + prevBlacklisted (false), |
421 | + currentSyncNum (0), |
422 | + currentSync (0), |
423 | + warmupSyncs (0) |
424 | { |
425 | ScreenInterface::setHandler (screen); |
426 | CompositeScreenInterface::setHandler (cScreen); |
427 | @@ -1563,6 +1622,16 @@ |
428 | * be recopying the root window pixmap all the time |
429 | * which is no good, so don't do that */ |
430 | } |
431 | + else if (event->type == screen->syncEvent () + XSyncAlarmNotify) |
432 | + { |
433 | + XSyncAlarmNotifyEvent *ae = |
434 | + reinterpret_cast<XSyncAlarmNotifyEvent*>(event); |
435 | + std::map<XSyncAlarm, XToGLSync*>::iterator it = |
436 | + alarmToSync.find (ae->alarm); |
437 | + |
438 | + if (it != alarmToSync.end ()) |
439 | + it->second->handleEvent (ae); |
440 | + } |
441 | break; |
442 | } |
443 | } |
444 | @@ -2026,6 +2095,101 @@ |
445 | { |
446 | } |
447 | |
448 | +bool |
449 | +PrivateGLScreen::syncObjectsInitialized () const |
450 | +{ |
451 | + return !xToGLSyncs.empty (); |
452 | +} |
453 | + |
454 | +bool |
455 | +PrivateGLScreen::syncObjectsEnabled () |
456 | +{ |
457 | + return GL::sync && GL::xToGLSync && optionGetEnableX11Sync (); |
458 | +} |
459 | + |
460 | +void |
461 | +PrivateGLScreen::initXToGLSyncs () |
462 | +{ |
463 | + assert (!syncObjectsInitialized ()); |
464 | + assert (xToGLSyncs.empty ()); |
465 | + assert (alarmToSync.empty ()); |
466 | + |
467 | + if (syncObjectsEnabled () && !syncObjectsInitialized ()) |
468 | + { |
469 | + xToGLSyncs.resize (NUM_X11_SYNCS, NULL); |
470 | + |
471 | + foreach (XToGLSync*& sync, xToGLSyncs) |
472 | + { |
473 | + sync = new XToGLSync (); |
474 | + alarmToSync[sync->alarm ()] = sync; |
475 | + } |
476 | + |
477 | + currentSyncNum = 0; |
478 | + currentSync = xToGLSyncs[0]; |
479 | + warmupSyncs = 0; |
480 | + } |
481 | +} |
482 | + |
483 | +void |
484 | +PrivateGLScreen::destroyXToGLSyncs () |
485 | +{ |
486 | + if (syncObjectsInitialized ()) |
487 | + { |
488 | + foreach (XToGLSync* sync, xToGLSyncs) |
489 | + delete sync; |
490 | + xToGLSyncs.resize (0); |
491 | + } |
492 | + alarmToSync.clear (); |
493 | + currentSyncNum = 0; |
494 | + currentSync = NULL; |
495 | + warmupSyncs = 0; |
496 | +} |
497 | + |
498 | +void |
499 | +PrivateGLScreen::updateXToGLSyncs () |
500 | +{ |
501 | + const std::vector<XToGLSync*>::size_type numSyncs = xToGLSyncs.size (); |
502 | + |
503 | + if (numSyncs) |
504 | + { |
505 | + if (warmupSyncs >= numSyncs / 2) |
506 | + { |
507 | + const std::vector<XToGLSync*>::size_type resetSyncIdx = |
508 | + (currentSyncNum + (numSyncs / 2)) % numSyncs; |
509 | + |
510 | + XToGLSync* syncToReset = xToGLSyncs[resetSyncIdx]; |
511 | + |
512 | + GLenum status = syncToReset->checkUpdateFinished (0); |
513 | + if (status == GL_TIMEOUT_EXPIRED) |
514 | + { |
515 | + status = syncToReset->checkUpdateFinished (MAX_SYNC_WAIT_TIME); |
516 | + } |
517 | + |
518 | + if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) |
519 | + { |
520 | + // This should never happen. If there was an error somewhere, |
521 | + // then we don't want to risk a hang here, so just destroy the |
522 | + // sync objects. We'll recreate them again in the next call to |
523 | + // prepareDrawing. |
524 | + compLogMessage ("opengl", CompLogLevelError, "Timed out waiting for sync object."); |
525 | + destroyXToGLSyncs (); |
526 | + return; |
527 | + } |
528 | + |
529 | + syncToReset->reset (); |
530 | + } |
531 | + else |
532 | + { |
533 | + warmupSyncs++; |
534 | + } |
535 | + |
536 | + currentSyncNum++; |
537 | + currentSyncNum %= numSyncs; |
538 | + |
539 | + currentSync = xToGLSyncs[currentSyncNum]; |
540 | + } |
541 | +} |
542 | + |
543 | #ifndef USE_GLES |
544 | |
545 | void |
546 | @@ -2199,6 +2363,9 @@ |
547 | glClear (GL_COLOR_BUFFER_BIT); |
548 | } |
549 | |
550 | + if (currentSync) |
551 | + currentSync->insertWait (); |
552 | + |
553 | // Disable everything that we don't usually need and could slow us down |
554 | glDisable (GL_BLEND); |
555 | glDisable (GL_STENCIL_TEST); |
556 | @@ -2352,6 +2519,8 @@ |
557 | doubleBuffer.render (paintRegion, fullscreen); |
558 | |
559 | lastMask = mask; |
560 | + |
561 | + updateXToGLSyncs (); |
562 | } |
563 | |
564 | unsigned int |
565 | @@ -2448,6 +2617,55 @@ |
566 | updateFrameProvider (); |
567 | CompositeScreen::get (screen)->damageScreen (); |
568 | } |
569 | + |
570 | + // Check if the option to use sync objects has been enabled or disabled. |
571 | + if (syncObjectsEnabled () && !syncObjectsInitialized ()) |
572 | + { |
573 | + initXToGLSyncs (); |
574 | + } |
575 | + else if (!syncObjectsEnabled () && syncObjectsInitialized ()) |
576 | + { |
577 | + destroyXToGLSyncs (); |
578 | + } |
579 | + |
580 | + if (currentSync) |
581 | + { |
582 | + if (!currentSync->isReady ()) |
583 | + { |
584 | + for (std::vector<XToGLSync*>::size_type i = xToGLSyncs.size () / 2; i > 0; i--) |
585 | + { |
586 | + // try to check next sync |
587 | + updateXToGLSyncs (); |
588 | + |
589 | + // method updateXToGLSync may disable syncs |
590 | + if (!currentSync) |
591 | + break; |
592 | + |
593 | + if (currentSync->isReady ()) |
594 | + break; |
595 | + } |
596 | + } |
597 | + } |
598 | + |
599 | + if (currentSync) |
600 | + { |
601 | + if (!currentSync->isReady ()) |
602 | + { |
603 | + // If this happens, then we must have missed an event or update |
604 | + // somewhere. Destroy and recreate the sync objects to put us back |
605 | + // into a good state. |
606 | + destroyXToGLSyncs (); |
607 | + initXToGLSyncs (); |
608 | + } |
609 | + } |
610 | + |
611 | + if (currentSync) |
612 | + { |
613 | + // Tell the server to trigger the fence object after all rendering has |
614 | + // completed. |
615 | + assert (currentSync->isReady ()); |
616 | + currentSync->trigger (); |
617 | + } |
618 | } |
619 | |
620 | bool |
621 | |
622 | === added file 'plugins/opengl/src/xtoglsync.cpp' |
623 | --- plugins/opengl/src/xtoglsync.cpp 1970-01-01 00:00:00 +0000 |
624 | +++ plugins/opengl/src/xtoglsync.cpp 2015-01-13 14:32:13 +0000 |
625 | @@ -0,0 +1,194 @@ |
626 | +/* |
627 | + * Copyright © 2011 NVIDIA Corporation |
628 | + * |
629 | + * Permission to use, copy, modify, distribute, and sell this software |
630 | + * and its documentation for any purpose is hereby granted without |
631 | + * fee, provided that the above copyright notice appear in all copies |
632 | + * and that both that copyright notice and this permission notice |
633 | + * appear in supporting documentation, and that the name of |
634 | + * NVIDIA Corporation not be used in advertising or publicity pertaining to |
635 | + * distribution of the software without specific, written prior permission. |
636 | + * NVIDIA Corporation makes no representations about the suitability of this |
637 | + * software for any purpose. It is provided "as is" without express or |
638 | + * implied warranty. |
639 | + * |
640 | + * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
641 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
642 | + * NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
643 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
644 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
645 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
646 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
647 | + * |
648 | + * Authors: James Jones <jajones@nvidia.com> |
649 | + */ |
650 | + |
651 | +#include "opengl/xtoglsync.h" |
652 | + |
653 | +bool XToGLSync::syncValuesInitialized = false; |
654 | +XSyncValue XToGLSync::zero; |
655 | +XSyncValue XToGLSync::one; |
656 | + |
657 | +XToGLSync::XToGLSync () : |
658 | + f (None), |
659 | + fGL (NULL), |
660 | + c (None), |
661 | + a (None), |
662 | + state (XToGLSync::XTOGLS_READY) |
663 | +{ |
664 | + Display *dpy = screen->dpy (); |
665 | + |
666 | + f = XSyncCreateFence (dpy, DefaultRootWindow (dpy), False); |
667 | + fGL = GL::importSync (GL_SYNC_X11_FENCE_EXT, f, 0); |
668 | + |
669 | + if (!syncValuesInitialized) |
670 | + { |
671 | + XSyncIntToValue (&zero, 0); |
672 | + XSyncIntToValue (&one, 1); |
673 | + syncValuesInitialized = true; |
674 | + } |
675 | + |
676 | + XSyncIntToValue (&nextCounterValue, 1); |
677 | + c = XSyncCreateCounter (dpy, zero); |
678 | + |
679 | + XSyncAlarmAttributes alarmAttribs; |
680 | + alarmAttribs.trigger.counter = c; |
681 | + alarmAttribs.trigger.value_type = XSyncAbsolute; |
682 | + alarmAttribs.trigger.wait_value = one; |
683 | + alarmAttribs.trigger.test_type = XSyncPositiveTransition; |
684 | + alarmAttribs.events = True; |
685 | + a = XSyncCreateAlarm (dpy, |
686 | + XSyncCACounter | |
687 | + XSyncCAValueType | |
688 | + XSyncCAValue | |
689 | + XSyncCATestType | |
690 | + XSyncCAEvents, |
691 | + &alarmAttribs); |
692 | + |
693 | +} |
694 | + |
695 | +XToGLSync::~XToGLSync () |
696 | +{ |
697 | + Display *dpy = screen->dpy (); |
698 | + |
699 | + switch (state) { |
700 | + case XTOGLS_WAITING: |
701 | + break; |
702 | + |
703 | + case XTOGLS_RESET_PENDING: |
704 | + { |
705 | + XEvent ev; |
706 | + |
707 | + XIfEvent (dpy, &ev, &XToGLSync::alarmEventPredicate, |
708 | + reinterpret_cast<XPointer>(this)); |
709 | + handleEvent(reinterpret_cast<XSyncAlarmNotifyEvent*>(&ev)); |
710 | + } |
711 | + // Fall through. |
712 | + case XTOGLS_READY: |
713 | + XSyncTriggerFence (dpy, f); |
714 | + XFlush (dpy); |
715 | + break; |
716 | + |
717 | + case XTOGLS_TRIGGER_SENT: |
718 | + case XTOGLS_DONE: |
719 | + // Nothing to do. |
720 | + break; |
721 | + } |
722 | + |
723 | + GL::deleteSync (fGL); |
724 | + XSyncDestroyFence (dpy, f); |
725 | + XSyncDestroyCounter (dpy, c); |
726 | + XSyncDestroyAlarm (dpy, a); |
727 | +} |
728 | + |
729 | +Bool XToGLSync::alarmEventPredicate (Display *dpy, XEvent *ev, XPointer arg) |
730 | +{ |
731 | + if (ev->type == screen->syncEvent () + XSyncAlarmNotify) |
732 | + { |
733 | + XToGLSync *sync = reinterpret_cast<XToGLSync*>(arg); |
734 | + XSyncAlarmNotifyEvent *ae = |
735 | + reinterpret_cast<XSyncAlarmNotifyEvent*>(ev); |
736 | + |
737 | + if (ae->alarm == sync->a) |
738 | + return True; |
739 | + } |
740 | + |
741 | + return False; |
742 | +} |
743 | + |
744 | +void XToGLSync::trigger (void) |
745 | +{ |
746 | + Display *dpy = screen->dpy (); |
747 | + assert (state == XTOGLS_READY); |
748 | + |
749 | + XSyncTriggerFence (dpy, f); |
750 | + XFlush (dpy); |
751 | + |
752 | + state = XTOGLS_TRIGGER_SENT; |
753 | +} |
754 | + |
755 | +void XToGLSync::insertWait (void) |
756 | +{ |
757 | + if (state != XTOGLS_TRIGGER_SENT) |
758 | + return; |
759 | + |
760 | + GL::waitSync (fGL, 0, GL_TIMEOUT_IGNORED); |
761 | + |
762 | + state = XTOGLS_WAITING; |
763 | +} |
764 | + |
765 | +GLenum XToGLSync::checkUpdateFinished (GLuint64 timeout) |
766 | +{ |
767 | + GLenum status; |
768 | + |
769 | + switch (state) { |
770 | + case XTOGLS_DONE: |
771 | + return GL_ALREADY_SIGNALED; |
772 | + |
773 | + case XTOGLS_WAITING: |
774 | + status = GL::clientWaitSync (fGL, 0, timeout); |
775 | + if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) |
776 | + { |
777 | + state = XTOGLS_DONE; |
778 | + } |
779 | + return status; |
780 | + |
781 | + default: |
782 | + return GL_WAIT_FAILED; |
783 | + } |
784 | +} |
785 | + |
786 | +void XToGLSync::reset (void) |
787 | +{ |
788 | + Display *dpy = screen->dpy (); |
789 | + if (state != XTOGLS_DONE) |
790 | + { |
791 | + return; |
792 | + } |
793 | + |
794 | + XSyncResetFence (dpy, f); |
795 | + |
796 | + XSyncAlarmAttributes values; |
797 | + values.trigger.wait_value = nextCounterValue; |
798 | + XSyncChangeAlarm (dpy, a, XSyncCAValue, &values); |
799 | + XSyncSetCounter (dpy, c, nextCounterValue); |
800 | + |
801 | + int overflow; |
802 | + XSyncValueAdd (&nextCounterValue, nextCounterValue, one, &overflow); |
803 | + |
804 | + state = XTOGLS_RESET_PENDING; |
805 | +} |
806 | + |
807 | +void XToGLSync::handleEvent (XSyncAlarmNotifyEvent* ae) |
808 | +{ |
809 | + if (ae->alarm == a) |
810 | + { |
811 | + if (state != XTOGLS_RESET_PENDING) |
812 | + { |
813 | + return; |
814 | + } |
815 | + |
816 | + state = XTOGLS_READY; |
817 | + } |
818 | +} |
819 | + |
HOW COULD THIS POSSIBLY HAVE A CONFLICT IN debian/ changelog? ????