summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2020-06-29 15:17:27 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2020-12-08 11:17:24 -0300
commitb566f406e20ec33153b2ddd48f101d20ca03e0b5 (patch)
treee738371d33c3d8f220692921e182a3bb9c14c1e0
parentb58deb2e69d140dab4b52c3e86cbdb0e56e42006 (diff)
downloadmutter-b566f406e20ec33153b2ddd48f101d20ca03e0b5.tar.gz
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 and pipeline to use, as this is a requirement for porting e.g. ClutterOffscreenEffect and subclasses. Add a new clutter_layer_node_new_to_framebuffer() API.
-rw-r--r--clutter/clutter/clutter-paint-nodes.c73
-rw-r--r--clutter/clutter/clutter-paint-nodes.h4
2 files changed, 61 insertions, 16 deletions
diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c
index e70946667..652141c4b 100644
--- a/clutter/clutter/clutter-paint-nodes.c
+++ b/clutter/clutter/clutter-paint-nodes.c
@@ -1338,6 +1338,8 @@ struct _ClutterLayerNode
CoglFramebuffer *offscreen;
guint8 opacity;
+
+ gboolean needs_fbo_setup : 1;
};
struct _ClutterLayerNodeClass
@@ -1365,25 +1367,27 @@ 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->needs_fbo_setup)
+ {
+ /* 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,
@@ -1522,6 +1526,7 @@ clutter_layer_node_new (const graphene_matrix_t *projection,
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
+ res->needs_fbo_setup = TRUE;
res->projection = *projection;
res->viewport = *viewport;
res->fbo_width = width;
@@ -1566,3 +1571,39 @@ out:
return (ClutterPaintNode *) res;
}
+
+/**
+ * clutter_layer_node_new_to_framebuffer:
+ * @framebuffer: a #CoglFramebuffer
+ * @pipeline: a #CoglPipeline
+ *
+ * Creates a new #ClutterLayerNode that will redirect drawing at
+ * @framebuffer. It will then use @pipeline to paint the stored
+ * operations.
+ *
+ * When using this constructor, the caller is reponsible for setting
+ * up @framebuffer, including its modelview and projection matrices,
+ * and the viewport, and the @pipeline as well.
+ *
+ * Return value: (transfer full): the newly created #ClutterLayerNode.
+ * Use clutter_paint_node_unref() when done.
+ */
+ClutterPaintNode *
+clutter_layer_node_new_to_framebuffer (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline)
+{
+ ClutterLayerNode *res;
+
+ g_return_val_if_fail (COGL_IS_FRAMEBUFFER (framebuffer), NULL);
+ g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL);
+
+ res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
+
+ res->needs_fbo_setup = FALSE;
+ res->fbo_width = cogl_framebuffer_get_width (framebuffer);
+ res->fbo_height = cogl_framebuffer_get_height (framebuffer);
+ res->offscreen = g_object_ref (framebuffer);
+ res->pipeline = cogl_pipeline_copy (pipeline);
+
+ return (ClutterPaintNode *) res;
+}
diff --git a/clutter/clutter/clutter-paint-nodes.h b/clutter/clutter/clutter-paint-nodes.h
index 32b56a8d3..082419af8 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_to_framebuffer (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline);
+
#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))