From 261f516af4e635d4bb263bbbbb2f843f0cbe09de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Wed, 24 May 2023 20:09:25 +0200 Subject: [PATCH] clutter/stage: Avoid queueing stage updates when they're already queued We're using clutter_stage_schedule_update() now from ClutterActor to kick off the stage updating machinery when a redraw needs to happen. This introduced a bunch of unnecessary calls to clutter_stage_schedule_update() and thus clutter_stage_view_schedule_update() when multiple actors request redraws during the same stage update cycle, which is a very common case. Cut off all those unnecessary calls by bailing out in clutter_stage_schedule_update() when updates are already queued. Part-of: --- clutter/clutter/clutter-stage-private.h | 2 +- clutter/clutter/clutter-stage-view.c | 2 +- clutter/clutter/clutter-stage.c | 30 ++++++++++++++++--------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h index b17b63be9..e7e0cbce4 100644 --- a/clutter/clutter/clutter-stage-private.h +++ b/clutter/clutter/clutter-stage-private.h @@ -60,7 +60,7 @@ void clutter_stage_emit_before_paint (ClutterStage void clutter_stage_emit_after_paint (ClutterStage *stage, ClutterStageView *view, ClutterFrame *frame); -void clutter_stage_emit_after_update (ClutterStage *stage, +void clutter_stage_after_update (ClutterStage *stage, ClutterStageView *view, ClutterFrame *frame); diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c index 7d11789f1..81216440c 100644 --- a/clutter/clutter/clutter-stage-view.c +++ b/clutter/clutter/clutter-stage-view.c @@ -1280,7 +1280,7 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock, priv->needs_update_devices = FALSE; _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_POST_PAINT); - clutter_stage_emit_after_update (stage, view, frame); + clutter_stage_after_update (stage, view, frame); return clutter_frame_get_result (frame); } diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 80704fb06..fd318c0e7 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -137,6 +137,8 @@ struct _ClutterStagePrivate int update_freeze_count; + gboolean update_scheduled; + GHashTable *pointer_devices; GHashTable *touch_sequences; @@ -518,11 +520,15 @@ clutter_stage_emit_after_paint (ClutterStage *stage, } void -clutter_stage_emit_after_update (ClutterStage *stage, - ClutterStageView *view, - ClutterFrame *frame) +clutter_stage_after_update (ClutterStage *stage, + ClutterStageView *view, + ClutterFrame *frame) { + ClutterStagePrivate *priv = stage->priv; + g_signal_emit (stage, stage_signals[AFTER_UPDATE], 0, view, frame); + + priv->update_scheduled = FALSE; } static gboolean @@ -633,19 +639,15 @@ _clutter_stage_queue_event (ClutterStage *stage, gboolean copy_event) { ClutterStagePrivate *priv; - gboolean first_event; g_return_if_fail (CLUTTER_IS_STAGE (stage)); priv = stage->priv; - first_event = priv->event_queue->length == 0; - g_queue_push_tail (priv->event_queue, copy_event ? clutter_event_copy (event) : event); - if (first_event) - clutter_stage_schedule_update (stage); + clutter_stage_schedule_update (stage); } gboolean @@ -778,8 +780,7 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage, { ClutterStagePrivate *priv = stage->priv; - if (priv->pending_relayouts == NULL) - clutter_stage_schedule_update (stage); + clutter_stage_schedule_update (stage); priv->pending_relayouts = g_slist_prepend (priv->pending_relayouts, g_object_ref (actor)); @@ -2452,12 +2453,19 @@ _clutter_stage_get_default_window (void) void clutter_stage_schedule_update (ClutterStage *stage) { + ClutterStagePrivate *priv = stage->priv; ClutterStageWindow *stage_window; + gboolean first_event; GList *l; if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) return; + first_event = priv->event_queue->length == 0; + + if (priv->update_scheduled && !first_event) + return; + stage_window = _clutter_stage_get_window (stage); if (stage_window == NULL) return; @@ -2468,6 +2476,8 @@ clutter_stage_schedule_update (ClutterStage *stage) clutter_stage_view_schedule_update (view); } + + priv->update_scheduled = TRUE; } ClutterPaintVolume *