[rectangle] Avoid modifying materials mid scene
To improve batching of geometry in the Cogl journal we need to avoid modifying materials midscene. Currently cogl_set_source_color and cogl_set_source_texture simply modify a single shared material. In the future we can improve this so they use a pool of materials that gets recycled as the journal is flushed, but for now we give all ClutterRectangles their own private materials for painting with.
This commit is contained in:
parent
dc1ca79398
commit
938452f1b1
@ -60,8 +60,10 @@ enum
|
|||||||
|
|
||||||
struct _ClutterRectanglePrivate
|
struct _ClutterRectanglePrivate
|
||||||
{
|
{
|
||||||
ClutterColor color;
|
ClutterColor primary_color;
|
||||||
ClutterColor border_color;
|
CoglHandle primary_material;
|
||||||
|
ClutterColor border_color;
|
||||||
|
CoglHandle border_material;
|
||||||
|
|
||||||
guint border_width;
|
guint border_width;
|
||||||
|
|
||||||
@ -78,6 +80,7 @@ clutter_rectangle_paint (ClutterActor *self)
|
|||||||
ClutterRectanglePrivate *priv;
|
ClutterRectanglePrivate *priv;
|
||||||
ClutterGeometry geom;
|
ClutterGeometry geom;
|
||||||
guint8 tmp_alpha;
|
guint8 tmp_alpha;
|
||||||
|
guint8 opacity;
|
||||||
|
|
||||||
rectangle = CLUTTER_RECTANGLE(self);
|
rectangle = CLUTTER_RECTANGLE(self);
|
||||||
priv = rectangle->priv;
|
priv = rectangle->priv;
|
||||||
@ -88,6 +91,8 @@ clutter_rectangle_paint (ClutterActor *self)
|
|||||||
: "unknown");
|
: "unknown");
|
||||||
clutter_actor_get_allocation_geometry (self, &geom);
|
clutter_actor_get_allocation_geometry (self, &geom);
|
||||||
|
|
||||||
|
opacity = clutter_actor_get_paint_opacity (self);
|
||||||
|
|
||||||
/* parent paint call will have translated us into position so
|
/* parent paint call will have translated us into position so
|
||||||
* paint from 0, 0
|
* paint from 0, 0
|
||||||
*/
|
*/
|
||||||
@ -96,15 +101,26 @@ clutter_rectangle_paint (ClutterActor *self)
|
|||||||
/* compute the composited opacity of the actor taking into
|
/* compute the composited opacity of the actor taking into
|
||||||
* account the opacity of the color set by the user
|
* account the opacity of the color set by the user
|
||||||
*/
|
*/
|
||||||
tmp_alpha = clutter_actor_get_paint_opacity (self)
|
tmp_alpha = opacity * priv->border_color.alpha / 255;
|
||||||
* priv->border_color.alpha
|
|
||||||
/ 255;
|
|
||||||
|
|
||||||
/* paint the border */
|
/* paint the border */
|
||||||
cogl_set_source_color4ub (priv->border_color.red,
|
|
||||||
priv->border_color.green,
|
/* We are assuming this is a NOP when the color doesn't change.
|
||||||
priv->border_color.blue,
|
* This is important since we should aim to never modify
|
||||||
tmp_alpha);
|
* materials mid-scene. */
|
||||||
|
cogl_material_set_color4ub (priv->border_material,
|
||||||
|
priv->border_color.red,
|
||||||
|
priv->border_color.green,
|
||||||
|
priv->border_color.blue,
|
||||||
|
tmp_alpha);
|
||||||
|
|
||||||
|
cogl_set_source (priv->border_material);
|
||||||
|
|
||||||
|
cogl_material_set_color4ub (priv->border_material,
|
||||||
|
priv->border_color.red,
|
||||||
|
priv->border_color.green,
|
||||||
|
priv->border_color.blue,
|
||||||
|
tmp_alpha);
|
||||||
|
|
||||||
/* this sucks, but it's the only way to make a border */
|
/* this sucks, but it's the only way to make a border */
|
||||||
cogl_rectangle (priv->border_width, 0,
|
cogl_rectangle (priv->border_width, 0,
|
||||||
@ -124,15 +140,16 @@ clutter_rectangle_paint (ClutterActor *self)
|
|||||||
priv->border_width,
|
priv->border_width,
|
||||||
geom.height - priv->border_width);
|
geom.height - priv->border_width);
|
||||||
|
|
||||||
tmp_alpha = clutter_actor_get_paint_opacity (self)
|
tmp_alpha = opacity * priv->primary_color.alpha / 255;
|
||||||
* priv->color.alpha
|
|
||||||
/ 255;
|
|
||||||
|
|
||||||
/* now paint the rectangle */
|
/* now paint the rectangle */
|
||||||
cogl_set_source_color4ub (priv->color.red,
|
cogl_set_source (priv->primary_material);
|
||||||
priv->color.green,
|
|
||||||
priv->color.blue,
|
cogl_material_set_color4ub (priv->primary_material,
|
||||||
tmp_alpha);
|
priv->primary_color.red,
|
||||||
|
priv->primary_color.green,
|
||||||
|
priv->primary_color.blue,
|
||||||
|
tmp_alpha);
|
||||||
|
|
||||||
cogl_rectangle (priv->border_width, priv->border_width,
|
cogl_rectangle (priv->border_width, priv->border_width,
|
||||||
geom.width - priv->border_width,
|
geom.width - priv->border_width,
|
||||||
@ -143,14 +160,16 @@ clutter_rectangle_paint (ClutterActor *self)
|
|||||||
/* compute the composited opacity of the actor taking into
|
/* compute the composited opacity of the actor taking into
|
||||||
* account the opacity of the color set by the user
|
* account the opacity of the color set by the user
|
||||||
*/
|
*/
|
||||||
tmp_alpha = clutter_actor_get_paint_opacity (self)
|
tmp_alpha = opacity * priv->primary_color.alpha / 255;
|
||||||
* priv->color.alpha
|
|
||||||
/ 255;
|
|
||||||
|
|
||||||
cogl_set_source_color4ub (priv->color.red,
|
/* now paint the rectangle */
|
||||||
priv->color.green,
|
cogl_set_source (priv->primary_material);
|
||||||
priv->color.blue,
|
|
||||||
tmp_alpha);
|
cogl_material_set_color4ub (priv->primary_material,
|
||||||
|
priv->primary_color.red,
|
||||||
|
priv->primary_color.green,
|
||||||
|
priv->primary_color.blue,
|
||||||
|
tmp_alpha);
|
||||||
|
|
||||||
cogl_rectangle (0, 0, geom.width, geom.height);
|
cogl_rectangle (0, 0, geom.width, geom.height);
|
||||||
}
|
}
|
||||||
@ -197,7 +216,7 @@ clutter_rectangle_get_property (GObject *object,
|
|||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_COLOR:
|
case PROP_COLOR:
|
||||||
clutter_value_set_color (value, &priv->color);
|
clutter_value_set_color (value, &priv->primary_color);
|
||||||
break;
|
break;
|
||||||
case PROP_BORDER_COLOR:
|
case PROP_BORDER_COLOR:
|
||||||
clutter_value_set_color (value, &priv->border_color);
|
clutter_value_set_color (value, &priv->border_color);
|
||||||
@ -308,8 +327,10 @@ clutter_rectangle_init (ClutterRectangle *self)
|
|||||||
|
|
||||||
self->priv = priv = CLUTTER_RECTANGLE_GET_PRIVATE (self);
|
self->priv = priv = CLUTTER_RECTANGLE_GET_PRIVATE (self);
|
||||||
|
|
||||||
priv->color = default_color;
|
priv->primary_color = default_color;
|
||||||
priv->border_color = default_border_color;
|
priv->border_color = default_border_color;
|
||||||
|
priv->primary_material = cogl_material_new ();
|
||||||
|
priv->border_material = cogl_material_new ();
|
||||||
|
|
||||||
priv->border_width = 0;
|
priv->border_width = 0;
|
||||||
|
|
||||||
@ -364,10 +385,10 @@ clutter_rectangle_get_color (ClutterRectangle *rectangle,
|
|||||||
|
|
||||||
priv = rectangle->priv;
|
priv = rectangle->priv;
|
||||||
|
|
||||||
color->red = priv->color.red;
|
color->red = priv->primary_color.red;
|
||||||
color->green = priv->color.green;
|
color->green = priv->primary_color.green;
|
||||||
color->blue = priv->color.blue;
|
color->blue = priv->primary_color.blue;
|
||||||
color->alpha = priv->color.alpha;
|
color->alpha = priv->primary_color.alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -390,10 +411,10 @@ clutter_rectangle_set_color (ClutterRectangle *rectangle,
|
|||||||
|
|
||||||
priv = rectangle->priv;
|
priv = rectangle->priv;
|
||||||
|
|
||||||
priv->color.red = color->red;
|
priv->primary_color.red = color->red;
|
||||||
priv->color.green = color->green;
|
priv->primary_color.green = color->green;
|
||||||
priv->color.blue = color->blue;
|
priv->primary_color.blue = color->blue;
|
||||||
priv->color.alpha = color->alpha;
|
priv->primary_color.alpha = color->alpha;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* FIXME - appears to be causing border to always get drawn */
|
/* FIXME - appears to be causing border to always get drawn */
|
||||||
@ -525,7 +546,7 @@ clutter_rectangle_set_border_color (ClutterRectangle *rectangle,
|
|||||||
priv->border_color.blue = color->blue;
|
priv->border_color.blue = color->blue;
|
||||||
priv->border_color.alpha = color->alpha;
|
priv->border_color.alpha = color->alpha;
|
||||||
|
|
||||||
if (clutter_color_equal (&priv->color, &priv->border_color))
|
if (clutter_color_equal (&priv->primary_color, &priv->border_color))
|
||||||
priv->has_border = FALSE;
|
priv->has_border = FALSE;
|
||||||
else
|
else
|
||||||
priv->has_border = TRUE;
|
priv->has_border = TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user