[mutter/gbsneto/effects-paint-nodes: 5/8] clutter/paint-nodes: Add new ClutterLayerNode API



commit f6a5c2c5c81ebea5ad23f542661d2c86815cc568
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 framebuffer to use,
    as this is a requirement for porting e.g. ClutterOffscreenEffect
    and subclasses.
    
    Add a new clutter_layer_node_new_with_framebuffer() API.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340

 clutter/clutter/clutter-paint-nodes.c | 80 +++++++++++++++++++++++++++--------
 clutter/clutter/clutter-paint-nodes.h |  5 +++
 2 files changed, 67 insertions(+), 18 deletions(-)
---
diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c
index d6827f66be..e08beee0c4 100644
--- a/clutter/clutter/clutter-paint-nodes.c
+++ b/clutter/clutter/clutter-paint-nodes.c
@@ -1235,6 +1235,7 @@ struct _ClutterLayerNode
   CoglFramebuffer *offscreen;
 
   guint8 opacity;
+  gboolean update_modelview;
 };
 
 struct _ClutterLayerNodeClass
@@ -1249,8 +1250,6 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
                              ClutterPaintContext *paint_context)
 {
   ClutterLayerNode *lnode = (ClutterLayerNode *) node;
-  CoglFramebuffer *framebuffer;
-  CoglMatrix matrix;
 
   /* if we were unable to create an offscreen buffer for this node, then
    * we simply ignore it
@@ -1262,25 +1261,30 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
   if (node->operations == NULL)
     return FALSE;
 
-  /* copy the same modelview from the current framebuffer to the one we
-   * are going to use
-   */
-  framebuffer = clutter_paint_context_get_framebuffer (paint_context);
-  cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix);
+  if (lnode->update_modelview)
+    {
+      CoglFramebuffer *framebuffer;
+      CoglMatrix matrix;
+
+      /* copy the same modelview from the current framebuffer to the one we
+       * are going to use
+       */
+      framebuffer = clutter_paint_context_get_framebuffer (paint_context);
+      cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix);
+      cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
+
+      cogl_framebuffer_set_viewport (lnode->offscreen,
+                                     lnode->viewport.x,
+                                     lnode->viewport.y,
+                                     lnode->viewport.width,
+                                     lnode->viewport.height);
+
+      cogl_framebuffer_set_projection_matrix (lnode->offscreen,
+                                              &lnode->projection);
+    }
 
   clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen);
 
-  cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
-
-  cogl_framebuffer_set_viewport (lnode->offscreen,
-                                 lnode->viewport.x,
-                                 lnode->viewport.y,
-                                 lnode->viewport.width,
-                                 lnode->viewport.height);
-
-  cogl_framebuffer_set_projection_matrix (lnode->offscreen,
-                                          &lnode->projection);
-
   /* clear out the target framebuffer */
   cogl_framebuffer_clear4f (lnode->offscreen,
                             COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH,
@@ -1417,6 +1421,7 @@ clutter_layer_node_new (const CoglMatrix        *projection,
 
   res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
 
+  res->update_modelview = TRUE;
   res->projection = *projection;
   res->viewport = *viewport;
   res->fbo_width = width;
@@ -1456,3 +1461,42 @@ out:
 
   return (ClutterPaintNode *) res;
 }
+
+/**
+ * clutter_layer_node_new_with_framebuffer:
+ * @framebuffer: a #CoglFramebuffer
+ * @pipeline: a #CoglPipeline
+ * @opacity: the opacity to be used when drawing the layer
+ *
+ * Creates a new #ClutterLayerNode with @framebuffer and
+ * @pipeline. @framebuffer will then be painted using the
+ * given @opacity.
+ *
+ * When using this constructor, the caller is responsible
+ * for setting up the framebuffer's modelview and projection
+ * matrices.
+ *
+ * Return value: (transfer full)(nullable): the newly created #ClutterLayerNode.
+ *   Use clutter_paint_node_unref() when done.
+ */
+ClutterPaintNode *
+clutter_layer_node_new_with_framebuffer (CoglFramebuffer *framebuffer,
+                                         CoglPipeline    *pipeline,
+                                         guint8           opacity)
+{
+  ClutterLayerNode *res;
+  CoglColor color;
+
+  g_return_val_if_fail (cogl_is_framebuffer (framebuffer), NULL);
+
+  res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
+
+  res->update_modelview = FALSE;
+  res->offscreen = cogl_object_ref (framebuffer);
+  res->pipeline = cogl_pipeline_copy (pipeline);
+
+  cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
+  cogl_pipeline_set_color (res->pipeline, &color);
+
+  return (ClutterPaintNode *) res;
+}
diff --git a/clutter/clutter/clutter-paint-nodes.h b/clutter/clutter/clutter-paint-nodes.h
index 235f4bc456..75015aef6e 100644
--- a/clutter/clutter/clutter-paint-nodes.h
+++ b/clutter/clutter/clutter-paint-nodes.h
@@ -208,6 +208,11 @@ ClutterPaintNode *      clutter_layer_node_new          (const CoglMatrix
                                                          float                    height,
                                                          guint8                   opacity);
 
+CLUTTER_EXPORT
+ClutterPaintNode * clutter_layer_node_new_with_framebuffer (CoglFramebuffer *framebuffer,
+                                                            CoglPipeline    *pipeline,
+                                                            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]