clutter/stage: Add signals for different update stages

Right now the stage only had a signal called 'after-paint' which was not
tied to painting but updating. Change this to offer 4 signals, for the 4
different stages:

 * before-update - emitted in the beginning before the actual stage
   updating

 * before-paint - emitted before painting if there will be any stage
   painting

 * after-paint - emitted after painting if there was any stage painting

 * after-update - emitted as a last step of updating, no matter whether
   there were any painting or not

Currently there were only one listener, that should only really have
been called if there was any painting, so no changes to listeners are
needed.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
This commit is contained in:
Jonas Ådahl 2020-05-29 20:25:07 +02:00
parent de99dd7eb6
commit 2afe3e9223
3 changed files with 88 additions and 4 deletions

View File

@ -40,7 +40,10 @@ void clutter_stage_paint_view (ClutterStage
ClutterStageView *view, ClutterStageView *view,
const cairo_region_t *redraw_clip); const cairo_region_t *redraw_clip);
void _clutter_stage_emit_after_paint (ClutterStage *stage); void clutter_stage_emit_before_update (ClutterStage *stage);
void clutter_stage_emit_before_paint (ClutterStage *stage);
void clutter_stage_emit_after_paint (ClutterStage *stage);
void clutter_stage_emit_after_update (ClutterStage *stage);
CLUTTER_EXPORT CLUTTER_EXPORT
void _clutter_stage_set_window (ClutterStage *stage, void _clutter_stage_set_window (ClutterStage *stage,

View File

@ -167,7 +167,10 @@ enum
ACTIVATE, ACTIVATE,
DEACTIVATE, DEACTIVATE,
DELETE_EVENT, DELETE_EVENT,
BEFORE_UPDATE,
BEFORE_PAINT,
AFTER_PAINT, AFTER_PAINT,
AFTER_UPDATE,
PAINT_VIEW, PAINT_VIEW,
PRESENTED, PRESENTED,
@ -890,11 +893,29 @@ clutter_stage_paint_view (ClutterStage *stage,
} }
void void
_clutter_stage_emit_after_paint (ClutterStage *stage) clutter_stage_emit_before_update (ClutterStage *stage)
{
g_signal_emit (stage, stage_signals[BEFORE_UPDATE], 0);
}
void
clutter_stage_emit_before_paint (ClutterStage *stage)
{
g_signal_emit (stage, stage_signals[BEFORE_PAINT], 0);
}
void
clutter_stage_emit_after_paint (ClutterStage *stage)
{ {
g_signal_emit (stage, stage_signals[AFTER_PAINT], 0); g_signal_emit (stage, stage_signals[AFTER_PAINT], 0);
} }
void
clutter_stage_emit_after_update (ClutterStage *stage)
{
g_signal_emit (stage, stage_signals[AFTER_UPDATE], 0);
}
static gboolean static gboolean
clutter_stage_get_paint_volume (ClutterActor *self, clutter_stage_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume) ClutterPaintVolume *volume)
@ -1438,6 +1459,8 @@ _clutter_stage_do_update (ClutterStage *stage)
COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update"); COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update");
clutter_stage_emit_before_update (stage);
/* NB: We need to ensure we have an up to date layout *before* we /* NB: We need to ensure we have an up to date layout *before* we
* check or clear the pending redraws flag since a relayout may * check or clear the pending redraws flag since a relayout may
* queue a redraw. * queue a redraw.
@ -1445,7 +1468,10 @@ _clutter_stage_do_update (ClutterStage *stage)
clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage)); clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
if (!priv->redraw_pending) if (!priv->redraw_pending)
{
clutter_stage_emit_after_update (stage);
return FALSE; return FALSE;
}
clutter_stage_update_actor_stage_views (stage); clutter_stage_update_actor_stage_views (stage);
clutter_stage_maybe_finish_queue_redraws (stage); clutter_stage_maybe_finish_queue_redraws (stage);
@ -1469,6 +1495,8 @@ _clutter_stage_do_update (ClutterStage *stage)
clutter_stage_update_devices (stage, devices); clutter_stage_update_devices (stage, devices);
clutter_stage_emit_after_update (stage);
return TRUE; return TRUE;
} }
@ -1997,6 +2025,31 @@ clutter_stage_class_init (ClutterStageClass *klass)
G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN, 1,
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* ClutterStage::before-update:
* @stage: the #ClutterStage
*/
stage_signals[BEFORE_UPDATE] =
g_signal_new (I_("before-update"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/**
* ClutterStage::before-paint:
* @stage: the stage that received the event
*
* The ::before-paint signal is emitted before the stage is painted.
*/
stage_signals[BEFORE_PAINT] =
g_signal_new (I_("before-paint"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/** /**
* ClutterStage::after-paint: * ClutterStage::after-paint:
* @stage: the stage that received the event * @stage: the stage that received the event
@ -2015,6 +2068,18 @@ clutter_stage_class_init (ClutterStageClass *klass)
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/**
* ClutterStage::after-update:
* @stage: the #ClutterStage
*/
stage_signals[AFTER_UPDATE] =
g_signal_new (I_("after-update"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/** /**
* ClutterStage::paint-view: * ClutterStage::paint-view:
* @stage: the stage that received the event * @stage: the stage that received the event

View File

@ -790,11 +790,26 @@ static void
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{ {
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
gboolean has_redraw_clip = FALSE;
gboolean swap_event = FALSE; gboolean swap_event = FALSE;
GList *l; GList *l;
COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)"); COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)");
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{
ClutterStageView *view = l->data;
if (!clutter_stage_view_has_redraw_clip (view))
continue;
has_redraw_clip = TRUE;
break;
}
if (has_redraw_clip)
clutter_stage_emit_before_paint (stage_cogl->wrapper);
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next) for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{ {
ClutterStageView *view = l->data; ClutterStageView *view = l->data;
@ -817,7 +832,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
} }
} }
_clutter_stage_emit_after_paint (stage_cogl->wrapper); if (has_redraw_clip)
clutter_stage_emit_after_paint (stage_cogl->wrapper);
_clutter_stage_window_finish_frame (stage_window); _clutter_stage_window_finish_frame (stage_window);