Compare commits
11 Commits
wip/fmuell
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8d75ea69e3 | ||
![]() |
a7ee7559e4 | ||
![]() |
af3475f65f | ||
![]() |
77fd682c8b | ||
![]() |
fa8e4f60f6 | ||
![]() |
b98a8d9932 | ||
![]() |
864bc793aa | ||
![]() |
e5b06754e0 | ||
![]() |
3402c50625 | ||
![]() |
060543466c | ||
![]() |
65e816908a |
@@ -283,9 +283,6 @@ void _clutter_actor_queue_redraw_full
|
|||||||
ClutterPaintVolume *volume,
|
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);
|
||||||
|
|
||||||
|
@@ -840,6 +840,7 @@ struct _ClutterActorPrivate
|
|||||||
guint needs_compute_expand : 1;
|
guint needs_compute_expand : 1;
|
||||||
guint needs_x_expand : 1;
|
guint needs_x_expand : 1;
|
||||||
guint needs_y_expand : 1;
|
guint needs_y_expand : 1;
|
||||||
|
guint needs_paint_volume_update : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@@ -2619,6 +2620,7 @@ clutter_actor_real_allocate (ClutterActor *self,
|
|||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
changed = clutter_actor_set_allocation_internal (self, box, flags);
|
changed = clutter_actor_set_allocation_internal (self, box, flags);
|
||||||
|
priv->needs_paint_volume_update = changed;
|
||||||
|
|
||||||
/* we allocate our children before we notify changes in our geometry,
|
/* we allocate our children before we notify changes in our geometry,
|
||||||
* so that people connecting to properties will be able to get valid
|
* so that people connecting to properties will be able to get valid
|
||||||
@@ -2641,9 +2643,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;
|
||||||
@@ -2652,27 +2657,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 */
|
||||||
|
if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW],
|
||||||
/* calls klass->queue_redraw in default handler */
|
|
||||||
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)
|
||||||
@@ -2680,13 +2691,14 @@ 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 */
|
||||||
if (self != origin)
|
if (self != origin)
|
||||||
{
|
{
|
||||||
self->priv->is_dirty = TRUE;
|
self->priv->is_dirty = TRUE;
|
||||||
|
self->priv->needs_paint_volume_update = TRUE;
|
||||||
self->priv->effect_to_redraw = NULL;
|
self->priv->effect_to_redraw = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2695,7 +2707,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
|
||||||
@@ -2709,7 +2721,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;
|
||||||
@@ -2717,12 +2729,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
|
||||||
@@ -8011,10 +8018,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:
|
||||||
@@ -8519,6 +8528,7 @@ clutter_actor_init (ClutterActor *self)
|
|||||||
priv->needs_width_request = TRUE;
|
priv->needs_width_request = TRUE;
|
||||||
priv->needs_height_request = TRUE;
|
priv->needs_height_request = TRUE;
|
||||||
priv->needs_allocation = TRUE;
|
priv->needs_allocation = TRUE;
|
||||||
|
priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
priv->cached_width_age = 1;
|
priv->cached_width_age = 1;
|
||||||
priv->cached_height_age = 1;
|
priv->cached_height_age = 1;
|
||||||
@@ -8612,8 +8622,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
|
||||||
@@ -8640,8 +8649,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))
|
||||||
{
|
{
|
||||||
@@ -8651,36 +8659,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
|
||||||
@@ -8841,8 +8825,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8916,6 +8899,7 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->is_dirty = TRUE;
|
priv->is_dirty = TRUE;
|
||||||
|
priv->needs_paint_volume_update = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12973,6 +12957,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
|
|||||||
child->priv->needs_width_request = TRUE;
|
child->priv->needs_width_request = TRUE;
|
||||||
child->priv->needs_height_request = TRUE;
|
child->priv->needs_height_request = TRUE;
|
||||||
child->priv->needs_allocation = TRUE;
|
child->priv->needs_allocation = TRUE;
|
||||||
|
child->priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
/* we only queue a relayout here, because any possible
|
/* we only queue a relayout here, because any possible
|
||||||
* redraw has already been queued either by show() or
|
* redraw has already been queued either by show() or
|
||||||
@@ -16650,26 +16635,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
|
||||||
@@ -17516,16 +17481,22 @@ _clutter_actor_get_paint_volume_mutable (ClutterActor *self)
|
|||||||
priv = self->priv;
|
priv = self->priv;
|
||||||
|
|
||||||
if (priv->paint_volume_valid)
|
if (priv->paint_volume_valid)
|
||||||
clutter_paint_volume_free (&priv->paint_volume);
|
{
|
||||||
|
if (!priv->needs_paint_volume_update)
|
||||||
|
return &priv->paint_volume;
|
||||||
|
clutter_paint_volume_free (&priv->paint_volume);
|
||||||
|
}
|
||||||
|
|
||||||
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
|
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
|
||||||
{
|
{
|
||||||
priv->paint_volume_valid = TRUE;
|
priv->paint_volume_valid = TRUE;
|
||||||
|
priv->needs_paint_volume_update = FALSE;
|
||||||
return &priv->paint_volume;
|
return &priv->paint_volume;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
priv->paint_volume_valid = FALSE;
|
priv->paint_volume_valid = FALSE;
|
||||||
|
priv->needs_paint_volume_update = FALSE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -1166,6 +1166,21 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
|
|||||||
|
|
||||||
_clutter_paint_volume_get_bounding_box (&projected_pv, box);
|
_clutter_paint_volume_get_bounding_box (&projected_pv, box);
|
||||||
|
|
||||||
|
if (pv->is_2d && pv->actor &&
|
||||||
|
clutter_actor_get_z_position (pv->actor) == 0)
|
||||||
|
{
|
||||||
|
/* If the volume/actor are perfectly 2D, take the bounding box as
|
||||||
|
* good. We won't need to add any extra room for sub-pixel positioning
|
||||||
|
* in this case.
|
||||||
|
*/
|
||||||
|
clutter_paint_volume_free (&projected_pv);
|
||||||
|
box->x1 = CLUTTER_NEARBYINT (box->x1);
|
||||||
|
box->y1 = CLUTTER_NEARBYINT (box->y1);
|
||||||
|
box->x2 = CLUTTER_NEARBYINT (box->x2);
|
||||||
|
box->y2 = CLUTTER_NEARBYINT (box->y2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* The aim here is that for a given rectangle defined with floating point
|
/* The aim here is that for a given rectangle defined with floating point
|
||||||
* coordinates we want to determine a stable quantized size in pixels
|
* coordinates we want to determine a stable quantized size in pixels
|
||||||
* that doesn't vary due to the original box's sub-pixel position.
|
* that doesn't vary due to the original box's sub-pixel position.
|
||||||
|
@@ -231,19 +231,35 @@ _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
cairo_region_t *
|
||||||
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
_clutter_stage_window_get_redraw_clip (ClutterStageWindow *window)
|
||||||
cairo_rectangle_int_t *stage_clip)
|
|
||||||
{
|
{
|
||||||
ClutterStageWindowIface *iface;
|
ClutterStageWindowIface *iface;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
||||||
|
|
||||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||||
if (iface->get_redraw_clip_bounds != NULL)
|
if (iface->get_redraw_clip != NULL)
|
||||||
return iface->get_redraw_clip_bounds (window, stage_clip);
|
return iface->get_redraw_clip (window);
|
||||||
|
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
||||||
|
cairo_rectangle_int_t *stage_clip)
|
||||||
|
{
|
||||||
|
cairo_region_t *redraw_clip;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
|
||||||
|
|
||||||
|
redraw_clip = _clutter_stage_window_get_redraw_clip (window);
|
||||||
|
if (!redraw_clip)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cairo_region_get_extents (redraw_clip, stage_clip);
|
||||||
|
cairo_region_destroy (redraw_clip);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -68,9 +68,7 @@ struct _ClutterStageWindowIface
|
|||||||
cairo_rectangle_int_t *stage_rectangle);
|
cairo_rectangle_int_t *stage_rectangle);
|
||||||
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
|
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
|
||||||
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
|
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
|
||||||
gboolean (* get_redraw_clip_bounds) (ClutterStageWindow *stage_window,
|
cairo_region_t * (* get_redraw_clip) (ClutterStageWindow *stage_window);
|
||||||
cairo_rectangle_int_t *clip);
|
|
||||||
|
|
||||||
|
|
||||||
void (* set_accept_focus) (ClutterStageWindow *stage_window,
|
void (* set_accept_focus) (ClutterStageWindow *stage_window,
|
||||||
gboolean accept_focus);
|
gboolean accept_focus);
|
||||||
@@ -125,6 +123,7 @@ gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWin
|
|||||||
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
|
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
|
||||||
gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
|
||||||
cairo_rectangle_int_t *clip);
|
cairo_rectangle_int_t *clip);
|
||||||
|
cairo_region_t * _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window);
|
||||||
|
|
||||||
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
||||||
gboolean accept_focus);
|
gboolean accept_focus);
|
||||||
|
@@ -1199,45 +1199,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,
|
||||||
@@ -1253,7 +1252,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... */
|
||||||
@@ -1263,6 +1262,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
|
||||||
@@ -1315,6 +1315,31 @@ clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_t *
|
||||||
|
clutter_stage_get_redraw_clip (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
ClutterStagePrivate *priv;
|
||||||
|
cairo_rectangle_int_t clip;
|
||||||
|
cairo_region_t *region;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||||
|
|
||||||
|
priv = stage->priv;
|
||||||
|
|
||||||
|
region = _clutter_stage_window_get_redraw_clip (priv->impl);
|
||||||
|
if (region)
|
||||||
|
return region;
|
||||||
|
|
||||||
|
if (!region)
|
||||||
|
{
|
||||||
|
/* Set clip to the full extents of the stage */
|
||||||
|
_clutter_stage_window_get_geometry (priv->impl, &clip);
|
||||||
|
region = cairo_region_create_rectangle (&clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_pixels_to_file (char *filename_stem,
|
read_pixels_to_file (char *filename_stem,
|
||||||
int x,
|
int x,
|
||||||
|
@@ -245,6 +245,9 @@ guchar * clutter_stage_read_pixels (ClutterStage
|
|||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
|
||||||
cairo_rectangle_int_t *clip);
|
cairo_rectangle_int_t *clip);
|
||||||
|
CLUTTER_AVAILABLE_IN_MUTTER
|
||||||
|
cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage);
|
||||||
|
|
||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
void clutter_stage_ensure_viewport (ClutterStage *stage);
|
void clutter_stage_ensure_viewport (ClutterStage *stage);
|
||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
|
@@ -54,7 +54,7 @@ typedef struct _ClutterStageViewCoglPrivate
|
|||||||
/* Stores a list of previous damaged areas in the stage coordinate space */
|
/* Stores a list of previous damaged areas in the stage coordinate space */
|
||||||
#define DAMAGE_HISTORY_MAX 16
|
#define DAMAGE_HISTORY_MAX 16
|
||||||
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
||||||
cairo_rectangle_int_t damage_history[DAMAGE_HISTORY_MAX];
|
cairo_region_t * damage_history[DAMAGE_HISTORY_MAX];
|
||||||
unsigned int damage_index;
|
unsigned int damage_index;
|
||||||
} ClutterStageViewCoglPrivate;
|
} ClutterStageViewCoglPrivate;
|
||||||
|
|
||||||
@@ -246,13 +246,10 @@ clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window)
|
|||||||
/* NB: at the start of each new frame there is an implied clip that
|
/* NB: at the start of each new frame there is an implied clip that
|
||||||
* clips everything (i.e. nothing would be drawn) so we need to make
|
* clips everything (i.e. nothing would be drawn) so we need to make
|
||||||
* sure we return True in the un-initialized case here.
|
* sure we return True in the un-initialized case here.
|
||||||
*
|
|
||||||
* NB: a clip width of 0 means a full stage redraw has been queued
|
|
||||||
* so we effectively don't have any redraw clips in that case.
|
|
||||||
*/
|
*/
|
||||||
if (!stage_cogl->initialized_redraw_clip ||
|
if (!stage_cogl->initialized_redraw_clip ||
|
||||||
(stage_cogl->initialized_redraw_clip &&
|
(stage_cogl->initialized_redraw_clip &&
|
||||||
stage_cogl->bounding_redraw_clip.width != 0))
|
stage_cogl->redraw_clip))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -263,9 +260,9 @@ clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
|
|||||||
{
|
{
|
||||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||||
|
|
||||||
/* NB: a clip width of 0 means a full stage redraw is required */
|
/* NB: a NULL clip means a full stage redraw is required */
|
||||||
if (stage_cogl->initialized_redraw_clip &&
|
if (stage_cogl->initialized_redraw_clip &&
|
||||||
stage_cogl->bounding_redraw_clip.width == 0)
|
!stage_cogl->redraw_clip)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -296,11 +293,11 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* A NULL stage clip means a full stage redraw has been queued and
|
/* A NULL stage clip means a full stage redraw has been queued and
|
||||||
* we keep track of this by setting a zero width
|
* we keep track of this by setting a NULL redraw_clip.
|
||||||
* stage_cogl->bounding_redraw_clip */
|
*/
|
||||||
if (stage_clip == NULL)
|
if (stage_clip == NULL)
|
||||||
{
|
{
|
||||||
stage_cogl->bounding_redraw_clip.width = 0;
|
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
|
||||||
stage_cogl->initialized_redraw_clip = TRUE;
|
stage_cogl->initialized_redraw_clip = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,34 +306,27 @@ clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
|
|||||||
if (stage_clip->width == 0 || stage_clip->height == 0)
|
if (stage_clip->width == 0 || stage_clip->height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!stage_cogl->initialized_redraw_clip)
|
if (!stage_cogl->redraw_clip)
|
||||||
{
|
{
|
||||||
stage_cogl->bounding_redraw_clip = *stage_clip;
|
stage_cogl->redraw_clip = cairo_region_create_rectangle (stage_clip);
|
||||||
}
|
}
|
||||||
else if (stage_cogl->bounding_redraw_clip.width > 0)
|
else
|
||||||
{
|
{
|
||||||
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
|
cairo_region_union_rectangle (stage_cogl->redraw_clip, stage_clip);
|
||||||
stage_clip,
|
|
||||||
&stage_cogl->bounding_redraw_clip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stage_cogl->initialized_redraw_clip = TRUE;
|
stage_cogl->initialized_redraw_clip = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static cairo_region_t *
|
||||||
clutter_stage_cogl_get_redraw_clip_bounds (ClutterStageWindow *stage_window,
|
clutter_stage_cogl_get_redraw_clip (ClutterStageWindow *stage_window)
|
||||||
cairo_rectangle_int_t *stage_clip)
|
|
||||||
{
|
{
|
||||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||||
|
|
||||||
if (stage_cogl->using_clipped_redraw)
|
if (stage_cogl->using_clipped_redraw && stage_cogl->redraw_clip)
|
||||||
{
|
return cairo_region_copy (stage_cogl->redraw_clip);
|
||||||
*stage_clip = stage_cogl->bounding_redraw_clip;
|
|
||||||
|
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
@@ -414,37 +404,51 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
|||||||
static void
|
static void
|
||||||
paint_stage (ClutterStageCogl *stage_cogl,
|
paint_stage (ClutterStageCogl *stage_cogl,
|
||||||
ClutterStageView *view,
|
ClutterStageView *view,
|
||||||
const cairo_rectangle_int_t *clip)
|
cairo_region_t *clip)
|
||||||
{
|
{
|
||||||
ClutterStage *stage = stage_cogl->wrapper;
|
ClutterStage *stage = stage_cogl->wrapper;
|
||||||
|
cairo_rectangle_int_t clip_rect;
|
||||||
|
|
||||||
|
cairo_region_get_extents (clip, &clip_rect);
|
||||||
|
|
||||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||||
_clutter_stage_paint_view (stage, view, clip);
|
_clutter_stage_paint_view (stage, view, &clip_rect);
|
||||||
|
|
||||||
if (clutter_stage_view_get_onscreen (view) !=
|
if (clutter_stage_view_get_onscreen (view) !=
|
||||||
clutter_stage_view_get_framebuffer (view))
|
clutter_stage_view_get_framebuffer (view))
|
||||||
{
|
{
|
||||||
clutter_stage_view_blit_offscreen (view, clip);
|
clutter_stage_view_blit_offscreen (view, &clip_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_current_damage_history_and_step (ClutterStageView *view)
|
fill_current_damage_history (ClutterStageView *view,
|
||||||
|
cairo_region_t *damage)
|
||||||
{
|
{
|
||||||
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
|
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
|
||||||
ClutterStageViewCoglPrivate *view_priv =
|
ClutterStageViewCoglPrivate *view_priv =
|
||||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||||
cairo_rectangle_int_t view_rect;
|
cairo_region_t **current_damage;
|
||||||
cairo_rectangle_int_t *current_damage;
|
|
||||||
|
|
||||||
current_damage =
|
current_damage =
|
||||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
||||||
clutter_stage_view_get_layout (view, &view_rect);
|
|
||||||
|
|
||||||
*current_damage = view_rect;
|
g_clear_pointer (current_damage, cairo_region_destroy);
|
||||||
|
*current_damage = cairo_region_copy (damage);
|
||||||
view_priv->damage_index++;
|
view_priv->damage_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_current_damage_history_rectangle (ClutterStageView *view,
|
||||||
|
const cairo_rectangle_int_t *rect)
|
||||||
|
{
|
||||||
|
cairo_region_t *damage;
|
||||||
|
|
||||||
|
damage = cairo_region_create_rectangle (rect);
|
||||||
|
fill_current_damage_history (view, damage);
|
||||||
|
cairo_region_destroy (damage);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
transform_swap_region_to_onscreen (ClutterStageView *view,
|
transform_swap_region_to_onscreen (ClutterStageView *view,
|
||||||
cairo_rectangle_int_t *swap_region)
|
cairo_rectangle_int_t *swap_region)
|
||||||
@@ -499,9 +503,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
gboolean do_swap_buffer;
|
gboolean do_swap_buffer;
|
||||||
gboolean swap_with_damage;
|
gboolean swap_with_damage;
|
||||||
ClutterActor *wrapper;
|
ClutterActor *wrapper;
|
||||||
cairo_rectangle_int_t redraw_clip;
|
cairo_region_t *redraw_clip;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
cairo_rectangle_int_t swap_region;
|
cairo_rectangle_int_t swap_region;
|
||||||
cairo_rectangle_int_t clip_region;
|
cairo_rectangle_int_t clip_rect;
|
||||||
|
cairo_rectangle_int_t redraw_rect;
|
||||||
gboolean clip_region_empty;
|
gboolean clip_region_empty;
|
||||||
int fb_scale;
|
int fb_scale;
|
||||||
|
|
||||||
@@ -517,20 +523,19 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
cogl_is_onscreen (fb) &&
|
cogl_is_onscreen (fb) &&
|
||||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
||||||
|
|
||||||
/* NB: a zero width redraw clip == full stage redraw */
|
/* NB: a NULL redraw clip == full stage redraw */
|
||||||
if (stage_cogl->bounding_redraw_clip.width == 0)
|
if (!stage_cogl->redraw_clip)
|
||||||
have_clip = FALSE;
|
have_clip = FALSE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
redraw_clip = stage_cogl->bounding_redraw_clip;
|
cairo_region_t *view_region;
|
||||||
_clutter_util_rectangle_intersection (&redraw_clip,
|
redraw_clip = cairo_region_copy (stage_cogl->redraw_clip);
|
||||||
&view_rect,
|
|
||||||
&redraw_clip);
|
|
||||||
|
|
||||||
have_clip = !(redraw_clip.x == view_rect.x &&
|
view_region = cairo_region_create_rectangle (&view_rect);
|
||||||
redraw_clip.y == view_rect.y &&
|
cairo_region_intersect (redraw_clip, view_region);
|
||||||
redraw_clip.width == view_rect.width &&
|
|
||||||
redraw_clip.height == view_rect.height);
|
have_clip = !cairo_region_equal (redraw_clip, view_region);
|
||||||
|
cairo_region_destroy (view_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
may_use_clipped_redraw = FALSE;
|
may_use_clipped_redraw = FALSE;
|
||||||
@@ -542,11 +547,12 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
|
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
|
||||||
{
|
{
|
||||||
may_use_clipped_redraw = TRUE;
|
may_use_clipped_redraw = TRUE;
|
||||||
clip_region = redraw_clip;
|
clip_region = cairo_region_reference (redraw_clip);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clip_region = (cairo_rectangle_int_t){ 0 };
|
clip_region = cairo_region_create ();
|
||||||
|
redraw_clip = cairo_region_reference (clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (may_use_clipped_redraw &&
|
if (may_use_clipped_redraw &&
|
||||||
@@ -555,7 +561,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
else
|
else
|
||||||
use_clipped_redraw = FALSE;
|
use_clipped_redraw = FALSE;
|
||||||
|
|
||||||
clip_region_empty = may_use_clipped_redraw && clip_region.width == 0;
|
clip_region_empty = may_use_clipped_redraw && cairo_region_is_empty (clip_region);
|
||||||
|
|
||||||
fb_scale = clutter_stage_view_get_scale (view);
|
fb_scale = clutter_stage_view_get_scale (view);
|
||||||
|
|
||||||
@@ -565,34 +571,26 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
if (use_clipped_redraw && !clip_region_empty)
|
if (use_clipped_redraw && !clip_region_empty)
|
||||||
{
|
{
|
||||||
int age, i;
|
int age, i;
|
||||||
cairo_rectangle_int_t *current_damage =
|
|
||||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index++)];
|
|
||||||
|
|
||||||
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
||||||
|
|
||||||
if (valid_buffer_age (view_cogl, age))
|
if (valid_buffer_age (view_cogl, age))
|
||||||
{
|
{
|
||||||
*current_damage = clip_region;
|
fill_current_damage_history (view, clip_region);
|
||||||
|
|
||||||
for (i = 1; i <= age; i++)
|
for (i = 1; i <= age; i++)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t *damage =
|
cairo_region_t *damage =
|
||||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
|
view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
|
||||||
|
cairo_region_union (clip_region, damage);
|
||||||
_clutter_util_rectangle_union (&clip_region, damage, &clip_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the bounding redraw clip state with the extra damage. */
|
/* Update the redraw clip state with the extra damage. */
|
||||||
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
|
cairo_region_union (stage_cogl->redraw_clip, clip_region);
|
||||||
&clip_region,
|
|
||||||
&stage_cogl->bounding_redraw_clip);
|
|
||||||
|
|
||||||
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: x=%d, y=%d, width=%d, height=%d\n",
|
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
|
||||||
age,
|
age,
|
||||||
clip_region.x,
|
cairo_region_num_rectangles (clip_region));
|
||||||
clip_region.y,
|
|
||||||
clip_region.width,
|
|
||||||
clip_region.height);
|
|
||||||
|
|
||||||
swap_with_damage = TRUE;
|
swap_with_damage = TRUE;
|
||||||
}
|
}
|
||||||
@@ -600,15 +598,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
{
|
{
|
||||||
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
|
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
|
||||||
use_clipped_redraw = FALSE;
|
use_clipped_redraw = FALSE;
|
||||||
*current_damage = view_rect;
|
fill_current_damage_history_rectangle (view, &view_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!use_clipped_redraw)
|
else if (!use_clipped_redraw)
|
||||||
{
|
{
|
||||||
fill_current_damage_history_and_step (view);
|
fill_current_damage_history_rectangle (view, &view_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_get_extents (clip_region, &clip_rect);
|
||||||
|
|
||||||
cogl_push_framebuffer (fb);
|
cogl_push_framebuffer (fb);
|
||||||
if (use_clipped_redraw && clip_region_empty)
|
if (use_clipped_redraw && clip_region_empty)
|
||||||
{
|
{
|
||||||
@@ -621,21 +621,21 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
|
|
||||||
CLUTTER_NOTE (CLIPPING,
|
CLUTTER_NOTE (CLIPPING,
|
||||||
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
||||||
clip_region.x,
|
clip_rect.x,
|
||||||
clip_region.y,
|
clip_rect.y,
|
||||||
clip_region.width,
|
clip_rect.width,
|
||||||
clip_region.height);
|
clip_rect.height);
|
||||||
|
|
||||||
stage_cogl->using_clipped_redraw = TRUE;
|
stage_cogl->using_clipped_redraw = TRUE;
|
||||||
|
|
||||||
scissor_x = (clip_region.x - view_rect.x) * fb_scale;
|
scissor_x = (clip_rect.x - view_rect.x) * fb_scale;
|
||||||
scissor_y = (clip_region.y - view_rect.y) * fb_scale;
|
scissor_y = (clip_rect.y - view_rect.y) * fb_scale;
|
||||||
cogl_framebuffer_push_scissor_clip (fb,
|
cogl_framebuffer_push_scissor_clip (fb,
|
||||||
scissor_x,
|
scissor_x,
|
||||||
scissor_y,
|
scissor_y,
|
||||||
clip_region.width * fb_scale,
|
clip_rect.width * fb_scale,
|
||||||
clip_region.height * fb_scale);
|
clip_rect.height * fb_scale);
|
||||||
paint_stage (stage_cogl, view, &clip_region);
|
paint_stage (stage_cogl, view, clip_region);
|
||||||
cogl_framebuffer_pop_clip (fb);
|
cogl_framebuffer_pop_clip (fb);
|
||||||
|
|
||||||
stage_cogl->using_clipped_redraw = FALSE;
|
stage_cogl->using_clipped_redraw = FALSE;
|
||||||
@@ -645,7 +645,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
|
CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
|
||||||
|
|
||||||
/* If we are trying to debug redraw issues then we want to pass
|
/* If we are trying to debug redraw issues then we want to pass
|
||||||
* the bounding_redraw_clip so it can be visualized */
|
* the redraw_clip so it can be visualized */
|
||||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
|
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
|
||||||
may_use_clipped_redraw &&
|
may_use_clipped_redraw &&
|
||||||
!clip_region_empty)
|
!clip_region_empty)
|
||||||
@@ -653,31 +653,39 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
int scissor_x;
|
int scissor_x;
|
||||||
int scissor_y;
|
int scissor_y;
|
||||||
|
|
||||||
scissor_x = (clip_region.x - view_rect.x) * fb_scale;;
|
scissor_x = (clip_rect.x - view_rect.x) * fb_scale;;
|
||||||
scissor_y = (clip_region.y - view_rect.y) * fb_scale;
|
scissor_y = (clip_rect.y - view_rect.y) * fb_scale;
|
||||||
cogl_framebuffer_push_scissor_clip (fb,
|
cogl_framebuffer_push_scissor_clip (fb,
|
||||||
scissor_x,
|
scissor_x,
|
||||||
scissor_y,
|
scissor_y,
|
||||||
clip_region.width * fb_scale,
|
clip_rect.width * fb_scale,
|
||||||
clip_region.height * fb_scale);
|
clip_rect.height * fb_scale);
|
||||||
paint_stage (stage_cogl, view, &clip_region);
|
paint_stage (stage_cogl, view, clip_region);
|
||||||
cogl_framebuffer_pop_clip (fb);
|
cogl_framebuffer_pop_clip (fb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
paint_stage (stage_cogl, view, &view_rect);
|
{
|
||||||
|
cairo_region_t *view_region;
|
||||||
|
|
||||||
|
view_region = cairo_region_create_rectangle (&view_rect);
|
||||||
|
paint_stage (stage_cogl, view, view_region);
|
||||||
|
cairo_region_destroy (view_region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cogl_pop_framebuffer ();
|
cogl_pop_framebuffer ();
|
||||||
|
|
||||||
|
cairo_region_get_extents (redraw_clip, &redraw_rect);
|
||||||
|
|
||||||
if (may_use_clipped_redraw &&
|
if (may_use_clipped_redraw &&
|
||||||
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
|
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
|
||||||
{
|
{
|
||||||
CoglContext *ctx = cogl_framebuffer_get_context (fb);
|
CoglContext *ctx = cogl_framebuffer_get_context (fb);
|
||||||
static CoglPipeline *outline = NULL;
|
static CoglPipeline *outline = NULL;
|
||||||
ClutterActor *actor = CLUTTER_ACTOR (wrapper);
|
ClutterActor *actor = CLUTTER_ACTOR (wrapper);
|
||||||
float x_1 = redraw_clip.x;
|
float x_1 = redraw_rect.x;
|
||||||
float x_2 = redraw_clip.x + redraw_clip.width;
|
float x_2 = redraw_rect.x + redraw_rect.width;
|
||||||
float y_1 = redraw_clip.y;
|
float y_1 = redraw_rect.y;
|
||||||
float y_2 = redraw_clip.y + redraw_clip.height;
|
float y_2 = redraw_rect.y + redraw_rect.height;
|
||||||
CoglVertexP2 quad[4] = {
|
CoglVertexP2 quad[4] = {
|
||||||
{ x_1, y_1 },
|
{ x_1, y_1 },
|
||||||
{ x_2, y_1 },
|
{ x_2, y_1 },
|
||||||
@@ -724,10 +732,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
else if (use_clipped_redraw)
|
else if (use_clipped_redraw)
|
||||||
{
|
{
|
||||||
swap_region = (cairo_rectangle_int_t) {
|
swap_region = (cairo_rectangle_int_t) {
|
||||||
.x = (clip_region.x - view_rect.x) * fb_scale,
|
.x = (clip_rect.x - view_rect.x) * fb_scale,
|
||||||
.y = (clip_region.y - view_rect.y) * fb_scale,
|
.y = (clip_rect.y - view_rect.y) * fb_scale,
|
||||||
.width = clip_region.width * fb_scale,
|
.width = clip_rect.width * fb_scale,
|
||||||
.height = clip_region.height * fb_scale,
|
.height = clip_rect.height * fb_scale,
|
||||||
};
|
};
|
||||||
g_assert (swap_region.width > 0);
|
g_assert (swap_region.width > 0);
|
||||||
do_swap_buffer = TRUE;
|
do_swap_buffer = TRUE;
|
||||||
@@ -749,6 +757,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
|||||||
do_swap_buffer = TRUE;
|
do_swap_buffer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (redraw_clip)
|
||||||
|
cairo_region_destroy (redraw_clip);
|
||||||
|
if (clip_region)
|
||||||
|
cairo_region_destroy (clip_region);
|
||||||
|
|
||||||
if (do_swap_buffer)
|
if (do_swap_buffer)
|
||||||
{
|
{
|
||||||
if (clutter_stage_view_get_onscreen (view) !=
|
if (clutter_stage_view_get_onscreen (view) !=
|
||||||
@@ -796,6 +809,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
|||||||
|
|
||||||
/* reset the redraw clipping for the next paint... */
|
/* reset the redraw clipping for the next paint... */
|
||||||
stage_cogl->initialized_redraw_clip = FALSE;
|
stage_cogl->initialized_redraw_clip = FALSE;
|
||||||
|
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
|
||||||
|
|
||||||
stage_cogl->frame_count++;
|
stage_cogl->frame_count++;
|
||||||
}
|
}
|
||||||
@@ -810,7 +824,7 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
|||||||
gboolean has_buffer_age =
|
gboolean has_buffer_age =
|
||||||
cogl_is_onscreen (framebuffer) &&
|
cogl_is_onscreen (framebuffer) &&
|
||||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
||||||
cairo_rectangle_int_t *rect;
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
if (!has_buffer_age)
|
if (!has_buffer_age)
|
||||||
{
|
{
|
||||||
@@ -823,12 +837,18 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
|||||||
ClutterStageViewCoglPrivate *view_priv =
|
ClutterStageViewCoglPrivate *view_priv =
|
||||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||||
cairo_rectangle_int_t view_layout;
|
cairo_rectangle_int_t view_layout;
|
||||||
|
cairo_region_t *damage;
|
||||||
|
|
||||||
clutter_stage_view_get_layout (view, &view_layout);
|
clutter_stage_view_get_layout (view, &view_layout);
|
||||||
|
|
||||||
rect = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
damage = view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||||
*x = rect->x - view_layout.x;
|
if (damage)
|
||||||
*y = rect->y - view_layout.y;
|
cairo_region_get_rectangle (damage, 0, &rect);
|
||||||
|
else
|
||||||
|
rect.x = rect.y = 0;
|
||||||
|
|
||||||
|
*x = rect.x - view_layout.x;
|
||||||
|
*y = rect.y - view_layout.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -847,7 +867,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
|||||||
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
|
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
|
||||||
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
|
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
|
||||||
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
|
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
|
||||||
iface->get_redraw_clip_bounds = clutter_stage_cogl_get_redraw_clip_bounds;
|
iface->get_redraw_clip = clutter_stage_cogl_get_redraw_clip;
|
||||||
iface->redraw = clutter_stage_cogl_redraw;
|
iface->redraw = clutter_stage_cogl_redraw;
|
||||||
iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
|
iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
|
||||||
}
|
}
|
||||||
|
@@ -59,7 +59,7 @@ struct _ClutterStageCogl
|
|||||||
* junk frames to start with. */
|
* junk frames to start with. */
|
||||||
unsigned int frame_count;
|
unsigned int frame_count;
|
||||||
|
|
||||||
cairo_rectangle_int_t bounding_redraw_clip;
|
cairo_region_t *redraw_clip;
|
||||||
|
|
||||||
guint initialized_redraw_clip : 1;
|
guint initialized_redraw_clip : 1;
|
||||||
|
|
||||||
|
@@ -193,6 +193,11 @@ struct _CoglFramebuffer
|
|||||||
CoglFramebufferBits bits;
|
CoglFramebufferBits bits;
|
||||||
|
|
||||||
int samples_per_pixel;
|
int samples_per_pixel;
|
||||||
|
|
||||||
|
/* Whether the depth buffer was enabled for this framebuffer,
|
||||||
|
* usually means it needs to be cleared before being reused next.
|
||||||
|
*/
|
||||||
|
CoglBool depth_buffer_clear_needed;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@@ -117,6 +117,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
|
|||||||
framebuffer->viewport_age_for_scissor_workaround = -1;
|
framebuffer->viewport_age_for_scissor_workaround = -1;
|
||||||
framebuffer->dither_enabled = TRUE;
|
framebuffer->dither_enabled = TRUE;
|
||||||
framebuffer->depth_writing_enabled = TRUE;
|
framebuffer->depth_writing_enabled = TRUE;
|
||||||
|
framebuffer->depth_buffer_clear_needed = TRUE;
|
||||||
|
|
||||||
framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
|
framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
|
||||||
framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
|
framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
|
||||||
@@ -268,6 +269,13 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
|||||||
int scissor_y1;
|
int scissor_y1;
|
||||||
CoglBool saved_viewport_scissor_workaround;
|
CoglBool saved_viewport_scissor_workaround;
|
||||||
|
|
||||||
|
if (!framebuffer->depth_buffer_clear_needed &&
|
||||||
|
(buffers & COGL_BUFFER_BIT_DEPTH))
|
||||||
|
buffers &= ~(COGL_BUFFER_BIT_DEPTH);
|
||||||
|
|
||||||
|
if (buffers == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
_cogl_clip_stack_get_bounds (clip_stack,
|
_cogl_clip_stack_get_bounds (clip_stack,
|
||||||
&scissor_x0, &scissor_y0,
|
&scissor_x0, &scissor_y0,
|
||||||
&scissor_x1, &scissor_y1);
|
&scissor_x1, &scissor_y1);
|
||||||
@@ -415,6 +423,9 @@ cleared:
|
|||||||
_cogl_framebuffer_mark_mid_scene (framebuffer);
|
_cogl_framebuffer_mark_mid_scene (framebuffer);
|
||||||
_cogl_framebuffer_mark_clear_clip_dirty (framebuffer);
|
_cogl_framebuffer_mark_clear_clip_dirty (framebuffer);
|
||||||
|
|
||||||
|
if (buffers & COGL_BUFFER_BIT_DEPTH)
|
||||||
|
framebuffer->depth_buffer_clear_needed = FALSE;
|
||||||
|
|
||||||
if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH)
|
if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH)
|
||||||
{
|
{
|
||||||
/* For our fast-path for reading back a single pixel of simple
|
/* For our fast-path for reading back a single pixel of simple
|
||||||
|
@@ -418,7 +418,11 @@ flush_depth_state (CoglContext *ctx,
|
|||||||
if (ctx->depth_test_enabled_cache != depth_state->test_enabled)
|
if (ctx->depth_test_enabled_cache != depth_state->test_enabled)
|
||||||
{
|
{
|
||||||
if (depth_state->test_enabled == TRUE)
|
if (depth_state->test_enabled == TRUE)
|
||||||
GE (ctx, glEnable (GL_DEPTH_TEST));
|
{
|
||||||
|
GE (ctx, glEnable (GL_DEPTH_TEST));
|
||||||
|
if (ctx->current_draw_buffer)
|
||||||
|
ctx->current_draw_buffer->depth_buffer_clear_needed = TRUE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
GE (ctx, glDisable (GL_DEPTH_TEST));
|
GE (ctx, glDisable (GL_DEPTH_TEST));
|
||||||
ctx->depth_test_enabled_cache = depth_state->test_enabled;
|
ctx->depth_test_enabled_cache = depth_state->test_enabled;
|
||||||
|
@@ -220,11 +220,7 @@ meta_shadow_paint (MetaShadow *shadow,
|
|||||||
int dest_x[4];
|
int dest_x[4];
|
||||||
int dest_y[4];
|
int dest_y[4];
|
||||||
int n_x, n_y;
|
int n_x, n_y;
|
||||||
|
gboolean source_updated = FALSE;
|
||||||
cogl_pipeline_set_color4ub (shadow->pipeline,
|
|
||||||
opacity, opacity, opacity, opacity);
|
|
||||||
|
|
||||||
cogl_set_source (shadow->pipeline);
|
|
||||||
|
|
||||||
if (shadow->scale_width)
|
if (shadow->scale_width)
|
||||||
{
|
{
|
||||||
@@ -300,6 +296,17 @@ meta_shadow_paint (MetaShadow *shadow,
|
|||||||
else
|
else
|
||||||
overlap = CAIRO_REGION_OVERLAP_IN;
|
overlap = CAIRO_REGION_OVERLAP_IN;
|
||||||
|
|
||||||
|
if (overlap == CAIRO_REGION_OVERLAP_OUT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!source_updated)
|
||||||
|
{
|
||||||
|
cogl_pipeline_set_color4ub (shadow->pipeline,
|
||||||
|
opacity, opacity, opacity, opacity);
|
||||||
|
cogl_set_source (shadow->pipeline);
|
||||||
|
source_updated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* There's quite a bit of overhead from allocating a new
|
/* There's quite a bit of overhead from allocating a new
|
||||||
* region in order to find an exact intersection and
|
* region in order to find an exact intersection and
|
||||||
* generating more geometry - we make the assumption that
|
* generating more geometry - we make the assumption that
|
||||||
|
@@ -35,7 +35,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_
|
|||||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REPAINT_SCHEDULED,
|
|
||||||
SIZE_CHANGED,
|
SIZE_CHANGED,
|
||||||
|
|
||||||
LAST_SIGNAL,
|
LAST_SIGNAL,
|
||||||
@@ -121,13 +120,6 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
|||||||
object_class->dispose = meta_surface_actor_dispose;
|
object_class->dispose = meta_surface_actor_dispose;
|
||||||
actor_class->pick = meta_surface_actor_pick;
|
actor_class->pick = meta_surface_actor_pick;
|
||||||
|
|
||||||
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
|
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
0,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
G_TYPE_NONE, 0);
|
|
||||||
|
|
||||||
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
@@ -201,8 +193,7 @@ meta_surface_actor_update_area (MetaSurfaceActor *self,
|
|||||||
{
|
{
|
||||||
MetaSurfaceActorPrivate *priv = self->priv;
|
MetaSurfaceActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
if (meta_shaped_texture_update_area (priv->texture, x, y, width, height))
|
meta_shaped_texture_update_area (priv->texture, x, y, width, height);
|
||||||
g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@@ -82,7 +82,6 @@ struct _MetaWindowActorPrivate
|
|||||||
guint send_frame_messages_timer;
|
guint send_frame_messages_timer;
|
||||||
gint64 frame_drawn_time;
|
gint64 frame_drawn_time;
|
||||||
|
|
||||||
guint repaint_scheduled_id;
|
|
||||||
guint size_changed_id;
|
guint size_changed_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -194,6 +193,18 @@ frame_data_free (FrameData *frame)
|
|||||||
g_slice_free (FrameData, frame);
|
g_slice_free (FrameData, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_window_actor_queue_redraw (ClutterActor *actor,
|
||||||
|
ClutterActor *leaf,
|
||||||
|
ClutterPaintVolume *paint_volume)
|
||||||
|
{
|
||||||
|
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
||||||
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
priv->repaint_scheduled = TRUE;
|
||||||
|
return CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->queue_redraw (actor, leaf, paint_volume);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_actor_class_init (MetaWindowActorClass *klass)
|
meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||||
{
|
{
|
||||||
@@ -211,6 +222,7 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
|||||||
|
|
||||||
actor_class->paint = meta_window_actor_paint;
|
actor_class->paint = meta_window_actor_paint;
|
||||||
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
||||||
|
actor_class->queue_redraw = meta_window_actor_queue_redraw;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetaWindowActor::first-frame:
|
* MetaWindowActor::first-frame:
|
||||||
@@ -297,16 +309,6 @@ surface_size_changed (MetaSurfaceActor *actor,
|
|||||||
meta_window_actor_update_shape (self);
|
meta_window_actor_update_shape (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
surface_repaint_scheduled (MetaSurfaceActor *actor,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
|
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
|
||||||
|
|
||||||
priv->repaint_scheduled = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_argb32 (MetaWindowActor *self)
|
is_argb32 (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
@@ -396,9 +398,7 @@ set_surface (MetaWindowActor *self,
|
|||||||
|
|
||||||
if (priv->surface)
|
if (priv->surface)
|
||||||
{
|
{
|
||||||
g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
|
|
||||||
g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
|
g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
|
||||||
priv->repaint_scheduled_id = 0;
|
|
||||||
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||||
g_object_unref (priv->surface);
|
g_object_unref (priv->surface);
|
||||||
}
|
}
|
||||||
@@ -408,8 +408,6 @@ set_surface (MetaWindowActor *self,
|
|||||||
if (priv->surface)
|
if (priv->surface)
|
||||||
{
|
{
|
||||||
g_object_ref_sink (priv->surface);
|
g_object_ref_sink (priv->surface);
|
||||||
priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
|
|
||||||
G_CALLBACK (surface_repaint_scheduled), self);
|
|
||||||
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
|
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
|
||||||
G_CALLBACK (surface_size_changed), self);
|
G_CALLBACK (surface_size_changed), self);
|
||||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||||
@@ -717,6 +715,7 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
cairo_rectangle_int_t shape_bounds;
|
cairo_rectangle_int_t shape_bounds;
|
||||||
cairo_region_t *clip = priv->shadow_clip;
|
cairo_region_t *clip = priv->shadow_clip;
|
||||||
MetaWindow *window = priv->window;
|
MetaWindow *window = priv->window;
|
||||||
|
gboolean partially_drawn = FALSE;
|
||||||
|
|
||||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||||
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
||||||
@@ -734,6 +733,17 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
|
|
||||||
cairo_region_subtract (clip, frame_bounds);
|
cairo_region_subtract (clip, frame_bounds);
|
||||||
}
|
}
|
||||||
|
else if (clip)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t shadow_bounds;
|
||||||
|
cairo_region_t *shadow_region;
|
||||||
|
|
||||||
|
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
|
||||||
|
shadow_region = cairo_region_create_rectangle (&shadow_bounds);
|
||||||
|
cairo_region_intersect (shadow_region, clip);
|
||||||
|
partially_drawn = !cairo_region_is_empty (shadow_region);
|
||||||
|
cairo_region_destroy (shadow_region);
|
||||||
|
}
|
||||||
|
|
||||||
meta_shadow_paint (shadow,
|
meta_shadow_paint (shadow,
|
||||||
params.x_offset + shape_bounds.x,
|
params.x_offset + shape_bounds.x,
|
||||||
@@ -742,7 +752,7 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
shape_bounds.height,
|
shape_bounds.height,
|
||||||
(clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255),
|
(clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255),
|
||||||
clip,
|
clip,
|
||||||
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
|
clip_shadow_under_window (self) || partially_drawn);
|
||||||
|
|
||||||
if (clip && clip != priv->shadow_clip)
|
if (clip && clip != priv->shadow_clip)
|
||||||
cairo_region_destroy (clip);
|
cairo_region_destroy (clip);
|
||||||
|
@@ -57,7 +57,7 @@ meta_window_group_paint (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
cairo_region_t *clip_region;
|
cairo_region_t *clip_region;
|
||||||
cairo_region_t *unobscured_region;
|
cairo_region_t *unobscured_region;
|
||||||
cairo_rectangle_int_t visible_rect, clip_rect;
|
cairo_rectangle_int_t visible_rect;
|
||||||
int paint_x_origin, paint_y_origin;
|
int paint_x_origin, paint_y_origin;
|
||||||
int screen_width, screen_height;
|
int screen_width, screen_height;
|
||||||
|
|
||||||
@@ -109,11 +109,7 @@ meta_window_group_paint (ClutterActor *actor)
|
|||||||
* sizes, we could intersect this with an accurate union of the
|
* sizes, we could intersect this with an accurate union of the
|
||||||
* monitors to avoid painting shadows that are visible only in the
|
* monitors to avoid painting shadows that are visible only in the
|
||||||
* holes. */
|
* holes. */
|
||||||
clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
|
clip_region = clutter_stage_get_redraw_clip (CLUTTER_STAGE (stage));
|
||||||
&clip_rect);
|
|
||||||
|
|
||||||
clip_region = cairo_region_create_rectangle (&clip_rect);
|
|
||||||
|
|
||||||
cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
|
cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
|
||||||
|
|
||||||
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
|
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
|
||||||
|
@@ -470,14 +470,6 @@ queue_surface_actor_frame_callbacks (MetaWaylandSurface *surface,
|
|||||||
wl_list_init (&pending->frame_callback_list);
|
wl_list_init (&pending->frame_callback_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
pending_buffer_resource_destroyed (MetaWaylandBuffer *buffer,
|
|
||||||
MetaWaylandPendingState *pending)
|
|
||||||
{
|
|
||||||
g_signal_handler_disconnect (buffer, pending->buffer_destroy_handler_id);
|
|
||||||
pending->buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pending_state_init (MetaWaylandPendingState *state)
|
pending_state_init (MetaWaylandPendingState *state)
|
||||||
{
|
{
|
||||||
@@ -510,8 +502,9 @@ pending_state_destroy (MetaWaylandPendingState *state)
|
|||||||
g_clear_pointer (&state->opaque_region, cairo_region_destroy);
|
g_clear_pointer (&state->opaque_region, cairo_region_destroy);
|
||||||
|
|
||||||
if (state->buffer)
|
if (state->buffer)
|
||||||
g_signal_handler_disconnect (state->buffer,
|
g_object_remove_weak_pointer (G_OBJECT (state->buffer),
|
||||||
state->buffer_destroy_handler_id);
|
(gpointer *) &state->buffer);
|
||||||
|
|
||||||
wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
|
wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
|
||||||
wl_resource_destroy (cb->resource);
|
wl_resource_destroy (cb->resource);
|
||||||
}
|
}
|
||||||
@@ -528,7 +521,10 @@ move_pending_state (MetaWaylandPendingState *from,
|
|||||||
MetaWaylandPendingState *to)
|
MetaWaylandPendingState *to)
|
||||||
{
|
{
|
||||||
if (from->buffer)
|
if (from->buffer)
|
||||||
g_signal_handler_disconnect (from->buffer, from->buffer_destroy_handler_id);
|
{
|
||||||
|
g_object_remove_weak_pointer (G_OBJECT (from->buffer),
|
||||||
|
(gpointer *) &from->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
to->newly_attached = from->newly_attached;
|
to->newly_attached = from->newly_attached;
|
||||||
to->buffer = from->buffer;
|
to->buffer = from->buffer;
|
||||||
@@ -554,10 +550,8 @@ move_pending_state (MetaWaylandPendingState *from,
|
|||||||
|
|
||||||
if (to->buffer)
|
if (to->buffer)
|
||||||
{
|
{
|
||||||
to->buffer_destroy_handler_id =
|
g_object_add_weak_pointer (G_OBJECT (to->buffer),
|
||||||
g_signal_connect (to->buffer, "resource-destroyed",
|
(gpointer *) &to->buffer);
|
||||||
G_CALLBACK (pending_buffer_resource_destroyed),
|
|
||||||
to);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_state_init (from);
|
pending_state_init (from);
|
||||||
@@ -913,8 +907,8 @@ wl_surface_attach (struct wl_client *client,
|
|||||||
|
|
||||||
if (surface->pending->buffer)
|
if (surface->pending->buffer)
|
||||||
{
|
{
|
||||||
g_signal_handler_disconnect (surface->pending->buffer,
|
g_object_remove_weak_pointer (G_OBJECT (surface->pending->buffer),
|
||||||
surface->pending->buffer_destroy_handler_id);
|
(gpointer *) &surface->pending->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->pending->newly_attached = TRUE;
|
surface->pending->newly_attached = TRUE;
|
||||||
@@ -924,10 +918,8 @@ wl_surface_attach (struct wl_client *client,
|
|||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
surface->pending->buffer_destroy_handler_id =
|
g_object_add_weak_pointer (G_OBJECT (surface->pending->buffer),
|
||||||
g_signal_connect (buffer, "resource-destroyed",
|
(gpointer *) &surface->pending->buffer);
|
||||||
G_CALLBACK (pending_buffer_resource_destroyed),
|
|
||||||
surface->pending);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -123,7 +123,6 @@ struct _MetaWaylandPendingState
|
|||||||
/* wl_surface.attach */
|
/* wl_surface.attach */
|
||||||
gboolean newly_attached;
|
gboolean newly_attached;
|
||||||
MetaWaylandBuffer *buffer;
|
MetaWaylandBuffer *buffer;
|
||||||
gulong buffer_destroy_handler_id;
|
|
||||||
int32_t dx;
|
int32_t dx;
|
||||||
int32_t dy;
|
int32_t dy;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user