1 |
commit: 2c00b2f8422f0ea593daa6792c3ec6caf83210ef |
2 |
Author: Pacho Ramos <pacho <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Oct 3 09:02:56 2015 +0000 |
4 |
Commit: Pacho Ramos <pacho <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Oct 3 09:02:56 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2c00b2f8 |
7 |
|
8 |
x11-wm/mutter: Apply some upstream fixes from 3.16 branch and also stop crashing when keymap cannot be get on a first try (from master) |
9 |
|
10 |
Package-Manager: portage-2.2.22 |
11 |
|
12 |
.../mutter-3.16.3-GL_EXT_x11_sync_object.patch | 840 +++++++++++++++++++++ |
13 |
.../mutter/files/mutter-3.16.3-crash-border.patch | 32 + |
14 |
.../files/mutter-3.16.3-fallback-keymap.patch | 28 + |
15 |
x11-wm/mutter/files/mutter-3.16.3-fix-race.patch | 114 +++ |
16 |
x11-wm/mutter/files/mutter-3.16.3-fix-return.patch | 32 + |
17 |
x11-wm/mutter/files/mutter-3.16.3-flickering.patch | 114 +++ |
18 |
x11-wm/mutter/mutter-3.16.3-r1.ebuild | 114 +++ |
19 |
7 files changed, 1274 insertions(+) |
20 |
|
21 |
diff --git a/x11-wm/mutter/files/mutter-3.16.3-GL_EXT_x11_sync_object.patch b/x11-wm/mutter/files/mutter-3.16.3-GL_EXT_x11_sync_object.patch |
22 |
new file mode 100644 |
23 |
index 0000000..401c175 |
24 |
--- /dev/null |
25 |
+++ b/x11-wm/mutter/files/mutter-3.16.3-GL_EXT_x11_sync_object.patch |
26 |
@@ -0,0 +1,840 @@ |
27 |
+From 9cc80497a262edafc58062fd860ef7a9dcab688c Mon Sep 17 00:00:00 2001 |
28 |
+From: Rui Matos <tiagomatos@×××××.com> |
29 |
+Date: Fri, 18 Apr 2014 20:21:20 +0200 |
30 |
+Subject: compositor: Add support for GL_EXT_x11_sync_object |
31 |
+ |
32 |
+If GL advertises this extension we'll use it to synchronize X with GL |
33 |
+rendering instead of relying on the XSync() behavior with open source |
34 |
+drivers. |
35 |
+ |
36 |
+Some driver bugs were uncovered while working on this so if we have |
37 |
+had to reboot the ring a few times, something is probably wrong and |
38 |
+we're likely to just make things worse by continuing to try. Let's |
39 |
+err on the side of caution, disable ourselves and fallback to the |
40 |
+XSync() path in the compositor. |
41 |
+ |
42 |
+https://bugzilla.gnome.org/show_bug.cgi?id=728464 |
43 |
+ |
44 |
+diff --git a/configure.ac b/configure.ac |
45 |
+index 01d75cb..6eea6b2 100644 |
46 |
+--- a/configure.ac |
47 |
++++ b/configure.ac |
48 |
+@@ -332,6 +332,11 @@ fi |
49 |
+ |
50 |
+ GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) |
51 |
+ |
52 |
++AC_CHECK_DECL([GL_EXT_x11_sync_object], |
53 |
++ [], |
54 |
++ [AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])], |
55 |
++ [#include <GL/glx.h>]) |
56 |
++ |
57 |
+ #### Warnings (last since -Werror can disturb other tests) |
58 |
+ |
59 |
+ # Stay command-line compatible with the gnome-common configure option. Here |
60 |
+diff --git a/src/Makefile.am b/src/Makefile.am |
61 |
+index baadb41..a4e07a9 100644 |
62 |
+--- a/src/Makefile.am |
63 |
++++ b/src/Makefile.am |
64 |
+@@ -139,6 +139,8 @@ libmutter_la_SOURCES = \ |
65 |
+ compositor/meta-surface-actor.h \ |
66 |
+ compositor/meta-surface-actor-x11.c \ |
67 |
+ compositor/meta-surface-actor-x11.h \ |
68 |
++ compositor/meta-sync-ring.c \ |
69 |
++ compositor/meta-sync-ring.h \ |
70 |
+ compositor/meta-texture-rectangle.c \ |
71 |
+ compositor/meta-texture-rectangle.h \ |
72 |
+ compositor/meta-texture-tower.c \ |
73 |
+diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c |
74 |
+index 3ff8431..ac38ffc 100644 |
75 |
+--- a/src/backends/x11/meta-backend-x11.c |
76 |
++++ b/src/backends/x11/meta-backend-x11.c |
77 |
+@@ -45,6 +45,7 @@ |
78 |
+ #include <meta/util.h> |
79 |
+ #include "display-private.h" |
80 |
+ #include "compositor/compositor-private.h" |
81 |
++#include "compositor/meta-sync-ring.h" |
82 |
+ |
83 |
+ struct _MetaBackendX11Private |
84 |
+ { |
85 |
+@@ -255,6 +256,8 @@ handle_host_xevent (MetaBackend *backend, |
86 |
+ MetaCompositor *compositor = display->compositor; |
87 |
+ if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) |
88 |
+ bypass_clutter = TRUE; |
89 |
++ if (compositor->have_x11_sync_object) |
90 |
++ meta_sync_ring_handle_event (event); |
91 |
+ } |
92 |
+ } |
93 |
+ |
94 |
+diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h |
95 |
+index 80fb4e2..9e3e73d 100644 |
96 |
+--- a/src/compositor/compositor-private.h |
97 |
++++ b/src/compositor/compositor-private.h |
98 |
+@@ -15,7 +15,8 @@ struct _MetaCompositor |
99 |
+ { |
100 |
+ MetaDisplay *display; |
101 |
+ |
102 |
+- guint repaint_func_id; |
103 |
++ guint pre_paint_func_id; |
104 |
++ guint post_paint_func_id; |
105 |
+ |
106 |
+ gint64 server_time_query_time; |
107 |
+ gint64 server_time_offset; |
108 |
+@@ -40,6 +41,7 @@ struct _MetaCompositor |
109 |
+ MetaPluginManager *plugin_mgr; |
110 |
+ |
111 |
+ gboolean frame_has_updated_xsurfaces; |
112 |
++ gboolean have_x11_sync_object; |
113 |
+ }; |
114 |
+ |
115 |
+ /* Wait 2ms after vblank before starting to draw next frame */ |
116 |
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c |
117 |
+index 250d489..554faa1 100644 |
118 |
+--- a/src/compositor/compositor.c |
119 |
++++ b/src/compositor/compositor.c |
120 |
+@@ -79,6 +79,7 @@ |
121 |
+ #include "frame.h" |
122 |
+ #include <X11/extensions/shape.h> |
123 |
+ #include <X11/extensions/Xcomposite.h> |
124 |
++#include "meta-sync-ring.h" |
125 |
+ |
126 |
+ #include "backends/x11/meta-backend-x11.h" |
127 |
+ |
128 |
+@@ -125,7 +126,11 @@ meta_switch_workspace_completed (MetaCompositor *compositor) |
129 |
+ void |
130 |
+ meta_compositor_destroy (MetaCompositor *compositor) |
131 |
+ { |
132 |
+- clutter_threads_remove_repaint_func (compositor->repaint_func_id); |
133 |
++ clutter_threads_remove_repaint_func (compositor->pre_paint_func_id); |
134 |
++ clutter_threads_remove_repaint_func (compositor->post_paint_func_id); |
135 |
++ |
136 |
++ if (compositor->have_x11_sync_object) |
137 |
++ meta_sync_ring_destroy (); |
138 |
+ } |
139 |
+ |
140 |
+ static void |
141 |
+@@ -468,13 +473,11 @@ meta_compositor_manage (MetaCompositor *compositor) |
142 |
+ MetaDisplay *display = compositor->display; |
143 |
+ Display *xdisplay = display->xdisplay; |
144 |
+ MetaScreen *screen = display->screen; |
145 |
++ MetaBackend *backend = meta_get_backend (); |
146 |
+ |
147 |
+ meta_screen_set_cm_selection (display->screen); |
148 |
+ |
149 |
+- { |
150 |
+- MetaBackend *backend = meta_get_backend (); |
151 |
+- compositor->stage = meta_backend_get_stage (backend); |
152 |
+- } |
153 |
++ compositor->stage = meta_backend_get_stage (backend); |
154 |
+ |
155 |
+ /* We use connect_after() here to accomodate code in GNOME Shell that, |
156 |
+ * when benchmarking drawing performance, connects to ::after-paint |
157 |
+@@ -510,7 +513,7 @@ meta_compositor_manage (MetaCompositor *compositor) |
158 |
+ |
159 |
+ compositor->output = screen->composite_overlay_window; |
160 |
+ |
161 |
+- xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ())); |
162 |
++ xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); |
163 |
+ |
164 |
+ XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); |
165 |
+ |
166 |
+@@ -530,6 +533,9 @@ meta_compositor_manage (MetaCompositor *compositor) |
167 |
+ * contents until we show the stage. |
168 |
+ */ |
169 |
+ XMapWindow (xdisplay, compositor->output); |
170 |
++ |
171 |
++ compositor->have_x11_sync_object = |
172 |
++ meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend))); |
173 |
+ } |
174 |
+ |
175 |
+ redirect_windows (display->screen); |
176 |
+@@ -1044,11 +1050,12 @@ frame_callback (CoglOnscreen *onscreen, |
177 |
+ } |
178 |
+ } |
179 |
+ |
180 |
+-static void |
181 |
+-pre_paint_windows (MetaCompositor *compositor) |
182 |
++static gboolean |
183 |
++meta_pre_paint_func (gpointer data) |
184 |
+ { |
185 |
+ GList *l; |
186 |
+ MetaWindowActor *top_window; |
187 |
++ MetaCompositor *compositor = data; |
188 |
+ |
189 |
+ if (compositor->onscreen == NULL) |
190 |
+ { |
191 |
+@@ -1060,7 +1067,7 @@ pre_paint_windows (MetaCompositor *compositor) |
192 |
+ } |
193 |
+ |
194 |
+ if (compositor->windows == NULL) |
195 |
+- return; |
196 |
++ return TRUE; |
197 |
+ |
198 |
+ top_window = g_list_last (compositor->windows)->data; |
199 |
+ |
200 |
+@@ -1077,10 +1084,12 @@ pre_paint_windows (MetaCompositor *compositor) |
201 |
+ { |
202 |
+ /* We need to make sure that any X drawing that happens before |
203 |
+ * the XDamageSubtract() for each window above is visible to |
204 |
+- * subsequent GL rendering; the only standardized way to do this |
205 |
+- * is EXT_x11_sync_object, which isn't yet widely available. For |
206 |
+- * now, we count on details of Xorg and the open source drivers, |
207 |
+- * and hope for the best otherwise. |
208 |
++ * subsequent GL rendering; the standardized way to do this is |
209 |
++ * GL_EXT_X11_sync_object. Since this isn't implemented yet in |
210 |
++ * mesa, we also have a path that relies on the implementation |
211 |
++ * of the open source drivers. |
212 |
++ * |
213 |
++ * Anything else, we just hope for the best. |
214 |
+ * |
215 |
+ * Xorg and open source driver specifics: |
216 |
+ * |
217 |
+@@ -1095,17 +1104,28 @@ pre_paint_windows (MetaCompositor *compositor) |
218 |
+ * round trip request at this point is sufficient to flush the |
219 |
+ * GLX buffers. |
220 |
+ */ |
221 |
+- XSync (compositor->display->xdisplay, False); |
222 |
+- |
223 |
+- compositor->frame_has_updated_xsurfaces = FALSE; |
224 |
++ if (compositor->have_x11_sync_object) |
225 |
++ compositor->have_x11_sync_object = meta_sync_ring_insert_wait (); |
226 |
++ else |
227 |
++ XSync (compositor->display->xdisplay, False); |
228 |
+ } |
229 |
++ |
230 |
++ return TRUE; |
231 |
+ } |
232 |
+ |
233 |
+ static gboolean |
234 |
+-meta_repaint_func (gpointer data) |
235 |
++meta_post_paint_func (gpointer data) |
236 |
+ { |
237 |
+ MetaCompositor *compositor = data; |
238 |
+- pre_paint_windows (compositor); |
239 |
++ |
240 |
++ if (compositor->frame_has_updated_xsurfaces) |
241 |
++ { |
242 |
++ if (compositor->have_x11_sync_object) |
243 |
++ compositor->have_x11_sync_object = meta_sync_ring_after_frame (); |
244 |
++ |
245 |
++ compositor->frame_has_updated_xsurfaces = FALSE; |
246 |
++ } |
247 |
++ |
248 |
+ return TRUE; |
249 |
+ } |
250 |
+ |
251 |
+@@ -1140,10 +1160,16 @@ meta_compositor_new (MetaDisplay *display) |
252 |
+ G_CALLBACK (on_shadow_factory_changed), |
253 |
+ compositor); |
254 |
+ |
255 |
+- compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, |
256 |
+- compositor, |
257 |
+- NULL); |
258 |
+- |
259 |
++ compositor->pre_paint_func_id = |
260 |
++ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT, |
261 |
++ meta_pre_paint_func, |
262 |
++ compositor, |
263 |
++ NULL); |
264 |
++ compositor->post_paint_func_id = |
265 |
++ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, |
266 |
++ meta_post_paint_func, |
267 |
++ compositor, |
268 |
++ NULL); |
269 |
+ return compositor; |
270 |
+ } |
271 |
+ |
272 |
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c |
273 |
+new file mode 100644 |
274 |
+index 0000000..4ee61f8 |
275 |
+--- /dev/null |
276 |
++++ b/src/compositor/meta-sync-ring.c |
277 |
+@@ -0,0 +1,566 @@ |
278 |
++/* |
279 |
++ * This is based on an original C++ implementation for compiz that |
280 |
++ * carries the following copyright notice: |
281 |
++ * |
282 |
++ * |
283 |
++ * Copyright © 2011 NVIDIA Corporation |
284 |
++ * |
285 |
++ * Permission to use, copy, modify, distribute, and sell this software |
286 |
++ * and its documentation for any purpose is hereby granted without |
287 |
++ * fee, provided that the above copyright notice appear in all copies |
288 |
++ * and that both that copyright notice and this permission notice |
289 |
++ * appear in supporting documentation, and that the name of NVIDIA |
290 |
++ * Corporation not be used in advertising or publicity pertaining to |
291 |
++ * distribution of the software without specific, written prior |
292 |
++ * permission. NVIDIA Corporation makes no representations about the |
293 |
++ * suitability of this software for any purpose. It is provided "as |
294 |
++ * is" without express or implied warranty. |
295 |
++ * |
296 |
++ * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS |
297 |
++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND |
298 |
++ * FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY |
299 |
++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
300 |
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN |
301 |
++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING |
302 |
++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
303 |
++ * SOFTWARE. |
304 |
++ * |
305 |
++ * Authors: James Jones <jajones@××××××.com> |
306 |
++ */ |
307 |
++ |
308 |
++#include <string.h> |
309 |
++ |
310 |
++#include <GL/gl.h> |
311 |
++#include <GL/glx.h> |
312 |
++#include <X11/extensions/sync.h> |
313 |
++ |
314 |
++#include <cogl/cogl.h> |
315 |
++#include <clutter/clutter.h> |
316 |
++ |
317 |
++#include <meta/util.h> |
318 |
++ |
319 |
++#include "meta-sync-ring.h" |
320 |
++ |
321 |
++/* Theory of operation: |
322 |
++ * |
323 |
++ * We use a ring of NUM_SYNCS fence objects. On each frame we advance |
324 |
++ * to the next fence in the ring. For each fence we do: |
325 |
++ * |
326 |
++ * 1. fence is XSyncTriggerFence()'d and glWaitSync()'d |
327 |
++ * 2. NUM_SYNCS / 2 frames later, fence should be triggered |
328 |
++ * 3. fence is XSyncResetFence()'d |
329 |
++ * 4. NUM_SYNCS / 2 frames later, fence should be reset |
330 |
++ * 5. go back to 1 and re-use fence |
331 |
++ * |
332 |
++ * glClientWaitSync() and XAlarms are used in steps 2 and 4, |
333 |
++ * respectively, to double-check the expectections. |
334 |
++ */ |
335 |
++ |
336 |
++#define NUM_SYNCS 10 |
337 |
++#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */ |
338 |
++#define MAX_REBOOT_ATTEMPTS 2 |
339 |
++ |
340 |
++typedef enum |
341 |
++{ |
342 |
++ META_SYNC_STATE_READY, |
343 |
++ META_SYNC_STATE_WAITING, |
344 |
++ META_SYNC_STATE_DONE, |
345 |
++ META_SYNC_STATE_RESET_PENDING, |
346 |
++} MetaSyncState; |
347 |
++ |
348 |
++typedef struct |
349 |
++{ |
350 |
++ Display *xdisplay; |
351 |
++ |
352 |
++ XSyncFence xfence; |
353 |
++ GLsync glsync; |
354 |
++ |
355 |
++ XSyncCounter xcounter; |
356 |
++ XSyncAlarm xalarm; |
357 |
++ XSyncValue next_counter_value; |
358 |
++ |
359 |
++ MetaSyncState state; |
360 |
++} MetaSync; |
361 |
++ |
362 |
++typedef struct |
363 |
++{ |
364 |
++ Display *xdisplay; |
365 |
++ int xsync_event_base; |
366 |
++ int xsync_error_base; |
367 |
++ |
368 |
++ GHashTable *alarm_to_sync; |
369 |
++ |
370 |
++ MetaSync *syncs_array[NUM_SYNCS]; |
371 |
++ guint current_sync_idx; |
372 |
++ MetaSync *current_sync; |
373 |
++ guint warmup_syncs; |
374 |
++ |
375 |
++ guint reboots; |
376 |
++} MetaSyncRing; |
377 |
++ |
378 |
++static MetaSyncRing meta_sync_ring = { 0 }; |
379 |
++ |
380 |
++static XSyncValue SYNC_VALUE_ZERO; |
381 |
++static XSyncValue SYNC_VALUE_ONE; |
382 |
++ |
383 |
++static const char* (*meta_gl_get_string) (GLenum name); |
384 |
++static void (*meta_gl_get_integerv) (GLenum pname, |
385 |
++ GLint *params); |
386 |
++static const char* (*meta_gl_get_stringi) (GLenum name, |
387 |
++ GLuint index); |
388 |
++static void (*meta_gl_delete_sync) (GLsync sync); |
389 |
++static GLenum (*meta_gl_client_wait_sync) (GLsync sync, |
390 |
++ GLbitfield flags, |
391 |
++ GLuint64 timeout); |
392 |
++static void (*meta_gl_wait_sync) (GLsync sync, |
393 |
++ GLbitfield flags, |
394 |
++ GLuint64 timeout); |
395 |
++static GLsync (*meta_gl_import_sync) (GLenum external_sync_type, |
396 |
++ GLintptr external_sync, |
397 |
++ GLbitfield flags); |
398 |
++ |
399 |
++static MetaSyncRing * |
400 |
++meta_sync_ring_get (void) |
401 |
++{ |
402 |
++ if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS) |
403 |
++ return NULL; |
404 |
++ |
405 |
++ return &meta_sync_ring; |
406 |
++} |
407 |
++ |
408 |
++static gboolean |
409 |
++load_gl_symbol (const char *name, |
410 |
++ void **func) |
411 |
++{ |
412 |
++ *func = cogl_get_proc_address (name); |
413 |
++ if (!*func) |
414 |
++ { |
415 |
++ meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name); |
416 |
++ return FALSE; |
417 |
++ } |
418 |
++ return TRUE; |
419 |
++} |
420 |
++ |
421 |
++static gboolean |
422 |
++check_gl_extensions (void) |
423 |
++{ |
424 |
++ ClutterBackend *backend; |
425 |
++ CoglContext *cogl_context; |
426 |
++ CoglDisplay *cogl_display; |
427 |
++ CoglRenderer *cogl_renderer; |
428 |
++ |
429 |
++ backend = clutter_get_default_backend (); |
430 |
++ cogl_context = clutter_backend_get_cogl_context (backend); |
431 |
++ cogl_display = cogl_context_get_display (cogl_context); |
432 |
++ cogl_renderer = cogl_display_get_renderer (cogl_display); |
433 |
++ |
434 |
++ switch (cogl_renderer_get_driver (cogl_renderer)) |
435 |
++ { |
436 |
++ case COGL_DRIVER_GL3: |
437 |
++ { |
438 |
++ int num_extensions, i; |
439 |
++ gboolean arb_sync = FALSE; |
440 |
++ gboolean x11_sync_object = FALSE; |
441 |
++ |
442 |
++ meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions); |
443 |
++ |
444 |
++ for (i = 0; i < num_extensions; ++i) |
445 |
++ { |
446 |
++ const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i); |
447 |
++ |
448 |
++ if (g_strcmp0 ("GL_ARB_sync", ext) == 0) |
449 |
++ arb_sync = TRUE; |
450 |
++ else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0) |
451 |
++ x11_sync_object = TRUE; |
452 |
++ } |
453 |
++ |
454 |
++ return arb_sync && x11_sync_object; |
455 |
++ } |
456 |
++ case COGL_DRIVER_GL: |
457 |
++ { |
458 |
++ const char *extensions = meta_gl_get_string (GL_EXTENSIONS); |
459 |
++ return (extensions != NULL && |
460 |
++ strstr (extensions, "GL_ARB_sync") != NULL && |
461 |
++ strstr (extensions, "GL_EXT_x11_sync_object") != NULL); |
462 |
++ } |
463 |
++ default: |
464 |
++ break; |
465 |
++ } |
466 |
++ |
467 |
++ return FALSE; |
468 |
++} |
469 |
++ |
470 |
++static gboolean |
471 |
++load_required_symbols (void) |
472 |
++{ |
473 |
++ static gboolean success = FALSE; |
474 |
++ |
475 |
++ if (success) |
476 |
++ return TRUE; |
477 |
++ |
478 |
++ /* We don't link against libGL directly because cogl may want to |
479 |
++ * use something else. This assumes that cogl has been initialized |
480 |
++ * and dynamically loaded libGL at this point. |
481 |
++ */ |
482 |
++ |
483 |
++ if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string)) |
484 |
++ goto out; |
485 |
++ if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv)) |
486 |
++ goto out; |
487 |
++ if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi)) |
488 |
++ goto out; |
489 |
++ |
490 |
++ if (!check_gl_extensions ()) |
491 |
++ { |
492 |
++ meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n"); |
493 |
++ goto out; |
494 |
++ } |
495 |
++ |
496 |
++ if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync)) |
497 |
++ goto out; |
498 |
++ if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync)) |
499 |
++ goto out; |
500 |
++ if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync)) |
501 |
++ goto out; |
502 |
++ if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync)) |
503 |
++ goto out; |
504 |
++ |
505 |
++ success = TRUE; |
506 |
++ out: |
507 |
++ return success; |
508 |
++} |
509 |
++ |
510 |
++static void |
511 |
++meta_sync_insert (MetaSync *self) |
512 |
++{ |
513 |
++ g_return_if_fail (self->state == META_SYNC_STATE_READY); |
514 |
++ |
515 |
++ XSyncTriggerFence (self->xdisplay, self->xfence); |
516 |
++ XFlush (self->xdisplay); |
517 |
++ |
518 |
++ meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED); |
519 |
++ |
520 |
++ self->state = META_SYNC_STATE_WAITING; |
521 |
++} |
522 |
++ |
523 |
++static GLenum |
524 |
++meta_sync_check_update_finished (MetaSync *self, |
525 |
++ GLuint64 timeout) |
526 |
++{ |
527 |
++ GLenum status = GL_WAIT_FAILED; |
528 |
++ |
529 |
++ switch (self->state) |
530 |
++ { |
531 |
++ case META_SYNC_STATE_DONE: |
532 |
++ status = GL_ALREADY_SIGNALED; |
533 |
++ break; |
534 |
++ case META_SYNC_STATE_WAITING: |
535 |
++ status = meta_gl_client_wait_sync (self->glsync, 0, timeout); |
536 |
++ if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) |
537 |
++ self->state = META_SYNC_STATE_DONE; |
538 |
++ break; |
539 |
++ default: |
540 |
++ break; |
541 |
++ } |
542 |
++ |
543 |
++ g_warn_if_fail (status != GL_WAIT_FAILED); |
544 |
++ |
545 |
++ return status; |
546 |
++} |
547 |
++ |
548 |
++static void |
549 |
++meta_sync_reset (MetaSync *self) |
550 |
++{ |
551 |
++ XSyncAlarmAttributes attrs; |
552 |
++ int overflow; |
553 |
++ |
554 |
++ g_return_if_fail (self->state == META_SYNC_STATE_DONE); |
555 |
++ |
556 |
++ XSyncResetFence (self->xdisplay, self->xfence); |
557 |
++ |
558 |
++ attrs.trigger.wait_value = self->next_counter_value; |
559 |
++ |
560 |
++ XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs); |
561 |
++ XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value); |
562 |
++ |
563 |
++ XSyncValueAdd (&self->next_counter_value, |
564 |
++ self->next_counter_value, |
565 |
++ SYNC_VALUE_ONE, |
566 |
++ &overflow); |
567 |
++ |
568 |
++ self->state = META_SYNC_STATE_RESET_PENDING; |
569 |
++} |
570 |
++ |
571 |
++static void |
572 |
++meta_sync_handle_event (MetaSync *self, |
573 |
++ XSyncAlarmNotifyEvent *event) |
574 |
++{ |
575 |
++ g_return_if_fail (event->alarm == self->xalarm); |
576 |
++ g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING); |
577 |
++ |
578 |
++ self->state = META_SYNC_STATE_READY; |
579 |
++} |
580 |
++ |
581 |
++static MetaSync * |
582 |
++meta_sync_new (Display *xdisplay) |
583 |
++{ |
584 |
++ MetaSync *self; |
585 |
++ XSyncAlarmAttributes attrs; |
586 |
++ |
587 |
++ self = g_malloc0 (sizeof (MetaSync)); |
588 |
++ |
589 |
++ self->xdisplay = xdisplay; |
590 |
++ |
591 |
++ self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); |
592 |
++ self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); |
593 |
++ |
594 |
++ self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); |
595 |
++ |
596 |
++ attrs.trigger.counter = self->xcounter; |
597 |
++ attrs.trigger.value_type = XSyncAbsolute; |
598 |
++ attrs.trigger.wait_value = SYNC_VALUE_ONE; |
599 |
++ attrs.trigger.test_type = XSyncPositiveTransition; |
600 |
++ attrs.events = TRUE; |
601 |
++ self->xalarm = XSyncCreateAlarm (xdisplay, |
602 |
++ XSyncCACounter | |
603 |
++ XSyncCAValueType | |
604 |
++ XSyncCAValue | |
605 |
++ XSyncCATestType | |
606 |
++ XSyncCAEvents, |
607 |
++ &attrs); |
608 |
++ |
609 |
++ XSyncIntToValue (&self->next_counter_value, 1); |
610 |
++ |
611 |
++ self->state = META_SYNC_STATE_READY; |
612 |
++ |
613 |
++ return self; |
614 |
++} |
615 |
++ |
616 |
++static Bool |
617 |
++alarm_event_predicate (Display *dpy, |
618 |
++ XEvent *event, |
619 |
++ XPointer data) |
620 |
++{ |
621 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
622 |
++ |
623 |
++ if (!ring) |
624 |
++ return False; |
625 |
++ |
626 |
++ if (event->type == ring->xsync_event_base + XSyncAlarmNotify) |
627 |
++ { |
628 |
++ if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm) |
629 |
++ return True; |
630 |
++ } |
631 |
++ return False; |
632 |
++} |
633 |
++ |
634 |
++static void |
635 |
++meta_sync_free (MetaSync *self) |
636 |
++{ |
637 |
++ /* When our assumptions don't hold, something has gone wrong but we |
638 |
++ * don't know what, so we reboot the ring. While doing that, we |
639 |
++ * trigger fences before deleting them to try to get ourselves out |
640 |
++ * of a potentially stuck GPU state. |
641 |
++ */ |
642 |
++ switch (self->state) |
643 |
++ { |
644 |
++ case META_SYNC_STATE_WAITING: |
645 |
++ case META_SYNC_STATE_DONE: |
646 |
++ /* nothing to do */ |
647 |
++ break; |
648 |
++ case META_SYNC_STATE_RESET_PENDING: |
649 |
++ { |
650 |
++ XEvent event; |
651 |
++ XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self); |
652 |
++ meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event); |
653 |
++ } |
654 |
++ /* fall through */ |
655 |
++ case META_SYNC_STATE_READY: |
656 |
++ XSyncTriggerFence (self->xdisplay, self->xfence); |
657 |
++ XFlush (self->xdisplay); |
658 |
++ break; |
659 |
++ default: |
660 |
++ break; |
661 |
++ } |
662 |
++ |
663 |
++ meta_gl_delete_sync (self->glsync); |
664 |
++ XSyncDestroyFence (self->xdisplay, self->xfence); |
665 |
++ XSyncDestroyCounter (self->xdisplay, self->xcounter); |
666 |
++ XSyncDestroyAlarm (self->xdisplay, self->xalarm); |
667 |
++ |
668 |
++ g_free (self); |
669 |
++} |
670 |
++ |
671 |
++gboolean |
672 |
++meta_sync_ring_init (Display *xdisplay) |
673 |
++{ |
674 |
++ gint major, minor; |
675 |
++ guint i; |
676 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
677 |
++ |
678 |
++ if (!ring) |
679 |
++ return FALSE; |
680 |
++ |
681 |
++ g_return_val_if_fail (xdisplay != NULL, FALSE); |
682 |
++ g_return_val_if_fail (ring->xdisplay == NULL, FALSE); |
683 |
++ |
684 |
++ if (!load_required_symbols ()) |
685 |
++ return FALSE; |
686 |
++ |
687 |
++ if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, &ring->xsync_error_base) || |
688 |
++ !XSyncInitialize (xdisplay, &major, &minor)) |
689 |
++ return FALSE; |
690 |
++ |
691 |
++ XSyncIntToValue (&SYNC_VALUE_ZERO, 0); |
692 |
++ XSyncIntToValue (&SYNC_VALUE_ONE, 1); |
693 |
++ |
694 |
++ ring->xdisplay = xdisplay; |
695 |
++ |
696 |
++ ring->alarm_to_sync = g_hash_table_new (NULL, NULL); |
697 |
++ |
698 |
++ for (i = 0; i < NUM_SYNCS; ++i) |
699 |
++ { |
700 |
++ MetaSync *sync = meta_sync_new (ring->xdisplay); |
701 |
++ ring->syncs_array[i] = sync; |
702 |
++ g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync); |
703 |
++ } |
704 |
++ |
705 |
++ ring->current_sync_idx = 0; |
706 |
++ ring->current_sync = ring->syncs_array[0]; |
707 |
++ ring->warmup_syncs = 0; |
708 |
++ |
709 |
++ return TRUE; |
710 |
++} |
711 |
++ |
712 |
++void |
713 |
++meta_sync_ring_destroy (void) |
714 |
++{ |
715 |
++ guint i; |
716 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
717 |
++ |
718 |
++ if (!ring) |
719 |
++ return; |
720 |
++ |
721 |
++ g_return_if_fail (ring->xdisplay != NULL); |
722 |
++ |
723 |
++ ring->current_sync_idx = 0; |
724 |
++ ring->current_sync = NULL; |
725 |
++ ring->warmup_syncs = 0; |
726 |
++ |
727 |
++ for (i = 0; i < NUM_SYNCS; ++i) |
728 |
++ meta_sync_free (ring->syncs_array[i]); |
729 |
++ |
730 |
++ g_hash_table_destroy (ring->alarm_to_sync); |
731 |
++ |
732 |
++ ring->xsync_event_base = 0; |
733 |
++ ring->xsync_error_base = 0; |
734 |
++ ring->xdisplay = NULL; |
735 |
++} |
736 |
++ |
737 |
++static gboolean |
738 |
++meta_sync_ring_reboot (Display *xdisplay) |
739 |
++{ |
740 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
741 |
++ |
742 |
++ if (!ring) |
743 |
++ return FALSE; |
744 |
++ |
745 |
++ meta_sync_ring_destroy (); |
746 |
++ |
747 |
++ ring->reboots += 1; |
748 |
++ |
749 |
++ if (!meta_sync_ring_get ()) |
750 |
++ { |
751 |
++ meta_warning ("MetaSyncRing: Too many reboots -- disabling\n"); |
752 |
++ return FALSE; |
753 |
++ } |
754 |
++ |
755 |
++ return meta_sync_ring_init (xdisplay); |
756 |
++} |
757 |
++ |
758 |
++gboolean |
759 |
++meta_sync_ring_after_frame (void) |
760 |
++{ |
761 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
762 |
++ |
763 |
++ if (!ring) |
764 |
++ return FALSE; |
765 |
++ |
766 |
++ g_return_if_fail (ring->xdisplay != NULL); |
767 |
++ |
768 |
++ if (ring->warmup_syncs >= NUM_SYNCS / 2) |
769 |
++ { |
770 |
++ guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS; |
771 |
++ MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx]; |
772 |
++ |
773 |
++ GLenum status = meta_sync_check_update_finished (sync_to_reset, 0); |
774 |
++ if (status == GL_TIMEOUT_EXPIRED) |
775 |
++ { |
776 |
++ meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n"); |
777 |
++ status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME); |
778 |
++ } |
779 |
++ |
780 |
++ if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) |
781 |
++ { |
782 |
++ meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n"); |
783 |
++ return meta_sync_ring_reboot (ring->xdisplay); |
784 |
++ } |
785 |
++ |
786 |
++ meta_sync_reset (sync_to_reset); |
787 |
++ } |
788 |
++ else |
789 |
++ { |
790 |
++ ring->warmup_syncs += 1; |
791 |
++ } |
792 |
++ |
793 |
++ ring->current_sync_idx += 1; |
794 |
++ ring->current_sync_idx %= NUM_SYNCS; |
795 |
++ |
796 |
++ ring->current_sync = ring->syncs_array[ring->current_sync_idx]; |
797 |
++ |
798 |
++ return TRUE; |
799 |
++} |
800 |
++ |
801 |
++gboolean |
802 |
++meta_sync_ring_insert_wait (void) |
803 |
++{ |
804 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
805 |
++ |
806 |
++ if (!ring) |
807 |
++ return FALSE; |
808 |
++ |
809 |
++ g_return_if_fail (ring->xdisplay != NULL); |
810 |
++ |
811 |
++ if (ring->current_sync->state != META_SYNC_STATE_READY) |
812 |
++ { |
813 |
++ meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n"); |
814 |
++ if (!meta_sync_ring_reboot (ring->xdisplay)) |
815 |
++ return FALSE; |
816 |
++ } |
817 |
++ |
818 |
++ meta_sync_insert (ring->current_sync); |
819 |
++ |
820 |
++ return TRUE; |
821 |
++} |
822 |
++ |
823 |
++void |
824 |
++meta_sync_ring_handle_event (XEvent *xevent) |
825 |
++{ |
826 |
++ XSyncAlarmNotifyEvent *event; |
827 |
++ MetaSync *sync; |
828 |
++ MetaSyncRing *ring = meta_sync_ring_get (); |
829 |
++ |
830 |
++ if (!ring) |
831 |
++ return; |
832 |
++ |
833 |
++ g_return_if_fail (ring->xdisplay != NULL); |
834 |
++ |
835 |
++ if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify)) |
836 |
++ return; |
837 |
++ |
838 |
++ event = (XSyncAlarmNotifyEvent *) xevent; |
839 |
++ |
840 |
++ sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm); |
841 |
++ if (sync) |
842 |
++ meta_sync_handle_event (sync, event); |
843 |
++} |
844 |
+diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h |
845 |
+new file mode 100644 |
846 |
+index 0000000..6dca8ef |
847 |
+--- /dev/null |
848 |
++++ b/src/compositor/meta-sync-ring.h |
849 |
+@@ -0,0 +1,14 @@ |
850 |
++#ifndef _META_SYNC_RING_H_ |
851 |
++#define _META_SYNC_RING_H_ |
852 |
++ |
853 |
++#include <glib.h> |
854 |
++ |
855 |
++#include <X11/Xlib.h> |
856 |
++ |
857 |
++gboolean meta_sync_ring_init (Display *dpy); |
858 |
++void meta_sync_ring_destroy (void); |
859 |
++gboolean meta_sync_ring_after_frame (void); |
860 |
++gboolean meta_sync_ring_insert_wait (void); |
861 |
++void meta_sync_ring_handle_event (XEvent *event); |
862 |
++ |
863 |
++#endif /* _META_SYNC_RING_H_ */ |
864 |
+-- |
865 |
+cgit v0.10.2 |
866 |
+ |
867 |
|
868 |
diff --git a/x11-wm/mutter/files/mutter-3.16.3-crash-border.patch b/x11-wm/mutter/files/mutter-3.16.3-crash-border.patch |
869 |
new file mode 100644 |
870 |
index 0000000..9cbd0d0 |
871 |
--- /dev/null |
872 |
+++ b/x11-wm/mutter/files/mutter-3.16.3-crash-border.patch |
873 |
@@ -0,0 +1,32 @@ |
874 |
+From f60c33b5afc4b1dff0b31f17d7ae222db8aa789f Mon Sep 17 00:00:00 2001 |
875 |
+From: Marek Chalupa <mchqwerty@×××××.com> |
876 |
+Date: Fri, 3 Jul 2015 11:28:00 +0200 |
877 |
+Subject: frames: handle META_FRAME_CONTROL_NONE on left click |
878 |
+ |
879 |
+We can get this operation in some cases, for example when |
880 |
+we're trying to resize window that cannot be resized. |
881 |
+This can occur with maximized windows that have a border |
882 |
+(without border we couldn't resize them by mouse in maximized state). |
883 |
+In this case we reached abort() beacuse we did not handle this op. |
884 |
+ |
885 |
+https://bugzilla.gnome.org/show_bug.cgi?id=751884 |
886 |
+ |
887 |
+diff --git a/src/ui/frames.c b/src/ui/frames.c |
888 |
+index 362d7b6..a2f7f45 100644 |
889 |
+--- a/src/ui/frames.c |
890 |
++++ b/src/ui/frames.c |
891 |
+@@ -1053,6 +1053,11 @@ meta_frame_left_click_event (MetaUIFrame *frame, |
892 |
+ } |
893 |
+ |
894 |
+ return TRUE; |
895 |
++ case META_FRAME_CONTROL_NONE: |
896 |
++ /* We can get this for example when trying to resize window |
897 |
++ * that cannot be resized (e. g. it is maximized and the theme |
898 |
++ * currently used has borders for maximized windows), see #751884 */ |
899 |
++ return FALSE; |
900 |
+ default: |
901 |
+ g_assert_not_reached (); |
902 |
+ } |
903 |
+-- |
904 |
+cgit v0.10.2 |
905 |
+ |
906 |
|
907 |
diff --git a/x11-wm/mutter/files/mutter-3.16.3-fallback-keymap.patch b/x11-wm/mutter/files/mutter-3.16.3-fallback-keymap.patch |
908 |
new file mode 100644 |
909 |
index 0000000..f77234b |
910 |
--- /dev/null |
911 |
+++ b/x11-wm/mutter/files/mutter-3.16.3-fallback-keymap.patch |
912 |
@@ -0,0 +1,28 @@ |
913 |
+From 9abc0712836c9e56ed08796645874cc0d10b1826 Mon Sep 17 00:00:00 2001 |
914 |
+From: Rui Matos <tiagomatos@×××××.com> |
915 |
+Date: Mon, 21 Sep 2015 17:25:40 +0200 |
916 |
+Subject: backend-x11: Fallback to a default keymap if getting it from X fails |
917 |
+ |
918 |
+This shouldn't fail but apparently sometimes it does and in that case |
919 |
+having a possibly wrong idea of the keymap is still better than |
920 |
+crashing. |
921 |
+ |
922 |
+https://bugzilla.gnome.org/show_bug.cgi?id=754979 |
923 |
+ |
924 |
+diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c |
925 |
+index 7ad28fd..dbcd13f 100644 |
926 |
+--- a/src/backends/x11/meta-backend-x11.c |
927 |
++++ b/src/backends/x11/meta-backend-x11.c |
928 |
+@@ -760,6 +760,9 @@ meta_backend_x11_get_keymap (MetaBackend *backend) |
929 |
+ priv->xcb, |
930 |
+ xkb_x11_get_core_keyboard_device_id (priv->xcb), |
931 |
+ XKB_KEYMAP_COMPILE_NO_FLAGS); |
932 |
++ if (priv->keymap == NULL) |
933 |
++ priv->keymap = xkb_keymap_new_from_names (context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS); |
934 |
++ |
935 |
+ xkb_context_unref (context); |
936 |
+ } |
937 |
+ |
938 |
+-- |
939 |
+cgit v0.10.2 |
940 |
+ |
941 |
|
942 |
diff --git a/x11-wm/mutter/files/mutter-3.16.3-fix-race.patch b/x11-wm/mutter/files/mutter-3.16.3-fix-race.patch |
943 |
new file mode 100644 |
944 |
index 0000000..a0b493b |
945 |
--- /dev/null |
946 |
+++ b/x11-wm/mutter/files/mutter-3.16.3-fix-race.patch |
947 |
@@ -0,0 +1,114 @@ |
948 |
+From c77e482b60bea40a422691b16af02a429d9c2edc Mon Sep 17 00:00:00 2001 |
949 |
+From: Aaron Plattner <aplattner@××××××.com> |
950 |
+Date: Mon, 3 Aug 2015 21:15:15 -0700 |
951 |
+Subject: compositor: Fix GL_EXT_x11_sync_object race condition |
952 |
+ |
953 |
+The compositor maintains a ring of shared fences with the X server in order to |
954 |
+properly synchronize rendering between the X server and the compositor's GPU |
955 |
+channel. When all of the fences have been used, the compositor needs to reset |
956 |
+one so that it can be reused. It does this by first waiting on the CPU for the |
957 |
+fence to become triggered, and then sending a request to the X server to reset |
958 |
+the fence. |
959 |
+ |
960 |
+If the compositor's GPU channel is busy processing other work (e.g. the desktop |
961 |
+switcher animation), then the X server may process the reset request before the |
962 |
+GPU has consumed the fence. This causes the GPU channel to hang. |
963 |
+ |
964 |
+Fix the problem by having the compositor's GPU channel trigger its own fence |
965 |
+after waiting for the X server's fence. Wait for that fence on the CPU before |
966 |
+sending the reset request to the X server. This ensures that the GPU has |
967 |
+consumed the X11 fence before the server resets it. |
968 |
+ |
969 |
+Signed-off-by: Aaron Plattner <aplattner@××××××.com> |
970 |
+ |
971 |
+https://bugzilla.gnome.org/show_bug.cgi?id=728464 |
972 |
+ |
973 |
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c |
974 |
+index 4ee61f8..44b1c41 100644 |
975 |
+--- a/src/compositor/meta-sync-ring.c |
976 |
++++ b/src/compositor/meta-sync-ring.c |
977 |
+@@ -73,7 +73,8 @@ typedef struct |
978 |
+ Display *xdisplay; |
979 |
+ |
980 |
+ XSyncFence xfence; |
981 |
+- GLsync glsync; |
982 |
++ GLsync gl_x11_sync; |
983 |
++ GLsync gpu_fence; |
984 |
+ |
985 |
+ XSyncCounter xcounter; |
986 |
+ XSyncAlarm xalarm; |
987 |
+@@ -118,6 +119,8 @@ static void (*meta_gl_wait_sync) (GLsync sync, |
988 |
+ static GLsync (*meta_gl_import_sync) (GLenum external_sync_type, |
989 |
+ GLintptr external_sync, |
990 |
+ GLbitfield flags); |
991 |
++static GLsync (*meta_gl_fence_sync) (GLenum condition, |
992 |
++ GLbitfield flags); |
993 |
+ |
994 |
+ static MetaSyncRing * |
995 |
+ meta_sync_ring_get (void) |
996 |
+@@ -224,6 +227,8 @@ load_required_symbols (void) |
997 |
+ goto out; |
998 |
+ if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync)) |
999 |
+ goto out; |
1000 |
++ if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync)) |
1001 |
++ goto out; |
1002 |
+ |
1003 |
+ success = TRUE; |
1004 |
+ out: |
1005 |
+@@ -238,7 +243,8 @@ meta_sync_insert (MetaSync *self) |
1006 |
+ XSyncTriggerFence (self->xdisplay, self->xfence); |
1007 |
+ XFlush (self->xdisplay); |
1008 |
+ |
1009 |
+- meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED); |
1010 |
++ meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED); |
1011 |
++ self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0); |
1012 |
+ |
1013 |
+ self->state = META_SYNC_STATE_WAITING; |
1014 |
+ } |
1015 |
+@@ -255,9 +261,13 @@ meta_sync_check_update_finished (MetaSync *self, |
1016 |
+ status = GL_ALREADY_SIGNALED; |
1017 |
+ break; |
1018 |
+ case META_SYNC_STATE_WAITING: |
1019 |
+- status = meta_gl_client_wait_sync (self->glsync, 0, timeout); |
1020 |
++ status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout); |
1021 |
+ if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) |
1022 |
+- self->state = META_SYNC_STATE_DONE; |
1023 |
++ { |
1024 |
++ self->state = META_SYNC_STATE_DONE; |
1025 |
++ meta_gl_delete_sync (self->gpu_fence); |
1026 |
++ self->gpu_fence = 0; |
1027 |
++ } |
1028 |
+ break; |
1029 |
+ default: |
1030 |
+ break; |
1031 |
+@@ -312,7 +322,8 @@ meta_sync_new (Display *xdisplay) |
1032 |
+ self->xdisplay = xdisplay; |
1033 |
+ |
1034 |
+ self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); |
1035 |
+- self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); |
1036 |
++ self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); |
1037 |
++ self->gpu_fence = 0; |
1038 |
+ |
1039 |
+ self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); |
1040 |
+ |
1041 |
+@@ -365,6 +376,8 @@ meta_sync_free (MetaSync *self) |
1042 |
+ switch (self->state) |
1043 |
+ { |
1044 |
+ case META_SYNC_STATE_WAITING: |
1045 |
++ meta_gl_delete_sync (self->gpu_fence); |
1046 |
++ break; |
1047 |
+ case META_SYNC_STATE_DONE: |
1048 |
+ /* nothing to do */ |
1049 |
+ break; |
1050 |
+@@ -383,7 +396,7 @@ meta_sync_free (MetaSync *self) |
1051 |
+ break; |
1052 |
+ } |
1053 |
+ |
1054 |
+- meta_gl_delete_sync (self->glsync); |
1055 |
++ meta_gl_delete_sync (self->gl_x11_sync); |
1056 |
+ XSyncDestroyFence (self->xdisplay, self->xfence); |
1057 |
+ XSyncDestroyCounter (self->xdisplay, self->xcounter); |
1058 |
+ XSyncDestroyAlarm (self->xdisplay, self->xalarm); |
1059 |
+-- |
1060 |
+cgit v0.10.2 |
1061 |
+ |
1062 |
|
1063 |
diff --git a/x11-wm/mutter/files/mutter-3.16.3-fix-return.patch b/x11-wm/mutter/files/mutter-3.16.3-fix-return.patch |
1064 |
new file mode 100644 |
1065 |
index 0000000..2898d52 |
1066 |
--- /dev/null |
1067 |
+++ b/x11-wm/mutter/files/mutter-3.16.3-fix-return.patch |
1068 |
@@ -0,0 +1,32 @@ |
1069 |
+From a54b1261d3ec5ccf7a8262c88557b6b952bc8a2e Mon Sep 17 00:00:00 2001 |
1070 |
+From: Ting-Wei Lan <lantw@×××××××××.org> |
1071 |
+Date: Sat, 8 Aug 2015 20:12:09 +0800 |
1072 |
+Subject: build: Fix return value in meta-sync-ring.c |
1073 |
+ |
1074 |
+https://bugzilla.gnome.org/show_bug.cgi?id=753380 |
1075 |
+ |
1076 |
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c |
1077 |
+index 44b1c41..217ebe5 100644 |
1078 |
+--- a/src/compositor/meta-sync-ring.c |
1079 |
++++ b/src/compositor/meta-sync-ring.c |
1080 |
+@@ -499,7 +499,7 @@ meta_sync_ring_after_frame (void) |
1081 |
+ if (!ring) |
1082 |
+ return FALSE; |
1083 |
+ |
1084 |
+- g_return_if_fail (ring->xdisplay != NULL); |
1085 |
++ g_return_val_if_fail (ring->xdisplay != NULL, FALSE); |
1086 |
+ |
1087 |
+ if (ring->warmup_syncs >= NUM_SYNCS / 2) |
1088 |
+ { |
1089 |
+@@ -542,7 +542,7 @@ meta_sync_ring_insert_wait (void) |
1090 |
+ if (!ring) |
1091 |
+ return FALSE; |
1092 |
+ |
1093 |
+- g_return_if_fail (ring->xdisplay != NULL); |
1094 |
++ g_return_val_if_fail (ring->xdisplay != NULL, FALSE); |
1095 |
+ |
1096 |
+ if (ring->current_sync->state != META_SYNC_STATE_READY) |
1097 |
+ { |
1098 |
+-- |
1099 |
+cgit v0.10.2 |
1100 |
+ |
1101 |
|
1102 |
diff --git a/x11-wm/mutter/files/mutter-3.16.3-flickering.patch b/x11-wm/mutter/files/mutter-3.16.3-flickering.patch |
1103 |
new file mode 100644 |
1104 |
index 0000000..6267a4e |
1105 |
--- /dev/null |
1106 |
+++ b/x11-wm/mutter/files/mutter-3.16.3-flickering.patch |
1107 |
@@ -0,0 +1,114 @@ |
1108 |
+From 916070cc7218cc80f4565ea265b0dd6e5e93cb98 Mon Sep 17 00:00:00 2001 |
1109 |
+From: Rui Matos <tiagomatos@×××××.com> |
1110 |
+Date: Wed, 12 Aug 2015 15:26:34 +0200 |
1111 |
+Subject: compositor: Handle fences in the frontend X connection |
1112 |
+ |
1113 |
+Since mutter has two X connections and does damage handling on the |
1114 |
+frontend while fence triggering is done on the backend, we have a race |
1115 |
+between XDamageSubtract() and XSyncFenceTrigger() causing missed |
1116 |
+redraws in the GL_EXT_X11_sync_object path. |
1117 |
+ |
1118 |
+If the fence trigger gets processed first by the server, any client |
1119 |
+drawing that happens between that and the damage subtract being |
1120 |
+processed and is completely contained in the last damage event box |
1121 |
+that mutter got, won't be included in the current frame nor will it |
1122 |
+cause a new damage event. |
1123 |
+ |
1124 |
+A simple fix for this would be XSync()ing on the frontend connection |
1125 |
+after doing all the damage subtracts but that would add a round trip |
1126 |
+on every frame again which defeats the asynchronous design of X |
1127 |
+fences. |
1128 |
+ |
1129 |
+Instead, if we move fence handling to the frontend we automatically |
1130 |
+get the right ordering between damage subtracts and fence triggers. |
1131 |
+ |
1132 |
+https://bugzilla.gnome.org/show_bug.cgi?id=728464 |
1133 |
+ |
1134 |
+diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c |
1135 |
+index ac38ffc..3ff8431 100644 |
1136 |
+--- a/src/backends/x11/meta-backend-x11.c |
1137 |
++++ b/src/backends/x11/meta-backend-x11.c |
1138 |
+@@ -45,7 +45,6 @@ |
1139 |
+ #include <meta/util.h> |
1140 |
+ #include "display-private.h" |
1141 |
+ #include "compositor/compositor-private.h" |
1142 |
+-#include "compositor/meta-sync-ring.h" |
1143 |
+ |
1144 |
+ struct _MetaBackendX11Private |
1145 |
+ { |
1146 |
+@@ -256,8 +255,6 @@ handle_host_xevent (MetaBackend *backend, |
1147 |
+ MetaCompositor *compositor = display->compositor; |
1148 |
+ if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) |
1149 |
+ bypass_clutter = TRUE; |
1150 |
+- if (compositor->have_x11_sync_object) |
1151 |
+- meta_sync_ring_handle_event (event); |
1152 |
+ } |
1153 |
+ } |
1154 |
+ |
1155 |
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c |
1156 |
+index 554faa1..2e182c2 100644 |
1157 |
+--- a/src/compositor/compositor.c |
1158 |
++++ b/src/compositor/compositor.c |
1159 |
+@@ -534,8 +534,7 @@ meta_compositor_manage (MetaCompositor *compositor) |
1160 |
+ */ |
1161 |
+ XMapWindow (xdisplay, compositor->output); |
1162 |
+ |
1163 |
+- compositor->have_x11_sync_object = |
1164 |
+- meta_sync_ring_init (meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend))); |
1165 |
++ compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay); |
1166 |
+ } |
1167 |
+ |
1168 |
+ redirect_windows (display->screen); |
1169 |
+@@ -737,6 +736,9 @@ meta_compositor_process_event (MetaCompositor *compositor, |
1170 |
+ process_damage (compositor, (XDamageNotifyEvent *) event, window); |
1171 |
+ } |
1172 |
+ |
1173 |
++ if (compositor->have_x11_sync_object) |
1174 |
++ meta_sync_ring_handle_event (event); |
1175 |
++ |
1176 |
+ /* Clutter needs to know about MapNotify events otherwise it will |
1177 |
+ think the stage is invisible */ |
1178 |
+ if (!meta_is_wayland_compositor () && event->type == MapNotify) |
1179 |
+diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c |
1180 |
+index 217ebe5..336ccd4 100644 |
1181 |
+--- a/src/compositor/meta-sync-ring.c |
1182 |
++++ b/src/compositor/meta-sync-ring.c |
1183 |
+@@ -322,7 +322,7 @@ meta_sync_new (Display *xdisplay) |
1184 |
+ self->xdisplay = xdisplay; |
1185 |
+ |
1186 |
+ self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); |
1187 |
+- self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); |
1188 |
++ self->gl_x11_sync = 0; |
1189 |
+ self->gpu_fence = 0; |
1190 |
+ |
1191 |
+ self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); |
1192 |
+@@ -347,6 +347,13 @@ meta_sync_new (Display *xdisplay) |
1193 |
+ return self; |
1194 |
+ } |
1195 |
+ |
1196 |
++static void |
1197 |
++meta_sync_import (MetaSync *self) |
1198 |
++{ |
1199 |
++ g_return_if_fail (self->gl_x11_sync == 0); |
1200 |
++ self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); |
1201 |
++} |
1202 |
++ |
1203 |
+ static Bool |
1204 |
+ alarm_event_predicate (Display *dpy, |
1205 |
+ XEvent *event, |
1206 |
+@@ -437,6 +444,12 @@ meta_sync_ring_init (Display *xdisplay) |
1207 |
+ ring->syncs_array[i] = sync; |
1208 |
+ g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync); |
1209 |
+ } |
1210 |
++ /* Since the connection we create the X fences on isn't the same as |
1211 |
++ * the one used for the GLX context, we need to XSync() here to |
1212 |
++ * ensure glImportSync() succeeds. */ |
1213 |
++ XSync (xdisplay, False); |
1214 |
++ for (i = 0; i < NUM_SYNCS; ++i) |
1215 |
++ meta_sync_import (ring->syncs_array[i]); |
1216 |
+ |
1217 |
+ ring->current_sync_idx = 0; |
1218 |
+ ring->current_sync = ring->syncs_array[0]; |
1219 |
+-- |
1220 |
+cgit v0.10.2 |
1221 |
+ |
1222 |
|
1223 |
diff --git a/x11-wm/mutter/mutter-3.16.3-r1.ebuild b/x11-wm/mutter/mutter-3.16.3-r1.ebuild |
1224 |
new file mode 100644 |
1225 |
index 0000000..98cc39c |
1226 |
--- /dev/null |
1227 |
+++ b/x11-wm/mutter/mutter-3.16.3-r1.ebuild |
1228 |
@@ -0,0 +1,114 @@ |
1229 |
+# Copyright 1999-2015 Gentoo Foundation |
1230 |
+# Distributed under the terms of the GNU General Public License v2 |
1231 |
+# $Id$ |
1232 |
+ |
1233 |
+EAPI="5" |
1234 |
+GCONF_DEBUG="yes" |
1235 |
+ |
1236 |
+inherit autotools eutils gnome2 |
1237 |
+ |
1238 |
+DESCRIPTION="GNOME 3 compositing window manager based on Clutter" |
1239 |
+HOMEPAGE="https://git.gnome.org/browse/mutter/" |
1240 |
+ |
1241 |
+LICENSE="GPL-2+" |
1242 |
+SLOT="0" |
1243 |
+IUSE="+introspection +kms test wayland" |
1244 |
+KEYWORDS="~alpha ~amd64 ~arm ~ia64 ~ppc ~ppc64 ~sparc ~x86" |
1245 |
+ |
1246 |
+# libXi-1.7.4 or newer needed per: |
1247 |
+# https://bugzilla.gnome.org/show_bug.cgi?id=738944 |
1248 |
+COMMON_DEPEND=" |
1249 |
+ >=x11-libs/pango-1.2[X,introspection?] |
1250 |
+ >=x11-libs/cairo-1.10[X] |
1251 |
+ >=x11-libs/gtk+-3.9.11:3[X,introspection?] |
1252 |
+ >=dev-libs/glib-2.36.0:2[dbus] |
1253 |
+ >=media-libs/clutter-1.21.3:1.0[introspection?] |
1254 |
+ >=media-libs/cogl-1.17.1:1.0=[introspection?] |
1255 |
+ >=media-libs/libcanberra-0.26[gtk3] |
1256 |
+ >=x11-libs/startup-notification-0.7 |
1257 |
+ >=x11-libs/libXcomposite-0.2 |
1258 |
+ >=gnome-base/gsettings-desktop-schemas-3.15.92[introspection?] |
1259 |
+ gnome-base/gnome-desktop:3= |
1260 |
+ >sys-power/upower-0.99:= |
1261 |
+ |
1262 |
+ x11-libs/libICE |
1263 |
+ x11-libs/libSM |
1264 |
+ x11-libs/libX11 |
1265 |
+ >=x11-libs/libXcomposite-0.2 |
1266 |
+ x11-libs/libXcursor |
1267 |
+ x11-libs/libXdamage |
1268 |
+ x11-libs/libXext |
1269 |
+ x11-libs/libXfixes |
1270 |
+ >=x11-libs/libXi-1.7.4 |
1271 |
+ x11-libs/libXinerama |
1272 |
+ x11-libs/libXrandr |
1273 |
+ x11-libs/libXrender |
1274 |
+ x11-libs/libxcb |
1275 |
+ x11-libs/libxkbfile |
1276 |
+ >=x11-libs/libxkbcommon-0.4.3[X] |
1277 |
+ x11-misc/xkeyboard-config |
1278 |
+ |
1279 |
+ gnome-extra/zenity |
1280 |
+ |
1281 |
+ introspection? ( >=dev-libs/gobject-introspection-1.42:= ) |
1282 |
+ kms? ( |
1283 |
+ dev-libs/libinput |
1284 |
+ >=media-libs/clutter-1.20[egl] |
1285 |
+ media-libs/cogl:1.0=[kms] |
1286 |
+ >=media-libs/mesa-10.3[gbm] |
1287 |
+ sys-apps/systemd |
1288 |
+ virtual/libgudev |
1289 |
+ x11-libs/libdrm:= ) |
1290 |
+ wayland? ( |
1291 |
+ >=dev-libs/wayland-1.6.90 |
1292 |
+ >=media-libs/clutter-1.20[wayland] |
1293 |
+ x11-base/xorg-server[wayland] ) |
1294 |
+" |
1295 |
+DEPEND="${COMMON_DEPEND} |
1296 |
+ >=dev-util/gtk-doc-am-1.15 |
1297 |
+ >=dev-util/intltool-0.41 |
1298 |
+ sys-devel/gettext |
1299 |
+ virtual/pkgconfig |
1300 |
+ x11-proto/xextproto |
1301 |
+ x11-proto/xineramaproto |
1302 |
+ x11-proto/xproto |
1303 |
+ test? ( app-text/docbook-xml-dtd:4.5 ) |
1304 |
+" |
1305 |
+RDEPEND="${COMMON_DEPEND} |
1306 |
+ !x11-misc/expocity |
1307 |
+" |
1308 |
+ |
1309 |
+src_prepare() { |
1310 |
+ # Fallback to a default keymap if getting it from X fails (from 'master') |
1311 |
+ epatch "${FILESDIR}"/${PN}-3.16.3-fallback-keymap.patch |
1312 |
+ |
1313 |
+ # frames: handle META_FRAME_CONTROL_NONE on left click (from '3.16') |
1314 |
+ epatch "${FILESDIR}"/${P}-crash-border.patch |
1315 |
+ |
1316 |
+ # compositor: Add support for GL_EXT_x11_sync_object (from '3.16') |
1317 |
+ epatch "${FILESDIR}"/${P}-GL_EXT_x11_sync_object.patch |
1318 |
+ |
1319 |
+ # compositor: Fix GL_EXT_x11_sync_object race condition (from '3.16') |
1320 |
+ epatch "${FILESDIR}"/${P}-fix-race.patch |
1321 |
+ |
1322 |
+ # build: Fix return value in meta-sync-ring.c (from '3.16') |
1323 |
+ epatch "${FILESDIR}"/${P}-fix-return.patch |
1324 |
+ |
1325 |
+ # compositor: Handle fences in the frontend X connection (from '3.16') |
1326 |
+ epatch "${FILESDIR}"/${P}-flickering.patch |
1327 |
+ |
1328 |
+ eautoreconf |
1329 |
+ gnome2_src_prepare |
1330 |
+} |
1331 |
+ |
1332 |
+src_configure() { |
1333 |
+ gnome2_src_configure \ |
1334 |
+ --disable-static \ |
1335 |
+ --enable-sm \ |
1336 |
+ --enable-startup-notification \ |
1337 |
+ --enable-verbose-mode \ |
1338 |
+ --with-libcanberra \ |
1339 |
+ $(use_enable introspection) \ |
1340 |
+ $(use_enable kms native-backend) \ |
1341 |
+ $(use_enable wayland) |
1342 |
+} |