Gentoo Archives: gentoo-commits

From: Pacho Ramos <pacho@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: x11-wm/mutter/, x11-wm/mutter/files/
Date: Sat, 03 Oct 2015 09:04:09
Message-Id: 1443862976.2c00b2f8422f0ea593daa6792c3ec6caf83210ef.pacho@gentoo
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 +}