From d5262f0f4db1e69a54bb8274cf9d84dc8d31ce1b Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 26 Dec 2018 23:09:17 -0200 Subject: [PATCH] clutter/paint-node: Add multitexture API The multitexture API is not a shortcut for multiple calls to the single texture API. It is meant to wrap calls to cogl_framebuffer_draw_multitexture_rectangle(), which uses the passed texture coordinates at different layers of the pipeline. https://gitlab.gnome.org/GNOME/mutter/merge_requests/405 --- clutter/clutter/clutter-paint-node-private.h | 3 + clutter/clutter/clutter-paint-node.c | 68 +++++++++++++++++++- clutter/clutter/clutter-paint-node.h | 6 ++ clutter/clutter/clutter-paint-nodes.c | 25 +++++++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h index 2945b78a4..feecdd811 100644 --- a/clutter/clutter/clutter-paint-node-private.h +++ b/clutter/clutter/clutter-paint-node-private.h @@ -77,6 +77,7 @@ struct _ClutterPaintNodeClass typedef enum { PAINT_OP_INVALID = 0, PAINT_OP_TEX_RECT, + PAINT_OP_MULTITEX_RECT, PAINT_OP_PATH, PAINT_OP_PRIMITIVE } PaintOpCode; @@ -85,6 +86,8 @@ struct _ClutterPaintOperation { PaintOpCode opcode; + GArray *multitex_coords; + union { float texrect[8]; diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c index 3dafca0f1..c31a0c702 100644 --- a/clutter/clutter/clutter-paint-node.c +++ b/clutter/clutter/clutter-paint-node.c @@ -761,6 +761,11 @@ clutter_paint_operation_clear (ClutterPaintOperation *op) case PAINT_OP_TEX_RECT: break; + case PAINT_OP_MULTITEX_RECT: + if (op->multitex_coords != NULL) + g_array_unref (op->multitex_coords); + break; + case PAINT_OP_PATH: if (op->op.path != NULL) cogl_object_unref (op->op.path); @@ -794,6 +799,27 @@ clutter_paint_op_init_tex_rect (ClutterPaintOperation *op, op->op.texrect[7] = y_2; } +static inline void +clutter_paint_op_init_multitex_rect (ClutterPaintOperation *op, + const ClutterActorBox *rect, + const float *tex_coords, + unsigned int tex_coords_len) +{ + clutter_paint_operation_clear (op); + + op->opcode = PAINT_OP_MULTITEX_RECT; + op->multitex_coords = g_array_sized_new (FALSE, FALSE, + sizeof (float), + tex_coords_len); + + g_array_append_vals (op->multitex_coords, tex_coords, tex_coords_len); + + op->op.texrect[0] = rect->x1; + op->op.texrect[1] = rect->y1; + op->op.texrect[2] = rect->x2; + op->op.texrect[3] = rect->y2; +} + static inline void clutter_paint_op_init_path (ClutterPaintOperation *op, CoglPath *path) @@ -881,6 +907,33 @@ clutter_paint_node_add_texture_rectangle (ClutterPaintNode *node, g_array_append_val (node->operations, operation); } + +/** + * clutter_paint_node_add_multitexture_rectangle: + * @node: a #ClutterPaintNode + * @rect: a #ClutterActorBox + * @text_coords: array of multitexture values + * @text_coords_len: number of items of @text_coords + * + * Adds a rectangle region to the @node, with multitexture coordinates. + */ +void +clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node, + const ClutterActorBox *rect, + const float *text_coords, + unsigned int text_coords_len) +{ + ClutterPaintOperation operation = PAINT_OP_INIT; + + g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); + g_return_if_fail (rect != NULL); + + clutter_paint_node_maybe_init_operations (node); + + clutter_paint_op_init_multitex_rect (&operation, rect, text_coords, text_coords_len); + g_array_append_val (node->operations, operation); +} + /** * clutter_paint_node_add_path: (skip) * @node: a #ClutterPaintNode @@ -1006,7 +1059,7 @@ clutter_paint_node_to_json (ClutterPaintNode *node) if (node->operations != NULL) { - guint i; + guint i, j; for (i = 0; i < node->operations->len; i++) { @@ -1031,6 +1084,19 @@ clutter_paint_node_to_json (ClutterPaintNode *node) json_builder_end_array (builder); break; + case PAINT_OP_MULTITEX_RECT: + json_builder_set_member_name (builder, "texrect"); + json_builder_begin_array (builder); + + for (j = 0; i < op->multitex_coords->len; j++) + { + float coord = g_array_index (op->multitex_coords, float, j); + json_builder_add_double_value (builder, coord); + } + + json_builder_end_array (builder); + break; + case PAINT_OP_PATH: json_builder_set_member_name (builder, "path"); json_builder_add_int_value (builder, (gint64) op->op.path); diff --git a/clutter/clutter/clutter-paint-node.h b/clutter/clutter/clutter-paint-node.h index 779b15e35..e459e74ed 100644 --- a/clutter/clutter/clutter-paint-node.h +++ b/clutter/clutter/clutter-paint-node.h @@ -67,6 +67,12 @@ void clutter_paint_node_add_texture_rectangle (Clutter float x_2, float y_2); +CLUTTER_EXPORT +void clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node, + const ClutterActorBox *rect, + const float *text_coords, + unsigned int text_coords_len); + CLUTTER_EXPORT void clutter_paint_node_add_path (ClutterPaintNode *node, CoglPath *path); diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c index 2707dcf62..638ddb4a7 100644 --- a/clutter/clutter/clutter-paint-nodes.c +++ b/clutter/clutter/clutter-paint-nodes.c @@ -431,6 +431,17 @@ clutter_pipeline_node_draw (ClutterPaintNode *node) op->op.texrect[7]); break; + case PAINT_OP_MULTITEX_RECT: + cogl_framebuffer_draw_multitextured_rectangle (cogl_get_draw_framebuffer (), + pnode->pipeline, + op->op.texrect[0], + op->op.texrect[1], + op->op.texrect[2], + op->op.texrect[3], + (float*) op->multitex_coords->data, + op->multitex_coords->len); + break; + case PAINT_OP_PATH: cogl_path_fill (op->op.path); break; @@ -827,6 +838,7 @@ clutter_text_node_draw (ClutterPaintNode *node) cogl_framebuffer_pop_clip (fb); break; + case PAINT_OP_MULTITEX_RECT: case PAINT_OP_PATH: case PAINT_OP_PRIMITIVE: case PAINT_OP_INVALID: @@ -992,6 +1004,7 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node) retval = TRUE; break; + case PAINT_OP_MULTITEX_RECT: case PAINT_OP_PRIMITIVE: case PAINT_OP_INVALID: break; @@ -1025,6 +1038,7 @@ clutter_clip_node_post_draw (ClutterPaintNode *node) cogl_framebuffer_pop_clip (fb); break; + case PAINT_OP_MULTITEX_RECT: case PAINT_OP_PRIMITIVE: case PAINT_OP_INVALID: break; @@ -1180,6 +1194,17 @@ clutter_layer_node_post_draw (ClutterPaintNode *node) cogl_pop_source (); break; + case PAINT_OP_MULTITEX_RECT: + cogl_framebuffer_draw_multitextured_rectangle (cogl_get_draw_framebuffer (), + lnode->state, + op->op.texrect[0], + op->op.texrect[1], + op->op.texrect[2], + op->op.texrect[3], + (float*) op->multitex_coords->data, + op->multitex_coords->len); + break; + case PAINT_OP_PATH: cogl_push_source (lnode->state); cogl_path_fill (op->op.path);