[mutter] clutter/paint-node: Add multi-rect operations
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter/paint-node: Add multi-rect operations
- Date: Thu, 17 Dec 2020 03:32:32 +0000 (UTC)
commit 2f01ef69e31d5434d2f6f57453f548e208e90606
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Mon Dec 14 14:28:42 2020 -0300
clutter/paint-node: Add multi-rect operations
Add a new pair of APIs corresponding to CoglFramebuffer's draw_rectangles()
and draw_textured_rectangles(). They're generally more performance compared
to adding multiple single-rect operations. These variants are heavily used
by GNOME Shell's CSS implementation.
The op array is built to match cogl_framebuffer_draw_textured_rectangles()
always, which means it's a series of 8 floats composed (x1 y1 x2 y2) and
(s1 t1 s2 t2). To avoid adding new struct fields to ClutterPaintOperation,
which is a performance and memory sensitive structure, simply divide the
array length by 8 (which is guaranteed to be correct).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1637>
clutter/clutter/clutter-paint-node-private.h | 1 +
clutter/clutter/clutter-paint-node.c | 112 +++++++++++++++++++++++++++
clutter/clutter/clutter-paint-node.h | 9 +++
clutter/clutter/clutter-paint-nodes.c | 18 +++++
4 files changed, 140 insertions(+)
---
diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h
index ee2b894391..b084e81d42 100644
--- a/clutter/clutter/clutter-paint-node-private.h
+++ b/clutter/clutter/clutter-paint-node-private.h
@@ -82,6 +82,7 @@ typedef enum
{
PAINT_OP_INVALID = 0,
PAINT_OP_TEX_RECT,
+ PAINT_OP_TEX_RECTS,
PAINT_OP_MULTITEX_RECT,
PAINT_OP_PRIMITIVE
} PaintOpCode;
diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c
index 116cfa833e..4df3dac34b 100644
--- a/clutter/clutter/clutter-paint-node.c
+++ b/clutter/clutter/clutter-paint-node.c
@@ -777,6 +777,7 @@ clutter_paint_operation_clear (ClutterPaintOperation *op)
case PAINT_OP_TEX_RECT:
break;
+ case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
g_clear_pointer (&op->coords, g_array_unref);
break;
@@ -809,6 +810,36 @@ clutter_paint_op_init_tex_rect (ClutterPaintOperation *op,
op->op.texrect[7] = y_2;
}
+static inline void
+clutter_paint_op_init_tex_rects (ClutterPaintOperation *op,
+ const float *coords,
+ unsigned int n_rects,
+ gboolean use_default_tex_coords)
+{
+ const unsigned int n_floats = n_rects * 8;
+
+ clutter_paint_operation_clear (op);
+
+ op->opcode = PAINT_OP_TEX_RECTS;
+ op->coords = g_array_sized_new (FALSE, FALSE, sizeof (float), n_floats);
+
+ if (use_default_tex_coords)
+ {
+ const float default_tex_coords[4] = { 0.0, 0.0, 1.0, 1.0 };
+ int i;
+
+ for (i = 0; i < n_rects; i++)
+ {
+ g_array_append_vals (op->coords, &coords[i * 4], 4);
+ g_array_append_vals (op->coords, default_tex_coords, 4);
+ }
+ }
+ else
+ {
+ g_array_append_vals (op->coords, coords, n_floats);
+ }
+}
+
static inline void
clutter_paint_op_init_multitex_rect (ClutterPaintOperation *op,
const ClutterActorBox *rect,
@@ -934,6 +965,74 @@ clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node,
g_array_append_val (node->operations, operation);
}
+/**
+ * clutter_paint_node_add_rectangles:
+ * @node: a #ClutterPaintNode
+ * @coords: (in) (array length=n_rects) (transfer none): array of
+ * coordinates containing groups of 4 float values: [x_1, y_1, x_2, y_2] that
+ * are interpreted as two position coordinates; one for the top left of the
+ * rectangle (x1, y1), and one for the bottom right of the rectangle
+ * (x2, y2).
+ * @n_rects: number of rectangles defined in @coords.
+ *
+ * Adds a series of rectangles to @node.
+ *
+ * As a general rule for better performance its recommended to use this API
+ * instead of calling clutter_paint_node_add_rectangle() separately for
+ * multiple rectangles if all of the rectangles will be drawn together.
+ *
+ * See cogl_framebuffer_draw_rectangles().
+ */
+void
+clutter_paint_node_add_rectangles (ClutterPaintNode *node,
+ const float *coords,
+ unsigned int n_rects)
+{
+ ClutterPaintOperation operation = PAINT_OP_INIT;
+
+ g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
+ g_return_if_fail (coords != NULL);
+
+ clutter_paint_node_maybe_init_operations (node);
+
+ clutter_paint_op_init_tex_rects (&operation, coords, n_rects, TRUE);
+ g_array_append_val (node->operations, operation);
+}
+
+/**
+ * clutter_paint_node_add_texture_rectangles:
+ * @node: a #ClutterPaintNode
+ * @coords: (in) (array length=n_rects) (transfer none): array containing
+ * groups of 8 float values: [x_1, y_1, x_2, y_2, s_1, t_1, s_2, t_2]
+ * that have the same meaning as the arguments for
+ * cogl_framebuffer_draw_textured_rectangle().
+ * @n_rects: number of rectangles defined in @coords.
+ *
+ * Adds a series of rectangles to @node.
+ *
+ * The given texture coordinates should always be normalized such that
+ * (0, 0) corresponds to the top left and (1, 1) corresponds to the
+ * bottom right. To map an entire texture across the rectangle pass
+ * in s_1=0, t_1=0, s_2=1, t_2=1.
+ *
+ * See cogl_framebuffer_draw_textured_rectangles().
+ */
+void
+clutter_paint_node_add_texture_rectangles (ClutterPaintNode *node,
+ const float *coords,
+ unsigned int n_rects)
+{
+ ClutterPaintOperation operation = PAINT_OP_INIT;
+
+ g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
+ g_return_if_fail (coords != NULL);
+
+ clutter_paint_node_maybe_init_operations (node);
+
+ clutter_paint_op_init_tex_rects (&operation, coords, n_rects, FALSE);
+ g_array_append_val (node->operations, operation);
+}
+
/**
* clutter_paint_node_add_primitive: (skip)
* @node: a #ClutterPaintNode
@@ -1057,6 +1156,19 @@ clutter_paint_node_to_json (ClutterPaintNode *node)
json_builder_end_array (builder);
break;
+ case PAINT_OP_TEX_RECTS:
+ json_builder_set_member_name (builder, "texrects");
+ json_builder_begin_array (builder);
+
+ for (j = 0; i < op->coords->len; j++)
+ {
+ float coord = g_array_index (op->coords, float, j);
+ json_builder_add_double_value (builder, coord);
+ }
+
+ json_builder_end_array (builder);
+ break;
+
case PAINT_OP_MULTITEX_RECT:
json_builder_set_member_name (builder, "texrect");
json_builder_begin_array (builder);
diff --git a/clutter/clutter/clutter-paint-node.h b/clutter/clutter/clutter-paint-node.h
index 7afc60f662..b9f174962e 100644
--- a/clutter/clutter/clutter-paint-node.h
+++ b/clutter/clutter/clutter-paint-node.h
@@ -83,6 +83,15 @@ void clutter_paint_node_add_multitexture_rectangle (ClutterP
const float *text_coords,
unsigned int
text_coords_len);
+CLUTTER_EXPORT
+void clutter_paint_node_add_rectangles (ClutterPaintNode *node,
+ const float *coords,
+ unsigned int n_rects);
+CLUTTER_EXPORT
+void clutter_paint_node_add_texture_rectangles (ClutterPaintNode *node,
+ const float *coords,
+ unsigned int n_rects);
+
CLUTTER_EXPORT
void clutter_paint_node_add_primitive (ClutterPaintNode *node,
CoglPrimitive *primitive);
diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c
index db42f2f3f3..9da5b450f0 100644
--- a/clutter/clutter/clutter-paint-nodes.c
+++ b/clutter/clutter/clutter-paint-nodes.c
@@ -467,6 +467,13 @@ clutter_pipeline_node_draw (ClutterPaintNode *node,
op->op.texrect[7]);
break;
+ case PAINT_OP_TEX_RECTS:
+ cogl_framebuffer_draw_textured_rectangles (fb,
+ pnode->pipeline,
+ (float *) op->coords->data,
+ op->coords->len / 8);
+ break;
+
case PAINT_OP_MULTITEX_RECT:
cogl_framebuffer_draw_multitextured_rectangle (fb,
pnode->pipeline,
@@ -872,6 +879,7 @@ clutter_text_node_draw (ClutterPaintNode *node,
cogl_framebuffer_pop_clip (fb);
break;
+ case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
case PAINT_OP_INVALID:
@@ -1033,6 +1041,7 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node,
retval = TRUE;
break;
+ case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
case PAINT_OP_INVALID:
@@ -1067,6 +1076,7 @@ clutter_clip_node_post_draw (ClutterPaintNode *node,
cogl_framebuffer_pop_clip (fb);
break;
+ case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
case PAINT_OP_INVALID:
@@ -1440,6 +1450,13 @@ clutter_layer_node_post_draw (ClutterPaintNode *node,
op->op.texrect[7]);
break;
+ case PAINT_OP_TEX_RECTS:
+ cogl_framebuffer_draw_textured_rectangles (fb,
+ lnode->pipeline,
+ (float *) op->coords->data,
+ op->coords->len / 8);
+ break;
+
case PAINT_OP_MULTITEX_RECT:
cogl_framebuffer_draw_multitextured_rectangle (fb,
lnode->pipeline,
@@ -1695,6 +1712,7 @@ clutter_blit_node_draw (ClutterPaintNode *node,
}
break;
+ case PAINT_OP_TEX_RECTS:
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]