From 26c1a5eedfe7863bd40db28f073f0e443efb49f0 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sun, 5 Jul 2020 17:44:38 -0300 Subject: [PATCH] clutter/offscreen-effect: Use paint nodes to paint target Add a new ClutterPaintNode parameter to the paint_target() vfunc. For now, create a temporary ClutterEffectNode that is passed to paint_target() and immediately painted; next commits will move this to upper layers. Part-of: --- clutter/clutter/clutter-deform-effect.c | 44 ++++++++++++++----- clutter/clutter/clutter-offscreen-effect.c | 33 ++++++++++---- clutter/clutter/clutter-offscreen-effect.h | 1 + clutter/clutter/clutter-shader-effect.c | 3 +- .../clutter/conform/actor-shader-effect.c | 6 ++- 5 files changed, 64 insertions(+), 23 deletions(-) diff --git a/clutter/clutter/clutter-deform-effect.c b/clutter/clutter/clutter-deform-effect.c index e92d10600..eca46e8f9 100644 --- a/clutter/clutter/clutter-deform-effect.c +++ b/clutter/clutter/clutter-deform-effect.c @@ -58,9 +58,12 @@ #include +#include "clutter-color.h" #include "clutter-debug.h" #include "clutter-enum-types.h" #include "clutter-offscreen-effect-private.h" +#include "clutter-paint-node.h" +#include "clutter-paint-nodes.h" #include "clutter-private.h" #define DEFAULT_N_TILES 32 @@ -166,14 +169,13 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta, static void clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect); ClutterDeformEffectPrivate *priv = self->priv; CoglPipeline *pipeline; CoglDepthState depth_state; - CoglFramebuffer *fb = - clutter_paint_context_get_framebuffer (paint_context); if (priv->is_dirty) { @@ -285,11 +287,21 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, /* draw the front */ if (pipeline != NULL) - cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive); + { + ClutterPaintNode *front_node; + + front_node = clutter_pipeline_node_new (pipeline); + clutter_paint_node_set_static_name (front_node, + "ClutterDeformEffect (front)"); + clutter_paint_node_add_child (node, front_node); + clutter_paint_node_add_primitive (front_node, priv->primitive); + clutter_paint_node_unref (front_node); + } /* draw the back */ if (priv->back_pipeline != NULL) { + ClutterPaintNode *back_node; CoglPipeline *back_pipeline; /* We probably shouldn't be modifying the user's material so @@ -299,20 +311,30 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, cogl_pipeline_set_cull_face_mode (back_pipeline, COGL_PIPELINE_CULL_FACE_MODE_FRONT); - cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive); + back_node = clutter_pipeline_node_new (back_pipeline); + clutter_paint_node_set_static_name (back_node, + "ClutterDeformEffect (back)"); + clutter_paint_node_add_child (node, back_node); + clutter_paint_node_add_primitive (back_node, priv->primitive); + + clutter_paint_node_unref (back_node); cogl_object_unref (back_pipeline); } if (G_UNLIKELY (priv->lines_primitive != NULL)) { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx); - cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0); - cogl_framebuffer_draw_primitive (fb, lines_pipeline, - priv->lines_primitive); - cogl_object_unref (lines_pipeline); + const ClutterColor *red; + ClutterPaintNode *lines_node; + + red = clutter_color_get_static (CLUTTER_COLOR_RED); + + lines_node = clutter_color_node_new (red); + clutter_paint_node_set_static_name (lines_node, + "ClutterDeformEffect (lines)"); + clutter_paint_node_add_child (node, lines_node); + clutter_paint_node_add_primitive (lines_node, priv->lines_primitive); + clutter_paint_node_unref (lines_node); } } diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c index 3de2373b7..84a2d8557 100644 --- a/clutter/clutter/clutter-offscreen-effect.c +++ b/clutter/clutter/clutter-offscreen-effect.c @@ -75,6 +75,8 @@ #include "clutter-private.h" #include "clutter-stage-private.h" #include "clutter-paint-context-private.h" +#include "clutter-paint-node-private.h" +#include "clutter-paint-nodes.h" #include "clutter-paint-volume-private.h" #include "clutter-actor-box-private.h" @@ -386,11 +388,11 @@ disable_effect: static void clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterOffscreenEffectPrivate *priv = effect->priv; - CoglFramebuffer *framebuffer = - clutter_paint_context_get_framebuffer (paint_context); + ClutterPaintNode *pipeline_node; guint8 paint_opacity; paint_opacity = clutter_actor_get_paint_opacity (priv->actor); @@ -401,18 +403,24 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect, paint_opacity, paint_opacity); + pipeline_node = clutter_pipeline_node_new (priv->pipeline); + clutter_paint_node_set_static_name (pipeline_node, + "ClutterOffscreenEffect (pipeline)"); + clutter_paint_node_add_child (node, pipeline_node); + /* At this point we are in stage coordinates translated so if * we draw our texture using a textured quad the size of the paint * box then we will overlay where the actor would have drawn if it * hadn't been redirected offscreen. */ - cogl_framebuffer_draw_textured_rectangle (framebuffer, - priv->pipeline, - 0, 0, - cogl_texture_get_width (priv->texture), - cogl_texture_get_height (priv->texture), - 0.0, 0.0, - 1.0, 1.0); + clutter_paint_node_add_rectangle (pipeline_node, + &(ClutterActorBox) { + 0.f, 0.f, + cogl_texture_get_width (priv->texture), + cogl_texture_get_height (priv->texture), + }); + + clutter_paint_node_unref (pipeline_node); } static void @@ -626,10 +634,17 @@ void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, ClutterPaintContext *paint_context) { + ClutterPaintNode *node; + g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect)); + node = clutter_effect_node_new (CLUTTER_EFFECT (effect)); + CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect, + node, paint_context); + clutter_paint_node_paint (node, paint_context); + clutter_paint_node_unref (node); } /** diff --git a/clutter/clutter/clutter-offscreen-effect.h b/clutter/clutter/clutter-offscreen-effect.h index 51382f43b..a53c269ff 100644 --- a/clutter/clutter/clutter-offscreen-effect.h +++ b/clutter/clutter/clutter-offscreen-effect.h @@ -82,6 +82,7 @@ struct _ClutterOffscreenEffectClass CoglPipeline* (* create_pipeline) (ClutterOffscreenEffect *effect, CoglTexture *texture); void (* paint_target) (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context); /*< private >*/ diff --git a/clutter/clutter/clutter-shader-effect.c b/clutter/clutter/clutter-shader-effect.c index f409399ee..7bbc97d0d 100644 --- a/clutter/clutter/clutter-shader-effect.c +++ b/clutter/clutter/clutter-shader-effect.c @@ -384,6 +384,7 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self) static void clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect); @@ -414,7 +415,7 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect, out: /* paint the offscreen buffer */ parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class); - parent->paint_target (effect, paint_context); + parent->paint_target (effect, node, paint_context); } diff --git a/src/tests/clutter/conform/actor-shader-effect.c b/src/tests/clutter/conform/actor-shader-effect.c index 79b792dc7..38a2d862d 100644 --- a/src/tests/clutter/conform/actor-shader-effect.c +++ b/src/tests/clutter/conform/actor-shader-effect.c @@ -37,6 +37,7 @@ G_DEFINE_TYPE (FooOldShaderEffect, static void foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect), @@ -47,7 +48,7 @@ foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect, 1.0f, 0.0f, 0.0f); CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)-> - paint_target (effect, paint_context); + paint_target (effect, node, paint_context); } static void @@ -112,6 +113,7 @@ foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect) static void foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect), @@ -120,7 +122,7 @@ foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect, 0.0f, 1.0f, 0.0f); CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)-> - paint_target (effect, paint_context); + paint_target (effect, node, paint_context); } static void