mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
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
This commit is contained in:
parent
fa4a787386
commit
20c1295a33
@ -99,9 +99,9 @@ typedef struct _CoglOnscreenGLX
|
|||||||
CoglOnscreenXlib _parent;
|
CoglOnscreenXlib _parent;
|
||||||
GLXDrawable glxwin;
|
GLXDrawable glxwin;
|
||||||
uint32_t last_swap_vsync_counter;
|
uint32_t last_swap_vsync_counter;
|
||||||
gboolean pending_sync_notify;
|
uint32_t pending_sync_notify;
|
||||||
gboolean pending_complete_notify;
|
uint32_t pending_complete_notify;
|
||||||
gboolean pending_resize_notify;
|
uint32_t pending_resize_notify;
|
||||||
|
|
||||||
GThread *swap_wait_thread;
|
GThread *swap_wait_thread;
|
||||||
GQueue *swap_wait_queue;
|
GQueue *swap_wait_queue;
|
||||||
@ -347,35 +347,35 @@ flush_pending_notifications_cb (void *data,
|
|||||||
{
|
{
|
||||||
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
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
|
while (glx_onscreen->pending_sync_notify > 0 ||
|
||||||
* potentially immediately queue a subsequent pending notify so
|
glx_onscreen->pending_complete_notify > 0 ||
|
||||||
* we need to clear the flag before invoking the callback */
|
glx_onscreen->pending_resize_notify > 0)
|
||||||
glx_onscreen->pending_sync_notify = FALSE;
|
|
||||||
glx_onscreen->pending_complete_notify = FALSE;
|
|
||||||
|
|
||||||
if (pending_sync_notify)
|
|
||||||
{
|
{
|
||||||
CoglFrameInfo *info = g_queue_peek_head (&onscreen->pending_frame_infos);
|
if (glx_onscreen->pending_sync_notify > 0)
|
||||||
|
{
|
||||||
|
CoglFrameInfo *info =
|
||||||
|
g_queue_peek_head (&onscreen->pending_frame_infos);
|
||||||
|
|
||||||
_cogl_onscreen_notify_frame_sync (onscreen, info);
|
_cogl_onscreen_notify_frame_sync (onscreen, info);
|
||||||
|
glx_onscreen->pending_sync_notify--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending_complete_notify)
|
if (glx_onscreen->pending_complete_notify > 0)
|
||||||
{
|
{
|
||||||
CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);
|
CoglFrameInfo *info =
|
||||||
|
g_queue_pop_head (&onscreen->pending_frame_infos);
|
||||||
|
|
||||||
_cogl_onscreen_notify_complete (onscreen, info);
|
_cogl_onscreen_notify_complete (onscreen, info);
|
||||||
|
|
||||||
cogl_object_unref (info);
|
cogl_object_unref (info);
|
||||||
|
glx_onscreen->pending_complete_notify--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glx_onscreen->pending_resize_notify)
|
if (glx_onscreen->pending_resize_notify > 0)
|
||||||
{
|
{
|
||||||
_cogl_onscreen_notify_resize (onscreen);
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
glx_onscreen->pending_resize_notify = FALSE;
|
glx_onscreen->pending_resize_notify--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +417,7 @@ set_sync_pending (CoglOnscreen *onscreen)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_onscreen->pending_sync_notify = TRUE;
|
glx_onscreen->pending_sync_notify++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -440,7 +440,7 @@ set_complete_pending (CoglOnscreen *onscreen)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_onscreen->pending_complete_notify = TRUE;
|
glx_onscreen->pending_complete_notify++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -533,7 +533,7 @@ notify_resize (CoglContext *context,
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_onscreen->pending_resize_notify = TRUE;
|
glx_onscreen->pending_resize_notify++;
|
||||||
|
|
||||||
if (!xlib_onscreen->is_foreign_xwin)
|
if (!xlib_onscreen->is_foreign_xwin)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user