mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
clutter: Add ClutterPaintVolume argument to ClutterActor::queue_redraw
This is an ABI break, hopefully an unimportant one since this signal/vmethod is barely overridden. The signal has been added an extra ClutterPaintVolume argument, and has been given a boolean return value. The recursion to the parents has been taken out of the default implementation and into the caller, using the returned boolean parameter to control further propagation. Passing the ClutterPaintVolume is easier on performance, as we don't need setting this pointer as gobject data just to retrieve/unset it further in propagation. https://bugzilla.gnome.org/show_bug.cgi?id=782344
This commit is contained in:
parent
8a9a78ec8a
commit
55d168d01a
@ -283,9 +283,6 @@ void _clutter_actor_queue_redraw_full
|
|||||||
const ClutterPaintVolume *volume,
|
const ClutterPaintVolume *volume,
|
||||||
ClutterEffect *effect);
|
ClutterEffect *effect);
|
||||||
|
|
||||||
ClutterPaintVolume * _clutter_actor_get_queue_redraw_clip (ClutterActor *self);
|
|
||||||
void _clutter_actor_set_queue_redraw_clip (ClutterActor *self,
|
|
||||||
ClutterPaintVolume *clip_volume);
|
|
||||||
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
||||||
ClutterPaintVolume *clip);
|
ClutterPaintVolume *clip);
|
||||||
|
|
||||||
|
@ -2689,9 +2689,12 @@ clutter_actor_real_allocate (ClutterActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_clutter_actor_signal_queue_redraw (ClutterActor *self,
|
_clutter_actor_propagate_queue_redraw (ClutterActor *self,
|
||||||
ClutterActor *origin)
|
ClutterActor *origin,
|
||||||
|
ClutterPaintVolume *pv)
|
||||||
{
|
{
|
||||||
|
gboolean stop = FALSE;
|
||||||
|
|
||||||
/* no point in queuing a redraw on a destroyed actor */
|
/* no point in queuing a redraw on a destroyed actor */
|
||||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||||
return;
|
return;
|
||||||
@ -2700,27 +2703,33 @@ _clutter_actor_signal_queue_redraw (ClutterActor *self,
|
|||||||
* the actor bas been cloned. In this case the clone will need to
|
* the actor bas been cloned. In this case the clone will need to
|
||||||
* receive the signal so it can queue its own redraw.
|
* receive the signal so it can queue its own redraw.
|
||||||
*/
|
*/
|
||||||
|
while (self)
|
||||||
|
{
|
||||||
_clutter_actor_queue_redraw_on_clones (self);
|
_clutter_actor_queue_redraw_on_clones (self);
|
||||||
|
|
||||||
/* calls klass->queue_redraw in default handler */
|
/* calls klass->queue_redraw in default handler */
|
||||||
if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW],
|
if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW],
|
||||||
0, TRUE))
|
0, TRUE))
|
||||||
{
|
{
|
||||||
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
|
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin, pv, &stop);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin);
|
stop = CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin, pv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stop)
|
||||||
|
break;
|
||||||
|
|
||||||
|
self = clutter_actor_get_parent (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
clutter_actor_real_queue_redraw (ClutterActor *self,
|
clutter_actor_real_queue_redraw (ClutterActor *self,
|
||||||
ClutterActor *origin)
|
ClutterActor *origin,
|
||||||
|
ClutterPaintVolume *paint_volume)
|
||||||
{
|
{
|
||||||
ClutterActor *parent;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (PAINT, "Redraw queued on '%s' (from: '%s')",
|
CLUTTER_NOTE (PAINT, "Redraw queued on '%s' (from: '%s')",
|
||||||
_clutter_actor_get_debug_name (self),
|
_clutter_actor_get_debug_name (self),
|
||||||
origin != NULL ? _clutter_actor_get_debug_name (origin)
|
origin != NULL ? _clutter_actor_get_debug_name (origin)
|
||||||
@ -2728,7 +2737,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
|
|||||||
|
|
||||||
/* no point in queuing a redraw on a destroyed actor */
|
/* no point in queuing a redraw on a destroyed actor */
|
||||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
/* If the queue redraw is coming from a child then the actor has
|
/* If the queue redraw is coming from a child then the actor has
|
||||||
become dirty and any queued effect is no longer valid */
|
become dirty and any queued effect is no longer valid */
|
||||||
@ -2743,7 +2752,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
|
|||||||
* won't change so we don't have to propagate up the hierarchy.
|
* won't change so we don't have to propagate up the hierarchy.
|
||||||
*/
|
*/
|
||||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
|
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
/* Although we could determine here that a full stage redraw
|
/* Although we could determine here that a full stage redraw
|
||||||
* has already been queued and immediately bail out, we actually
|
* has already been queued and immediately bail out, we actually
|
||||||
@ -2757,7 +2766,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
|
|||||||
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
|
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
|
||||||
if (stage != NULL &&
|
if (stage != NULL &&
|
||||||
_clutter_stage_has_full_redraw_queued (CLUTTER_STAGE (stage)))
|
_clutter_stage_has_full_redraw_queued (CLUTTER_STAGE (stage)))
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->priv->propagated_one_redraw = TRUE;
|
self->priv->propagated_one_redraw = TRUE;
|
||||||
@ -2765,12 +2774,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
|
|||||||
/* notify parents, if they are all visible eventually we'll
|
/* notify parents, if they are all visible eventually we'll
|
||||||
* queue redraw on the stage, which queues the redraw idle.
|
* queue redraw on the stage, which queues the redraw idle.
|
||||||
*/
|
*/
|
||||||
parent = clutter_actor_get_parent (self);
|
return FALSE;
|
||||||
if (parent != NULL)
|
|
||||||
{
|
|
||||||
/* this will go up recursively */
|
|
||||||
_clutter_actor_signal_queue_redraw (parent, origin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -8063,10 +8067,12 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
|||||||
G_SIGNAL_RUN_LAST |
|
G_SIGNAL_RUN_LAST |
|
||||||
G_SIGNAL_NO_HOOKS,
|
G_SIGNAL_NO_HOOKS,
|
||||||
G_STRUCT_OFFSET (ClutterActorClass, queue_redraw),
|
G_STRUCT_OFFSET (ClutterActorClass, queue_redraw),
|
||||||
NULL, NULL,
|
g_signal_accumulator_true_handled,
|
||||||
_clutter_marshal_VOID__OBJECT,
|
NULL,
|
||||||
G_TYPE_NONE, 1,
|
_clutter_marshal_BOOLEAN__OBJECT_BOXED,
|
||||||
CLUTTER_TYPE_ACTOR);
|
G_TYPE_BOOLEAN, 2,
|
||||||
|
CLUTTER_TYPE_ACTOR,
|
||||||
|
CLUTTER_TYPE_PAINT_VOLUME);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterActor::queue-relayout:
|
* ClutterActor::queue-relayout:
|
||||||
@ -8665,8 +8671,7 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
|||||||
ClutterPaintVolume *clip)
|
ClutterPaintVolume *clip)
|
||||||
{
|
{
|
||||||
ClutterActorPrivate *priv = self->priv;
|
ClutterActorPrivate *priv = self->priv;
|
||||||
ClutterPaintVolume *pv;
|
ClutterPaintVolume *pv = NULL;
|
||||||
gboolean clipped;
|
|
||||||
|
|
||||||
/* Remove queue entry early in the process, otherwise a new
|
/* Remove queue entry early in the process, otherwise a new
|
||||||
queue_redraw() during signal handling could put back this
|
queue_redraw() during signal handling could put back this
|
||||||
@ -8693,8 +8698,7 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
|||||||
*/
|
*/
|
||||||
if (clip)
|
if (clip)
|
||||||
{
|
{
|
||||||
_clutter_actor_set_queue_redraw_clip (self, clip);
|
pv = clip;
|
||||||
clipped = TRUE;
|
|
||||||
}
|
}
|
||||||
else if (G_LIKELY (priv->last_paint_volume_valid))
|
else if (G_LIKELY (priv->last_paint_volume_valid))
|
||||||
{
|
{
|
||||||
@ -8704,36 +8708,12 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
|||||||
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
|
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
|
||||||
|
|
||||||
/* make sure we redraw the actors old position... */
|
/* make sure we redraw the actors old position... */
|
||||||
_clutter_actor_set_queue_redraw_clip (stage,
|
_clutter_actor_propagate_queue_redraw (stage, stage,
|
||||||
&priv->last_paint_volume);
|
&priv->last_paint_volume);
|
||||||
_clutter_actor_signal_queue_redraw (stage, stage);
|
|
||||||
_clutter_actor_set_queue_redraw_clip (stage, NULL);
|
|
||||||
|
|
||||||
/* XXX: Ideally the redraw signal would take a clip volume
|
|
||||||
* argument, but that would be an ABI break. Until we can
|
|
||||||
* break the ABI we pass the argument out-of-band
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* setup the clip for the actors new position... */
|
|
||||||
_clutter_actor_set_queue_redraw_clip (self, pv);
|
|
||||||
clipped = TRUE;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
clipped = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
clipped = FALSE;
|
|
||||||
|
|
||||||
_clutter_actor_signal_queue_redraw (self, self);
|
_clutter_actor_propagate_queue_redraw (self, self, pv);
|
||||||
|
|
||||||
/* Just in case anyone is manually firing redraw signals without
|
|
||||||
* using the public queue_redraw() API we are careful to ensure that
|
|
||||||
* our out-of-band clip member is cleared before returning...
|
|
||||||
*
|
|
||||||
* Note: A NULL clip denotes a full-stage, un-clipped redraw
|
|
||||||
*/
|
|
||||||
if (G_LIKELY (clipped))
|
|
||||||
_clutter_actor_set_queue_redraw_clip (self, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -8893,8 +8873,7 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
|
|||||||
{
|
{
|
||||||
/* NB: NULL denotes an undefined clip which will result in a
|
/* NB: NULL denotes an undefined clip which will result in a
|
||||||
* full redraw... */
|
* full redraw... */
|
||||||
_clutter_actor_set_queue_redraw_clip (self, NULL);
|
_clutter_actor_propagate_queue_redraw (self, self, NULL);
|
||||||
_clutter_actor_signal_queue_redraw (self, self);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16704,26 +16683,6 @@ clutter_actor_has_pointer (ClutterActor *self)
|
|||||||
return self->priv->has_pointer;
|
return self->priv->has_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: This is a workaround for not being able to break the ABI of
|
|
||||||
* the QUEUE_REDRAW signal. It is an out-of-band argument. See
|
|
||||||
* clutter_actor_queue_clipped_redraw() for details.
|
|
||||||
*/
|
|
||||||
ClutterPaintVolume *
|
|
||||||
_clutter_actor_get_queue_redraw_clip (ClutterActor *self)
|
|
||||||
{
|
|
||||||
return g_object_get_data (G_OBJECT (self),
|
|
||||||
"-clutter-actor-queue-redraw-clip");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_clutter_actor_set_queue_redraw_clip (ClutterActor *self,
|
|
||||||
ClutterPaintVolume *clip)
|
|
||||||
{
|
|
||||||
g_object_set_data (G_OBJECT (self),
|
|
||||||
"-clutter-actor-queue-redraw-clip",
|
|
||||||
clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_actor_has_allocation:
|
* clutter_actor_has_allocation:
|
||||||
* @self: a #ClutterActor
|
* @self: a #ClutterActor
|
||||||
|
@ -236,8 +236,9 @@ struct _ClutterActorClass
|
|||||||
void (* pick) (ClutterActor *actor,
|
void (* pick) (ClutterActor *actor,
|
||||||
const ClutterColor *color);
|
const ClutterColor *color);
|
||||||
|
|
||||||
void (* queue_redraw) (ClutterActor *actor,
|
gboolean (* queue_redraw) (ClutterActor *actor,
|
||||||
ClutterActor *leaf_that_queued);
|
ClutterActor *leaf_that_queued,
|
||||||
|
ClutterPaintVolume *paint_volume);
|
||||||
|
|
||||||
/* size negotiation */
|
/* size negotiation */
|
||||||
void (* get_preferred_width) (ClutterActor *self,
|
void (* get_preferred_width) (ClutterActor *self,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
BOOLEAN:BOXED
|
BOOLEAN:BOXED
|
||||||
BOOLEAN:BOXED,INT,INT
|
BOOLEAN:BOXED,INT,INT
|
||||||
BOOLEAN:OBJECT,BOOLEAN
|
BOOLEAN:OBJECT,BOOLEAN
|
||||||
|
BOOLEAN:OBJECT,BOXED
|
||||||
BOOLEAN:OBJECT,BOXED,DOUBLE
|
BOOLEAN:OBJECT,BOXED,DOUBLE
|
||||||
BOOLEAN:OBJECT,DOUBLE
|
BOOLEAN:OBJECT,DOUBLE
|
||||||
BOOLEAN:OBJECT,ENUM
|
BOOLEAN:OBJECT,ENUM
|
||||||
|
@ -1274,45 +1274,44 @@ clutter_stage_real_queue_relayout (ClutterActor *self)
|
|||||||
parent_class->queue_relayout (self);
|
parent_class->queue_relayout (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
clutter_stage_real_queue_redraw (ClutterActor *actor,
|
clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||||
ClutterActor *leaf)
|
ClutterActor *leaf,
|
||||||
|
ClutterPaintVolume *redraw_clip)
|
||||||
{
|
{
|
||||||
ClutterStage *stage = CLUTTER_STAGE (actor);
|
ClutterStage *stage = CLUTTER_STAGE (actor);
|
||||||
ClutterStageWindow *stage_window;
|
ClutterStageWindow *stage_window;
|
||||||
ClutterPaintVolume *redraw_clip;
|
|
||||||
ClutterActorBox bounding_box;
|
ClutterActorBox bounding_box;
|
||||||
ClutterActorBox intersection_box;
|
ClutterActorBox intersection_box;
|
||||||
cairo_rectangle_int_t geom, stage_clip;
|
cairo_rectangle_int_t geom, stage_clip;
|
||||||
|
|
||||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (actor))
|
if (CLUTTER_ACTOR_IN_DESTRUCTION (actor))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
/* If the backend can't do anything with redraw clips (e.g. it already knows
|
/* If the backend can't do anything with redraw clips (e.g. it already knows
|
||||||
* it needs to redraw everything anyway) then don't spend time transforming
|
* it needs to redraw everything anyway) then don't spend time transforming
|
||||||
* any clip volume into stage coordinates... */
|
* any clip volume into stage coordinates... */
|
||||||
stage_window = _clutter_stage_get_window (stage);
|
stage_window = _clutter_stage_get_window (stage);
|
||||||
if (stage_window == NULL)
|
if (stage_window == NULL)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
|
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
|
||||||
{
|
{
|
||||||
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the clip volume into stage coordinates and then into an
|
/* Convert the clip volume into stage coordinates and then into an
|
||||||
* axis aligned stage coordinates bounding box...
|
* axis aligned stage coordinates bounding box...
|
||||||
*/
|
*/
|
||||||
redraw_clip = _clutter_actor_get_queue_redraw_clip (leaf);
|
|
||||||
if (redraw_clip == NULL)
|
if (redraw_clip == NULL)
|
||||||
{
|
{
|
||||||
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redraw_clip->is_empty)
|
if (redraw_clip->is_empty)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
_clutter_paint_volume_get_stage_paint_box (redraw_clip,
|
_clutter_paint_volume_get_stage_paint_box (redraw_clip,
|
||||||
stage,
|
stage,
|
||||||
@ -1328,7 +1327,7 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
|
|||||||
/* There is no need to track degenerate/empty redraw clips */
|
/* There is no need to track degenerate/empty redraw clips */
|
||||||
if (intersection_box.x2 <= intersection_box.x1 ||
|
if (intersection_box.x2 <= intersection_box.x1 ||
|
||||||
intersection_box.y2 <= intersection_box.y1)
|
intersection_box.y2 <= intersection_box.y1)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
/* when converting to integer coordinates make sure we round the edges of the
|
/* when converting to integer coordinates make sure we round the edges of the
|
||||||
* clip rectangle outwards... */
|
* clip rectangle outwards... */
|
||||||
@ -1338,6 +1337,7 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
|
|||||||
stage_clip.height = intersection_box.y2 - stage_clip.y;
|
stage_clip.height = intersection_box.y2 - stage_clip.y;
|
||||||
|
|
||||||
_clutter_stage_window_add_redraw_clip (stage_window, &stage_clip);
|
_clutter_stage_window_add_redraw_clip (stage_window, &stage_clip);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
Loading…
Reference in New Issue
Block a user