[mutter/gbsneto/effects-paint-nodes: 170/172] clutter/paint-nodes: Add new ClutterLayerNode API
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/effects-paint-nodes: 170/172] clutter/paint-nodes: Add new ClutterLayerNode API
- Date: Wed, 7 Oct 2020 20:31:37 +0000 (UTC)
commit d16539391ca546bb4a906e5fc45ffaa058e52447
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Mon Jun 29 15:17:27 2020 -0300
clutter/paint-nodes: Add new ClutterLayerNode API
ClutterLayerNode is the "offscreen framebuffer" node, that paints
it's child nodes in a separate framebuffer, and then copies that
framebuffer to the parent one.
It'll be useful to hand ClutterLayerNode which texture to use, as
this is a requirement for porting e.g. ClutterOffscreenEffect and
subclasses.
Add a new clutter_layer_node_new_with_texture() API.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
clutter/clutter/clutter-paint-nodes.c | 93 +++++++++++++++++++++++++++++++----
clutter/clutter/clutter-paint-nodes.h | 4 ++
2 files changed, 88 insertions(+), 9 deletions(-)
---
diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c
index 2b5924858c..c3e6f94df6 100644
--- a/clutter/clutter/clutter-paint-nodes.c
+++ b/clutter/clutter/clutter-paint-nodes.c
@@ -1338,6 +1338,9 @@ struct _ClutterLayerNode
CoglFramebuffer *offscreen;
guint8 opacity;
+
+ gboolean projection_set : 1;
+ gboolean viewport_set : 1;
};
struct _ClutterLayerNodeClass
@@ -1370,19 +1373,38 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
*/
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix);
+ cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
- clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen);
+ if (lnode->viewport_set)
+ {
+ cogl_framebuffer_set_viewport (lnode->offscreen,
+ lnode->viewport.x,
+ lnode->viewport.y,
+ lnode->viewport.width,
+ lnode->viewport.height);
+ }
+ else
+ {
+ float viewport[4];
- cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
+ cogl_framebuffer_get_viewport4fv (framebuffer, viewport);
+ cogl_framebuffer_set_viewport (lnode->offscreen,
+ viewport[0], viewport[1],
+ viewport[2], viewport[3]);
+ }
- cogl_framebuffer_set_viewport (lnode->offscreen,
- lnode->viewport.x,
- lnode->viewport.y,
- lnode->viewport.width,
- lnode->viewport.height);
+ if (lnode->projection_set)
+ {
+ cogl_framebuffer_set_projection_matrix (lnode->offscreen,
+ &lnode->projection);
+ }
+ else
+ {
+ cogl_framebuffer_get_projection_matrix (framebuffer, &matrix);
+ cogl_framebuffer_set_projection_matrix (lnode->offscreen, &matrix);
+ }
- cogl_framebuffer_set_projection_matrix (lnode->offscreen,
- &lnode->projection);
+ clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen);
/* clear out the target framebuffer */
cogl_framebuffer_clear4f (lnode->offscreen,
@@ -1521,7 +1543,9 @@ clutter_layer_node_new (const graphene_matrix_t *projection,
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
+ res->projection_set = TRUE;
res->projection = *projection;
+ res->viewport_set = TRUE;
res->viewport = *viewport;
res->fbo_width = width;
res->fbo_height = height;
@@ -1561,3 +1585,54 @@ out:
return (ClutterPaintNode *) res;
}
+
+/**
+ * clutter_layer_node_new_with_texture:
+ * @texture: a #CoglTexture
+ * @opacity: the opacity to be used when drawing the layer
+ *
+ * Creates a new #ClutterLayerNode that will redirect drawing at
+ * @texture. The @texture will then be painted using the given
+ * @opacity.
+ *
+ * Return value: (transfer full): the newly created #ClutterLayerNode.
+ * Use clutter_paint_node_unref() when done.
+ */
+ClutterPaintNode *
+clutter_layer_node_new_with_texture (CoglTexture *texture,
+ guint8 opacity)
+{
+ ClutterLayerNode *res;
+ CoglColor color;
+
+ res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
+
+ res->projection_set = FALSE;
+ res->viewport_set = FALSE;
+ res->fbo_width = cogl_texture_get_width (texture);
+ res->fbo_height = cogl_texture_get_height (texture);
+ res->opacity = opacity;
+
+ res->offscreen = COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (texture));
+ if (res->offscreen == NULL)
+ {
+ g_critical ("%s: Unable to create an offscreen buffer", G_STRLOC);
+ goto out;
+ }
+
+ cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
+
+ /* the pipeline used to paint the texture; we use nearest
+ * interpolation filters because the texture is always
+ * going to be painted at a 1:1 texel:pixel ratio
+ */
+ res->pipeline = cogl_pipeline_copy (default_texture_pipeline);
+ cogl_pipeline_set_layer_filters (res->pipeline, 0,
+ COGL_PIPELINE_FILTER_NEAREST,
+ COGL_PIPELINE_FILTER_NEAREST);
+ cogl_pipeline_set_layer_texture (res->pipeline, 0, texture);
+ cogl_pipeline_set_color (res->pipeline, &color);
+
+out:
+ return (ClutterPaintNode *) res;
+}
diff --git a/clutter/clutter/clutter-paint-nodes.h b/clutter/clutter/clutter-paint-nodes.h
index 32b56a8d39..bac93752ef 100644
--- a/clutter/clutter/clutter-paint-nodes.h
+++ b/clutter/clutter/clutter-paint-nodes.h
@@ -209,6 +209,10 @@ ClutterPaintNode * clutter_layer_node_new (const graphene_matrix_t
float height,
guint8 opacity);
+CLUTTER_EXPORT
+ClutterPaintNode * clutter_layer_node_new_with_texture (CoglTexture *texture,
+ guint8 opacity);
+
#define CLUTTER_TYPE_TRANSFORM_NODE (clutter_transform_node_get_type ())
#define CLUTTER_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
CLUTTER_TYPE_TRANSFORM_NODE, ClutterTransformNode))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]