[actor] Add ::queue-redraw signal
Bug 1454 - move queue_redraw virtualization to ClutterActor The ClutterActor::queue-redraw signal allows parent containers to track whether their children need a redraw. Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:
parent
5706105123
commit
961aac3fb3
@ -244,6 +244,8 @@ struct _ClutterActorPrivate
|
||||
/* cached allocation is invalid (request has changed, probably) */
|
||||
guint needs_allocation : 1;
|
||||
|
||||
guint queued_redraw : 1;
|
||||
|
||||
guint show_on_set_parent : 1;
|
||||
guint has_clip : 1;
|
||||
guint clip_to_allocation : 1;
|
||||
@ -379,7 +381,7 @@ enum
|
||||
PICK,
|
||||
REALIZE,
|
||||
UNREALIZE,
|
||||
|
||||
QUEUE_REDRAW,
|
||||
EVENT,
|
||||
CAPTURED_EVENT,
|
||||
BUTTON_PRESS_EVENT,
|
||||
@ -881,6 +883,49 @@ clutter_actor_real_allocate (ClutterActor *self,
|
||||
g_object_thaw_notify (G_OBJECT (self));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_queue_redraw_with_origin (ClutterActor *self,
|
||||
ClutterActor *origin)
|
||||
{
|
||||
/* short-circuit the trivial case */
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE(self))
|
||||
return;
|
||||
|
||||
/* already queued since last paint() */
|
||||
if (self->priv->queued_redraw)
|
||||
return;
|
||||
|
||||
/* calls klass->queue_redraw in default handler */
|
||||
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_real_queue_redraw (ClutterActor *self,
|
||||
ClutterActor *origin)
|
||||
{
|
||||
ClutterActor *parent;
|
||||
|
||||
/* short-circuit the trivial case */
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
|
||||
return;
|
||||
|
||||
/* already queued since last paint() */
|
||||
if (self->priv->queued_redraw)
|
||||
return;
|
||||
|
||||
self->priv->queued_redraw = TRUE;
|
||||
|
||||
/* notify parents, if they are all visible eventually we'll
|
||||
* queue redraw on the stage, which queues the redraw idle.
|
||||
*/
|
||||
parent = clutter_actor_get_parent (self);
|
||||
if (parent != NULL)
|
||||
{
|
||||
/* this will go up recursively */
|
||||
clutter_actor_queue_redraw_with_origin (parent, origin);
|
||||
}
|
||||
}
|
||||
|
||||
/* like ClutterVertex, but with a w component */
|
||||
typedef struct {
|
||||
gfloat x;
|
||||
@ -1571,6 +1616,7 @@ clutter_actor_paint (ClutterActor *self)
|
||||
{
|
||||
clutter_actor_shader_pre_paint (self, FALSE);
|
||||
|
||||
self->priv->queued_redraw = FALSE;
|
||||
g_signal_emit (self, actor_signals[PAINT], 0);
|
||||
|
||||
clutter_actor_shader_post_paint (self);
|
||||
@ -2890,6 +2936,66 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
/**
|
||||
* ClutterActor::queue-redraw:
|
||||
* @actor: the actor we're bubbling the redraw request through
|
||||
* @origin: the actor which initiated the redraw request
|
||||
*
|
||||
* The ::queue_redraw signal is emitted when clutter_actor_queue_redraw()
|
||||
* is called on @origin.
|
||||
*
|
||||
* The default implementation for #ClutterActor chains up to the
|
||||
* parent actor and queues a redraw on the parent, thus "bubbling"
|
||||
* the redraw queue up through the actor graph. The default
|
||||
* implementation for #ClutterStage queues a clutter_redraw() in a
|
||||
* main loop idle handler.
|
||||
*
|
||||
* Note that the @origin actor may be the stage, or a container; it
|
||||
* does not have to be a leaf node in the actor graph.
|
||||
*
|
||||
* Toolkits embedding a #ClutterStage which require a redraw and
|
||||
* relayout cycle can stop the emission of this signal using the
|
||||
* GSignal API, redraw the UI and then call clutter_redraw()
|
||||
* themselves, like:
|
||||
*
|
||||
* |[
|
||||
* static void
|
||||
* on_redraw_complete (void)
|
||||
* {
|
||||
* /* execute the Clutter drawing pipeline */
|
||||
* clutter_redraw ();
|
||||
* }
|
||||
*
|
||||
* static void
|
||||
* on_stage_queue_redraw (ClutterStage *stage)
|
||||
* {
|
||||
* /* this prevents the default handler to run */
|
||||
* g_signal_stop_emission_by_name (stage, "queue-redraw");
|
||||
*
|
||||
* /* queue a redraw with the host toolkit and call
|
||||
* * a function when the redraw has been completed
|
||||
* */
|
||||
* queue_a_redraw (G_CALLBACK (on_redraw_complete));
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* <note><para>This signal is emitted before the Clutter paint
|
||||
* pipeline is executed. If you want to know when the pipeline has
|
||||
* been completed you should connect to the ::paint signal on the
|
||||
* Stage with g_signal_connect_after().</para></note>
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
actor_signals[QUEUE_REDRAW] =
|
||||
g_signal_new (I_("queue-redraw"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterActorClass, queue_redraw),
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
/**
|
||||
* ClutterActor::event:
|
||||
* @actor: the actor which received the event
|
||||
@ -3247,6 +3353,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
klass->get_preferred_width = clutter_actor_real_get_preferred_width;
|
||||
klass->get_preferred_height = clutter_actor_real_get_preferred_height;
|
||||
klass->allocate = clutter_actor_real_allocate;
|
||||
klass->queue_redraw = clutter_actor_real_queue_redraw;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3329,22 +3436,9 @@ clutter_actor_destroy (ClutterActor *self)
|
||||
void
|
||||
clutter_actor_queue_redraw (ClutterActor *self)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
|
||||
/* short-circuit the trivial case */
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
|
||||
return;
|
||||
|
||||
/* check if any part of the scenegraph we're in
|
||||
* is not visible
|
||||
*/
|
||||
if (!clutter_actor_get_paint_visibility (self))
|
||||
return;
|
||||
|
||||
if ((stage = clutter_actor_get_stage (self)) != NULL)
|
||||
clutter_stage_queue_redraw (CLUTTER_STAGE (stage));
|
||||
clutter_actor_queue_redraw_with_origin (self, self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,6 +227,9 @@ struct _ClutterActorClass
|
||||
void (* pick) (ClutterActor *actor,
|
||||
const ClutterColor *color);
|
||||
|
||||
void (* queue_redraw) (ClutterActor *actor,
|
||||
ClutterActor *leaf_that_queued);
|
||||
|
||||
/* size negotiation */
|
||||
void (* get_preferred_width) (ClutterActor *actor,
|
||||
ClutterUnit for_height,
|
||||
|
@ -116,7 +116,6 @@ enum
|
||||
UNFULLSCREEN,
|
||||
ACTIVATE,
|
||||
DEACTIVATE,
|
||||
QUEUE_REDRAW,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -376,8 +375,10 @@ redraw_update_idle (gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_real_queue_redraw (ClutterStage *stage)
|
||||
clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||
ClutterActor *leaf)
|
||||
{
|
||||
ClutterStage *stage = CLUTTER_STAGE (actor);
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (priv->update_idle == 0)
|
||||
@ -585,6 +586,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
actor_class->unrealize = clutter_stage_unrealize;
|
||||
actor_class->show = clutter_stage_show;
|
||||
actor_class->hide = clutter_stage_hide;
|
||||
actor_class->queue_redraw = clutter_stage_real_queue_redraw;
|
||||
|
||||
/**
|
||||
* ClutterStage:fullscreen:
|
||||
@ -777,58 +779,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterStage::queue-redraw:
|
||||
* @stage: the stage which was queued for redraw
|
||||
*
|
||||
* The ::queue-redraw signal is emitted each time a #ClutterStage
|
||||
* has been queued for a redraw. You can use this signal to know
|
||||
* when clutter_stage_queue_redraw() has been called.
|
||||
*
|
||||
* Toolkits embedding a #ClutterStage which require a redraw and
|
||||
* relayout cycle can stop the emission of this signal using the
|
||||
* GSignal API, redraw the UI and then call clutter_redraw()
|
||||
* themselves, like:
|
||||
*
|
||||
* |[
|
||||
* static void
|
||||
* on_redraw_complete (void)
|
||||
* {
|
||||
* /* execute the Clutter drawing pipeline */
|
||||
* clutter_redraw ();
|
||||
* }
|
||||
*
|
||||
* static void
|
||||
* on_stage_queue_redraw (ClutterStage *stage)
|
||||
* {
|
||||
* /* this prevents the default handler to run */
|
||||
* g_signal_stop_emission_by_name (stage, "queue-redraw");
|
||||
*
|
||||
* /* queue a redraw with the host toolkit and call
|
||||
* * a function when the redraw has been completed
|
||||
* */
|
||||
* queue_a_redraw (G_CALLBACK (on_redraw_complete));
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* <note><para>This signal is emitted before the Clutter paint
|
||||
* pipeline is run. If you want to know when the pipeline has been
|
||||
* completed you should connect to the ::paint signal on the Stage
|
||||
* with g_signal_connect_after().</para></note>
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
stage_signals[QUEUE_REDRAW] =
|
||||
g_signal_new (I_("queue-redraw"),
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterStageClass, queue_redraw),
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
klass->fullscreen = clutter_stage_real_fullscreen;
|
||||
klass->queue_redraw = clutter_stage_real_queue_redraw;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
|
||||
}
|
||||
@ -1793,7 +1745,7 @@ clutter_stage_ensure_viewport (ClutterStage *stage)
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||
|
||||
clutter_stage_queue_redraw (stage);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1805,6 +1757,9 @@ clutter_stage_ensure_viewport (ClutterStage *stage)
|
||||
* <note>Applications should call clutter_actor_queue_redraw() and not
|
||||
* this function.</note>
|
||||
*
|
||||
* <note>This function is just a wrapper for clutter_actor_queue_redraw()
|
||||
* and should probably go away.</note>
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
@ -1812,7 +1767,7 @@ clutter_stage_queue_redraw (ClutterStage *stage)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
g_signal_emit (stage, stage_signals[QUEUE_REDRAW], 0);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,8 +106,6 @@ struct _ClutterStageClass
|
||||
void (* activate) (ClutterStage *stage);
|
||||
void (* deactivate) (ClutterStage *stage);
|
||||
|
||||
void (* queue_redraw) (ClutterStage *stage);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[32];
|
||||
|
Loading…
Reference in New Issue
Block a user