From 0f0b411f6ed3b515dd946a4a45abb06edbc72e29 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 26 Dec 2018 23:17:29 -0200 Subject: [PATCH 1/6] clutter/content: Add clutter_content_invalidate_size() ClutterContent has the ability to dictate the layout of any given actor, through the CLUTTER_REQUEST_CONTENT_SIZE request mode. However, there is no way for ClutterContent implementations to notify their attached actors that the content size changed. Add a new optional ClutterContent.invalidate_size() vfunc and clutter_content_invalidate_size(). https://gitlab.gnome.org/GNOME/mutter/merge_requests/405 --- clutter/clutter/clutter-content.c | 46 +++++++++++++++++++++++++++++++ clutter/clutter/clutter-content.h | 5 ++++ 2 files changed, 51 insertions(+) diff --git a/clutter/clutter/clutter-content.c b/clutter/clutter/clutter-content.c index 35419305e00..b7aea04c2af 100644 --- a/clutter/clutter/clutter-content.c +++ b/clutter/clutter/clutter-content.c @@ -38,6 +38,7 @@ #include "clutter-build-config.h" +#include "clutter-actor-private.h" #include "clutter-content-private.h" #include "clutter-debug.h" @@ -91,6 +92,11 @@ clutter_content_real_invalidate (ClutterContent *content) { } +static void +clutter_content_real_invalidate_size (ClutterContent *content) +{ +} + static void clutter_content_real_paint_content (ClutterContent *content, ClutterActor *actor, @@ -108,6 +114,7 @@ clutter_content_default_init (ClutterContentInterface *iface) iface->attached = clutter_content_real_attached; iface->detached = clutter_content_real_detached; iface->invalidate = clutter_content_real_invalidate; + iface->invalidate_size = clutter_content_real_invalidate_size; /** * ClutterContent::attached: @@ -188,6 +195,45 @@ clutter_content_invalidate (ClutterContent *content) } } +/** + * clutter_content_invalidate_size: + * @content: a #ClutterContent + * + * Signals that @content's size changed. Attached actors with request mode + * set to %CLUTTER_REQUEST_CONTENT_SIZE will have a relayout queued. + * + * Attached actors with other request modes are not redrawn. To redraw them + * too, use clutter_content_invalidate(). + */ +void +clutter_content_invalidate_size (ClutterContent *content) +{ + ClutterActor *actor; + GHashTable *actors; + GHashTableIter iter; + + g_return_if_fail (CLUTTER_IS_CONTENT (content)); + + CLUTTER_CONTENT_GET_IFACE (content)->invalidate_size (content); + + actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors); + if (actors == NULL) + return; + + g_hash_table_iter_init (&iter, actors); + while (g_hash_table_iter_next (&iter, (gpointer *) &actor, NULL)) + { + ClutterRequestMode request_mode; + + g_assert (actor != NULL); + + request_mode = clutter_actor_get_request_mode (actor); + + if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE) + _clutter_actor_queue_only_relayout (actor); + } +} + /*< private > * _clutter_content_attached: * @content: a #ClutterContent diff --git a/clutter/clutter/clutter-content.h b/clutter/clutter/clutter-content.h index 69836d5a1c8..0b676f6e3cb 100644 --- a/clutter/clutter/clutter-content.h +++ b/clutter/clutter/clutter-content.h @@ -86,6 +86,8 @@ struct _ClutterContentIface ClutterActor *actor); void (* invalidate) (ClutterContent *content); + + void (* invalidate_size) (ClutterContent *content); }; CLUTTER_EXPORT @@ -98,6 +100,9 @@ gboolean clutter_content_get_preferred_size (ClutterContent *content CLUTTER_EXPORT void clutter_content_invalidate (ClutterContent *content); +CLUTTER_EXPORT +void clutter_content_invalidate_size (ClutterContent *content); + G_END_DECLS #endif /* __CLUTTER_CONTENT_H__ */ -- GitLab From 25f36b3892713b1877839bf0271a354273bb7ec5 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sun, 27 Jan 2019 13:53:06 -0200 Subject: [PATCH 2/6] clutter/image: Also invalidate size ClutterImage is a ClutterContent implementation that has an internally managed CoglTexture. This texture is recreated when new image data is set. ClutterContent implementations may have control over the allocation of the widgets they're attached to, through CLUTTER_REQUEST_CONTENT_SIZE. On those cases, if the new image data differs in size from the previous data, it is important to notify those actors about the size change. However, currently ClutterImage does not notify them. With the introduction of clutter_content_invalidate_size(), it is possible to report the size changes to attached actors. Adapt ClutterImage to invalidate_size() when image data has different sizes. https://gitlab.gnome.org/GNOME/mutter/merge_requests/405 --- clutter/clutter/clutter-image.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/clutter/clutter/clutter-image.c b/clutter/clutter/clutter-image.c index d4356598b7e..924626be04a 100644 --- a/clutter/clutter/clutter-image.c +++ b/clutter/clutter/clutter-image.c @@ -53,6 +53,8 @@ struct _ClutterImagePrivate { CoglTexture *texture; + gint width; + gint height; }; static void clutter_content_iface_init (ClutterContentIface *iface); @@ -68,6 +70,27 @@ clutter_image_error_quark (void) return g_quark_from_static_string ("clutter-image-error-quark"); } +static void +update_image_size (ClutterImage *self) +{ + gint width, height; + + if (self->priv->texture == NULL) + return; + + width = cogl_texture_get_width (self->priv->texture); + height = cogl_texture_get_height (self->priv->texture); + + if (self->priv->width == width && + self->priv->height == height) + return; + + self->priv->width = width; + self->priv->height = height; + + clutter_content_invalidate_size (CLUTTER_CONTENT (self)); +} + static void clutter_image_finalize (GObject *gobject) { @@ -238,6 +261,7 @@ clutter_image_set_data (ClutterImage *image, } clutter_content_invalidate (CLUTTER_CONTENT (image)); + update_image_size (image); return TRUE; } @@ -306,6 +330,7 @@ clutter_image_set_bytes (ClutterImage *image, } clutter_content_invalidate (CLUTTER_CONTENT (image)); + update_image_size (image); return TRUE; } @@ -399,6 +424,7 @@ clutter_image_set_area (ClutterImage *image, } clutter_content_invalidate (CLUTTER_CONTENT (image)); + update_image_size (image); return TRUE; } -- GitLab From d8c7583922d3428eae4a700e30d4c73030397239 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 26 Dec 2018 23:09:17 -0200 Subject: [PATCH 3/6] 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 2945b78a432..feecdd81159 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 3dafca0f180..c31a0c7023c 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 779b15e35e9..e459e74eda6 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 2707dcf6210..638ddb4a7f1 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); -- GitLab From 02b184bfd703648cb48d649b8b907180bd56de59 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Mon, 28 Jan 2019 12:59:03 -0200 Subject: [PATCH 4/6] clutter/paint-node: Expose clutter_paint_node_paint() When painting to an offscreen framebuffer, MetaShapedTexture will need to have full control of the painting routines of paint nodes. As such, expose clutter_paint_node_paint() to allow forcing a paint nodes paint from MetaShapedTexture. https://gitlab.gnome.org/GNOME/mutter/merge_requests/405 --- clutter/clutter/clutter-actor.c | 2 +- clutter/clutter/clutter-paint-node-private.h | 1 - clutter/clutter/clutter-paint-node.c | 8 ++++---- clutter/clutter/clutter-paint-node.h | 3 +++ 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index fd9aab289df..bebbc3eb7f2 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -3779,7 +3779,7 @@ clutter_actor_paint_node (ClutterActor *actor, } #endif /* CLUTTER_ENABLE_DEBUG */ - _clutter_paint_node_paint (root); + clutter_paint_node_paint (root); return TRUE; } diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h index feecdd81159..e6573ecd91b 100644 --- a/clutter/clutter/clutter-paint-node-private.h +++ b/clutter/clutter/clutter-paint-node-private.h @@ -116,7 +116,6 @@ ClutterPaintNode * _clutter_root_node_new (CoglFra ClutterPaintNode * _clutter_transform_node_new (const CoglMatrix *matrix); ClutterPaintNode * _clutter_dummy_node_new (ClutterActor *actor); -void _clutter_paint_node_paint (ClutterPaintNode *root); void _clutter_paint_node_dump_tree (ClutterPaintNode *root); G_GNUC_INTERNAL diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c index c31a0c7023c..e731ca60a26 100644 --- a/clutter/clutter/clutter-paint-node.c +++ b/clutter/clutter/clutter-paint-node.c @@ -989,15 +989,15 @@ clutter_paint_node_add_primitive (ClutterPaintNode *node, g_array_append_val (node->operations, operation); } -/*< private > - * _clutter_paint_node_paint: +/** + * clutter_paint_node_paint: * @node: a #ClutterPaintNode * * Paints the @node using the class implementation, traversing * its children, if any. */ void -_clutter_paint_node_paint (ClutterPaintNode *node) +clutter_paint_node_paint (ClutterPaintNode *node) { ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node); ClutterPaintNode *iter; @@ -1014,7 +1014,7 @@ _clutter_paint_node_paint (ClutterPaintNode *node) iter != NULL; iter = iter->next_sibling) { - _clutter_paint_node_paint (iter); + clutter_paint_node_paint (iter); } if (res) diff --git a/clutter/clutter/clutter-paint-node.h b/clutter/clutter/clutter-paint-node.h index e459e74eda6..c42abbc3d8a 100644 --- a/clutter/clutter/clutter-paint-node.h +++ b/clutter/clutter/clutter-paint-node.h @@ -49,6 +49,9 @@ ClutterPaintNode * clutter_paint_node_ref (Clutter CLUTTER_EXPORT void clutter_paint_node_unref (ClutterPaintNode *node); +CLUTTER_EXPORT +void clutter_paint_node_paint (ClutterPaintNode *node); + CLUTTER_EXPORT void clutter_paint_node_set_name (ClutterPaintNode *node, const char *name); -- GitLab From b63e104561cfe68c958f73c7a17c9cac69689f54 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 29 Jan 2019 12:46:08 -0200 Subject: [PATCH 5/6] clutter/paint-nodes: Expose ClutterRootNode The ClutterRootNode paint node is theoretically the top-most node of a paint nodes tree, except that we are not in the point of having full rendering trees in Clutter (all rendering performed by paint nodes is still local and immediate). When controlling the rendering tree, MetaShapedTexture may need to paint into an offscreen framebuffer under some circumstations. Expose ClutterRootNode so that MetaShapedTexture can use it to render to offscreen framebuffers. https://gitlab.gnome.org/GNOME/mutter/merge_requests/405 --- clutter/clutter/clutter-actor.c | 2 +- clutter/clutter/clutter-paint-node-private.h | 4 ---- clutter/clutter/clutter-paint-nodes.c | 15 ++++++--------- clutter/clutter/clutter-paint-nodes.h | 20 ++++++++++++++++++++ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index bebbc3eb7f2..4701daab766 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -3740,7 +3740,7 @@ clutter_actor_paint_node (ClutterActor *actor, if (!clutter_stage_get_no_clear_hint (CLUTTER_STAGE (actor))) clear_flags |= COGL_BUFFER_BIT_COLOR; - node = _clutter_root_node_new (fb, &bg_color, clear_flags); + node = clutter_root_node_new (fb, &bg_color, clear_flags); clutter_paint_node_set_name (node, "stageClear"); clutter_paint_node_add_rectangle (node, &box); clutter_paint_node_add_child (root, node); diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h index e6573ecd91b..55cf9efd2b4 100644 --- a/clutter/clutter/clutter-paint-node-private.h +++ b/clutter/clutter/clutter-paint-node-private.h @@ -97,7 +97,6 @@ struct _ClutterPaintOperation } op; }; -GType _clutter_root_node_get_type (void) G_GNUC_CONST; GType _clutter_transform_node_get_type (void) G_GNUC_CONST; GType _clutter_dummy_node_get_type (void) G_GNUC_CONST; @@ -110,9 +109,6 @@ void _clutter_paint_operation_paint_primitive (const C void _clutter_paint_node_init_types (void); gpointer _clutter_paint_node_create (GType gtype); -ClutterPaintNode * _clutter_root_node_new (CoglFramebuffer *framebuffer, - const ClutterColor *clear_color, - CoglBufferBit clear_flags); ClutterPaintNode * _clutter_transform_node_new (const CoglMatrix *matrix); ClutterPaintNode * _clutter_dummy_node_new (ClutterActor *actor); diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c index 638ddb4a7f1..74e544b51f4 100644 --- a/clutter/clutter/clutter-paint-nodes.c +++ b/clutter/clutter/clutter-paint-nodes.c @@ -83,16 +83,13 @@ _clutter_paint_node_init_types (void) } /* - * Root node, private + * Root node * * any frame can only have a since RootNode instance for each * top-level actor. */ -#define clutter_root_node_get_type _clutter_root_node_get_type - -typedef struct _ClutterRootNode ClutterRootNode; -typedef struct _ClutterPaintNodeClass ClutterRootNodeClass; +#define clutter_root_node_get_type clutter_root_node_get_type struct _ClutterRootNode { @@ -158,13 +155,13 @@ clutter_root_node_init (ClutterRootNode *self) } ClutterPaintNode * -_clutter_root_node_new (CoglFramebuffer *framebuffer, - const ClutterColor *clear_color, - CoglBufferBit clear_flags) +clutter_root_node_new (CoglFramebuffer *framebuffer, + const ClutterColor *clear_color, + CoglBufferBit clear_flags) { ClutterRootNode *res; - res = _clutter_paint_node_create (_clutter_root_node_get_type ()); + res = _clutter_paint_node_create (CLUTTER_TYPE_ROOT_NODE); cogl_color_init_from_4ub (&res->clear_color, clear_color->red, diff --git a/clutter/clutter/clutter-paint-nodes.h b/clutter/clutter/clutter-paint-nodes.h index 381c7f8a7b8..ecaae60ba9f 100644 --- a/clutter/clutter/clutter-paint-nodes.h +++ b/clutter/clutter/clutter-paint-nodes.h @@ -143,6 +143,26 @@ CLUTTER_EXPORT ClutterPaintNode * clutter_text_node_new (PangoLayout *layout, const ClutterColor *color); +#define CLUTTER_TYPE_ROOT_NODE (clutter_root_node_get_type ()) +#define CLUTTER_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ROOT_NODE, ClutterRootNode)) +#define CLUTTER_IS_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ROOT_NODE)) + +/** + * ClutterRootNode: + * + * The #ClutterRootNode structure is an opaque + * type whose members cannot be directly accessed. + */ +typedef struct _ClutterRootNode ClutterRootNode; +typedef struct _ClutterPaintNodeClass ClutterRootNodeClass; + +CLUTTER_EXPORT +GType clutter_root_node_get_type (void) G_GNUC_CONST; + +CLUTTER_EXPORT +ClutterPaintNode * clutter_root_node_new (CoglFramebuffer *framebuffer, + const ClutterColor *clear_color, + CoglBufferBit clear_flags); G_END_DECLS #endif /* __CLUTTER_PAINT_NODES_H__ */ -- GitLab From 317414ab26e0043d2d60d8cb924224168f3a2997 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 29 Jan 2019 12:55:11 -0200 Subject: [PATCH 6/6] clutter/paint-nodes: Push/pop framebuffer Unfortunately, many parts of GNOME Shell and Mutter and Clutter still use the implicit Cogl1 API. As such, it as a transition between the old and new APIs, it is important to keep the implicit draw framebuffer updated. ClutterRootNode does not keep it updated though, and it might lead to problems when rendering offscreen textures. Fix that by pushing and popping the root node framebuffer on pre- and post-draw, respectively. https://gitlab.gnome.org/GNOME/mutter/merge_requests/405 --- clutter/clutter/clutter-paint-nodes.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c index 74e544b51f4..d5efd586425 100644 --- a/clutter/clutter/clutter-paint-nodes.c +++ b/clutter/clutter/clutter-paint-nodes.c @@ -108,6 +108,8 @@ clutter_root_node_pre_draw (ClutterPaintNode *node) { ClutterRootNode *rnode = (ClutterRootNode *) node; + cogl_push_framebuffer (rnode->framebuffer); + cogl_framebuffer_clear (rnode->framebuffer, rnode->clear_flags, &rnode->clear_color); @@ -118,6 +120,7 @@ clutter_root_node_pre_draw (ClutterPaintNode *node) static void clutter_root_node_post_draw (ClutterPaintNode *node) { + cogl_pop_framebuffer (); } static void -- GitLab