Merge lp:~bregma/compiz/lp-269904-trusty into lp:compiz/0.9.11

Proposed by Stephen M. Webb
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
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_x11_sync_object OpenGL extension to synchronize updates with X11 to avoid unrefreshed parts of the screen on Nvidia hardware.

Description of the change

Use the GL_EXT_x11_sync_object OpenGL extension to synchronize updates with X11 to avoid unrefreshed parts of the screen on Nvidia hardware.

Cherry-picked for backport from COmpiz 0.9.12.

To post a comment you must log in.
Revision history for this message
Stephen M. Webb (bregma) wrote :

HOW COULD THIS POSSIBLY HAVE A CONFLICT IN debian/changelog?????

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~bregma/compiz/lp-269904-trusty updated
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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Stephen M. Webb (bregma) wrote :

C'mon Jenkins, you can do better than that.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

Changelog version should be 1:0.9.11.3-0ubuntu2 instead of 1:0.9.12.3-0ubuntu2.

review: Needs Fixing
lp:~bregma/compiz/lp-269904-trusty updated
3871. By Stephen M. Webb

debian/changelog: fixed Ubuntu package versaion

Revision history for this message
Christopher Townsend (townsend) wrote :

Ok, looks good now.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2014-11-04 19:42:46 +0000
+++ debian/changelog 2015-01-13 14:32:13 +0000
@@ -1,3 +1,27 @@
1compiz (1:0.9.11.3-0ubuntu2) UNRELEASED; urgency=medium
2
3 [ James Jones ]
4 * Added support for GL_EXT_x11_sync_object OpenGL extension for Nvidia
5 based GPUs to avoid screen refresh issues. (LP: #269904)
6
7 [ Kyle Brenneman ]
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 [ Viktor A. Danilov ]
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 [ Chris Townsend ]
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 [ Stephen M. Webb ]
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 -- Chris Townsend <christopher.townsend@canonical.com> Wed, 10 Dec 2014 08:19:58 -0500
24
1compiz (1:0.9.11.3+14.04.20141104-0ubuntu1) trusty; urgency=medium25compiz (1:0.9.11.3+14.04.20141104-0ubuntu1) trusty; urgency=medium
226
3 [ Chris Townsend ]27 [ Chris Townsend ]
428
=== modified file 'debian/patches/100_workaround_virtualbox_hang.patch'
--- debian/patches/100_workaround_virtualbox_hang.patch 2014-03-03 14:32:56 +0000
+++ debian/patches/100_workaround_virtualbox_hang.patch 2015-01-13 14:32:13 +0000
@@ -79,10 +79,10 @@
79 bool incorrectRefreshRate; // hack for NVIDIA specifying an incorrect79 bool incorrectRefreshRate; // hack for NVIDIA specifying an incorrect
80 // refresh rate, causing us to miss vblanks80 // refresh rate, causing us to miss vblanks
81 81
82@@ -253,6 +273,10 @@82@@ -266,6 +266,10 @@
83 bool postprocessingRequired;83 std::vector<XToGLSync*>::size_type currentSyncNum;
84 mutable CompString prevRegex;84 XToGLSync *currentSync;
85 mutable bool prevBlacklisted;85 std::vector<XToGLSync*>::size_type warmupSyncs;
86+86+
87+ private:87+ private:
88+88+
8989
=== modified file 'plugins/opengl/include/opengl/opengl.h'
--- plugins/opengl/include/opengl/opengl.h 2013-04-27 23:30:28 +0000
+++ plugins/opengl/include/opengl/opengl.h 2015-01-13 14:32:13 +0000
@@ -36,7 +36,9 @@
36#include <EGL/eglext.h>36#include <EGL/eglext.h>
37#else37#else
38#include <GL/gl.h>38#include <GL/gl.h>
39#include <GL/glext.h>
39#include <GL/glx.h>40#include <GL/glx.h>
41#include <inttypes.h>
4042
41/* Some implementations have not yet given a definition43/* Some implementations have not yet given a definition
42 * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined44 * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined
@@ -117,6 +119,39 @@
117#define GLX_FRONT_LEFT_EXT 0x20DE119#define GLX_FRONT_LEFT_EXT 0x20DE
118#endif120#endif
119121
122#ifndef GL_ARB_sync
123# ifndef GL_ES_VERSION_2_0
124typedef struct __GLsync *GLsync;
125typedef int64_t GLint64;
126typedef uint64_t GLuint64;
127typedef intptr_t GLintptr;
128# endif
129
130# ifdef GL_APPLE_sync
131# define GL_TIMEOUT_IGNORED GL_TIMEOUT_IGNORED_APPLE
132# define GL_ALREADY_SIGNALED GL_ALREADY_SIGNALED_APPLE
133# define GL_TIMEOUT_EXPIRED GL_TIMEOUT_EXPIRED_APPLE
134# define GL_CONDITION_SATISFIED GL_CONDITION_SATISFIED_APPLE
135# define GL_WAIT_FAILED GL_WAIT_FAILED_APPLE
136# define GL_SYNC_GPU_COMMANDS_COMPLETE GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE
137# define GL_SYNC_STATUS GL_SYNC_STATUS _APPLE
138# define GL_SIGNALED GL_SIGNALED_APPLE
139# else
140# define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
141# define GL_ALREADY_SIGNALED 0x911A
142# define GL_TIMEOUT_EXPIRED 0x911B
143# define GL_CONDITION_SATISFIED 0x911C
144# define GL_WAIT_FAILED 0x911D
145# define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
146# define GL_SYNC_STATUS 0x9114
147# define GL_SIGNALED 0x9119
148# endif
149#endif
150
151#ifndef GL_EXT_x11_sync_object
152#define GL_SYNC_X11_FENCE_EXT 0x90E1
153#endif
154
120namespace GL {155namespace GL {
121 #ifdef USE_GLES156 #ifdef USE_GLES
122 typedef EGLImageKHR (*EGLCreateImageKHRProc) (EGLDisplay dpy,157 typedef EGLImageKHR (*EGLCreateImageKHRProc) (EGLDisplay dpy,
@@ -320,6 +355,24 @@
320 GLsizei width,355 GLsizei width,
321 GLsizei height);356 GLsizei height);
322357
358 typedef GLsync (*GLFenceSyncProc) (GLenum condition, GLbitfield flags);
359 typedef void (*GLDeleteSyncProc) (GLsync sync);
360 typedef GLenum (*GLClientWaitSyncProc) (GLsync sync,
361 GLbitfield flags,
362 GLuint64 timeout);
363 typedef void (*GLWaitSyncProc) (GLsync sync,
364 GLbitfield flags,
365 GLuint64 timeout);
366 typedef void (*GLGetSyncivProc) (GLsync sync,
367 GLenum pname,
368 GLsizei bufSize,
369 GLsizei *length,
370 GLint *values);
371
372 typedef GLsync (*GLImportSyncProc) (GLenum external_sync_type,
373 GLintptr external_sync,
374 GLbitfield flags);
375
323376
324 /* GL_ARB_shader_objects */377 /* GL_ARB_shader_objects */
325 #ifndef USE_GLES378 #ifndef USE_GLES
@@ -519,6 +572,14 @@
519572
520#endif573#endif
521574
575 extern GLFenceSyncProc fenceSync;
576 extern GLDeleteSyncProc deleteSync;
577 extern GLClientWaitSyncProc clientWaitSync;
578 extern GLWaitSyncProc waitSync;
579 extern GLGetSyncivProc getSynciv;
580
581 extern GLImportSyncProc importSync;
582
522 extern bool textureFromPixmap;583 extern bool textureFromPixmap;
523 extern bool textureRectangle;584 extern bool textureRectangle;
524 extern bool textureNonPowerOfTwo;585 extern bool textureNonPowerOfTwo;
@@ -538,6 +599,9 @@
538 extern GLint maxTextureUnits;599 extern GLint maxTextureUnits;
539 extern bool bufferAge;600 extern bool bufferAge;
540601
602 extern bool sync;
603 extern bool xToGLSync;
604
541 extern bool canDoSaturated;605 extern bool canDoSaturated;
542 extern bool canDoSlightlySaturated;606 extern bool canDoSlightlySaturated;
543607
544608
=== added file 'plugins/opengl/include/opengl/xtoglsync.h'
--- plugins/opengl/include/opengl/xtoglsync.h 1970-01-01 00:00:00 +0000
+++ plugins/opengl/include/opengl/xtoglsync.h 2015-01-13 14:32:13 +0000
@@ -0,0 +1,99 @@
1/*
2 * Copyright © 2011 NVIDIA Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * NVIDIA Corporation not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * NVIDIA Corporation makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authors: James Jones <jajones@nvidia.com>
24 */
25
26#ifndef _GLXTOGLSYNC_H
27#define _GLXTOGLSYNC_H
28
29#include <composite/composite.h>
30#include <opengl/opengl.h>
31#include <X11/extensions/sync.h>
32
33#include "opengl/opengl.h"
34
35/**
36 * Class that manages an XFenceSync wrapped in a GLsync object.
37 *
38 * Can be used to synchronize operations in the GL command stream
39 * with operations in the X command stream.
40 */
41class XToGLSync {
42 public:
43 XToGLSync ();
44 ~XToGLSync ();
45
46 XSyncAlarm alarm (void) const { return a; }
47 bool isReady (void) const { return state == XTOGLS_READY; }
48
49 /**
50 * Sends the trigger request to the server. The fence will be signaled
51 * after all rendering has completed.
52 */
53 void trigger (void);
54
55 /**
56 * Calls glWaitSync. Any OpenGL commands after this will wait for the
57 * fence to be signaled.
58 */
59 void insertWait (void);
60
61 /**
62 * Blocks until the fence is signaled, or until a timeout expires.
63 *
64 * \param The maximum time to wait, in nanoseconds.
65 * \return One of \c GL_ALREADY_SIGNALED, \c GL_CONDITION_SATISFIED,
66 * \c GL_TIMEOUT_EXPIRED, or \c GL_WAIT_FAILED.
67 */
68 GLenum checkUpdateFinished (GLuint64 timeout);
69
70 /**
71 * Resets the fence.
72 */
73 void reset (void);
74 void handleEvent (XSyncAlarmNotifyEvent *ev);
75
76 private:
77 XSyncFence f;
78 GLsync fGL;
79
80 XSyncCounter c;
81 XSyncAlarm a;
82 XSyncValue nextCounterValue;
83
84 enum {
85 XTOGLS_READY,
86 XTOGLS_TRIGGER_SENT,
87 XTOGLS_WAITING,
88 XTOGLS_DONE,
89 XTOGLS_RESET_PENDING,
90 } state;
91
92 static bool syncValuesInitialized;
93 static XSyncValue zero;
94 static XSyncValue one;
95
96 static Bool alarmEventPredicate (Display *dpy, XEvent *ev, XPointer arg);
97};
98
99#endif
0100
=== modified file 'plugins/opengl/opengl.xml.in'
--- plugins/opengl/opengl.xml.in 2012-12-17 10:53:59 +0000
+++ plugins/opengl/opengl.xml.in 2015-01-13 14:32:13 +0000
@@ -59,6 +59,11 @@
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>
60 <default>true</default>60 <default>true</default>
61 </option>61 </option>
62 <option name="enable_x11_sync" type="bool">
63 <_short>X11 Sync objects</_short>
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>
65 <default>true</default>
66 </option>
62 <option name="unredirect_driver_blacklist" type="string">67 <option name="unredirect_driver_blacklist" type="string">
63 <_short>Unredirect Driver Blacklist</_short>68 <_short>Unredirect Driver Blacklist</_short>
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>
6570
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2013-04-25 17:01:46 +0000
+++ plugins/opengl/src/privates.h 2015-01-13 14:32:13 +0000
@@ -35,6 +35,7 @@
3535
36#include <composite/composite.h>36#include <composite/composite.h>
37#include <opengl/opengl.h>37#include <opengl/opengl.h>
38#include <opengl/xtoglsync.h>
38#include <core/atoms.h>39#include <core/atoms.h>
39#include <core/configurerequestbuffer.h>40#include <core/configurerequestbuffer.h>
4041
@@ -184,6 +185,12 @@
184185
185 void updateView ();186 void updateView ();
186187
188 bool syncObjectsInitialized () const;
189 bool syncObjectsEnabled ();
190 void initXToGLSyncs ();
191 void destroyXToGLSyncs ();
192 void updateXToGLSyncs ();
193
187 bool driverIsBlacklisted (const char *regex) const;194 bool driverIsBlacklisted (const char *regex) const;
188195
189 bool postprocessRequiredForCurrentFrame ();196 bool postprocessRequiredForCurrentFrame ();
@@ -253,6 +260,12 @@
253 bool postprocessingRequired;260 bool postprocessingRequired;
254 mutable CompString prevRegex;261 mutable CompString prevRegex;
255 mutable bool prevBlacklisted;262 mutable bool prevBlacklisted;
263
264 std::vector<XToGLSync*> xToGLSyncs;
265 std::map<XSyncAlarm, XToGLSync*> alarmToSync;
266 std::vector<XToGLSync*>::size_type currentSyncNum;
267 XToGLSync *currentSync;
268 std::vector<XToGLSync*>::size_type warmupSyncs;
256};269};
257270
258class PrivateGLWindow :271class PrivateGLWindow :
259272
=== modified file 'plugins/opengl/src/screen.cpp'
--- plugins/opengl/src/screen.cpp 2013-10-30 20:31:20 +0000
+++ plugins/opengl/src/screen.cpp 2015-01-13 14:32:13 +0000
@@ -68,6 +68,16 @@
6868
69using namespace compiz::opengl;69using namespace compiz::opengl;
7070
71/**
72 * The number of X11 sync objects to create.
73 */
74static const size_t NUM_X11_SYNCS = 16;
75
76/**
77 * The maximum time to wait for a sync object, in nanoseconds.
78 */
79static const GLuint64 MAX_SYNC_WAIT_TIME = 1000000000ull; // One second
80
71namespace GL {81namespace GL {
72 #ifdef USE_GLES82 #ifdef USE_GLES
73 EGLCreateImageKHRProc createImage;83 EGLCreateImageKHRProc createImage;
@@ -170,6 +180,14 @@
170 GLBindRenderbufferProc bindRenderbuffer = NULL;180 GLBindRenderbufferProc bindRenderbuffer = NULL;
171 GLRenderbufferStorageProc renderbufferStorage = NULL;181 GLRenderbufferStorageProc renderbufferStorage = NULL;
172182
183 GLFenceSyncProc fenceSync = NULL;
184 GLDeleteSyncProc deleteSync = NULL;
185 GLClientWaitSyncProc clientWaitSync = NULL;
186 GLWaitSyncProc waitSync = NULL;
187 GLGetSyncivProc getSynciv = NULL;
188
189 GLImportSyncProc importSync = NULL;
190
173 bool textureFromPixmap = true;191 bool textureFromPixmap = true;
174 bool textureRectangle = false;192 bool textureRectangle = false;
175 bool textureNonPowerOfTwo = false;193 bool textureNonPowerOfTwo = false;
@@ -188,6 +206,9 @@
188 GLint maxTextureUnits = 1;206 GLint maxTextureUnits = 1;
189 bool bufferAge = false;207 bool bufferAge = false;
190208
209 bool sync = false;
210 bool xToGLSync = false;
211
191 bool canDoSaturated = false;212 bool canDoSaturated = false;
192 bool canDoSlightlySaturated = false;213 bool canDoSlightlySaturated = false;
193214
@@ -1054,6 +1075,36 @@
1054 if (strstr (glExtensions, "GL_ARB_texture_compression"))1075 if (strstr (glExtensions, "GL_ARB_texture_compression"))
1055 GL::textureCompression = true;1076 GL::textureCompression = true;
10561077
1078 if (strstr (glExtensions, "GL_ARB_sync"))
1079 {
1080 GL::fenceSync = (GL::GLFenceSyncProc)
1081 getProcAddress ("glFenceSync");
1082 GL::deleteSync = (GL::GLDeleteSyncProc)
1083 getProcAddress ("glDeleteSync");
1084 GL::clientWaitSync = (GL::GLClientWaitSyncProc)
1085 getProcAddress ("glClientWaitSync");
1086 GL::waitSync = (GL::GLWaitSyncProc)
1087 getProcAddress ("glWaitSync");
1088 GL::getSynciv = (GL::GLGetSyncivProc)
1089 getProcAddress ("glGetSynciv");
1090
1091 if (GL::fenceSync &&
1092 GL::deleteSync &&
1093 GL::clientWaitSync &&
1094 GL::waitSync &&
1095 GL::getSynciv)
1096 GL::sync = true;
1097 }
1098
1099 if (strstr (glExtensions, "GL_EXT_x11_sync_object"))
1100 {
1101 GL::importSync = (GL::GLImportSyncProc)
1102 getProcAddress ("glImportSyncEXT");
1103
1104 if (GL::importSync)
1105 GL::xToGLSync = true;
1106 }
1107
1057 glClearColor (0.0, 0.0, 0.0, 1.0);1108 glClearColor (0.0, 0.0, 0.0, 1.0);
1058 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);1109 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1059 glEnable (GL_CULL_FACE);1110 glEnable (GL_CULL_FACE);
@@ -1257,6 +1308,8 @@
1257 getProcAddress ("glXSwapIntervalSGI");1308 getProcAddress ("glXSwapIntervalSGI");
1258 }1309 }
12591310
1311 priv->initXToGLSyncs ();
1312
1260 fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements);1313 fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements);
12611314
1262 GL::stencilBuffer = false;1315 GL::stencilBuffer = false;
@@ -1411,6 +1464,9 @@
14111464
1412GLScreen::~GLScreen ()1465GLScreen::~GLScreen ()
1413{1466{
1467 // Must occur before context is destroyed.
1468 priv->destroyXToGLSyncs ();
1469
1414 if (priv->hasCompositing)1470 if (priv->hasCompositing)
1415 CompositeScreen::get (screen)->unregisterPaintHandler ();1471 CompositeScreen::get (screen)->unregisterPaintHandler ();
14161472
@@ -1471,7 +1527,10 @@
1471 glVersion (NULL),1527 glVersion (NULL),
1472 postprocessingRequired (false),1528 postprocessingRequired (false),
1473 prevRegex (),1529 prevRegex (),
1474 prevBlacklisted (false)1530 prevBlacklisted (false),
1531 currentSyncNum (0),
1532 currentSync (0),
1533 warmupSyncs (0)
1475{1534{
1476 ScreenInterface::setHandler (screen);1535 ScreenInterface::setHandler (screen);
1477 CompositeScreenInterface::setHandler (cScreen);1536 CompositeScreenInterface::setHandler (cScreen);
@@ -1563,6 +1622,16 @@
1563 * be recopying the root window pixmap all the time1622 * be recopying the root window pixmap all the time
1564 * which is no good, so don't do that */1623 * which is no good, so don't do that */
1565 }1624 }
1625 else if (event->type == screen->syncEvent () + XSyncAlarmNotify)
1626 {
1627 XSyncAlarmNotifyEvent *ae =
1628 reinterpret_cast<XSyncAlarmNotifyEvent*>(event);
1629 std::map<XSyncAlarm, XToGLSync*>::iterator it =
1630 alarmToSync.find (ae->alarm);
1631
1632 if (it != alarmToSync.end ())
1633 it->second->handleEvent (ae);
1634 }
1566 break;1635 break;
1567 }1636 }
1568}1637}
@@ -2026,6 +2095,101 @@
2026{2095{
2027}2096}
20282097
2098bool
2099PrivateGLScreen::syncObjectsInitialized () const
2100{
2101 return !xToGLSyncs.empty ();
2102}
2103
2104bool
2105PrivateGLScreen::syncObjectsEnabled ()
2106{
2107 return GL::sync && GL::xToGLSync && optionGetEnableX11Sync ();
2108}
2109
2110void
2111PrivateGLScreen::initXToGLSyncs ()
2112{
2113 assert (!syncObjectsInitialized ());
2114 assert (xToGLSyncs.empty ());
2115 assert (alarmToSync.empty ());
2116
2117 if (syncObjectsEnabled () && !syncObjectsInitialized ())
2118 {
2119 xToGLSyncs.resize (NUM_X11_SYNCS, NULL);
2120
2121 foreach (XToGLSync*& sync, xToGLSyncs)
2122 {
2123 sync = new XToGLSync ();
2124 alarmToSync[sync->alarm ()] = sync;
2125 }
2126
2127 currentSyncNum = 0;
2128 currentSync = xToGLSyncs[0];
2129 warmupSyncs = 0;
2130 }
2131}
2132
2133void
2134PrivateGLScreen::destroyXToGLSyncs ()
2135{
2136 if (syncObjectsInitialized ())
2137 {
2138 foreach (XToGLSync* sync, xToGLSyncs)
2139 delete sync;
2140 xToGLSyncs.resize (0);
2141 }
2142 alarmToSync.clear ();
2143 currentSyncNum = 0;
2144 currentSync = NULL;
2145 warmupSyncs = 0;
2146}
2147
2148void
2149PrivateGLScreen::updateXToGLSyncs ()
2150{
2151 const std::vector<XToGLSync*>::size_type numSyncs = xToGLSyncs.size ();
2152
2153 if (numSyncs)
2154 {
2155 if (warmupSyncs >= numSyncs / 2)
2156 {
2157 const std::vector<XToGLSync*>::size_type resetSyncIdx =
2158 (currentSyncNum + (numSyncs / 2)) % numSyncs;
2159
2160 XToGLSync* syncToReset = xToGLSyncs[resetSyncIdx];
2161
2162 GLenum status = syncToReset->checkUpdateFinished (0);
2163 if (status == GL_TIMEOUT_EXPIRED)
2164 {
2165 status = syncToReset->checkUpdateFinished (MAX_SYNC_WAIT_TIME);
2166 }
2167
2168 if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
2169 {
2170 // This should never happen. If there was an error somewhere,
2171 // then we don't want to risk a hang here, so just destroy the
2172 // sync objects. We'll recreate them again in the next call to
2173 // prepareDrawing.
2174 compLogMessage ("opengl", CompLogLevelError, "Timed out waiting for sync object.");
2175 destroyXToGLSyncs ();
2176 return;
2177 }
2178
2179 syncToReset->reset ();
2180 }
2181 else
2182 {
2183 warmupSyncs++;
2184 }
2185
2186 currentSyncNum++;
2187 currentSyncNum %= numSyncs;
2188
2189 currentSync = xToGLSyncs[currentSyncNum];
2190 }
2191}
2192
2029#ifndef USE_GLES2193#ifndef USE_GLES
20302194
2031void2195void
@@ -2199,6 +2363,9 @@
2199 glClear (GL_COLOR_BUFFER_BIT);2363 glClear (GL_COLOR_BUFFER_BIT);
2200 }2364 }
22012365
2366 if (currentSync)
2367 currentSync->insertWait ();
2368
2202 // Disable everything that we don't usually need and could slow us down2369 // Disable everything that we don't usually need and could slow us down
2203 glDisable (GL_BLEND);2370 glDisable (GL_BLEND);
2204 glDisable (GL_STENCIL_TEST);2371 glDisable (GL_STENCIL_TEST);
@@ -2352,6 +2519,8 @@
2352 doubleBuffer.render (paintRegion, fullscreen);2519 doubleBuffer.render (paintRegion, fullscreen);
23532520
2354 lastMask = mask;2521 lastMask = mask;
2522
2523 updateXToGLSyncs ();
2355}2524}
23562525
2357unsigned int2526unsigned int
@@ -2448,6 +2617,55 @@
2448 updateFrameProvider ();2617 updateFrameProvider ();
2449 CompositeScreen::get (screen)->damageScreen ();2618 CompositeScreen::get (screen)->damageScreen ();
2450 }2619 }
2620
2621 // Check if the option to use sync objects has been enabled or disabled.
2622 if (syncObjectsEnabled () && !syncObjectsInitialized ())
2623 {
2624 initXToGLSyncs ();
2625 }
2626 else if (!syncObjectsEnabled () && syncObjectsInitialized ())
2627 {
2628 destroyXToGLSyncs ();
2629 }
2630
2631 if (currentSync)
2632 {
2633 if (!currentSync->isReady ())
2634 {
2635 for (std::vector<XToGLSync*>::size_type i = xToGLSyncs.size () / 2; i > 0; i--)
2636 {
2637 // try to check next sync
2638 updateXToGLSyncs ();
2639
2640 // method updateXToGLSync may disable syncs
2641 if (!currentSync)
2642 break;
2643
2644 if (currentSync->isReady ())
2645 break;
2646 }
2647 }
2648 }
2649
2650 if (currentSync)
2651 {
2652 if (!currentSync->isReady ())
2653 {
2654 // If this happens, then we must have missed an event or update
2655 // somewhere. Destroy and recreate the sync objects to put us back
2656 // into a good state.
2657 destroyXToGLSyncs ();
2658 initXToGLSyncs ();
2659 }
2660 }
2661
2662 if (currentSync)
2663 {
2664 // Tell the server to trigger the fence object after all rendering has
2665 // completed.
2666 assert (currentSync->isReady ());
2667 currentSync->trigger ();
2668 }
2451}2669}
24522670
2453bool2671bool
24542672
=== added file 'plugins/opengl/src/xtoglsync.cpp'
--- plugins/opengl/src/xtoglsync.cpp 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/xtoglsync.cpp 2015-01-13 14:32:13 +0000
@@ -0,0 +1,194 @@
1/*
2 * Copyright © 2011 NVIDIA Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * NVIDIA Corporation not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * NVIDIA Corporation makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authors: James Jones <jajones@nvidia.com>
24 */
25
26#include "opengl/xtoglsync.h"
27
28bool XToGLSync::syncValuesInitialized = false;
29XSyncValue XToGLSync::zero;
30XSyncValue XToGLSync::one;
31
32XToGLSync::XToGLSync () :
33 f (None),
34 fGL (NULL),
35 c (None),
36 a (None),
37 state (XToGLSync::XTOGLS_READY)
38{
39 Display *dpy = screen->dpy ();
40
41 f = XSyncCreateFence (dpy, DefaultRootWindow (dpy), False);
42 fGL = GL::importSync (GL_SYNC_X11_FENCE_EXT, f, 0);
43
44 if (!syncValuesInitialized)
45 {
46 XSyncIntToValue (&zero, 0);
47 XSyncIntToValue (&one, 1);
48 syncValuesInitialized = true;
49 }
50
51 XSyncIntToValue (&nextCounterValue, 1);
52 c = XSyncCreateCounter (dpy, zero);
53
54 XSyncAlarmAttributes alarmAttribs;
55 alarmAttribs.trigger.counter = c;
56 alarmAttribs.trigger.value_type = XSyncAbsolute;
57 alarmAttribs.trigger.wait_value = one;
58 alarmAttribs.trigger.test_type = XSyncPositiveTransition;
59 alarmAttribs.events = True;
60 a = XSyncCreateAlarm (dpy,
61 XSyncCACounter |
62 XSyncCAValueType |
63 XSyncCAValue |
64 XSyncCATestType |
65 XSyncCAEvents,
66 &alarmAttribs);
67
68}
69
70XToGLSync::~XToGLSync ()
71{
72 Display *dpy = screen->dpy ();
73
74 switch (state) {
75 case XTOGLS_WAITING:
76 break;
77
78 case XTOGLS_RESET_PENDING:
79 {
80 XEvent ev;
81
82 XIfEvent (dpy, &ev, &XToGLSync::alarmEventPredicate,
83 reinterpret_cast<XPointer>(this));
84 handleEvent(reinterpret_cast<XSyncAlarmNotifyEvent*>(&ev));
85 }
86 // Fall through.
87 case XTOGLS_READY:
88 XSyncTriggerFence (dpy, f);
89 XFlush (dpy);
90 break;
91
92 case XTOGLS_TRIGGER_SENT:
93 case XTOGLS_DONE:
94 // Nothing to do.
95 break;
96 }
97
98 GL::deleteSync (fGL);
99 XSyncDestroyFence (dpy, f);
100 XSyncDestroyCounter (dpy, c);
101 XSyncDestroyAlarm (dpy, a);
102}
103
104Bool XToGLSync::alarmEventPredicate (Display *dpy, XEvent *ev, XPointer arg)
105{
106 if (ev->type == screen->syncEvent () + XSyncAlarmNotify)
107 {
108 XToGLSync *sync = reinterpret_cast<XToGLSync*>(arg);
109 XSyncAlarmNotifyEvent *ae =
110 reinterpret_cast<XSyncAlarmNotifyEvent*>(ev);
111
112 if (ae->alarm == sync->a)
113 return True;
114 }
115
116 return False;
117}
118
119void XToGLSync::trigger (void)
120{
121 Display *dpy = screen->dpy ();
122 assert (state == XTOGLS_READY);
123
124 XSyncTriggerFence (dpy, f);
125 XFlush (dpy);
126
127 state = XTOGLS_TRIGGER_SENT;
128}
129
130void XToGLSync::insertWait (void)
131{
132 if (state != XTOGLS_TRIGGER_SENT)
133 return;
134
135 GL::waitSync (fGL, 0, GL_TIMEOUT_IGNORED);
136
137 state = XTOGLS_WAITING;
138}
139
140GLenum XToGLSync::checkUpdateFinished (GLuint64 timeout)
141{
142 GLenum status;
143
144 switch (state) {
145 case XTOGLS_DONE:
146 return GL_ALREADY_SIGNALED;
147
148 case XTOGLS_WAITING:
149 status = GL::clientWaitSync (fGL, 0, timeout);
150 if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
151 {
152 state = XTOGLS_DONE;
153 }
154 return status;
155
156 default:
157 return GL_WAIT_FAILED;
158 }
159}
160
161void XToGLSync::reset (void)
162{
163 Display *dpy = screen->dpy ();
164 if (state != XTOGLS_DONE)
165 {
166 return;
167 }
168
169 XSyncResetFence (dpy, f);
170
171 XSyncAlarmAttributes values;
172 values.trigger.wait_value = nextCounterValue;
173 XSyncChangeAlarm (dpy, a, XSyncCAValue, &values);
174 XSyncSetCounter (dpy, c, nextCounterValue);
175
176 int overflow;
177 XSyncValueAdd (&nextCounterValue, nextCounterValue, one, &overflow);
178
179 state = XTOGLS_RESET_PENDING;
180}
181
182void XToGLSync::handleEvent (XSyncAlarmNotifyEvent* ae)
183{
184 if (ae->alarm == a)
185 {
186 if (state != XTOGLS_RESET_PENDING)
187 {
188 return;
189 }
190
191 state = XTOGLS_READY;
192 }
193}
194

Subscribers

People subscribed via source and target branches