Merge lp:~townsend/compiz/fix-lp269904 into lp:compiz/0.9.12
- fix-lp269904
- Merge into 0.9.12
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Stephen M. Webb | ||||
Approved revision: | 3912 | ||||
Merged at revision: | 3916 | ||||
Proposed branch: | lp:~townsend/compiz/fix-lp269904 | ||||
Merge into: | lp:compiz/0.9.12 | ||||
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:~townsend/compiz/fix-lp269904 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Stephen M. Webb | Approve | ||
Review via email: mp+244149@code.launchpad.net |
Commit message
Use the GL_EXT_
Description of the change
Stephen M. Webb (bregma) wrote : | # |
FTBFS on ARM
- 3911. By Christopher Townsend
-
Fixed includes to try to fix armhf FTBFS.
Move a updateXToGLSyncs() call to the correct place due to a bad merge.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3911
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3912. By Christopher Townsend
-
Move an "#ifndef USE_GLES" after some functions to fix FTBFS on armhf.
Stephen M. Webb (bregma) wrote : | # |
Is now fixed, PS Jenkins Bot is late to the party.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3912
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/changelog' | |||
2 | --- debian/changelog 2014-12-08 20:58:07 +0000 | |||
3 | +++ debian/changelog 2014-12-10 19:46:40 +0000 | |||
4 | @@ -1,3 +1,27 @@ | |||
5 | 1 | compiz (1:0.9.12.0+15.04.20141120-0ubuntu4) UNRELEASED; urgency=medium | ||
6 | 2 | |||
7 | 3 | [ James Jones ] | ||
8 | 4 | * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia | ||
9 | 5 | based GPUs to avoid screen refresh issues. (LP: #269904) | ||
10 | 6 | |||
11 | 7 | [ Kyle Brenneman ] | ||
12 | 8 | * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia | ||
13 | 9 | based GPUs to avoid screen refresh issues. (LP: #269904) | ||
14 | 10 | |||
15 | 11 | [ Viktor A. Danilov ] | ||
16 | 12 | * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia | ||
17 | 13 | based GPUs to avoid screen refresh issues. (LP: #269904) | ||
18 | 14 | |||
19 | 15 | [ Chris Townsend ] | ||
20 | 16 | * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia | ||
21 | 17 | based GPUs to avoid screen refresh issues. (LP: #269904) | ||
22 | 18 | |||
23 | 19 | [ Stephen M. Webb ] | ||
24 | 20 | * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia | ||
25 | 21 | based GPUs to avoid screen refresh issues. (LP: #269904) | ||
26 | 22 | |||
27 | 23 | -- Chris Townsend <christopher.townsend@canonical.com> Wed, 10 Dec 2014 08:19:58 -0500 | ||
28 | 24 | |||
29 | 1 | compiz (1:0.9.12.0+15.04.20141120-0ubuntu3) vivid; urgency=medium | 25 | compiz (1:0.9.12.0+15.04.20141120-0ubuntu3) vivid; urgency=medium |
30 | 2 | 26 | ||
31 | 3 | * Drop gnome-python dependenices, as python-gconf was only used in 2012 | 27 | * Drop gnome-python dependenices, as python-gconf was only used in 2012 |
32 | 4 | 28 | ||
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 2014-12-10 19:46:40 +0000 | |||
36 | @@ -79,10 +79,10 @@ | |||
37 | 79 | bool incorrectRefreshRate; // hack for NVIDIA specifying an incorrect | 79 | bool incorrectRefreshRate; // hack for NVIDIA specifying an incorrect |
38 | 80 | // refresh rate, causing us to miss vblanks | 80 | // refresh rate, causing us to miss vblanks |
39 | 81 | 81 | ||
44 | 82 | @@ -253,6 +273,10 @@ | 82 | @@ -266,6 +266,10 @@ |
45 | 83 | bool postprocessingRequired; | 83 | std::vector<XToGLSync*>::size_type currentSyncNum; |
46 | 84 | mutable CompString prevRegex; | 84 | XToGLSync *currentSync; |
47 | 85 | mutable bool prevBlacklisted; | 85 | std::vector<XToGLSync*>::size_type warmupSyncs; |
48 | 86 | + | 86 | + |
49 | 87 | + private: | 87 | + private: |
50 | 88 | + | 88 | + |
51 | 89 | 89 | ||
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 2014-12-10 19:46:40 +0000 | |||
55 | @@ -36,7 +36,9 @@ | |||
56 | 36 | #include <EGL/eglext.h> | 36 | #include <EGL/eglext.h> |
57 | 37 | #else | 37 | #else |
58 | 38 | #include <GL/gl.h> | 38 | #include <GL/gl.h> |
59 | 39 | #include <GL/glext.h> | ||
60 | 39 | #include <GL/glx.h> | 40 | #include <GL/glx.h> |
61 | 41 | #include <inttypes.h> | ||
62 | 40 | 42 | ||
63 | 41 | /* Some implementations have not yet given a definition | 43 | /* Some implementations have not yet given a definition |
64 | 42 | * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined | 44 | * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined |
65 | @@ -117,6 +119,39 @@ | |||
66 | 117 | #define GLX_FRONT_LEFT_EXT 0x20DE | 119 | #define GLX_FRONT_LEFT_EXT 0x20DE |
67 | 118 | #endif | 120 | #endif |
68 | 119 | 121 | ||
69 | 122 | #ifndef GL_ARB_sync | ||
70 | 123 | # ifndef GL_ES_VERSION_2_0 | ||
71 | 124 | typedef struct __GLsync *GLsync; | ||
72 | 125 | typedef int64_t GLint64; | ||
73 | 126 | typedef uint64_t GLuint64; | ||
74 | 127 | typedef intptr_t GLintptr; | ||
75 | 128 | # endif | ||
76 | 129 | |||
77 | 130 | # ifdef GL_APPLE_sync | ||
78 | 131 | # define GL_TIMEOUT_IGNORED GL_TIMEOUT_IGNORED_APPLE | ||
79 | 132 | # define GL_ALREADY_SIGNALED GL_ALREADY_SIGNALED_APPLE | ||
80 | 133 | # define GL_TIMEOUT_EXPIRED GL_TIMEOUT_EXPIRED_APPLE | ||
81 | 134 | # define GL_CONDITION_SATISFIED GL_CONDITION_SATISFIED_APPLE | ||
82 | 135 | # define GL_WAIT_FAILED GL_WAIT_FAILED_APPLE | ||
83 | 136 | # define GL_SYNC_GPU_COMMANDS_COMPLETE GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE | ||
84 | 137 | # define GL_SYNC_STATUS GL_SYNC_STATUS _APPLE | ||
85 | 138 | # define GL_SIGNALED GL_SIGNALED_APPLE | ||
86 | 139 | # else | ||
87 | 140 | # define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull | ||
88 | 141 | # define GL_ALREADY_SIGNALED 0x911A | ||
89 | 142 | # define GL_TIMEOUT_EXPIRED 0x911B | ||
90 | 143 | # define GL_CONDITION_SATISFIED 0x911C | ||
91 | 144 | # define GL_WAIT_FAILED 0x911D | ||
92 | 145 | # define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 | ||
93 | 146 | # define GL_SYNC_STATUS 0x9114 | ||
94 | 147 | # define GL_SIGNALED 0x9119 | ||
95 | 148 | # endif | ||
96 | 149 | #endif | ||
97 | 150 | |||
98 | 151 | #ifndef GL_EXT_x11_sync_object | ||
99 | 152 | #define GL_SYNC_X11_FENCE_EXT 0x90E1 | ||
100 | 153 | #endif | ||
101 | 154 | |||
102 | 120 | namespace GL { | 155 | namespace GL { |
103 | 121 | #ifdef USE_GLES | 156 | #ifdef USE_GLES |
104 | 122 | typedef EGLImageKHR (*EGLCreateImageKHRProc) (EGLDisplay dpy, | 157 | typedef EGLImageKHR (*EGLCreateImageKHRProc) (EGLDisplay dpy, |
105 | @@ -320,6 +355,24 @@ | |||
106 | 320 | GLsizei width, | 355 | GLsizei width, |
107 | 321 | GLsizei height); | 356 | GLsizei height); |
108 | 322 | 357 | ||
109 | 358 | typedef GLsync (*GLFenceSyncProc) (GLenum condition, GLbitfield flags); | ||
110 | 359 | typedef void (*GLDeleteSyncProc) (GLsync sync); | ||
111 | 360 | typedef GLenum (*GLClientWaitSyncProc) (GLsync sync, | ||
112 | 361 | GLbitfield flags, | ||
113 | 362 | GLuint64 timeout); | ||
114 | 363 | typedef void (*GLWaitSyncProc) (GLsync sync, | ||
115 | 364 | GLbitfield flags, | ||
116 | 365 | GLuint64 timeout); | ||
117 | 366 | typedef void (*GLGetSyncivProc) (GLsync sync, | ||
118 | 367 | GLenum pname, | ||
119 | 368 | GLsizei bufSize, | ||
120 | 369 | GLsizei *length, | ||
121 | 370 | GLint *values); | ||
122 | 371 | |||
123 | 372 | typedef GLsync (*GLImportSyncProc) (GLenum external_sync_type, | ||
124 | 373 | GLintptr external_sync, | ||
125 | 374 | GLbitfield flags); | ||
126 | 375 | |||
127 | 323 | 376 | ||
128 | 324 | /* GL_ARB_shader_objects */ | 377 | /* GL_ARB_shader_objects */ |
129 | 325 | #ifndef USE_GLES | 378 | #ifndef USE_GLES |
130 | @@ -519,6 +572,14 @@ | |||
131 | 519 | 572 | ||
132 | 520 | #endif | 573 | #endif |
133 | 521 | 574 | ||
134 | 575 | extern GLFenceSyncProc fenceSync; | ||
135 | 576 | extern GLDeleteSyncProc deleteSync; | ||
136 | 577 | extern GLClientWaitSyncProc clientWaitSync; | ||
137 | 578 | extern GLWaitSyncProc waitSync; | ||
138 | 579 | extern GLGetSyncivProc getSynciv; | ||
139 | 580 | |||
140 | 581 | extern GLImportSyncProc importSync; | ||
141 | 582 | |||
142 | 522 | extern bool textureFromPixmap; | 583 | extern bool textureFromPixmap; |
143 | 523 | extern bool textureRectangle; | 584 | extern bool textureRectangle; |
144 | 524 | extern bool textureNonPowerOfTwo; | 585 | extern bool textureNonPowerOfTwo; |
145 | @@ -538,6 +599,9 @@ | |||
146 | 538 | extern GLint maxTextureUnits; | 599 | extern GLint maxTextureUnits; |
147 | 539 | extern bool bufferAge; | 600 | extern bool bufferAge; |
148 | 540 | 601 | ||
149 | 602 | extern bool sync; | ||
150 | 603 | extern bool xToGLSync; | ||
151 | 604 | |||
152 | 541 | extern bool canDoSaturated; | 605 | extern bool canDoSaturated; |
153 | 542 | extern bool canDoSlightlySaturated; | 606 | extern bool canDoSlightlySaturated; |
154 | 543 | 607 | ||
155 | 544 | 608 | ||
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 2014-12-10 19:46:40 +0000 | |||
159 | @@ -0,0 +1,99 @@ | |||
160 | 1 | /* | ||
161 | 2 | * Copyright © 2011 NVIDIA Corporation | ||
162 | 3 | * | ||
163 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
164 | 5 | * and its documentation for any purpose is hereby granted without | ||
165 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
166 | 7 | * and that both that copyright notice and this permission notice | ||
167 | 8 | * appear in supporting documentation, and that the name of | ||
168 | 9 | * NVIDIA Corporation not be used in advertising or publicity pertaining to | ||
169 | 10 | * distribution of the software without specific, written prior permission. | ||
170 | 11 | * NVIDIA Corporation makes no representations about the suitability of this | ||
171 | 12 | * software for any purpose. It is provided "as is" without express or | ||
172 | 13 | * implied warranty. | ||
173 | 14 | * | ||
174 | 15 | * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
175 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
176 | 17 | * NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
177 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
178 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
179 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
180 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
181 | 22 | * | ||
182 | 23 | * Authors: James Jones <jajones@nvidia.com> | ||
183 | 24 | */ | ||
184 | 25 | |||
185 | 26 | #ifndef _GLXTOGLSYNC_H | ||
186 | 27 | #define _GLXTOGLSYNC_H | ||
187 | 28 | |||
188 | 29 | #include <composite/composite.h> | ||
189 | 30 | #include <opengl/opengl.h> | ||
190 | 31 | #include <X11/extensions/sync.h> | ||
191 | 32 | |||
192 | 33 | #include "opengl/opengl.h" | ||
193 | 34 | |||
194 | 35 | /** | ||
195 | 36 | * Class that manages an XFenceSync wrapped in a GLsync object. | ||
196 | 37 | * | ||
197 | 38 | * Can be used to synchronize operations in the GL command stream | ||
198 | 39 | * with operations in the X command stream. | ||
199 | 40 | */ | ||
200 | 41 | class XToGLSync { | ||
201 | 42 | public: | ||
202 | 43 | XToGLSync (); | ||
203 | 44 | ~XToGLSync (); | ||
204 | 45 | |||
205 | 46 | XSyncAlarm alarm (void) const { return a; } | ||
206 | 47 | bool isReady (void) const { return state == XTOGLS_READY; } | ||
207 | 48 | |||
208 | 49 | /** | ||
209 | 50 | * Sends the trigger request to the server. The fence will be signaled | ||
210 | 51 | * after all rendering has completed. | ||
211 | 52 | */ | ||
212 | 53 | void trigger (void); | ||
213 | 54 | |||
214 | 55 | /** | ||
215 | 56 | * Calls glWaitSync. Any OpenGL commands after this will wait for the | ||
216 | 57 | * fence to be signaled. | ||
217 | 58 | */ | ||
218 | 59 | void insertWait (void); | ||
219 | 60 | |||
220 | 61 | /** | ||
221 | 62 | * Blocks until the fence is signaled, or until a timeout expires. | ||
222 | 63 | * | ||
223 | 64 | * \param The maximum time to wait, in nanoseconds. | ||
224 | 65 | * \return One of \c GL_ALREADY_SIGNALED, \c GL_CONDITION_SATISFIED, | ||
225 | 66 | * \c GL_TIMEOUT_EXPIRED, or \c GL_WAIT_FAILED. | ||
226 | 67 | */ | ||
227 | 68 | GLenum checkUpdateFinished (GLuint64 timeout); | ||
228 | 69 | |||
229 | 70 | /** | ||
230 | 71 | * Resets the fence. | ||
231 | 72 | */ | ||
232 | 73 | void reset (void); | ||
233 | 74 | void handleEvent (XSyncAlarmNotifyEvent *ev); | ||
234 | 75 | |||
235 | 76 | private: | ||
236 | 77 | XSyncFence f; | ||
237 | 78 | GLsync fGL; | ||
238 | 79 | |||
239 | 80 | XSyncCounter c; | ||
240 | 81 | XSyncAlarm a; | ||
241 | 82 | XSyncValue nextCounterValue; | ||
242 | 83 | |||
243 | 84 | enum { | ||
244 | 85 | XTOGLS_READY, | ||
245 | 86 | XTOGLS_TRIGGER_SENT, | ||
246 | 87 | XTOGLS_WAITING, | ||
247 | 88 | XTOGLS_DONE, | ||
248 | 89 | XTOGLS_RESET_PENDING, | ||
249 | 90 | } state; | ||
250 | 91 | |||
251 | 92 | static bool syncValuesInitialized; | ||
252 | 93 | static XSyncValue zero; | ||
253 | 94 | static XSyncValue one; | ||
254 | 95 | |||
255 | 96 | static Bool alarmEventPredicate (Display *dpy, XEvent *ev, XPointer arg); | ||
256 | 97 | }; | ||
257 | 98 | |||
258 | 99 | #endif | ||
259 | 0 | 100 | ||
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 2014-12-10 19:46:40 +0000 | |||
263 | @@ -59,6 +59,11 @@ | |||
264 | 59 | <_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> | 59 | <_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 | 60 | <default>true</default> | 60 | <default>true</default> |
266 | 61 | </option> | 61 | </option> |
267 | 62 | <option name="enable_x11_sync" type="bool"> | ||
268 | 63 | <_short>X11 Sync objects</_short> | ||
269 | 64 | <_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 | 65 | <default>true</default> | ||
271 | 66 | </option> | ||
272 | 62 | <option name="unredirect_driver_blacklist" type="string"> | 67 | <option name="unredirect_driver_blacklist" type="string"> |
273 | 63 | <_short>Unredirect Driver Blacklist</_short> | 68 | <_short>Unredirect Driver Blacklist</_short> |
274 | 64 | <_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> | 69 | <_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 | 65 | 70 | ||
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 2014-12-10 19:46:40 +0000 | |||
279 | @@ -35,6 +35,7 @@ | |||
280 | 35 | 35 | ||
281 | 36 | #include <composite/composite.h> | 36 | #include <composite/composite.h> |
282 | 37 | #include <opengl/opengl.h> | 37 | #include <opengl/opengl.h> |
283 | 38 | #include <opengl/xtoglsync.h> | ||
284 | 38 | #include <core/atoms.h> | 39 | #include <core/atoms.h> |
285 | 39 | #include <core/configurerequestbuffer.h> | 40 | #include <core/configurerequestbuffer.h> |
286 | 40 | 41 | ||
287 | @@ -184,6 +185,12 @@ | |||
288 | 184 | 185 | ||
289 | 185 | void updateView (); | 186 | void updateView (); |
290 | 186 | 187 | ||
291 | 188 | bool syncObjectsInitialized () const; | ||
292 | 189 | bool syncObjectsEnabled (); | ||
293 | 190 | void initXToGLSyncs (); | ||
294 | 191 | void destroyXToGLSyncs (); | ||
295 | 192 | void updateXToGLSyncs (); | ||
296 | 193 | |||
297 | 187 | bool driverIsBlacklisted (const char *regex) const; | 194 | bool driverIsBlacklisted (const char *regex) const; |
298 | 188 | 195 | ||
299 | 189 | bool postprocessRequiredForCurrentFrame (); | 196 | bool postprocessRequiredForCurrentFrame (); |
300 | @@ -253,6 +260,12 @@ | |||
301 | 253 | bool postprocessingRequired; | 260 | bool postprocessingRequired; |
302 | 254 | mutable CompString prevRegex; | 261 | mutable CompString prevRegex; |
303 | 255 | mutable bool prevBlacklisted; | 262 | mutable bool prevBlacklisted; |
304 | 263 | |||
305 | 264 | std::vector<XToGLSync*> xToGLSyncs; | ||
306 | 265 | std::map<XSyncAlarm, XToGLSync*> alarmToSync; | ||
307 | 266 | std::vector<XToGLSync*>::size_type currentSyncNum; | ||
308 | 267 | XToGLSync *currentSync; | ||
309 | 268 | std::vector<XToGLSync*>::size_type warmupSyncs; | ||
310 | 256 | }; | 269 | }; |
311 | 257 | 270 | ||
312 | 258 | class PrivateGLWindow : | 271 | class PrivateGLWindow : |
313 | 259 | 272 | ||
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 2014-12-10 19:46:40 +0000 | |||
317 | @@ -68,6 +68,16 @@ | |||
318 | 68 | 68 | ||
319 | 69 | using namespace compiz::opengl; | 69 | using namespace compiz::opengl; |
320 | 70 | 70 | ||
321 | 71 | /** | ||
322 | 72 | * The number of X11 sync objects to create. | ||
323 | 73 | */ | ||
324 | 74 | static const size_t NUM_X11_SYNCS = 16; | ||
325 | 75 | |||
326 | 76 | /** | ||
327 | 77 | * The maximum time to wait for a sync object, in nanoseconds. | ||
328 | 78 | */ | ||
329 | 79 | static const GLuint64 MAX_SYNC_WAIT_TIME = 1000000000ull; // One second | ||
330 | 80 | |||
331 | 71 | namespace GL { | 81 | namespace GL { |
332 | 72 | #ifdef USE_GLES | 82 | #ifdef USE_GLES |
333 | 73 | EGLCreateImageKHRProc createImage; | 83 | EGLCreateImageKHRProc createImage; |
334 | @@ -170,6 +180,14 @@ | |||
335 | 170 | GLBindRenderbufferProc bindRenderbuffer = NULL; | 180 | GLBindRenderbufferProc bindRenderbuffer = NULL; |
336 | 171 | GLRenderbufferStorageProc renderbufferStorage = NULL; | 181 | GLRenderbufferStorageProc renderbufferStorage = NULL; |
337 | 172 | 182 | ||
338 | 183 | GLFenceSyncProc fenceSync = NULL; | ||
339 | 184 | GLDeleteSyncProc deleteSync = NULL; | ||
340 | 185 | GLClientWaitSyncProc clientWaitSync = NULL; | ||
341 | 186 | GLWaitSyncProc waitSync = NULL; | ||
342 | 187 | GLGetSyncivProc getSynciv = NULL; | ||
343 | 188 | |||
344 | 189 | GLImportSyncProc importSync = NULL; | ||
345 | 190 | |||
346 | 173 | bool textureFromPixmap = true; | 191 | bool textureFromPixmap = true; |
347 | 174 | bool textureRectangle = false; | 192 | bool textureRectangle = false; |
348 | 175 | bool textureNonPowerOfTwo = false; | 193 | bool textureNonPowerOfTwo = false; |
349 | @@ -188,6 +206,9 @@ | |||
350 | 188 | GLint maxTextureUnits = 1; | 206 | GLint maxTextureUnits = 1; |
351 | 189 | bool bufferAge = false; | 207 | bool bufferAge = false; |
352 | 190 | 208 | ||
353 | 209 | bool sync = false; | ||
354 | 210 | bool xToGLSync = false; | ||
355 | 211 | |||
356 | 191 | bool canDoSaturated = false; | 212 | bool canDoSaturated = false; |
357 | 192 | bool canDoSlightlySaturated = false; | 213 | bool canDoSlightlySaturated = false; |
358 | 193 | 214 | ||
359 | @@ -1054,6 +1075,36 @@ | |||
360 | 1054 | if (strstr (glExtensions, "GL_ARB_texture_compression")) | 1075 | if (strstr (glExtensions, "GL_ARB_texture_compression")) |
361 | 1055 | GL::textureCompression = true; | 1076 | GL::textureCompression = true; |
362 | 1056 | 1077 | ||
363 | 1078 | if (strstr (glExtensions, "GL_ARB_sync")) | ||
364 | 1079 | { | ||
365 | 1080 | GL::fenceSync = (GL::GLFenceSyncProc) | ||
366 | 1081 | getProcAddress ("glFenceSync"); | ||
367 | 1082 | GL::deleteSync = (GL::GLDeleteSyncProc) | ||
368 | 1083 | getProcAddress ("glDeleteSync"); | ||
369 | 1084 | GL::clientWaitSync = (GL::GLClientWaitSyncProc) | ||
370 | 1085 | getProcAddress ("glClientWaitSync"); | ||
371 | 1086 | GL::waitSync = (GL::GLWaitSyncProc) | ||
372 | 1087 | getProcAddress ("glWaitSync"); | ||
373 | 1088 | GL::getSynciv = (GL::GLGetSyncivProc) | ||
374 | 1089 | getProcAddress ("glGetSynciv"); | ||
375 | 1090 | |||
376 | 1091 | if (GL::fenceSync && | ||
377 | 1092 | GL::deleteSync && | ||
378 | 1093 | GL::clientWaitSync && | ||
379 | 1094 | GL::waitSync && | ||
380 | 1095 | GL::getSynciv) | ||
381 | 1096 | GL::sync = true; | ||
382 | 1097 | } | ||
383 | 1098 | |||
384 | 1099 | if (strstr (glExtensions, "GL_EXT_x11_sync_object")) | ||
385 | 1100 | { | ||
386 | 1101 | GL::importSync = (GL::GLImportSyncProc) | ||
387 | 1102 | getProcAddress ("glImportSyncEXT"); | ||
388 | 1103 | |||
389 | 1104 | if (GL::importSync) | ||
390 | 1105 | GL::xToGLSync = true; | ||
391 | 1106 | } | ||
392 | 1107 | |||
393 | 1057 | glClearColor (0.0, 0.0, 0.0, 1.0); | 1108 | glClearColor (0.0, 0.0, 0.0, 1.0); |
394 | 1058 | glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); | 1109 | glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
395 | 1059 | glEnable (GL_CULL_FACE); | 1110 | glEnable (GL_CULL_FACE); |
396 | @@ -1257,6 +1308,8 @@ | |||
397 | 1257 | getProcAddress ("glXSwapIntervalSGI"); | 1308 | getProcAddress ("glXSwapIntervalSGI"); |
398 | 1258 | } | 1309 | } |
399 | 1259 | 1310 | ||
400 | 1311 | priv->initXToGLSyncs (); | ||
401 | 1312 | |||
402 | 1260 | fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements); | 1313 | fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements); |
403 | 1261 | 1314 | ||
404 | 1262 | GL::stencilBuffer = false; | 1315 | GL::stencilBuffer = false; |
405 | @@ -1411,6 +1464,9 @@ | |||
406 | 1411 | 1464 | ||
407 | 1412 | GLScreen::~GLScreen () | 1465 | GLScreen::~GLScreen () |
408 | 1413 | { | 1466 | { |
409 | 1467 | // Must occur before context is destroyed. | ||
410 | 1468 | priv->destroyXToGLSyncs (); | ||
411 | 1469 | |||
412 | 1414 | if (priv->hasCompositing) | 1470 | if (priv->hasCompositing) |
413 | 1415 | CompositeScreen::get (screen)->unregisterPaintHandler (); | 1471 | CompositeScreen::get (screen)->unregisterPaintHandler (); |
414 | 1416 | 1472 | ||
415 | @@ -1471,7 +1527,10 @@ | |||
416 | 1471 | glVersion (NULL), | 1527 | glVersion (NULL), |
417 | 1472 | postprocessingRequired (false), | 1528 | postprocessingRequired (false), |
418 | 1473 | prevRegex (), | 1529 | prevRegex (), |
420 | 1474 | prevBlacklisted (false) | 1530 | prevBlacklisted (false), |
421 | 1531 | currentSyncNum (0), | ||
422 | 1532 | currentSync (0), | ||
423 | 1533 | warmupSyncs (0) | ||
424 | 1475 | { | 1534 | { |
425 | 1476 | ScreenInterface::setHandler (screen); | 1535 | ScreenInterface::setHandler (screen); |
426 | 1477 | CompositeScreenInterface::setHandler (cScreen); | 1536 | CompositeScreenInterface::setHandler (cScreen); |
427 | @@ -1563,6 +1622,16 @@ | |||
428 | 1563 | * be recopying the root window pixmap all the time | 1622 | * be recopying the root window pixmap all the time |
429 | 1564 | * which is no good, so don't do that */ | 1623 | * which is no good, so don't do that */ |
430 | 1565 | } | 1624 | } |
431 | 1625 | else if (event->type == screen->syncEvent () + XSyncAlarmNotify) | ||
432 | 1626 | { | ||
433 | 1627 | XSyncAlarmNotifyEvent *ae = | ||
434 | 1628 | reinterpret_cast<XSyncAlarmNotifyEvent*>(event); | ||
435 | 1629 | std::map<XSyncAlarm, XToGLSync*>::iterator it = | ||
436 | 1630 | alarmToSync.find (ae->alarm); | ||
437 | 1631 | |||
438 | 1632 | if (it != alarmToSync.end ()) | ||
439 | 1633 | it->second->handleEvent (ae); | ||
440 | 1634 | } | ||
441 | 1566 | break; | 1635 | break; |
442 | 1567 | } | 1636 | } |
443 | 1568 | } | 1637 | } |
444 | @@ -2026,6 +2095,101 @@ | |||
445 | 2026 | { | 2095 | { |
446 | 2027 | } | 2096 | } |
447 | 2028 | 2097 | ||
448 | 2098 | bool | ||
449 | 2099 | PrivateGLScreen::syncObjectsInitialized () const | ||
450 | 2100 | { | ||
451 | 2101 | return !xToGLSyncs.empty (); | ||
452 | 2102 | } | ||
453 | 2103 | |||
454 | 2104 | bool | ||
455 | 2105 | PrivateGLScreen::syncObjectsEnabled () | ||
456 | 2106 | { | ||
457 | 2107 | return GL::sync && GL::xToGLSync && optionGetEnableX11Sync (); | ||
458 | 2108 | } | ||
459 | 2109 | |||
460 | 2110 | void | ||
461 | 2111 | PrivateGLScreen::initXToGLSyncs () | ||
462 | 2112 | { | ||
463 | 2113 | assert (!syncObjectsInitialized ()); | ||
464 | 2114 | assert (xToGLSyncs.empty ()); | ||
465 | 2115 | assert (alarmToSync.empty ()); | ||
466 | 2116 | |||
467 | 2117 | if (syncObjectsEnabled () && !syncObjectsInitialized ()) | ||
468 | 2118 | { | ||
469 | 2119 | xToGLSyncs.resize (NUM_X11_SYNCS, NULL); | ||
470 | 2120 | |||
471 | 2121 | foreach (XToGLSync*& sync, xToGLSyncs) | ||
472 | 2122 | { | ||
473 | 2123 | sync = new XToGLSync (); | ||
474 | 2124 | alarmToSync[sync->alarm ()] = sync; | ||
475 | 2125 | } | ||
476 | 2126 | |||
477 | 2127 | currentSyncNum = 0; | ||
478 | 2128 | currentSync = xToGLSyncs[0]; | ||
479 | 2129 | warmupSyncs = 0; | ||
480 | 2130 | } | ||
481 | 2131 | } | ||
482 | 2132 | |||
483 | 2133 | void | ||
484 | 2134 | PrivateGLScreen::destroyXToGLSyncs () | ||
485 | 2135 | { | ||
486 | 2136 | if (syncObjectsInitialized ()) | ||
487 | 2137 | { | ||
488 | 2138 | foreach (XToGLSync* sync, xToGLSyncs) | ||
489 | 2139 | delete sync; | ||
490 | 2140 | xToGLSyncs.resize (0); | ||
491 | 2141 | } | ||
492 | 2142 | alarmToSync.clear (); | ||
493 | 2143 | currentSyncNum = 0; | ||
494 | 2144 | currentSync = NULL; | ||
495 | 2145 | warmupSyncs = 0; | ||
496 | 2146 | } | ||
497 | 2147 | |||
498 | 2148 | void | ||
499 | 2149 | PrivateGLScreen::updateXToGLSyncs () | ||
500 | 2150 | { | ||
501 | 2151 | const std::vector<XToGLSync*>::size_type numSyncs = xToGLSyncs.size (); | ||
502 | 2152 | |||
503 | 2153 | if (numSyncs) | ||
504 | 2154 | { | ||
505 | 2155 | if (warmupSyncs >= numSyncs / 2) | ||
506 | 2156 | { | ||
507 | 2157 | const std::vector<XToGLSync*>::size_type resetSyncIdx = | ||
508 | 2158 | (currentSyncNum + (numSyncs / 2)) % numSyncs; | ||
509 | 2159 | |||
510 | 2160 | XToGLSync* syncToReset = xToGLSyncs[resetSyncIdx]; | ||
511 | 2161 | |||
512 | 2162 | GLenum status = syncToReset->checkUpdateFinished (0); | ||
513 | 2163 | if (status == GL_TIMEOUT_EXPIRED) | ||
514 | 2164 | { | ||
515 | 2165 | status = syncToReset->checkUpdateFinished (MAX_SYNC_WAIT_TIME); | ||
516 | 2166 | } | ||
517 | 2167 | |||
518 | 2168 | if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) | ||
519 | 2169 | { | ||
520 | 2170 | // This should never happen. If there was an error somewhere, | ||
521 | 2171 | // then we don't want to risk a hang here, so just destroy the | ||
522 | 2172 | // sync objects. We'll recreate them again in the next call to | ||
523 | 2173 | // prepareDrawing. | ||
524 | 2174 | compLogMessage ("opengl", CompLogLevelError, "Timed out waiting for sync object."); | ||
525 | 2175 | destroyXToGLSyncs (); | ||
526 | 2176 | return; | ||
527 | 2177 | } | ||
528 | 2178 | |||
529 | 2179 | syncToReset->reset (); | ||
530 | 2180 | } | ||
531 | 2181 | else | ||
532 | 2182 | { | ||
533 | 2183 | warmupSyncs++; | ||
534 | 2184 | } | ||
535 | 2185 | |||
536 | 2186 | currentSyncNum++; | ||
537 | 2187 | currentSyncNum %= numSyncs; | ||
538 | 2188 | |||
539 | 2189 | currentSync = xToGLSyncs[currentSyncNum]; | ||
540 | 2190 | } | ||
541 | 2191 | } | ||
542 | 2192 | |||
543 | 2029 | #ifndef USE_GLES | 2193 | #ifndef USE_GLES |
544 | 2030 | 2194 | ||
545 | 2031 | void | 2195 | void |
546 | @@ -2199,6 +2363,9 @@ | |||
547 | 2199 | glClear (GL_COLOR_BUFFER_BIT); | 2363 | glClear (GL_COLOR_BUFFER_BIT); |
548 | 2200 | } | 2364 | } |
549 | 2201 | 2365 | ||
550 | 2366 | if (currentSync) | ||
551 | 2367 | currentSync->insertWait (); | ||
552 | 2368 | |||
553 | 2202 | // Disable everything that we don't usually need and could slow us down | 2369 | // Disable everything that we don't usually need and could slow us down |
554 | 2203 | glDisable (GL_BLEND); | 2370 | glDisable (GL_BLEND); |
555 | 2204 | glDisable (GL_STENCIL_TEST); | 2371 | glDisable (GL_STENCIL_TEST); |
556 | @@ -2352,6 +2519,8 @@ | |||
557 | 2352 | doubleBuffer.render (paintRegion, fullscreen); | 2519 | doubleBuffer.render (paintRegion, fullscreen); |
558 | 2353 | 2520 | ||
559 | 2354 | lastMask = mask; | 2521 | lastMask = mask; |
560 | 2522 | |||
561 | 2523 | updateXToGLSyncs (); | ||
562 | 2355 | } | 2524 | } |
563 | 2356 | 2525 | ||
564 | 2357 | unsigned int | 2526 | unsigned int |
565 | @@ -2448,6 +2617,55 @@ | |||
566 | 2448 | updateFrameProvider (); | 2617 | updateFrameProvider (); |
567 | 2449 | CompositeScreen::get (screen)->damageScreen (); | 2618 | CompositeScreen::get (screen)->damageScreen (); |
568 | 2450 | } | 2619 | } |
569 | 2620 | |||
570 | 2621 | // Check if the option to use sync objects has been enabled or disabled. | ||
571 | 2622 | if (syncObjectsEnabled () && !syncObjectsInitialized ()) | ||
572 | 2623 | { | ||
573 | 2624 | initXToGLSyncs (); | ||
574 | 2625 | } | ||
575 | 2626 | else if (!syncObjectsEnabled () && syncObjectsInitialized ()) | ||
576 | 2627 | { | ||
577 | 2628 | destroyXToGLSyncs (); | ||
578 | 2629 | } | ||
579 | 2630 | |||
580 | 2631 | if (currentSync) | ||
581 | 2632 | { | ||
582 | 2633 | if (!currentSync->isReady ()) | ||
583 | 2634 | { | ||
584 | 2635 | for (std::vector<XToGLSync*>::size_type i = xToGLSyncs.size () / 2; i > 0; i--) | ||
585 | 2636 | { | ||
586 | 2637 | // try to check next sync | ||
587 | 2638 | updateXToGLSyncs (); | ||
588 | 2639 | |||
589 | 2640 | // method updateXToGLSync may disable syncs | ||
590 | 2641 | if (!currentSync) | ||
591 | 2642 | break; | ||
592 | 2643 | |||
593 | 2644 | if (currentSync->isReady ()) | ||
594 | 2645 | break; | ||
595 | 2646 | } | ||
596 | 2647 | } | ||
597 | 2648 | } | ||
598 | 2649 | |||
599 | 2650 | if (currentSync) | ||
600 | 2651 | { | ||
601 | 2652 | if (!currentSync->isReady ()) | ||
602 | 2653 | { | ||
603 | 2654 | // If this happens, then we must have missed an event or update | ||
604 | 2655 | // somewhere. Destroy and recreate the sync objects to put us back | ||
605 | 2656 | // into a good state. | ||
606 | 2657 | destroyXToGLSyncs (); | ||
607 | 2658 | initXToGLSyncs (); | ||
608 | 2659 | } | ||
609 | 2660 | } | ||
610 | 2661 | |||
611 | 2662 | if (currentSync) | ||
612 | 2663 | { | ||
613 | 2664 | // Tell the server to trigger the fence object after all rendering has | ||
614 | 2665 | // completed. | ||
615 | 2666 | assert (currentSync->isReady ()); | ||
616 | 2667 | currentSync->trigger (); | ||
617 | 2668 | } | ||
618 | 2451 | } | 2669 | } |
619 | 2452 | 2670 | ||
620 | 2453 | bool | 2671 | bool |
621 | 2454 | 2672 | ||
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 2014-12-10 19:46:40 +0000 | |||
625 | @@ -0,0 +1,194 @@ | |||
626 | 1 | /* | ||
627 | 2 | * Copyright © 2011 NVIDIA Corporation | ||
628 | 3 | * | ||
629 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
630 | 5 | * and its documentation for any purpose is hereby granted without | ||
631 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
632 | 7 | * and that both that copyright notice and this permission notice | ||
633 | 8 | * appear in supporting documentation, and that the name of | ||
634 | 9 | * NVIDIA Corporation not be used in advertising or publicity pertaining to | ||
635 | 10 | * distribution of the software without specific, written prior permission. | ||
636 | 11 | * NVIDIA Corporation makes no representations about the suitability of this | ||
637 | 12 | * software for any purpose. It is provided "as is" without express or | ||
638 | 13 | * implied warranty. | ||
639 | 14 | * | ||
640 | 15 | * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
641 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
642 | 17 | * NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
643 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
644 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
645 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
646 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
647 | 22 | * | ||
648 | 23 | * Authors: James Jones <jajones@nvidia.com> | ||
649 | 24 | */ | ||
650 | 25 | |||
651 | 26 | #include "opengl/xtoglsync.h" | ||
652 | 27 | |||
653 | 28 | bool XToGLSync::syncValuesInitialized = false; | ||
654 | 29 | XSyncValue XToGLSync::zero; | ||
655 | 30 | XSyncValue XToGLSync::one; | ||
656 | 31 | |||
657 | 32 | XToGLSync::XToGLSync () : | ||
658 | 33 | f (None), | ||
659 | 34 | fGL (NULL), | ||
660 | 35 | c (None), | ||
661 | 36 | a (None), | ||
662 | 37 | state (XToGLSync::XTOGLS_READY) | ||
663 | 38 | { | ||
664 | 39 | Display *dpy = screen->dpy (); | ||
665 | 40 | |||
666 | 41 | f = XSyncCreateFence (dpy, DefaultRootWindow (dpy), False); | ||
667 | 42 | fGL = GL::importSync (GL_SYNC_X11_FENCE_EXT, f, 0); | ||
668 | 43 | |||
669 | 44 | if (!syncValuesInitialized) | ||
670 | 45 | { | ||
671 | 46 | XSyncIntToValue (&zero, 0); | ||
672 | 47 | XSyncIntToValue (&one, 1); | ||
673 | 48 | syncValuesInitialized = true; | ||
674 | 49 | } | ||
675 | 50 | |||
676 | 51 | XSyncIntToValue (&nextCounterValue, 1); | ||
677 | 52 | c = XSyncCreateCounter (dpy, zero); | ||
678 | 53 | |||
679 | 54 | XSyncAlarmAttributes alarmAttribs; | ||
680 | 55 | alarmAttribs.trigger.counter = c; | ||
681 | 56 | alarmAttribs.trigger.value_type = XSyncAbsolute; | ||
682 | 57 | alarmAttribs.trigger.wait_value = one; | ||
683 | 58 | alarmAttribs.trigger.test_type = XSyncPositiveTransition; | ||
684 | 59 | alarmAttribs.events = True; | ||
685 | 60 | a = XSyncCreateAlarm (dpy, | ||
686 | 61 | XSyncCACounter | | ||
687 | 62 | XSyncCAValueType | | ||
688 | 63 | XSyncCAValue | | ||
689 | 64 | XSyncCATestType | | ||
690 | 65 | XSyncCAEvents, | ||
691 | 66 | &alarmAttribs); | ||
692 | 67 | |||
693 | 68 | } | ||
694 | 69 | |||
695 | 70 | XToGLSync::~XToGLSync () | ||
696 | 71 | { | ||
697 | 72 | Display *dpy = screen->dpy (); | ||
698 | 73 | |||
699 | 74 | switch (state) { | ||
700 | 75 | case XTOGLS_WAITING: | ||
701 | 76 | break; | ||
702 | 77 | |||
703 | 78 | case XTOGLS_RESET_PENDING: | ||
704 | 79 | { | ||
705 | 80 | XEvent ev; | ||
706 | 81 | |||
707 | 82 | XIfEvent (dpy, &ev, &XToGLSync::alarmEventPredicate, | ||
708 | 83 | reinterpret_cast<XPointer>(this)); | ||
709 | 84 | handleEvent(reinterpret_cast<XSyncAlarmNotifyEvent*>(&ev)); | ||
710 | 85 | } | ||
711 | 86 | // Fall through. | ||
712 | 87 | case XTOGLS_READY: | ||
713 | 88 | XSyncTriggerFence (dpy, f); | ||
714 | 89 | XFlush (dpy); | ||
715 | 90 | break; | ||
716 | 91 | |||
717 | 92 | case XTOGLS_TRIGGER_SENT: | ||
718 | 93 | case XTOGLS_DONE: | ||
719 | 94 | // Nothing to do. | ||
720 | 95 | break; | ||
721 | 96 | } | ||
722 | 97 | |||
723 | 98 | GL::deleteSync (fGL); | ||
724 | 99 | XSyncDestroyFence (dpy, f); | ||
725 | 100 | XSyncDestroyCounter (dpy, c); | ||
726 | 101 | XSyncDestroyAlarm (dpy, a); | ||
727 | 102 | } | ||
728 | 103 | |||
729 | 104 | Bool XToGLSync::alarmEventPredicate (Display *dpy, XEvent *ev, XPointer arg) | ||
730 | 105 | { | ||
731 | 106 | if (ev->type == screen->syncEvent () + XSyncAlarmNotify) | ||
732 | 107 | { | ||
733 | 108 | XToGLSync *sync = reinterpret_cast<XToGLSync*>(arg); | ||
734 | 109 | XSyncAlarmNotifyEvent *ae = | ||
735 | 110 | reinterpret_cast<XSyncAlarmNotifyEvent*>(ev); | ||
736 | 111 | |||
737 | 112 | if (ae->alarm == sync->a) | ||
738 | 113 | return True; | ||
739 | 114 | } | ||
740 | 115 | |||
741 | 116 | return False; | ||
742 | 117 | } | ||
743 | 118 | |||
744 | 119 | void XToGLSync::trigger (void) | ||
745 | 120 | { | ||
746 | 121 | Display *dpy = screen->dpy (); | ||
747 | 122 | assert (state == XTOGLS_READY); | ||
748 | 123 | |||
749 | 124 | XSyncTriggerFence (dpy, f); | ||
750 | 125 | XFlush (dpy); | ||
751 | 126 | |||
752 | 127 | state = XTOGLS_TRIGGER_SENT; | ||
753 | 128 | } | ||
754 | 129 | |||
755 | 130 | void XToGLSync::insertWait (void) | ||
756 | 131 | { | ||
757 | 132 | if (state != XTOGLS_TRIGGER_SENT) | ||
758 | 133 | return; | ||
759 | 134 | |||
760 | 135 | GL::waitSync (fGL, 0, GL_TIMEOUT_IGNORED); | ||
761 | 136 | |||
762 | 137 | state = XTOGLS_WAITING; | ||
763 | 138 | } | ||
764 | 139 | |||
765 | 140 | GLenum XToGLSync::checkUpdateFinished (GLuint64 timeout) | ||
766 | 141 | { | ||
767 | 142 | GLenum status; | ||
768 | 143 | |||
769 | 144 | switch (state) { | ||
770 | 145 | case XTOGLS_DONE: | ||
771 | 146 | return GL_ALREADY_SIGNALED; | ||
772 | 147 | |||
773 | 148 | case XTOGLS_WAITING: | ||
774 | 149 | status = GL::clientWaitSync (fGL, 0, timeout); | ||
775 | 150 | if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) | ||
776 | 151 | { | ||
777 | 152 | state = XTOGLS_DONE; | ||
778 | 153 | } | ||
779 | 154 | return status; | ||
780 | 155 | |||
781 | 156 | default: | ||
782 | 157 | return GL_WAIT_FAILED; | ||
783 | 158 | } | ||
784 | 159 | } | ||
785 | 160 | |||
786 | 161 | void XToGLSync::reset (void) | ||
787 | 162 | { | ||
788 | 163 | Display *dpy = screen->dpy (); | ||
789 | 164 | if (state != XTOGLS_DONE) | ||
790 | 165 | { | ||
791 | 166 | return; | ||
792 | 167 | } | ||
793 | 168 | |||
794 | 169 | XSyncResetFence (dpy, f); | ||
795 | 170 | |||
796 | 171 | XSyncAlarmAttributes values; | ||
797 | 172 | values.trigger.wait_value = nextCounterValue; | ||
798 | 173 | XSyncChangeAlarm (dpy, a, XSyncCAValue, &values); | ||
799 | 174 | XSyncSetCounter (dpy, c, nextCounterValue); | ||
800 | 175 | |||
801 | 176 | int overflow; | ||
802 | 177 | XSyncValueAdd (&nextCounterValue, nextCounterValue, one, &overflow); | ||
803 | 178 | |||
804 | 179 | state = XTOGLS_RESET_PENDING; | ||
805 | 180 | } | ||
806 | 181 | |||
807 | 182 | void XToGLSync::handleEvent (XSyncAlarmNotifyEvent* ae) | ||
808 | 183 | { | ||
809 | 184 | if (ae->alarm == a) | ||
810 | 185 | { | ||
811 | 186 | if (state != XTOGLS_RESET_PENDING) | ||
812 | 187 | { | ||
813 | 188 | return; | ||
814 | 189 | } | ||
815 | 190 | |||
816 | 191 | state = XTOGLS_READY; | ||
817 | 192 | } | ||
818 | 193 | } | ||
819 | 194 |
OK, let's get this egg hatched.