[mutter/gbsneto/offscreen-paint-node: 6/8] clutter/effect: Add paint nodes to all paint vfuncs



commit 5e680fd43fbefa10763065ce8e06a13094a10fd3
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sun Jul 5 18:45:03 2020 -0300

    clutter/effect: Add paint nodes to all paint vfuncs
    
    In the purely paint node based rendering future, ClutterEffects
    simply add more paint nodes to the tree when painting the actor.
    
    This is the leap to achieve that future.
    
    Add paint nodes to pre_paint, paint, and post_paint, and move the
    ClutterEffectNode creation to _clutter_effect_paint().
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355

 clutter/clutter/clutter-blur-effect.c              |  3 +-
 .../clutter/clutter-brightness-contrast-effect.c   |  3 +-
 clutter/clutter/clutter-colorize-effect.c          |  3 +-
 clutter/clutter/clutter-desaturate-effect.c        |  3 +-
 clutter/clutter/clutter-effect.c                   | 25 +++---
 clutter/clutter/clutter-effect.h                   |  3 +
 clutter/clutter/clutter-offscreen-effect.c         | 91 +++++++---------------
 7 files changed, 57 insertions(+), 74 deletions(-)
---
diff --git a/clutter/clutter/clutter-blur-effect.c b/clutter/clutter/clutter-blur-effect.c
index 99331dce23..92aeca697c 100644
--- a/clutter/clutter/clutter-blur-effect.c
+++ b/clutter/clutter/clutter-blur-effect.c
@@ -126,6 +126,7 @@ clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect,
 
 static gboolean
 clutter_blur_effect_pre_paint (ClutterEffect       *effect,
+                               ClutterPaintNode    *node,
                                ClutterPaintContext *paint_context)
 {
   ClutterEffectClass *parent_class;
@@ -143,7 +144,7 @@ clutter_blur_effect_pre_paint (ClutterEffect       *effect,
     }
 
   parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
-  return parent_class->pre_paint (effect, paint_context);
+  return parent_class->pre_paint (effect, node, paint_context);
 }
 
 static gboolean
diff --git a/clutter/clutter/clutter-brightness-contrast-effect.c 
b/clutter/clutter/clutter-brightness-contrast-effect.c
index aa196fa205..4942b87725 100644
--- a/clutter/clutter/clutter-brightness-contrast-effect.c
+++ b/clutter/clutter/clutter-brightness-contrast-effect.c
@@ -140,6 +140,7 @@ clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effe
 
 static gboolean
 clutter_brightness_contrast_effect_pre_paint (ClutterEffect       *effect,
+                                              ClutterPaintNode    *node,
                                               ClutterPaintContext *paint_context)
 {
   ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
@@ -164,7 +165,7 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect       *effect,
   parent_class =
     CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
 
-  return parent_class->pre_paint (effect, paint_context);
+  return parent_class->pre_paint (effect, node, paint_context);
 }
 
 static void
diff --git a/clutter/clutter/clutter-colorize-effect.c b/clutter/clutter/clutter-colorize-effect.c
index 8b8aba1d79..d73a0524fa 100644
--- a/clutter/clutter/clutter-colorize-effect.c
+++ b/clutter/clutter/clutter-colorize-effect.c
@@ -114,6 +114,7 @@ clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect,
 
 static gboolean
 clutter_colorize_effect_pre_paint (ClutterEffect       *effect,
+                                   ClutterPaintNode    *node,
                                    ClutterPaintContext *paint_context)
 {
   ClutterEffectClass *parent_class;
@@ -131,7 +132,7 @@ clutter_colorize_effect_pre_paint (ClutterEffect       *effect,
     }
 
   parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
-  return parent_class->pre_paint (effect, paint_context);
+  return parent_class->pre_paint (effect, node, paint_context);
 }
 
 static void
diff --git a/clutter/clutter/clutter-desaturate-effect.c b/clutter/clutter/clutter-desaturate-effect.c
index 52c6c08244..c0184c3ec5 100644
--- a/clutter/clutter/clutter-desaturate-effect.c
+++ b/clutter/clutter/clutter-desaturate-effect.c
@@ -125,6 +125,7 @@ clutter_desaturate_effect_create_pipeline (ClutterOffscreenEffect *effect,
 
 static gboolean
 clutter_desaturate_effect_pre_paint (ClutterEffect       *effect,
+                                     ClutterPaintNode    *node,
                                      ClutterPaintContext *paint_context)
 {
   ClutterEffectClass *parent_class;
@@ -142,7 +143,7 @@ clutter_desaturate_effect_pre_paint (ClutterEffect       *effect,
     }
 
   parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class);
-  return parent_class->pre_paint (effect, paint_context);
+  return parent_class->pre_paint (effect, node, paint_context);
 }
 
 static void
diff --git a/clutter/clutter/clutter-effect.c b/clutter/clutter/clutter-effect.c
index 4fa88efb80..9ff0dcd1fb 100644
--- a/clutter/clutter/clutter-effect.c
+++ b/clutter/clutter/clutter-effect.c
@@ -180,6 +180,7 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect,
 
 static gboolean
 clutter_effect_real_pre_paint (ClutterEffect       *effect,
+                               ClutterPaintNode    *node,
                                ClutterPaintContext *paint_context)
 {
   return TRUE;
@@ -187,6 +188,7 @@ clutter_effect_real_pre_paint (ClutterEffect       *effect,
 
 static void
 clutter_effect_real_post_paint (ClutterEffect       *effect,
+                                ClutterPaintNode    *node,
                                 ClutterPaintContext *paint_context)
 {
 }
@@ -216,28 +218,23 @@ clutter_effect_real_paint_node (ClutterEffect           *effect,
 
 static void
 clutter_effect_real_paint (ClutterEffect           *effect,
+                           ClutterPaintNode        *node,
                            ClutterPaintContext     *paint_context,
                            ClutterEffectPaintFlags  flags)
 {
   ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
-  ClutterPaintNode *node;
   gboolean pre_paint_succeeded;
 
   /* The default implementation provides a compatibility wrapper for
      effects that haven't migrated to use the 'paint' virtual yet. This
      just calls the old pre and post virtuals before chaining on */
 
-  pre_paint_succeeded = effect_class->pre_paint (effect, paint_context);
-
-  node = clutter_effect_node_new (effect);
+  pre_paint_succeeded = effect_class->pre_paint (effect, node,paint_context);
 
   effect_class->paint_node (effect, node, paint_context, flags);
-  clutter_paint_node_paint (node, paint_context);
 
   if (pre_paint_succeeded)
-    effect_class->post_paint (effect, paint_context);
-
-  clutter_paint_node_unref (node);
+    effect_class->post_paint (effect, node, paint_context);
 }
 
 static void
@@ -291,9 +288,19 @@ _clutter_effect_paint (ClutterEffect           *effect,
                        ClutterPaintContext     *paint_context,
                        ClutterEffectPaintFlags  flags)
 {
+  ClutterPaintNode *node;
+
   g_return_if_fail (CLUTTER_IS_EFFECT (effect));
 
-  CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, paint_context, flags);
+  node = clutter_effect_node_new (effect);
+
+  CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect,
+                                            node,
+                                            paint_context,
+                                            flags);
+
+  clutter_paint_node_paint (node, paint_context);
+  clutter_paint_node_unref (node);
 }
 
 void
diff --git a/clutter/clutter/clutter-effect.h b/clutter/clutter/clutter-effect.h
index d15015cf9e..8969fcd784 100644
--- a/clutter/clutter/clutter-effect.h
+++ b/clutter/clutter/clutter-effect.h
@@ -77,14 +77,17 @@ struct _ClutterEffectClass
 
   /*< public >*/
   gboolean (* pre_paint)           (ClutterEffect           *effect,
+                                    ClutterPaintNode        *node,
                                     ClutterPaintContext     *paint_context);
   void     (* post_paint)          (ClutterEffect           *effect,
+                                    ClutterPaintNode        *node,
                                     ClutterPaintContext     *paint_context);
 
   gboolean (* modify_paint_volume) (ClutterEffect           *effect,
                                     ClutterPaintVolume      *volume);
 
   void     (* paint)               (ClutterEffect           *effect,
+                                    ClutterPaintNode        *node,
                                     ClutterPaintContext     *paint_context,
                                     ClutterEffectPaintFlags  flags);
   void     (* paint_node)          (ClutterEffect           *effect,
diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c
index 47a803f1c3..7be3056b36 100644
--- a/clutter/clutter/clutter-offscreen-effect.c
+++ b/clutter/clutter/clutter-offscreen-effect.c
@@ -238,6 +238,7 @@ update_fbo (ClutterEffect *effect,
 
 static gboolean
 clutter_offscreen_effect_pre_paint (ClutterEffect       *effect,
+                                    ClutterPaintNode    *node,
                                     ClutterPaintContext *paint_context)
 {
   ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
@@ -246,7 +247,6 @@ clutter_offscreen_effect_pre_paint (ClutterEffect       *effect,
   ClutterActor *stage;
   CoglMatrix projection, modelview;
   const ClutterPaintVolume *volume;
-  CoglColor transparent;
   gfloat stage_width, stage_height;
   gfloat target_width = -1, target_height = -1;
   float resource_scale;
@@ -303,8 +303,6 @@ clutter_offscreen_effect_pre_paint (ClutterEffect       *effect,
   if (!update_fbo (effect, target_width, target_height, resource_scale))
     goto fail;
 
-  clutter_paint_context_push_framebuffer (paint_context, priv->offscreen);
-
   /* We don't want the FBO contents to be transformed. That could waste memory
    * (e.g. during zoom), or result in something that's not rectangular (clipped
    * incorrectly). So drop the modelview matrix of the current paint chain.
@@ -330,22 +328,6 @@ clutter_offscreen_effect_pre_paint (ClutterEffect       *effect,
 
   cogl_framebuffer_set_projection_matrix (priv->offscreen, &projection);
 
-  cogl_color_init_from_4ub (&transparent, 0, 0, 0, 0);
-  cogl_framebuffer_clear (priv->offscreen,
-                          COGL_BUFFER_BIT_COLOR |
-                          COGL_BUFFER_BIT_DEPTH,
-                          &transparent);
-
-  cogl_framebuffer_push_matrix (priv->offscreen);
-
-  /* Override the actor's opacity to fully opaque - we paint the offscreen
-   * texture with the actor's paint opacity, so we need to do this to avoid
-   * multiplying the opacity twice.
-   */
-  priv->old_opacity_override =
-    clutter_actor_get_opacity_override (priv->actor);
-  clutter_actor_set_opacity_override (priv->actor, 0xff);
-
   return TRUE;
 
 fail:
@@ -392,67 +374,60 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
 
 static void
 clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect,
+                                        ClutterPaintNode       *node,
                                         ClutterPaintContext    *paint_context)
 {
   ClutterOffscreenEffectPrivate *priv = effect->priv;
-  CoglFramebuffer *framebuffer =
-    clutter_paint_context_get_framebuffer (paint_context);
-  CoglMatrix modelview;
+  CoglMatrix transform;
   float resource_scale;
 
-  cogl_framebuffer_push_matrix (framebuffer);
-
-  /* The current modelview matrix is *almost* perfect already. It's only
-   * missing a correction for the expanded FBO and offset rendering within...
-   */
-  cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview);
+  cogl_matrix_init_identity (&transform);
 
   resource_scale = clutter_actor_get_resource_scale (priv->actor);
 
   if (resource_scale != 1.0f)
     {
       float paint_scale = 1.0f / resource_scale;
-      cogl_matrix_scale (&modelview, paint_scale, paint_scale, 1);
+      cogl_matrix_scale (&transform, paint_scale, paint_scale, 1);
     }
 
-  cogl_matrix_translate (&modelview,
+  cogl_matrix_translate (&transform,
                          priv->fbo_offset_x,
                          priv->fbo_offset_y,
                          0.0f);
-  cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview);
+
+  if (!cogl_matrix_is_identity (&transform))
+    {
+      ClutterPaintNode *transform_node;
+
+      transform_node = clutter_transform_node_new (&transform);
+      clutter_paint_node_set_static_name (transform_node,
+                                          "ClutterOffscreenEffect (transform)");
+      clutter_paint_node_add_child (node, transform_node);
+      clutter_paint_node_unref (transform_node);
+
+      node = transform_node;
+    }
 
   /* paint the target material; this is virtualized for
    * sub-classes that require special hand-holding
    */
-  clutter_offscreen_effect_paint_target (effect, paint_context);
-
-  cogl_framebuffer_pop_matrix (framebuffer);
+  clutter_offscreen_effect_paint_target (effect, node, paint_context);
 }
 
 static void
 clutter_offscreen_effect_post_paint (ClutterEffect       *effect,
+                                     ClutterPaintNode    *node,
                                      ClutterPaintContext *paint_context)
 {
   ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
   ClutterOffscreenEffectPrivate *priv = self->priv;
-  CoglFramebuffer *framebuffer;
 
   g_warn_if_fail (priv->offscreen);
   g_warn_if_fail (priv->pipeline);
   g_warn_if_fail (priv->actor);
 
-  /* Restore the previous opacity override */
-  if (priv->actor)
-    {
-      clutter_actor_set_opacity_override (priv->actor,
-                                          priv->old_opacity_override);
-    }
-
-  framebuffer = clutter_paint_context_get_framebuffer (paint_context);
-  cogl_framebuffer_pop_matrix (framebuffer);
-  clutter_paint_context_pop_framebuffer (paint_context);
-
-  clutter_offscreen_effect_paint_texture (self, paint_context);
+  clutter_offscreen_effect_paint_texture (self, node, paint_context);
 }
 
 static void
@@ -481,15 +456,18 @@ clutter_offscreen_effect_paint_node (ClutterEffect           *effect,
 
 static void
 clutter_offscreen_effect_paint (ClutterEffect           *effect,
+                                ClutterPaintNode        *node,
                                 ClutterPaintContext     *paint_context,
                                 ClutterEffectPaintFlags  flags)
 {
   ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
   ClutterOffscreenEffectPrivate *priv = self->priv;
+  ClutterEffectClass *parent_class =
+    CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class);
 
   if (flags & CLUTTER_EFFECT_PAINT_BYPASS_EFFECT)
     {
-      clutter_actor_continue_paint (priv->actor, paint_context);
+      parent_class->paint_node (effect, node, paint_context, flags);
       cogl_clear_object (&priv->offscreen);
       return;
     }
@@ -498,14 +476,9 @@ clutter_offscreen_effect_paint (ClutterEffect           *effect,
    * then we can just use the cached image in the FBO.
    */
   if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY))
-    {
-      ClutterEffectClass *parent_class =
-        CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class);
-
-      parent_class->paint (effect, paint_context, flags);
-    }
+    parent_class->paint (effect, node, paint_context, flags);
   else
-    clutter_offscreen_effect_paint_texture (self, paint_context);
+    clutter_offscreen_effect_paint_texture (self, node, paint_context);
 }
 
 static void
@@ -620,6 +593,7 @@ clutter_offscreen_effect_get_pipeline (ClutterOffscreenEffect *effect)
 /**
  * clutter_offscreen_effect_paint_target:
  * @effect: a #ClutterOffscreenEffect
+ * @node: a #ClutterPaintNode
  * @paint_context: a #ClutterPaintContext
  *
  * Calls the paint_target() virtual function of the @effect
@@ -628,19 +602,14 @@ clutter_offscreen_effect_get_pipeline (ClutterOffscreenEffect *effect)
  */
 void
 clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect,
+                                       ClutterPaintNode       *node,
                                        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);
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]