mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
stage: Add a paint callback
The ClutterActor::paint signal is deprecated, and connecting to it even to get notifications will disable clipped redraws because of violations of the paint volume. The only actual valid use case for notifications of a successful frame is on the ClutterStage, so we should add new (experimental) API for it, so that users can actually subscribe to it — at least if you're writing a compositor. Shoving a signal in a performance critical path is not an option, and I'm not sure I want to commit to an API like this yet. I reserve the right to revisit this decision in the future. https://bugzilla.gnome.org/show_bug.cgi?id=698783
This commit is contained in:
parent
264c67c2aa
commit
d061a47573
@ -159,6 +159,10 @@ struct _ClutterStagePrivate
|
||||
|
||||
ClutterStageState current_state;
|
||||
|
||||
ClutterStagePaintFunc paint_callback;
|
||||
gpointer paint_data;
|
||||
GDestroyNotify paint_notify;
|
||||
|
||||
guint relayout_pending : 1;
|
||||
guint redraw_pending : 1;
|
||||
guint is_fullscreen : 1;
|
||||
@ -210,8 +214,9 @@ static guint stage_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static const ClutterColor default_stage_color = { 255, 255, 255, 255 };
|
||||
|
||||
static void _clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage);
|
||||
static void clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage);
|
||||
static void free_queue_redraw_entry (ClutterStageQueueRedrawEntry *entry);
|
||||
static void clutter_stage_invoke_paint_callback (ClutterStage *stage);
|
||||
|
||||
static void
|
||||
clutter_stage_real_add (ClutterContainer *container,
|
||||
@ -669,6 +674,8 @@ _clutter_stage_do_paint (ClutterStage *stage,
|
||||
_clutter_stage_paint_volume_stack_free_all (stage);
|
||||
_clutter_stage_update_active_framebuffer (stage);
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||
|
||||
clutter_stage_invoke_paint_callback (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1226,7 +1233,7 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (!priv->redraw_pending)
|
||||
return FALSE;
|
||||
|
||||
_clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
|
||||
clutter_stage_do_redraw (stage);
|
||||
|
||||
@ -1879,6 +1886,9 @@ clutter_stage_finalize (GObject *object)
|
||||
if (priv->fps_timer != NULL)
|
||||
g_timer_destroy (priv->fps_timer);
|
||||
|
||||
if (priv->paint_notify != NULL)
|
||||
priv->paint_notify (priv->paint_data);
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -4137,7 +4147,7 @@ _clutter_stage_queue_redraw_entry_invalidate (ClutterStageQueueRedrawEntry *entr
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage)
|
||||
clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage)
|
||||
{
|
||||
/* Note: we have to repeat until the pending_queue_redraws list is
|
||||
* empty because actors are allowed to queue redraws in response to
|
||||
@ -4581,3 +4591,42 @@ clutter_stage_skip_sync_delay (ClutterStage *stage)
|
||||
if (stage_window)
|
||||
_clutter_stage_window_schedule_update (stage_window, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_set_paint_callback:
|
||||
* @stage: a #ClutterStage
|
||||
* @callback: (allow none): a callback
|
||||
* @data: (allow none): data to be passed to @callback
|
||||
* @notify: (allow none): function to be called when the callback is removed
|
||||
*
|
||||
* Sets a callback function to be invoked after the @stage has been
|
||||
* painted.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
void
|
||||
clutter_stage_set_paint_callback (ClutterStage *stage,
|
||||
ClutterStagePaintFunc callback,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
if (priv->paint_notify != NULL)
|
||||
priv->paint_notify (priv->paint_data);
|
||||
|
||||
priv->paint_callback = callback;
|
||||
priv->paint_data = data;
|
||||
priv->paint_notify = notify;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_invoke_paint_callback (ClutterStage *stage)
|
||||
{
|
||||
if (stage->priv->paint_callback != NULL)
|
||||
stage->priv->paint_callback (stage, stage->priv->paint_data);
|
||||
}
|
||||
|
@ -208,6 +208,15 @@ void clutter_stage_set_sync_delay (ClutterStage
|
||||
gint sync_delay);
|
||||
CLUTTER_AVAILABLE_IN_1_14
|
||||
void clutter_stage_skip_sync_delay (ClutterStage *stage);
|
||||
|
||||
typedef void (* ClutterStagePaintFunc) (ClutterStage *stage,
|
||||
gpointer data);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_14
|
||||
void clutter_stage_set_paint_callback (ClutterStage *stage,
|
||||
ClutterStagePaintFunc callback,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -1284,6 +1284,7 @@ clutter_stage_set_key_focus
|
||||
clutter_stage_set_minimum_size
|
||||
clutter_stage_set_motion_events_enabled
|
||||
clutter_stage_set_no_clear_hint
|
||||
clutter_stage_set_paint_callback
|
||||
clutter_stage_set_perspective
|
||||
clutter_stage_set_sync_delay
|
||||
clutter_stage_set_throttle_motion_events
|
||||
|
Loading…
Reference in New Issue
Block a user