mirror of
https://github.com/brl/mutter.git
synced 2024-12-29 14:22:13 +00:00
[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) */
|
/* cached allocation is invalid (request has changed, probably) */
|
||||||
guint needs_allocation : 1;
|
guint needs_allocation : 1;
|
||||||
|
|
||||||
|
guint queued_redraw : 1;
|
||||||
|
|
||||||
guint show_on_set_parent : 1;
|
guint show_on_set_parent : 1;
|
||||||
guint has_clip : 1;
|
guint has_clip : 1;
|
||||||
guint clip_to_allocation : 1;
|
guint clip_to_allocation : 1;
|
||||||
@ -379,7 +381,7 @@ enum
|
|||||||
PICK,
|
PICK,
|
||||||
REALIZE,
|
REALIZE,
|
||||||
UNREALIZE,
|
UNREALIZE,
|
||||||
|
QUEUE_REDRAW,
|
||||||
EVENT,
|
EVENT,
|
||||||
CAPTURED_EVENT,
|
CAPTURED_EVENT,
|
||||||
BUTTON_PRESS_EVENT,
|
BUTTON_PRESS_EVENT,
|
||||||
@ -881,6 +883,49 @@ clutter_actor_real_allocate (ClutterActor *self,
|
|||||||
g_object_thaw_notify (G_OBJECT (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 */
|
/* like ClutterVertex, but with a w component */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gfloat x;
|
gfloat x;
|
||||||
@ -1571,6 +1616,7 @@ clutter_actor_paint (ClutterActor *self)
|
|||||||
{
|
{
|
||||||
clutter_actor_shader_pre_paint (self, FALSE);
|
clutter_actor_shader_pre_paint (self, FALSE);
|
||||||
|
|
||||||
|
self->priv->queued_redraw = FALSE;
|
||||||
g_signal_emit (self, actor_signals[PAINT], 0);
|
g_signal_emit (self, actor_signals[PAINT], 0);
|
||||||
|
|
||||||
clutter_actor_shader_post_paint (self);
|
clutter_actor_shader_post_paint (self);
|
||||||
@ -2890,6 +2936,66 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
|||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
CLUTTER_TYPE_ACTOR);
|
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:
|
* ClutterActor::event:
|
||||||
* @actor: the actor which received the 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_width = clutter_actor_real_get_preferred_width;
|
||||||
klass->get_preferred_height = clutter_actor_real_get_preferred_height;
|
klass->get_preferred_height = clutter_actor_real_get_preferred_height;
|
||||||
klass->allocate = clutter_actor_real_allocate;
|
klass->allocate = clutter_actor_real_allocate;
|
||||||
|
klass->queue_redraw = clutter_actor_real_queue_redraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3329,22 +3436,9 @@ clutter_actor_destroy (ClutterActor *self)
|
|||||||
void
|
void
|
||||||
clutter_actor_queue_redraw (ClutterActor *self)
|
clutter_actor_queue_redraw (ClutterActor *self)
|
||||||
{
|
{
|
||||||
ClutterActor *stage;
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||||
|
|
||||||
/* short-circuit the trivial case */
|
clutter_actor_queue_redraw_with_origin (self, self);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,6 +227,9 @@ struct _ClutterActorClass
|
|||||||
void (* pick) (ClutterActor *actor,
|
void (* pick) (ClutterActor *actor,
|
||||||
const ClutterColor *color);
|
const ClutterColor *color);
|
||||||
|
|
||||||
|
void (* queue_redraw) (ClutterActor *actor,
|
||||||
|
ClutterActor *leaf_that_queued);
|
||||||
|
|
||||||
/* size negotiation */
|
/* size negotiation */
|
||||||
void (* get_preferred_width) (ClutterActor *actor,
|
void (* get_preferred_width) (ClutterActor *actor,
|
||||||
ClutterUnit for_height,
|
ClutterUnit for_height,
|
||||||
|
@ -116,7 +116,6 @@ enum
|
|||||||
UNFULLSCREEN,
|
UNFULLSCREEN,
|
||||||
ACTIVATE,
|
ACTIVATE,
|
||||||
DEACTIVATE,
|
DEACTIVATE,
|
||||||
QUEUE_REDRAW,
|
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
@ -376,8 +375,10 @@ redraw_update_idle (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
ClutterStagePrivate *priv = stage->priv;
|
||||||
|
|
||||||
if (priv->update_idle == 0)
|
if (priv->update_idle == 0)
|
||||||
@ -585,6 +586,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
actor_class->unrealize = clutter_stage_unrealize;
|
actor_class->unrealize = clutter_stage_unrealize;
|
||||||
actor_class->show = clutter_stage_show;
|
actor_class->show = clutter_stage_show;
|
||||||
actor_class->hide = clutter_stage_hide;
|
actor_class->hide = clutter_stage_hide;
|
||||||
|
actor_class->queue_redraw = clutter_stage_real_queue_redraw;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterStage:fullscreen:
|
* ClutterStage:fullscreen:
|
||||||
@ -777,58 +779,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
clutter_marshal_VOID__VOID,
|
clutter_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE, 0);
|
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->fullscreen = clutter_stage_real_fullscreen;
|
||||||
klass->queue_redraw = clutter_stage_real_queue_redraw;
|
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
|
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_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
|
* <note>Applications should call clutter_actor_queue_redraw() and not
|
||||||
* this function.</note>
|
* this function.</note>
|
||||||
*
|
*
|
||||||
|
* <note>This function is just a wrapper for clutter_actor_queue_redraw()
|
||||||
|
* and should probably go away.</note>
|
||||||
|
*
|
||||||
* Since: 0.8
|
* Since: 0.8
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -1812,7 +1767,7 @@ clutter_stage_queue_redraw (ClutterStage *stage)
|
|||||||
{
|
{
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (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 (* activate) (ClutterStage *stage);
|
||||||
void (* deactivate) (ClutterStage *stage);
|
void (* deactivate) (ClutterStage *stage);
|
||||||
|
|
||||||
void (* queue_redraw) (ClutterStage *stage);
|
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* padding for future expansion */
|
/* padding for future expansion */
|
||||||
gpointer _padding_dummy[32];
|
gpointer _padding_dummy[32];
|
||||||
|
Loading…
Reference in New Issue
Block a user