diff options
Diffstat (limited to '216.patch')
-rw-r--r-- | 216.patch | 128 |
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 + |