From 97140ab6346bd29208e99c9c9aab892c2eec0e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 27 Aug 2019 20:16:01 +0300 Subject: [PATCH] Revert "clutter/stage-cogl: Remove pending_swaps counter" This reverts commit f57ce7254d4abd462044318bb088fccd8557ccc8. It causes crashes, https://gitlab.gnome.org/GNOME/mutter/issues/735, and changes various expectations relied upon by the renderer code, and being close to release, it's safer to revert now and reconsider how to remove the pending swap counter at a later point. --- clutter/clutter/cogl/clutter-stage-cogl.c | 55 +++++++++++++++++++---- clutter/clutter/cogl/clutter-stage-cogl.h | 1 + 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 4dd7a900e..8f97a5fa6 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -95,7 +95,22 @@ _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl, CoglFrameEvent frame_event, ClutterFrameInfo *frame_info) { - if (frame_event == COGL_FRAME_EVENT_COMPLETE) + + if (frame_event == COGL_FRAME_EVENT_SYNC) + { + /* Early versions of the swap_event implementation in Mesa + * deliver BufferSwapComplete event when not selected for, + * so if we get a swap event we aren't expecting, just ignore it. + * + * https://bugs.freedesktop.org/show_bug.cgi?id=27962 + * + * FIXME: This issue can be hidden inside Cogl so we shouldn't + * need to care about this bug here. + */ + if (stage_cogl->pending_swaps > 0) + stage_cogl->pending_swaps--; + } + else if (frame_event == COGL_FRAME_EVENT_COMPLETE) { gint64 presentation_time_cogl = frame_info->presentation_time; @@ -228,6 +243,9 @@ clutter_stage_cogl_get_update_time (ClutterStageWindow *stage_window) { ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + if (stage_cogl->pending_swaps) + return -1; /* in the future, indefinite */ + return stage_cogl->update_time; } @@ -436,7 +454,7 @@ paint_damage_region (ClutterStageWindow *stage_window, cogl_framebuffer_pop_matrix (framebuffer); } -static void +static gboolean swap_framebuffer (ClutterStageWindow *stage_window, ClutterStageView *view, cairo_rectangle_int_t *swap_region, @@ -474,6 +492,8 @@ swap_framebuffer (ClutterStageWindow *stage_window, cogl_onscreen_swap_region (onscreen, damage, ndamage); + + return FALSE; } else { @@ -482,6 +502,8 @@ swap_framebuffer (ClutterStageWindow *stage_window, cogl_onscreen_swap_buffers_with_damage (onscreen, damage, ndamage); + + return TRUE; } } else @@ -489,6 +511,8 @@ swap_framebuffer (ClutterStageWindow *stage_window, CLUTTER_NOTE (BACKEND, "cogl_framebuffer_finish (framebuffer: %p)", framebuffer); cogl_framebuffer_finish (framebuffer); + + return FALSE; } } @@ -612,7 +636,7 @@ scale_and_clamp_rect (const ClutterRect *rect, _clutter_util_rectangle_int_extents (&tmp, dest); } -static void +static gboolean clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, ClutterStageView *view) { @@ -931,10 +955,14 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, transform_swap_region_to_onscreen (view, &swap_region); } - swap_framebuffer (stage_window, - view, - &swap_region, - swap_with_damage); + return swap_framebuffer (stage_window, + view, + &swap_region, + swap_with_damage); + } + else + { + return FALSE; } } @@ -942,6 +970,7 @@ static void clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) { ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + gboolean swap_event = FALSE; GList *l; COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)"); @@ -950,13 +979,23 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) { ClutterStageView *view = l->data; - clutter_stage_cogl_redraw_view (stage_window, view); + swap_event = + clutter_stage_cogl_redraw_view (stage_window, view) || swap_event; } _clutter_stage_emit_after_paint (stage_cogl->wrapper); _clutter_stage_window_finish_frame (stage_window); + if (swap_event) + { + /* If we have swap buffer events then cogl_onscreen_swap_buffers + * will return immediately and we need to track that there is a + * swap in progress... */ + if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS)) + stage_cogl->pending_swaps++; + } + /* reset the redraw clipping for the next paint... */ stage_cogl->initialized_redraw_clip = FALSE; diff --git a/clutter/clutter/cogl/clutter-stage-cogl.h b/clutter/clutter/cogl/clutter-stage-cogl.h index 53d0267de..a69c424eb 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.h +++ b/clutter/clutter/cogl/clutter-stage-cogl.h @@ -49,6 +49,7 @@ struct _ClutterStageCogl ClutterBackend *backend; float refresh_rate; + int pending_swaps; gint64 last_presentation_time; gint64 update_time;