summarylogtreecommitdiffstats
path: root/216.patch
diff options
context:
space:
mode:
Diffstat (limited to '216.patch')
-rw-r--r--216.patch128
1 files changed, 128 insertions, 0 deletions
diff --git a/216.patch b/216.patch
new file mode 100644
index 000000000000..ee92895446d8
--- /dev/null
+++ b/216.patch
@@ -0,0 +1,128 @@
+From 6d8d73beeef3a618c553e89b0b3e532ec3654a30 Mon Sep 17 00:00:00 2001
+From: Daniel van Vugt <daniel.van.vugt@canonical.com>
+Date: Mon, 23 Jul 2018 16:28:56 +0800
+Subject: [PATCH] cogl-winsys-glx: Fix frame notification race/leak
+
+If a second `set_{sync,complete}_pending` was queued before the idle
+handler had flushed the first then one of them would be forgotten.
+It would stay queued forever and never emitted as a notification.
+
+This could happen repeatedly causing a slow leak. But worse still,
+`clutter-stage-cogl` would then have `pending_swaps` permanently stuck
+above zero preventing the presentation timing logic from being used.
+
+The problem is that a boolean can only count to one, but in some cases
+(triple buffering, whether intentional or accidental #334) we need it to
+count to two. So just change booleans to integers and count properly.
+
+https://gitlab.gnome.org/GNOME/mutter/merge_requests/216
+---
+ cogl/cogl/winsys/cogl-winsys-glx.c | 58 +++++++++++++++---------------
+ 1 file changed, 29 insertions(+), 29 deletions(-)
+
+diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
+index 2623d02c6..235cfe81f 100644
+--- a/cogl/cogl/winsys/cogl-winsys-glx.c
++++ b/cogl/cogl/winsys/cogl-winsys-glx.c
+@@ -99,9 +99,9 @@ typedef struct _CoglOnscreenGLX
+ CoglOnscreenXlib _parent;
+ GLXDrawable glxwin;
+ uint32_t last_swap_vsync_counter;
+- gboolean pending_sync_notify;
+- gboolean pending_complete_notify;
+- gboolean pending_resize_notify;
++ uint32_t pending_sync_notify;
++ uint32_t pending_complete_notify;
++ uint32_t pending_resize_notify;
+
+ GThread *swap_wait_thread;
+ GQueue *swap_wait_queue;
+@@ -347,35 +347,35 @@ flush_pending_notifications_cb (void *data,
+ {
+ CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+ CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
+- gboolean pending_sync_notify = glx_onscreen->pending_sync_notify;
+- gboolean pending_complete_notify = glx_onscreen->pending_complete_notify;
+
+- /* If swap_region is called then notifying the sync event could
+- * potentially immediately queue a subsequent pending notify so
+- * we need to clear the flag before invoking the callback */
+- glx_onscreen->pending_sync_notify = FALSE;
+- glx_onscreen->pending_complete_notify = FALSE;
+-
+- if (pending_sync_notify)
++ while (glx_onscreen->pending_sync_notify > 0 ||
++ glx_onscreen->pending_complete_notify > 0 ||
++ glx_onscreen->pending_resize_notify > 0)
+ {
+- CoglFrameInfo *info = g_queue_peek_head (&onscreen->pending_frame_infos);
+-
+- _cogl_onscreen_notify_frame_sync (onscreen, info);
+- }
++ if (glx_onscreen->pending_sync_notify > 0)
++ {
++ CoglFrameInfo *info =
++ g_queue_peek_head (&onscreen->pending_frame_infos);
+
+- if (pending_complete_notify)
+- {
+- CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);
++ _cogl_onscreen_notify_frame_sync (onscreen, info);
++ glx_onscreen->pending_sync_notify--;
++ }
+
+- _cogl_onscreen_notify_complete (onscreen, info);
++ if (glx_onscreen->pending_complete_notify > 0)
++ {
++ CoglFrameInfo *info =
++ g_queue_pop_head (&onscreen->pending_frame_infos);
+
+- cogl_object_unref (info);
+- }
++ _cogl_onscreen_notify_complete (onscreen, info);
++ cogl_object_unref (info);
++ glx_onscreen->pending_complete_notify--;
++ }
+
+- if (glx_onscreen->pending_resize_notify)
+- {
+- _cogl_onscreen_notify_resize (onscreen);
+- glx_onscreen->pending_resize_notify = FALSE;
++ if (glx_onscreen->pending_resize_notify > 0)
++ {
++ _cogl_onscreen_notify_resize (onscreen);
++ glx_onscreen->pending_resize_notify--;
++ }
+ }
+ }
+ }
+@@ -417,7 +417,7 @@ set_sync_pending (CoglOnscreen *onscreen)
+ NULL);
+ }
+
+- glx_onscreen->pending_sync_notify = TRUE;
++ glx_onscreen->pending_sync_notify++;
+ }
+
+ static void
+@@ -440,7 +440,7 @@ set_complete_pending (CoglOnscreen *onscreen)
+ NULL);
+ }
+
+- glx_onscreen->pending_complete_notify = TRUE;
++ glx_onscreen->pending_complete_notify++;
+ }
+
+ static void
+@@ -533,7 +533,7 @@ notify_resize (CoglContext *context,
+ NULL);
+ }
+
+- glx_onscreen->pending_resize_notify = TRUE;
++ glx_onscreen->pending_resize_notify++;
+
+ if (!xlib_onscreen->is_foreign_xwin)
+ {
+--
+2.18.1
+