st: Switch to render nodes

Switch to render nodes. Most of the changes follow the pattern of
replacing a cogl_framebuffer_draw_*() call by (1) creating a paint
node, and (2) calling the corresponding clutter_paint_node_add_*()
API.

StWidget now overrides ClutterActor.paint_node(), instead of paint.
All subclasses that overrided the paint vfunc also are changed to
override paint_node.

The entry point for CSS rendering, st_widget_paint_background(), now
receives a root ClutterPaintNode, and propagates it to the rendering
machinery.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1538>
This commit is contained in:
Georges Basile Stavracas Neto 2020-12-10 17:21:11 -03:00 committed by Jonas Ådahl
parent 0cdddaa4a7
commit a96868d1b0
16 changed files with 398 additions and 272 deletions

View File

@ -817,13 +817,12 @@ st_entry_leave_event (ClutterActor *actor,
} }
static void static void
st_entry_paint (ClutterActor *actor, st_entry_paint_node (ClutterActor *actor,
ClutterPaintContext *paint_context) ClutterPaintNode *node)
{ {
StEntryPrivate *priv = ST_ENTRY_PRIV (actor); StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
ClutterActorClass *parent_class;
st_widget_paint_background (ST_WIDGET (actor), paint_context); st_widget_paint_background (ST_WIDGET (actor), node);
if (priv->shadow_spec) if (priv->shadow_spec)
{ {
@ -851,23 +850,13 @@ st_entry_paint (ClutterActor *actor,
if (priv->text_shadow_material != NULL) if (priv->text_shadow_material != NULL)
{ {
CoglFramebuffer *framebuffer =
clutter_paint_context_get_framebuffer (paint_context);
_st_paint_shadow_with_opacity (priv->shadow_spec, _st_paint_shadow_with_opacity (priv->shadow_spec,
framebuffer, node,
priv->text_shadow_material, priv->text_shadow_material,
&allocation, &allocation,
clutter_actor_get_paint_opacity (priv->entry)); clutter_actor_get_paint_opacity (priv->entry));
} }
} }
/* Since we paint the background ourselves, chain to the parent class
* of StWidget, to avoid painting it twice.
* This is needed as we still want to paint children.
*/
parent_class = g_type_class_peek_parent (st_entry_parent_class);
parent_class->paint (actor, paint_context);
} }
static void static void
@ -901,7 +890,7 @@ st_entry_class_init (StEntryClass *klass)
actor_class->get_preferred_width = st_entry_get_preferred_width; actor_class->get_preferred_width = st_entry_get_preferred_width;
actor_class->get_preferred_height = st_entry_get_preferred_height; actor_class->get_preferred_height = st_entry_get_preferred_height;
actor_class->allocate = st_entry_allocate; actor_class->allocate = st_entry_allocate;
actor_class->paint = st_entry_paint; actor_class->paint_node = st_entry_paint_node;
actor_class->unmap = st_entry_unmap; actor_class->unmap = st_entry_unmap;
actor_class->get_paint_volume = st_entry_get_paint_volume; actor_class->get_paint_volume = st_entry_get_paint_volume;

View File

@ -200,13 +200,13 @@ st_icon_dispose (GObject *gobject)
} }
static void static void
st_icon_paint (ClutterActor *actor, st_icon_paint_node (ClutterActor *actor,
ClutterPaintContext *paint_context) ClutterPaintNode *node)
{ {
StIcon *icon = ST_ICON (actor); StIcon *icon = ST_ICON (actor);
StIconPrivate *priv = icon->priv; StIconPrivate *priv = icon->priv;
st_widget_paint_background (ST_WIDGET (actor), paint_context); st_widget_paint_background (ST_WIDGET (actor), node);
if (priv->icon_texture) if (priv->icon_texture)
{ {
@ -215,18 +215,14 @@ st_icon_paint (ClutterActor *actor,
if (priv->shadow_pipeline) if (priv->shadow_pipeline)
{ {
ClutterActorBox allocation; ClutterActorBox allocation;
CoglFramebuffer *framebuffer;
clutter_actor_get_allocation_box (priv->icon_texture, &allocation); clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
_st_paint_shadow_with_opacity (priv->shadow_spec, _st_paint_shadow_with_opacity (priv->shadow_spec,
framebuffer, node,
priv->shadow_pipeline, priv->shadow_pipeline,
&allocation, &allocation,
clutter_actor_get_paint_opacity (priv->icon_texture)); clutter_actor_get_paint_opacity (priv->icon_texture));
} }
clutter_actor_paint (priv->icon_texture, paint_context);
} }
} }
@ -300,7 +296,7 @@ st_icon_class_init (StIconClass *klass)
object_class->set_property = st_icon_set_property; object_class->set_property = st_icon_set_property;
object_class->dispose = st_icon_dispose; object_class->dispose = st_icon_dispose;
actor_class->paint = st_icon_paint; actor_class->paint_node = st_icon_paint_node;
widget_class->style_changed = st_icon_style_changed; widget_class->style_changed = st_icon_style_changed;
actor_class->resource_scale_changed = st_icon_resource_scale_changed; actor_class->resource_scale_changed = st_icon_resource_scale_changed;

View File

@ -205,12 +205,12 @@ st_label_dispose (GObject *object)
} }
static void static void
st_label_paint (ClutterActor *actor, st_label_paint_node (ClutterActor *actor,
ClutterPaintContext *paint_context) ClutterPaintNode *node)
{ {
StLabelPrivate *priv = ST_LABEL (actor)->priv; StLabelPrivate *priv = ST_LABEL (actor)->priv;
st_widget_paint_background (ST_WIDGET (actor), paint_context); st_widget_paint_background (ST_WIDGET (actor), node);
if (priv->shadow_spec) if (priv->shadow_spec)
{ {
@ -241,19 +241,13 @@ st_label_paint (ClutterActor *actor,
if (priv->text_shadow_pipeline != NULL) if (priv->text_shadow_pipeline != NULL)
{ {
CoglFramebuffer *framebuffer;
framebuffer =
clutter_paint_context_get_framebuffer (paint_context);
_st_paint_shadow_with_opacity (priv->shadow_spec, _st_paint_shadow_with_opacity (priv->shadow_spec,
framebuffer, node,
priv->text_shadow_pipeline, priv->text_shadow_pipeline,
&allocation, &allocation,
clutter_actor_get_paint_opacity (priv->label)); clutter_actor_get_paint_opacity (priv->label));
} }
} }
clutter_actor_paint (priv->label, paint_context);
} }
static void static void
@ -278,7 +272,7 @@ st_label_class_init (StLabelClass *klass)
gobject_class->get_property = st_label_get_property; gobject_class->get_property = st_label_get_property;
gobject_class->dispose = st_label_dispose; gobject_class->dispose = st_label_dispose;
actor_class->paint = st_label_paint; actor_class->paint_node = st_label_paint_node;
actor_class->allocate = st_label_allocate; actor_class->allocate = st_label_allocate;
actor_class->get_preferred_width = st_label_get_preferred_width; actor_class->get_preferred_width = st_label_get_preferred_width;
actor_class->get_preferred_height = st_label_get_preferred_height; actor_class->get_preferred_height = st_label_get_preferred_height;

View File

@ -773,12 +773,13 @@ _st_create_shadow_cairo_pattern (StShadow *shadow_spec_in,
} }
void void
_st_paint_shadow_with_opacity (StShadow *shadow_spec, _st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
CoglPipeline *shadow_pipeline, CoglPipeline *shadow_pipeline,
ClutterActorBox *box, ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
ClutterActorBox shadow_box; ClutterActorBox shadow_box;
CoglColor color; CoglColor color;
@ -794,8 +795,8 @@ _st_paint_shadow_with_opacity (StShadow *shadow_spec,
shadow_spec->color.alpha / 255.0 * paint_opacity / 255.0); shadow_spec->color.alpha / 255.0 * paint_opacity / 255.0);
cogl_color_premultiply (&color); cogl_color_premultiply (&color);
cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color); cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color);
cogl_framebuffer_draw_rectangle (framebuffer,
shadow_pipeline, pipeline_node = clutter_pipeline_node_new (shadow_pipeline);
shadow_box.x1, shadow_box.y1, clutter_paint_node_add_child (node, pipeline_node);
shadow_box.x2, shadow_box.y2); clutter_paint_node_add_rectangle (pipeline_node, &shadow_box);
} }

View File

@ -66,10 +66,10 @@ CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec, cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec,
cairo_pattern_t *src_pattern); cairo_pattern_t *src_pattern);
void _st_paint_shadow_with_opacity (StShadow *shadow_spec, void _st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
CoglPipeline *shadow_pipeline, CoglPipeline *shadow_pipeline,
ClutterActorBox *box, ClutterActorBox *box,
guint8 paint_opacity); guint8 paint_opacity);
#endif /* __ST_PRIVATE_H__ */ #endif /* __ST_PRIVATE_H__ */

View File

@ -281,7 +281,7 @@ st_shadow_helper_free (StShadowHelper *helper)
/** /**
* st_shadow_helper_paint: * st_shadow_helper_paint:
* @helper: a #StShadowHelper * @helper: a #StShadowHelper
* @framebuffer: a #CoglFramebuffer * @node: a #ClutterPaintNode
* @actor_box: the bounding box of the shadow * @actor_box: the bounding box of the shadow
* @paint_opacity: the opacity at which the shadow is painted * @paint_opacity: the opacity at which the shadow is painted
* *
@ -289,13 +289,13 @@ st_shadow_helper_free (StShadowHelper *helper)
* be called from the implementation of ClutterActor::paint(). * be called from the implementation of ClutterActor::paint().
*/ */
void void
st_shadow_helper_paint (StShadowHelper *helper, st_shadow_helper_paint (StShadowHelper *helper,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
ClutterActorBox *actor_box, ClutterActorBox *actor_box,
guint8 paint_opacity) uint8_t paint_opacity)
{ {
_st_paint_shadow_with_opacity (helper->shadow, _st_paint_shadow_with_opacity (helper->shadow,
framebuffer, node,
helper->pipeline, helper->pipeline,
actor_box, actor_box,
paint_opacity); paint_opacity);

View File

@ -84,10 +84,10 @@ void st_shadow_helper_free (StShadowHelper *helper);
void st_shadow_helper_update (StShadowHelper *helper, void st_shadow_helper_update (StShadowHelper *helper,
ClutterActor *source); ClutterActor *source);
void st_shadow_helper_paint (StShadowHelper *helper, void st_shadow_helper_paint (StShadowHelper *helper,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
ClutterActorBox *actor_box, ClutterActorBox *actor_box,
guint8 paint_opacity); uint8_t paint_opacity);
G_END_DECLS G_END_DECLS

View File

@ -1363,7 +1363,7 @@ st_theme_node_prerender_background (StThemeNode *node,
} }
static void st_theme_node_paint_borders (StThemeNodePaintState *state, static void st_theme_node_paint_borders (StThemeNodePaintState *state,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
const ClutterActorBox *box, const ClutterActorBox *box,
StPaintBordersMode mode, StPaintBordersMode mode,
guint8 paint_opacity); guint8 paint_opacity);
@ -1667,12 +1667,13 @@ st_theme_node_update_resources (StThemeNodePaintState *state,
} }
static void static void
paint_material_with_opacity (CoglPipeline *material, paint_material_with_opacity (ClutterPaintNode *node,
CoglFramebuffer *framebuffer, CoglPipeline *material,
ClutterActorBox *box, ClutterActorBox *box,
ClutterActorBox *coords, ClutterActorBox *coords,
guint8 paint_opacity) guint8 paint_opacity)
{ {
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
CoglColor color; CoglColor color;
cogl_color_init_from_4f (&color, cogl_color_init_from_4f (&color,
@ -1680,37 +1681,20 @@ paint_material_with_opacity (CoglPipeline *material,
paint_opacity / 255.0, paint_opacity / 255.0); paint_opacity / 255.0, paint_opacity / 255.0);
cogl_pipeline_set_color (material, &color); cogl_pipeline_set_color (material, &color);
pipeline_node = clutter_pipeline_node_new (material);
clutter_paint_node_add_child (node, pipeline_node);
if (coords) if (coords)
cogl_framebuffer_draw_textured_rectangle (framebuffer, material, clutter_paint_node_add_texture_rectangle (pipeline_node, box,
box->x1, box->y1, box->x2, box->y2, coords->x1, coords->y1,
coords->x1, coords->y1, coords->x2, coords->y2); coords->x2, coords->y2);
else else
cogl_framebuffer_draw_rectangle (framebuffer, material, clutter_paint_node_add_rectangle (pipeline_node, box);
box->x1, box->y1, box->x2, box->y2);
}
static void
st_theme_node_ensure_color_pipeline (StThemeNode *node)
{
static CoglPipeline *color_pipeline_template = NULL;
if (node->color_pipeline != NULL)
return;
if (G_UNLIKELY (color_pipeline_template == NULL))
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
color_pipeline_template = cogl_pipeline_new (ctx);
}
node->color_pipeline = cogl_pipeline_copy (color_pipeline_template);
} }
static void static void
st_theme_node_paint_borders (StThemeNodePaintState *state, st_theme_node_paint_borders (StThemeNodePaintState *state,
CoglFramebuffer *framebuffer, ClutterPaintNode *root,
const ClutterActorBox *box, const ClutterActorBox *box,
StPaintBordersMode mode, StPaintBordersMode mode,
guint8 paint_opacity) guint8 paint_opacity)
@ -1766,13 +1750,14 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
if (alpha > 0) if (alpha > 0)
{ {
st_theme_node_ensure_color_pipeline (node); g_autoptr (ClutterPaintNode) border_color_node = NULL;
cogl_color_init_from_4f (&pipeline_color, CoglColor color;
effective_border.red / 255.0 * alpha / 255.0,
effective_border.green / 255.0 * alpha / 255.0, cogl_color_init_from_4f (&color,
effective_border.blue / 255.0 * alpha / 255.0, effective_border.red / 255.0f,
alpha / 255.0); effective_border.green / 255.0f,
cogl_pipeline_set_color (node->color_pipeline, &pipeline_color); effective_border.blue / 255.0f,
alpha / 255.0f);
/* NORTH */ /* NORTH */
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0; skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
@ -1815,9 +1800,11 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT] rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
: height - border_width[ST_SIDE_BOTTOM]; : height - border_width[ST_SIDE_BOTTOM];
cogl_framebuffer_draw_rectangles (framebuffer, border_color_node = clutter_color_node_new (&color);
node->color_pipeline, clutter_paint_node_set_static_name (border_color_node,
rects, 4); "StThemeNode (CSS borders)");
clutter_paint_node_add_child (root, border_color_node);
clutter_paint_node_add_rectangles (border_color_node, rects, 4);
} }
} }
@ -1833,44 +1820,67 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
{ {
for (corner_id = 0; corner_id < 4; corner_id++) for (corner_id = 0; corner_id < 4; corner_id++)
{ {
g_autoptr (ClutterPaintNode) corners_node = NULL;
if (state->corner_material[corner_id] == NULL) if (state->corner_material[corner_id] == NULL)
continue; continue;
cogl_pipeline_set_color (state->corner_material[corner_id], &pipeline_color); cogl_pipeline_set_color (state->corner_material[corner_id], &pipeline_color);
corners_node =
clutter_pipeline_node_new (state->corner_material[corner_id]);
clutter_paint_node_set_static_name (corners_node,
"StThemeNode (CSS border corners)");
clutter_paint_node_add_child (root, corners_node);
switch (corner_id) switch (corner_id)
{ {
case ST_CORNER_TOPLEFT: case ST_CORNER_TOPLEFT:
cogl_framebuffer_draw_textured_rectangle (framebuffer, clutter_paint_node_add_texture_rectangle (corners_node,
state->corner_material[corner_id], 0, 0, &(ClutterActorBox) {
max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT], 0, 0,
0, 0, 0.5, 0.5); max_width_radius[ST_CORNER_TOPLEFT],
break; max_width_radius[ST_CORNER_TOPLEFT],
case ST_CORNER_TOPRIGHT: },
cogl_framebuffer_draw_textured_rectangle (framebuffer, 0.0, 0.0,
state->corner_material[corner_id], 0.5, 0.5);
width - max_width_radius[ST_CORNER_TOPRIGHT], 0, break;
width, max_width_radius[ST_CORNER_TOPRIGHT], case ST_CORNER_TOPRIGHT:
0.5, 0, 1, 0.5); clutter_paint_node_add_texture_rectangle (corners_node,
break; &(ClutterActorBox) {
case ST_CORNER_BOTTOMRIGHT: width - max_width_radius[ST_CORNER_TOPRIGHT],
cogl_framebuffer_draw_textured_rectangle (framebuffer, 0,
state->corner_material[corner_id], width,
width - max_width_radius[ST_CORNER_BOTTOMRIGHT], max_width_radius[ST_CORNER_TOPRIGHT],
height - max_width_radius[ST_CORNER_BOTTOMRIGHT], },
width, height, 0.5, 0.0,
0.5, 0.5, 1, 1); 1.0, 0.5);
break; break;
case ST_CORNER_BOTTOMLEFT: case ST_CORNER_BOTTOMRIGHT:
cogl_framebuffer_draw_textured_rectangle (framebuffer, clutter_paint_node_add_texture_rectangle (corners_node,
state->corner_material[corner_id], &(ClutterActorBox) {
0, height - max_width_radius[ST_CORNER_BOTTOMLEFT], width - max_width_radius[ST_CORNER_BOTTOMRIGHT],
max_width_radius[ST_CORNER_BOTTOMLEFT], height, height - max_width_radius[ST_CORNER_BOTTOMRIGHT],
0, 0.5, 0.5, 1); width,
break; height,
default: },
g_assert_not_reached(); 0.5, 0.5,
break; 1.0, 1.0);
break;
case ST_CORNER_BOTTOMLEFT:
clutter_paint_node_add_texture_rectangle (corners_node,
&(ClutterActorBox) {
0,
height - max_width_radius[ST_CORNER_BOTTOMLEFT],
max_width_radius[ST_CORNER_BOTTOMLEFT],
height,
},
0.0, 0.5,
0.5, 1.0);
break;
default:
g_assert_not_reached();
break;
} }
} }
} }
@ -1881,13 +1891,20 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
paint_opacity * node->background_color.alpha / 255; paint_opacity * node->background_color.alpha / 255;
if (alpha > 0) if (alpha > 0)
{ {
st_theme_node_ensure_color_pipeline (node); g_autoptr (ClutterPaintNode) background_color_node = NULL;
cogl_color_init_from_4f (&pipeline_color, CoglColor color;
node->background_color.red / 255.0 * alpha / 255.0,
node->background_color.green / 255.0 * alpha / 255.0, cogl_color_init_from_4f (&color,
node->background_color.blue / 255.0 * alpha / 255.0, node->background_color.red / 255.0f,
alpha / 255.0); node->background_color.green / 255.0f,
cogl_pipeline_set_color (node->color_pipeline, &pipeline_color); node->background_color.blue / 255.0f,
alpha / 255.0f);
background_color_node = clutter_color_node_new (&color);
clutter_paint_node_set_static_name (background_color_node,
"StThemeNode (CSS background color)");
clutter_paint_node_add_child (root, background_color_node);
/* We add padding to each corner, so that all corners end up as if they /* We add padding to each corner, so that all corners end up as if they
* had a border-radius of max_border_radius, which allows us to treat * had a border-radius of max_border_radius, which allows us to treat
* corners as uniform further on. * corners as uniform further on.
@ -1973,9 +1990,10 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
g_assert_not_reached(); g_assert_not_reached();
break; break;
} }
cogl_framebuffer_draw_rectangles (framebuffer,
node->color_pipeline, clutter_paint_node_add_rectangles (background_color_node,
verts, n_rects); verts,
n_rects);
} }
/* Once we've drawn the borders and corners, if the corners are bigger /* Once we've drawn the borders and corners, if the corners are bigger
@ -1990,32 +2008,44 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
* necessary, then the main rectangle * necessary, then the main rectangle
*/ */
if (max_border_radius > border_width[ST_SIDE_TOP]) if (max_border_radius > border_width[ST_SIDE_TOP])
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, {
MAX(max_border_radius, border_width[ST_SIDE_LEFT]), clutter_paint_node_add_rectangle (background_color_node,
border_width[ST_SIDE_TOP], &(ClutterActorBox) {
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), MAX (max_border_radius, border_width[ST_SIDE_LEFT]),
max_border_radius); border_width[ST_SIDE_TOP],
if (max_border_radius > border_width[ST_SIDE_BOTTOM]) width - MAX (max_border_radius, border_width[ST_SIDE_RIGHT]),
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, max_border_radius,
MAX(max_border_radius, border_width[ST_SIDE_LEFT]), });
height - max_border_radius, }
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
height - border_width[ST_SIDE_BOTTOM]);
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, if (max_border_radius > border_width[ST_SIDE_BOTTOM])
border_width[ST_SIDE_LEFT], {
MAX(border_width[ST_SIDE_TOP], max_border_radius), clutter_paint_node_add_rectangle (background_color_node,
width - border_width[ST_SIDE_RIGHT], &(ClutterActorBox) {
height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius)); MAX (max_border_radius, border_width[ST_SIDE_LEFT]),
height - max_border_radius,
width - MAX (max_border_radius, border_width[ST_SIDE_RIGHT]),
height - border_width[ST_SIDE_BOTTOM],
});
}
clutter_paint_node_add_rectangle (background_color_node,
&(ClutterActorBox) {
border_width[ST_SIDE_LEFT],
MAX (border_width[ST_SIDE_TOP], max_border_radius),
width - border_width[ST_SIDE_RIGHT],
height - MAX (border_width[ST_SIDE_BOTTOM], max_border_radius)
});
} }
} }
static void static void
st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state, st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
CoglFramebuffer *framebuffer, ClutterPaintNode *root,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
StThemeNode *node = state->node; StThemeNode *node = state->node;
guint border_radius[4]; guint border_radius[4];
CoglColor color; CoglColor color;
@ -2261,50 +2291,118 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
} }
} }
cogl_framebuffer_draw_textured_rectangles (framebuffer, state->box_shadow_pipeline, pipeline_node = clutter_pipeline_node_new (state->box_shadow_pipeline);
rectangles, idx / 8); clutter_paint_node_set_static_name (pipeline_node,
"StThemeNode (CSS box-shadow)");
clutter_paint_node_add_child (root, pipeline_node);
clutter_paint_node_add_texture_rectangles (pipeline_node,
rectangles,
idx / 8);
#if 0 #if 0
g_autoptr (ClutterPaintNode) color_node = NULL;
CoglColor red;
/* Visual feedback on shadow's 9-slice and original offscreen buffer, /* Visual feedback on shadow's 9-slice and original offscreen buffer,
for debug purposes */ for debug purposes */
cogl_framebuffer_draw_rectangle (framebuffer, state->box_shadow_pipeline, clutter_paint_node_add_rectangle (pipeline_node,
xend, yoffset, xend + shadow_width, yoffset + shadow_height); &(ClutterActorBox) {
xend,
yoffset,
xend + shadow_width,
yoffset + shadow_height,
});
st_theme_node_ensure_color_pipeline (node); cogl_color_init_from_4f (&red, 1.0, 0.0, 0.0, 1.0);
cogl_color_init_from_4f (&color, 1.0, 0.0, 0.0, 1.0); cogl_pipeline_set_color (node->color_pipeline, &red);
cogl_pipeline_set_color (node->color_pipeline, &color); color_node = clutter_color_node_new (&red);
clutter_paint_node_set_static_name (color_node,
"StThemeNode (CSS box-shadow - debug)");
clutter_paint_node_add_child (root, color_node);
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, clutter_paint_node_add_rectangle (color_node,
xoffset, top, xend, top + 1); &(ClutterActorBox) {
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, xoffset,
xoffset, bottom, xend, bottom + 1); top,
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, xend,
left, yoffset, left + 1, yend); top + 1,
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, });
right, yoffset, right + 1, yend); clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
xoffset,
bottom,
xend,
bottom + 1,
});
clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
left,
yoffset,
left + 1,
yend,
});
clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
right,
yoffset,
right + 1,
yend,
});
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, clutter_paint_node_add_rectangle (color_node,
xend, yoffset, xend + shadow_width, yoffset + 1); &(ClutterActorBox) {
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, xend,
xend, yoffset + shadow_height, xend + shadow_width, yoffset + shadow_height + 1); yoffset,
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, xend + shadow_width,
xend, yoffset, xend + 1, yoffset + shadow_height); yoffset + 1,
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, });
xend + shadow_width, yoffset, xend + shadow_width + 1, yoffset + shadow_height); clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
xend,
yoffset + shadow_height,
xend + shadow_width,
yoffset + shadow_height + 1,
});
clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
xend,
yoffset,
xend + 1,
yoffset + shadow_height,
});
clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
xend + shadow_width,
yoffset,
xend + shadow_width + 1,
yoffset + shadow_height,
});
s_top *= shadow_height; s_top *= shadow_height;
s_bottom *= shadow_height; s_bottom *= shadow_height;
s_left *= shadow_width; s_left *= shadow_width;
s_right *= shadow_width; s_right *= shadow_width;
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, clutter_paint_node_add_rectangle (color_node,
xend, yoffset + s_top, xend + shadow_width, yoffset + s_top + 1); &(ClutterActorBox) {
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, xend, yoffset + s_top,
xend, yoffset + s_bottom, xend + shadow_width, yoffset + s_bottom + 1); xend + shadow_width, yoffset + s_top + 1,
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, });
xend + s_left, yoffset, xend + s_left + 1, yoffset + shadow_height); clutter_paint_node_add_rectangle (color_node,
cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline, &(ClutterActorBox) {
xend + s_right, yoffset, xend + s_right + 1, yoffset + shadow_height); xend, yoffset + s_bottom,
xend + shadow_width, yoffset + s_bottom + 1,
});
clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
xend + s_left, yoffset,
xend + s_left + 1, yoffset + shadow_height,
});
clutter_paint_node_add_rectangle (color_node,
&(ClutterActorBox) {
xend + s_right, yoffset,
xend + s_right + 1, yoffset + shadow_height,
});
#endif #endif
} }
@ -2334,6 +2432,9 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
if (cogl_framebuffer_allocate (framebuffer, &error)) if (cogl_framebuffer_allocate (framebuffer, &error))
{ {
g_autoptr (ClutterPaintNode) root_node = NULL;
ClutterPaintContext *paint_context;
CoglColor clear_color;
ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height}; ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height};
cogl_framebuffer_orthographic (framebuffer, 0, 0, cogl_framebuffer_orthographic (framebuffer, 0, 0,
@ -2341,9 +2442,21 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
cogl_framebuffer_scale (framebuffer, cogl_framebuffer_scale (framebuffer,
state->resource_scale, state->resource_scale,
state->resource_scale, 1); state->resource_scale, 1);
cogl_framebuffer_clear4f (framebuffer, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 0);
st_theme_node_paint_borders (state, framebuffer, &box, ST_PAINT_BORDERS_MODE_SILHOUETTE, 0xFF); cogl_color_init_from_4f (&clear_color, 0, 0, 0, 0);
root_node = clutter_root_node_new (framebuffer,
&clear_color,
COGL_BUFFER_BIT_COLOR);
st_theme_node_paint_borders (state, root_node, &box,
ST_PAINT_BORDERS_MODE_SILHOUETTE, 0xff);
paint_context =
clutter_paint_context_new_for_framebuffer (framebuffer,
NULL,
CLUTTER_PAINT_FLAG_NONE);
clutter_paint_node_paint (root_node, paint_context);
clutter_paint_context_destroy (paint_context);
state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node), state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node),
buffer, state->resource_scale); buffer, state->resource_scale);
@ -2388,12 +2501,13 @@ st_theme_node_compute_maximum_borders (StThemeNodePaintState *state)
} }
static void static void
st_theme_node_paint_sliced_border_image (StThemeNode *node, st_theme_node_paint_sliced_border_image (StThemeNode *node,
CoglFramebuffer *framebuffer, ClutterPaintNode *root,
float width, float width,
float height, float height,
guint8 paint_opacity) guint8 paint_opacity)
{ {
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
gfloat ex, ey; gfloat ex, ey;
gfloat tx1, ty1, tx2, ty2; gfloat tx1, ty1, tx2, ty2;
gint border_left, border_right, border_top, border_bottom; gint border_left, border_right, border_top, border_bottom;
@ -2479,21 +2593,27 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
1.0, 1.0 1.0, 1.0
}; };
cogl_framebuffer_draw_textured_rectangles (framebuffer, pipeline, rectangles, 9); pipeline_node = clutter_pipeline_node_new (pipeline);
clutter_paint_node_set_static_name (pipeline_node,
"StThemeNode (CSS border image)");
clutter_paint_node_add_child (root, pipeline_node);
clutter_paint_node_add_texture_rectangles (pipeline_node, rectangles, 9);
} }
} }
static void static void
st_theme_node_paint_outline (StThemeNode *node, st_theme_node_paint_outline (StThemeNode *node,
CoglFramebuffer *framebuffer, ClutterPaintNode *root,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
g_autoptr (ClutterPaintNode) outline_node = NULL;
CoglColor color;
float width, height; float width, height;
int outline_width; int outline_width;
float rects[16]; float rects[16];
CoglColor outline_color, effective_outline, pipeline_color; CoglColor outline_color, effective_outline;
guint8 alpha; guint8 alpha;
width = box->x2 - box->x1; width = box->x2 - box->x1;
@ -2508,13 +2628,11 @@ st_theme_node_paint_outline (StThemeNode *node,
alpha = paint_opacity * outline_color.alpha / 255; alpha = paint_opacity * outline_color.alpha / 255;
st_theme_node_ensure_color_pipeline (node); cogl_color_init_from_4f (&color,
cogl_color_init_from_4f (&pipeline_color, effective_outline.red / 255.0f,
effective_outline.red / 255.0 * alpha / 255.0, effective_outline.green / 255.0f,
effective_outline.green / 255.0 * alpha / 255.0, effective_outline.blue / 255.0f,
effective_outline.blue / 255.0 * alpha / 255.0, alpha / 255.0f);
alpha / 255.0);
cogl_pipeline_set_color (node->color_pipeline, &pipeline_color);
/* The outline is drawn just outside the border, which means just /* The outline is drawn just outside the border, which means just
* outside the allocation box. This means that in some situations * outside the allocation box. This means that in some situations
@ -2546,7 +2664,11 @@ st_theme_node_paint_outline (StThemeNode *node,
rects[14] = 0; rects[14] = 0;
rects[15] = height; rects[15] = height;
cogl_framebuffer_draw_rectangles (framebuffer, node->color_pipeline, rects, 4); outline_node = clutter_color_node_new (&color);
clutter_paint_node_set_static_name (outline_node,
"StThemeNode (CSS outline)");
clutter_paint_node_add_child (root, outline_node);
clutter_paint_node_add_rectangles (outline_node, rects, 4);
} }
static gboolean static gboolean
@ -2594,7 +2716,7 @@ st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state,
void void
st_theme_node_paint (StThemeNode *node, st_theme_node_paint (StThemeNode *node,
StThemeNodePaintState *state, StThemeNodePaintState *state,
CoglFramebuffer *framebuffer, ClutterPaintNode *root,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity, guint8 paint_opacity,
float resource_scale) float resource_scale)
@ -2669,13 +2791,13 @@ st_theme_node_paint (StThemeNode *node,
if (state->alloc_width < node->box_shadow_min_width || if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height) state->alloc_height < node->box_shadow_min_height)
_st_paint_shadow_with_opacity (node->box_shadow, _st_paint_shadow_with_opacity (node->box_shadow,
framebuffer, root,
state->box_shadow_pipeline, state->box_shadow_pipeline,
&allocation, &allocation,
paint_opacity); paint_opacity);
else else
st_theme_node_paint_sliced_shadow (state, st_theme_node_paint_sliced_shadow (state,
framebuffer, root,
&allocation, &allocation,
paint_opacity); paint_opacity);
} }
@ -2691,22 +2813,22 @@ st_theme_node_paint (StThemeNode *node,
&allocation, &allocation,
&paint_box); &paint_box);
paint_material_with_opacity (state->prerendered_pipeline, paint_material_with_opacity (root,
framebuffer, state->prerendered_pipeline,
&paint_box, &paint_box,
NULL, NULL,
paint_opacity); paint_opacity);
} }
if (node->border_slices_pipeline != NULL) if (node->border_slices_pipeline != NULL)
st_theme_node_paint_sliced_border_image (node, framebuffer, width, height, paint_opacity); st_theme_node_paint_sliced_border_image (node, root, width, height, paint_opacity);
} }
else else
{ {
st_theme_node_paint_borders (state, framebuffer, box, ST_PAINT_BORDERS_MODE_COLOR, paint_opacity); st_theme_node_paint_borders (state, root, box, ST_PAINT_BORDERS_MODE_COLOR, paint_opacity);
} }
st_theme_node_paint_outline (node, framebuffer, box, paint_opacity); st_theme_node_paint_outline (node, root, box, paint_opacity);
if (state->prerendered_pipeline == NULL && if (state->prerendered_pipeline == NULL &&
st_theme_node_load_background_image (node, resource_scale)) st_theme_node_load_background_image (node, resource_scale))
@ -2725,9 +2847,15 @@ st_theme_node_paint (StThemeNode *node,
&background_box, &texture_coords); &background_box, &texture_coords);
if (has_visible_outline || node->background_repeat) if (has_visible_outline || node->background_repeat)
cogl_framebuffer_push_rectangle_clip (framebuffer, {
allocation.x1, allocation.y1, g_autoptr (ClutterPaintNode) clip_node = NULL;
allocation.x2, allocation.y2);
clip_node = clutter_clip_node_new ();
clutter_paint_node_add_child (root, clip_node);
clutter_paint_node_add_rectangle (clip_node, &allocation);
root = clip_node;
}
/* CSS based drop shadows /* CSS based drop shadows
* *
@ -2744,19 +2872,16 @@ st_theme_node_paint (StThemeNode *node,
*/ */
if (node->background_shadow_pipeline != NULL) if (node->background_shadow_pipeline != NULL)
_st_paint_shadow_with_opacity (node->background_image_shadow, _st_paint_shadow_with_opacity (node->background_image_shadow,
framebuffer, root,
node->background_shadow_pipeline, node->background_shadow_pipeline,
&background_box, &background_box,
paint_opacity); paint_opacity);
paint_material_with_opacity (node->background_pipeline, paint_material_with_opacity (root,
framebuffer, node->background_pipeline,
&background_box, &background_box,
&texture_coords, &texture_coords,
paint_opacity); paint_opacity);
if (has_visible_outline || node->background_repeat)
cogl_framebuffer_pop_clip (framebuffer);
} }
} }

View File

@ -112,7 +112,6 @@ struct _StThemeNode {
CoglTexture *background_texture; CoglTexture *background_texture;
CoglPipeline *background_pipeline; CoglPipeline *background_pipeline;
CoglPipeline *background_shadow_pipeline; CoglPipeline *background_shadow_pipeline;
CoglPipeline *color_pipeline;
StThemeNodePaintState cached_state; StThemeNodePaintState cached_state;

View File

@ -244,10 +244,14 @@ st_theme_node_transition_get_paint_box (StThemeNodeTransition *transition,
static gboolean static gboolean
setup_framebuffers (StThemeNodeTransition *transition, setup_framebuffers (StThemeNodeTransition *transition,
ClutterPaintNode *node,
const ClutterActorBox *allocation, const ClutterActorBox *allocation,
float resource_scale) float resource_scale)
{ {
StThemeNodeTransitionPrivate *priv = transition->priv; StThemeNodeTransitionPrivate *priv = transition->priv;
g_autoptr (ClutterPaintNode) old_layer_node = NULL;
g_autoptr (ClutterPaintNode) new_layer_node = NULL;
CoglPipeline *noop_pipeline;
CoglContext *ctx; CoglContext *ctx;
guint width, height; guint width, height;
GError *catch_error = NULL; GError *catch_error = NULL;
@ -319,38 +323,45 @@ setup_framebuffers (StThemeNodeTransition *transition,
cogl_pipeline_set_layer_texture (priv->material, 0, priv->new_texture); cogl_pipeline_set_layer_texture (priv->material, 0, priv->new_texture);
cogl_pipeline_set_layer_texture (priv->material, 1, priv->old_texture); cogl_pipeline_set_layer_texture (priv->material, 1, priv->old_texture);
cogl_framebuffer_clear4f (priv->old_offscreen, COGL_BUFFER_BIT_COLOR, noop_pipeline = cogl_pipeline_new (ctx);
0, 0, 0, 0);
cogl_framebuffer_orthographic (priv->old_offscreen, cogl_framebuffer_orthographic (priv->old_offscreen,
priv->offscreen_box.x1, priv->offscreen_box.x1,
priv->offscreen_box.y1, priv->offscreen_box.y1,
priv->offscreen_box.x2, priv->offscreen_box.x2,
priv->offscreen_box.y2, 0.0, 1.0); priv->offscreen_box.y2, 0.0, 1.0);
st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state, old_layer_node = clutter_layer_node_new_to_framebuffer (priv->old_offscreen,
priv->old_offscreen, allocation, 255, resource_scale); noop_pipeline);
clutter_paint_node_add_child (node, old_layer_node);
cogl_framebuffer_clear4f (priv->new_offscreen, COGL_BUFFER_BIT_COLOR, st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state,
0, 0, 0, 0); old_layer_node, allocation, 255, resource_scale);
new_layer_node = clutter_layer_node_new_to_framebuffer (priv->new_offscreen,
noop_pipeline);
clutter_paint_node_add_child (node, new_layer_node);
cogl_framebuffer_orthographic (priv->new_offscreen, cogl_framebuffer_orthographic (priv->new_offscreen,
priv->offscreen_box.x1, priv->offscreen_box.x1,
priv->offscreen_box.y1, priv->offscreen_box.y1,
priv->offscreen_box.x2, priv->offscreen_box.x2,
priv->offscreen_box.y2, 0.0, 1.0); priv->offscreen_box.y2, 0.0, 1.0);
st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state, st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state,
priv->new_offscreen, allocation, 255, resource_scale); new_layer_node, allocation, 255, resource_scale);
g_clear_object (&noop_pipeline);
return TRUE; return TRUE;
} }
void void
st_theme_node_transition_paint (StThemeNodeTransition *transition, st_theme_node_transition_paint (StThemeNodeTransition *transition,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
ClutterActorBox *allocation, ClutterActorBox *allocation,
guint8 paint_opacity, guint8 paint_opacity,
float resource_scale) float resource_scale)
{ {
StThemeNodeTransitionPrivate *priv = transition->priv; StThemeNodeTransitionPrivate *priv = transition->priv;
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
CoglColor constant, pipeline_color; CoglColor constant, pipeline_color;
float tex_coords[] = { float tex_coords[] = {
@ -370,7 +381,9 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
calculate_offscreen_box (transition, allocation); calculate_offscreen_box (transition, allocation);
priv->needs_setup = clutter_actor_box_get_area (&priv->offscreen_box) == 0 || priv->needs_setup = clutter_actor_box_get_area (&priv->offscreen_box) == 0 ||
!setup_framebuffers (transition, allocation, !setup_framebuffers (transition,
node,
allocation,
resource_scale); resource_scale);
if (priv->needs_setup) /* setting up framebuffers failed */ if (priv->needs_setup) /* setting up framebuffers failed */
@ -386,13 +399,12 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
paint_opacity / 255.0, paint_opacity / 255.0); paint_opacity / 255.0, paint_opacity / 255.0);
cogl_pipeline_set_color (priv->material, &pipeline_color); cogl_pipeline_set_color (priv->material, &pipeline_color);
cogl_framebuffer_draw_multitextured_rectangle (framebuffer, pipeline_node = clutter_pipeline_node_new (priv->material);
priv->material, clutter_paint_node_add_child (node, pipeline_node);
priv->offscreen_box.x1, clutter_paint_node_add_multitexture_rectangle (pipeline_node,
priv->offscreen_box.y1, &priv->offscreen_box,
priv->offscreen_box.x2, tex_coords,
priv->offscreen_box.y2, 8);
tex_coords, 8);
} }
static void static void

View File

@ -42,7 +42,7 @@ void st_theme_node_transition_update (StThemeNodeTransition *transition,
StThemeNode *new_node); StThemeNode *new_node);
void st_theme_node_transition_paint (StThemeNodeTransition *transition, void st_theme_node_transition_paint (StThemeNodeTransition *transition,
CoglFramebuffer *framebuffer, ClutterPaintNode *node,
ClutterActorBox *allocation, ClutterActorBox *allocation,
guint8 paint_opacity, guint8 paint_opacity,
float resource_scale); float resource_scale);

View File

@ -132,7 +132,6 @@ st_theme_node_finalize (GObject *object)
g_clear_object (&node->background_shadow_pipeline); g_clear_object (&node->background_shadow_pipeline);
g_clear_object (&node->border_slices_texture); g_clear_object (&node->border_slices_texture);
g_clear_object (&node->border_slices_pipeline); g_clear_object (&node->border_slices_pipeline);
g_clear_object (&node->color_pipeline);
G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object); G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object);
} }

View File

@ -342,7 +342,7 @@ gboolean st_theme_node_paint_equal (StThemeNode *node,
*/ */
void st_theme_node_paint (StThemeNode *node, void st_theme_node_paint (StThemeNode *node,
StThemeNodePaintState *state, StThemeNodePaintState *state,
CoglFramebuffer *framebuffer, ClutterPaintNode *root,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity, guint8 paint_opacity,
float resource_scale); float resource_scale);

View File

@ -398,6 +398,31 @@ get_border_paint_offsets (StViewport *viewport,
} }
static void
st_viewport_paint_node (ClutterActor *actor,
ClutterPaintNode *node)
{
StViewport *viewport = ST_VIEWPORT (actor);
int x, y;
get_border_paint_offsets (viewport, &x, &y);
if (x != 0 || y != 0)
{
g_autoptr (ClutterPaintNode) transform_node = NULL;
graphene_matrix_t transform;
graphene_matrix_init_translate (&transform,
&GRAPHENE_POINT3D_INIT (x, y, 0));
transform_node = clutter_transform_node_new (&transform);
clutter_paint_node_add_child (node, transform_node);
node = transform_node;
}
st_widget_paint_background (ST_WIDGET (actor), node);
}
static void static void
st_viewport_paint (ClutterActor *actor, st_viewport_paint (ClutterActor *actor,
ClutterPaintContext *paint_context) ClutterPaintContext *paint_context)
@ -411,24 +436,14 @@ st_viewport_paint (ClutterActor *actor,
ClutterActor *child; ClutterActor *child;
CoglFramebuffer *fb = clutter_paint_context_get_framebuffer (paint_context); CoglFramebuffer *fb = clutter_paint_context_get_framebuffer (paint_context);
get_border_paint_offsets (viewport, &x, &y);
if (x != 0 || y != 0)
{
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_translate (fb, x, y, 0);
}
st_widget_paint_background (ST_WIDGET (actor), paint_context);
if (x != 0 || y != 0)
cogl_framebuffer_pop_matrix (fb);
if (clutter_actor_get_n_children (actor) == 0) if (clutter_actor_get_n_children (actor) == 0)
return; return;
clutter_actor_get_allocation_box (actor, &allocation_box); clutter_actor_get_allocation_box (actor, &allocation_box);
st_theme_node_get_content_box (theme_node, &allocation_box, &content_box); st_theme_node_get_content_box (theme_node, &allocation_box, &content_box);
get_border_paint_offsets (viewport, &x, &y);
content_box.x1 += x; content_box.x1 += x;
content_box.y1 += y; content_box.y1 += y;
content_box.x2 += x; content_box.x2 += x;
@ -564,6 +579,7 @@ st_viewport_class_init (StViewportClass *klass)
actor_class->allocate = st_viewport_allocate; actor_class->allocate = st_viewport_allocate;
actor_class->apply_transform = st_viewport_apply_transform; actor_class->apply_transform = st_viewport_apply_transform;
actor_class->paint_node = st_viewport_paint_node;
actor_class->paint = st_viewport_paint; actor_class->paint = st_viewport_paint;
actor_class->get_paint_volume = st_viewport_get_paint_volume; actor_class->get_paint_volume = st_viewport_get_paint_volume;
actor_class->pick = st_viewport_pick; actor_class->pick = st_viewport_pick;

View File

@ -418,11 +418,10 @@ st_widget_allocate (ClutterActor *actor,
* painting children. * painting children.
*/ */
void void
st_widget_paint_background (StWidget *widget, st_widget_paint_background (StWidget *widget,
ClutterPaintContext *paint_context) ClutterPaintNode *node)
{ {
StWidgetPrivate *priv = st_widget_get_instance_private (widget); StWidgetPrivate *priv = st_widget_get_instance_private (widget);
CoglFramebuffer *framebuffer;
StThemeNode *theme_node; StThemeNode *theme_node;
ClutterActorBox allocation; ClutterActorBox allocation;
float resource_scale; float resource_scale;
@ -430,7 +429,6 @@ st_widget_paint_background (StWidget *widget,
resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (widget)); resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (widget));
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
theme_node = st_widget_get_theme_node (widget); theme_node = st_widget_get_theme_node (widget);
clutter_actor_get_allocation_box (CLUTTER_ACTOR (widget), &allocation); clutter_actor_get_allocation_box (CLUTTER_ACTOR (widget), &allocation);
@ -439,27 +437,24 @@ st_widget_paint_background (StWidget *widget,
if (priv->transition_animation) if (priv->transition_animation)
st_theme_node_transition_paint (priv->transition_animation, st_theme_node_transition_paint (priv->transition_animation,
framebuffer, node,
&allocation, &allocation,
opacity, opacity,
resource_scale); resource_scale);
else else
st_theme_node_paint (theme_node, st_theme_node_paint (theme_node,
current_paint_state (widget), current_paint_state (widget),
framebuffer, node,
&allocation, &allocation,
opacity, opacity,
resource_scale); resource_scale);
} }
static void static void
st_widget_paint (ClutterActor *actor, st_widget_paint_node (ClutterActor *actor,
ClutterPaintContext *paint_context) ClutterPaintNode *node)
{ {
st_widget_paint_background (ST_WIDGET (actor), paint_context); st_widget_paint_background (ST_WIDGET (actor), node);
/* Chain up so we paint children. */
CLUTTER_ACTOR_CLASS (st_widget_parent_class)->paint (actor, paint_context);
} }
static void static void
@ -892,7 +887,7 @@ st_widget_class_init (StWidgetClass *klass)
actor_class->get_preferred_width = st_widget_get_preferred_width; actor_class->get_preferred_width = st_widget_get_preferred_width;
actor_class->get_preferred_height = st_widget_get_preferred_height; actor_class->get_preferred_height = st_widget_get_preferred_height;
actor_class->allocate = st_widget_allocate; actor_class->allocate = st_widget_allocate;
actor_class->paint = st_widget_paint; actor_class->paint_node = st_widget_paint_node;
actor_class->get_paint_volume = st_widget_get_paint_volume; actor_class->get_paint_volume = st_widget_get_paint_volume;
actor_class->parent_set = st_widget_parent_set; actor_class->parent_set = st_widget_parent_set;
actor_class->map = st_widget_map; actor_class->map = st_widget_map;

View File

@ -143,8 +143,8 @@ StThemeNode * st_widget_get_theme_node (StWidget *widg
StThemeNode * st_widget_peek_theme_node (StWidget *widget); StThemeNode * st_widget_peek_theme_node (StWidget *widget);
GList * st_widget_get_focus_chain (StWidget *widget); GList * st_widget_get_focus_chain (StWidget *widget);
void st_widget_paint_background (StWidget *widget, void st_widget_paint_background (StWidget *widget,
ClutterPaintContext *paint_context); ClutterPaintNode *node);
/* debug methods */ /* debug methods */
char *st_describe_actor (ClutterActor *actor); char *st_describe_actor (ClutterActor *actor);