mirror of
https://github.com/brl/mutter.git
synced 2024-11-30 03:50:47 -05:00
actor: make default get_paint_volume more conservative
There are too many examples where the default assumption that an actor paints inside its allocation isn't true, so we now return FALSE in the base implementation instead. This means that by default we are saying "we don't know the paint volume of the actor", so developers need to implement the get_paint_volume virtual to take advantage of culling and clipped redraws with their actors. This patch provides very conservative get_paint_volume implementations for ClutterTexture, ClutterCairoTexture, ClutterRectangle and ClutterText which all explicitly check the actor's object type to avoid making any assumptions about subclasses.
This commit is contained in:
parent
d9a7f1b03b
commit
72eeb8e809
@ -3457,19 +3457,7 @@ static gboolean
|
|||||||
clutter_actor_real_get_paint_volume (ClutterActor *self,
|
clutter_actor_real_get_paint_volume (ClutterActor *self,
|
||||||
ClutterPaintVolume *volume)
|
ClutterPaintVolume *volume)
|
||||||
{
|
{
|
||||||
ClutterActorPrivate *priv = self->priv;
|
return FALSE;
|
||||||
gfloat width, height;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (priv->needs_allocation))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* the default origin is set to { 0, 0, 0 } */
|
|
||||||
clutter_actor_box_get_size (&priv->allocation, &width, &height);
|
|
||||||
clutter_paint_volume_set_width (volume, width);
|
|
||||||
clutter_paint_volume_set_height (volume, height);
|
|
||||||
/* the default depth will be 0 since most actors are 2D */
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -366,6 +366,31 @@ clutter_cairo_texture_get_preferred_height (ClutterActor *actor,
|
|||||||
*natural_height = (gfloat) priv->height;
|
*natural_height = (gfloat) priv->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_cairo_texture_get_paint_volume (ClutterActor *self,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
ClutterGeometry allocation;
|
||||||
|
|
||||||
|
/* XXX: we are being conservative here and not making assumptions
|
||||||
|
* that sub-classes won't paint outside their allocation. */
|
||||||
|
if (G_OBJECT_TYPE (self) != CLUTTER_TYPE_CAIRO_TEXTURE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* XXX: clutter_actor_get_allocation can potentially be very
|
||||||
|
* expensive to call if called while the actor doesn't have a valid
|
||||||
|
* allocation since it will trigger a synchronous relayout of the
|
||||||
|
* scenegraph. We explicitly check we have a valid allocation
|
||||||
|
* to avoid hitting that codepath. */
|
||||||
|
if (!clutter_actor_has_allocation (self))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_actor_get_allocation_geometry (self, &allocation);
|
||||||
|
clutter_paint_volume_set_width (volume, allocation.width);
|
||||||
|
clutter_paint_volume_set_height (volume, allocation.height);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
|
clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
|
||||||
{
|
{
|
||||||
@ -378,6 +403,9 @@ clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
|
|||||||
gobject_class->get_property = clutter_cairo_texture_get_property;
|
gobject_class->get_property = clutter_cairo_texture_get_property;
|
||||||
gobject_class->notify = clutter_cairo_texture_notify;
|
gobject_class->notify = clutter_cairo_texture_notify;
|
||||||
|
|
||||||
|
actor_class->get_paint_volume =
|
||||||
|
clutter_cairo_texture_get_paint_volume;
|
||||||
|
|
||||||
actor_class->get_preferred_width =
|
actor_class->get_preferred_width =
|
||||||
clutter_cairo_texture_get_preferred_width;
|
clutter_cairo_texture_get_preferred_width;
|
||||||
actor_class->get_preferred_height =
|
actor_class->get_preferred_height =
|
||||||
|
@ -152,6 +152,31 @@ clutter_rectangle_paint (ClutterActor *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_rectangle_get_paint_volume (ClutterActor *self,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
ClutterGeometry allocation;
|
||||||
|
|
||||||
|
/* XXX: we are being conservative here and not making assumptions
|
||||||
|
* that sub-classes won't paint outside their allocation. */
|
||||||
|
if (G_OBJECT_TYPE (self) != CLUTTER_TYPE_RECTANGLE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* XXX: clutter_actor_get_allocation can potentially be very
|
||||||
|
* expensive to call if called while the actor doesn't have a valid
|
||||||
|
* allocation since it will trigger a synchronous relayout of the
|
||||||
|
* scenegraph. We explicitly check we have a valid allocation
|
||||||
|
* to avoid hitting that codepath. */
|
||||||
|
if (!clutter_actor_has_allocation (self))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_actor_get_allocation_geometry (self, &allocation);
|
||||||
|
clutter_paint_volume_set_width (volume, allocation.width);
|
||||||
|
clutter_paint_volume_set_height (volume, allocation.height);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_rectangle_set_property (GObject *object,
|
clutter_rectangle_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -231,7 +256,8 @@ clutter_rectangle_class_init (ClutterRectangleClass *klass)
|
|||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
actor_class->paint = clutter_rectangle_paint;
|
actor_class->paint = clutter_rectangle_paint;
|
||||||
|
actor_class->get_paint_volume = clutter_rectangle_get_paint_volume;
|
||||||
|
|
||||||
gobject_class->finalize = clutter_rectangle_finalize;
|
gobject_class->finalize = clutter_rectangle_finalize;
|
||||||
gobject_class->dispose = clutter_rectangle_dispose;
|
gobject_class->dispose = clutter_rectangle_dispose;
|
||||||
|
@ -1920,6 +1920,31 @@ clutter_text_paint (ClutterActor *self)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_text_get_paint_volume (ClutterActor *self,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
ClutterGeometry allocation;
|
||||||
|
|
||||||
|
/* XXX: we are being conservative here and not making assumptions
|
||||||
|
* that sub-classes won't paint outside their allocation. */
|
||||||
|
if (G_OBJECT_TYPE (self) != CLUTTER_TYPE_TEXT)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* XXX: clutter_actor_get_allocation can potentially be very
|
||||||
|
* expensive to call if called while the actor doesn't have a valid
|
||||||
|
* allocation since it will trigger a synchronous relayout of the
|
||||||
|
* scenegraph. We explicitly check we have a valid allocation
|
||||||
|
* to avoid hitting that codepath. */
|
||||||
|
if (!clutter_actor_has_allocation (self))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_actor_get_allocation_geometry (self, &allocation);
|
||||||
|
clutter_paint_volume_set_width (volume, allocation.width);
|
||||||
|
clutter_paint_volume_set_height (volume, allocation.height);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_text_get_preferred_width (ClutterActor *self,
|
clutter_text_get_preferred_width (ClutterActor *self,
|
||||||
gfloat for_height,
|
gfloat for_height,
|
||||||
@ -2492,6 +2517,7 @@ clutter_text_class_init (ClutterTextClass *klass)
|
|||||||
gobject_class->finalize = clutter_text_finalize;
|
gobject_class->finalize = clutter_text_finalize;
|
||||||
|
|
||||||
actor_class->paint = clutter_text_paint;
|
actor_class->paint = clutter_text_paint;
|
||||||
|
actor_class->get_paint_volume = clutter_text_get_paint_volume;
|
||||||
actor_class->get_preferred_width = clutter_text_get_preferred_width;
|
actor_class->get_preferred_width = clutter_text_get_preferred_width;
|
||||||
actor_class->get_preferred_height = clutter_text_get_preferred_height;
|
actor_class->get_preferred_height = clutter_text_get_preferred_height;
|
||||||
actor_class->allocate = clutter_text_allocate;
|
actor_class->allocate = clutter_text_allocate;
|
||||||
|
@ -685,6 +685,31 @@ clutter_texture_paint (ClutterActor *self)
|
|||||||
gen_texcoords_and_draw_cogl_rectangle (self);
|
gen_texcoords_and_draw_cogl_rectangle (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_texture_get_paint_volume (ClutterActor *self,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
ClutterGeometry allocation;
|
||||||
|
|
||||||
|
/* XXX: we are being conservative here and not making assumptions
|
||||||
|
* that sub-classes won't paint outside their allocation. */
|
||||||
|
if (G_OBJECT_TYPE (self) != CLUTTER_TYPE_TEXTURE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* XXX: clutter_actor_get_allocation can potentially be very
|
||||||
|
* expensive to call if called while the actor doesn't have a valid
|
||||||
|
* allocation since it will trigger a synchronous relayout of the
|
||||||
|
* scenegraph. We explicitly check we have a valid allocation
|
||||||
|
* to avoid hitting that codepath. */
|
||||||
|
if (!clutter_actor_has_allocation (self))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_actor_get_allocation_geometry (self, &allocation);
|
||||||
|
clutter_paint_volume_set_width (volume, allocation.width);
|
||||||
|
clutter_paint_volume_set_height (volume, allocation.height);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_texture_async_data_free (ClutterTextureAsyncData *data)
|
clutter_texture_async_data_free (ClutterTextureAsyncData *data)
|
||||||
{
|
{
|
||||||
@ -956,10 +981,11 @@ clutter_texture_class_init (ClutterTextureClass *klass)
|
|||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (ClutterTexturePrivate));
|
g_type_class_add_private (klass, sizeof (ClutterTexturePrivate));
|
||||||
|
|
||||||
actor_class->paint = clutter_texture_paint;
|
actor_class->paint = clutter_texture_paint;
|
||||||
actor_class->pick = clutter_texture_pick;
|
actor_class->pick = clutter_texture_pick;
|
||||||
actor_class->realize = clutter_texture_realize;
|
actor_class->get_paint_volume = clutter_texture_get_paint_volume;
|
||||||
actor_class->unrealize = clutter_texture_unrealize;
|
actor_class->realize = clutter_texture_realize;
|
||||||
|
actor_class->unrealize = clutter_texture_unrealize;
|
||||||
|
|
||||||
actor_class->get_preferred_width = clutter_texture_get_preferred_width;
|
actor_class->get_preferred_width = clutter_texture_get_preferred_width;
|
||||||
actor_class->get_preferred_height = clutter_texture_get_preferred_height;
|
actor_class->get_preferred_height = clutter_texture_get_preferred_height;
|
||||||
|
Loading…
Reference in New Issue
Block a user