[clutter/wip/neil/master-next] Update uniforms on change in internal shader effects



commit a97a0d15f7353b66b05276df087f60e0db3f601c
Author: Neil Roberts <neil linux intel com>
Date:   Tue Feb 14 11:26:45 2012 +0000

    Update uniforms on change in internal shader effects
    
    The blur, colorize and desaturate shader effects now update their
    uniforms only when the corresponding property on the effect changes
    rather than every time the effect is painted. This is possible because
    the uniform values are now attached to the pipeline which belongs to
    the effect rather than being set on a shared program object.
    
    The texture on the pipeline is now also only updated in reponse the
    pre_paint virtual. If the effect needs to change the texture it will
    also have to cause the effect to redraw the contents of the texture so
    this seems like a safe place to update it.

 clutter/clutter-blur-effect.c       |   58 ++++++++++++++++++------------
 clutter/clutter-colorize-effect.c   |   67 +++++++++++++++++++++++------------
 clutter/clutter-desaturate-effect.c |   38 ++++++++++++++++---
 3 files changed, 110 insertions(+), 53 deletions(-)
---
diff --git a/clutter/clutter-blur-effect.c b/clutter/clutter-blur-effect.c
index 1737b74..a7a7c09 100644
--- a/clutter/clutter-blur-effect.c
+++ b/clutter/clutter-blur-effect.c
@@ -84,6 +84,9 @@ struct _ClutterBlurEffect
 
   gint pixel_step_uniform;
 
+  gint tex_width;
+  gint tex_height;
+
   CoglPipeline *pipeline;
 };
 
@@ -124,36 +127,43 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect)
     }
 
   parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
-  return parent_class->pre_paint (effect);
-}
+  if (parent_class->pre_paint (effect))
+    {
+      ClutterOffscreenEffect *offscreen_effect =
+        CLUTTER_OFFSCREEN_EFFECT (effect);
+      CoglHandle texture;
 
-static void
-clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
-{
-  ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
-  guint8 paint_opacity;
-  CoglHandle texture;
-  int width, height;
+      texture = clutter_offscreen_effect_get_texture (offscreen_effect);
+      self->tex_width = cogl_texture_get_width (texture);
+      self->tex_height = cogl_texture_get_height (texture);
 
-  texture = clutter_offscreen_effect_get_texture (effect);
-  width = cogl_texture_get_width (texture);
-  height = cogl_texture_get_height (texture);
+      if (self->pixel_step_uniform > -1)
+        {
+          gfloat pixel_step[2];
 
-  if (self->pixel_step_uniform > -1)
-    {
-      gfloat pixel_step[2];
+          pixel_step[0] = 1.0f / self->tex_width;
+          pixel_step[1] = 1.0f / self->tex_height;
 
-      pixel_step[0] = 1.0f / width;
-      pixel_step[1] = 1.0f / height;
+          cogl_pipeline_set_uniform_float (self->pipeline,
+                                           self->pixel_step_uniform,
+                                           2, /* n_components */
+                                           1, /* count */
+                                           pixel_step);
+        }
 
-      cogl_pipeline_set_uniform_float (self->pipeline,
-                                       self->pixel_step_uniform,
-                                       2, /* n_components */
-                                       1, /* count */
-                                       pixel_step);
+      cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+
+      return TRUE;
     }
+  else
+    return FALSE;
+}
 
-  cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+static void
+clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
+{
+  ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
+  guint8 paint_opacity;
 
   paint_opacity = clutter_actor_get_paint_opacity (self->actor);
 
@@ -164,7 +174,7 @@ clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
                               paint_opacity);
   cogl_push_source (self->pipeline);
 
-  cogl_rectangle (0, 0, width, height);
+  cogl_rectangle (0, 0, self->tex_width, self->tex_height);
 
   cogl_pop_source ();
 }
diff --git a/clutter/clutter-colorize-effect.c b/clutter/clutter-colorize-effect.c
index a1dad4f..2ccd068 100644
--- a/clutter/clutter-colorize-effect.c
+++ b/clutter/clutter-colorize-effect.c
@@ -59,6 +59,9 @@ struct _ClutterColorizeEffect
 
   gint tint_uniform;
 
+  gint tex_width;
+  gint tex_height;
+
   CoglPipeline *pipeline;
 };
 
@@ -104,6 +107,7 @@ G_DEFINE_TYPE (ClutterColorizeEffect,
 static gboolean
 clutter_colorize_effect_pre_paint (ClutterEffect *effect)
 {
+  ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
   ClutterEffectClass *parent_class;
 
   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
@@ -122,7 +126,22 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect)
     }
 
   parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
-  return parent_class->pre_paint (effect);
+  if (parent_class->pre_paint (effect))
+    {
+      ClutterOffscreenEffect *offscreen_effect =
+        CLUTTER_OFFSCREEN_EFFECT (effect);
+      CoglHandle texture;
+
+      texture = clutter_offscreen_effect_get_texture (offscreen_effect);
+      self->tex_width = cogl_texture_get_width (texture);
+      self->tex_height = cogl_texture_get_height (texture);
+
+      cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
 static void
@@ -130,27 +149,8 @@ clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
 {
   ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
   ClutterActor *actor;
-  CoglHandle texture;
   guint8 paint_opacity;
 
-  if (self->tint_uniform > -1)
-    {
-      float tint[3] = {
-        self->tint.red / 255.0,
-        self->tint.green / 255.0,
-        self->tint.blue / 255.0
-      };
-
-      cogl_pipeline_set_uniform_float (self->pipeline,
-                                       self->tint_uniform,
-                                       3, /* n_components */
-                                       1, /* count */
-                                       tint);
-    }
-
-  texture = clutter_offscreen_effect_get_texture (effect);
-  cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
-
   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
   paint_opacity = clutter_actor_get_paint_opacity (actor);
 
@@ -161,9 +161,7 @@ clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
                               paint_opacity);
   cogl_push_source (self->pipeline);
 
-  cogl_rectangle (0, 0,
-                  cogl_texture_get_width (texture),
-                  cogl_texture_get_height (texture));
+  cogl_rectangle (0, 0, self->tex_width, self->tex_height);
 
   cogl_pop_source ();
 }
@@ -277,6 +275,25 @@ clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass)
 }
 
 static void
+update_tint_uniform (ClutterColorizeEffect *self)
+{
+  if (self->tint_uniform > -1)
+    {
+      float tint[3] = {
+        self->tint.red / 255.0,
+        self->tint.green / 255.0,
+        self->tint.blue / 255.0
+      };
+
+      cogl_pipeline_set_uniform_float (self->pipeline,
+                                       self->tint_uniform,
+                                       3, /* n_components */
+                                       1, /* count */
+                                       tint);
+    }
+}
+
+static void
 clutter_colorize_effect_init (ClutterColorizeEffect *self)
 {
   CoglPipeline *base_pipeline =
@@ -288,6 +305,8 @@ clutter_colorize_effect_init (ClutterColorizeEffect *self)
     cogl_pipeline_get_uniform_location (self->pipeline, "tint");
 
   self->tint = default_tint;
+
+  update_tint_uniform (self);
 }
 
 /**
@@ -326,6 +345,8 @@ clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
 
   effect->tint = *tint;
 
+  update_tint_uniform (effect);
+
   clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
 
   g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_TINT]);
diff --git a/clutter/clutter-desaturate-effect.c b/clutter/clutter-desaturate-effect.c
index 89ed352..9bdb70a 100644
--- a/clutter/clutter-desaturate-effect.c
+++ b/clutter/clutter-desaturate-effect.c
@@ -63,6 +63,9 @@ struct _ClutterDesaturateEffect
 
   gint factor_uniform;
 
+  gint tex_width;
+  gint tex_height;
+
   CoglPipeline *pipeline;
 };
 
@@ -111,6 +114,7 @@ G_DEFINE_TYPE (ClutterDesaturateEffect,
 static gboolean
 clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
 {
+  ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
   ClutterEffectClass *parent_class;
 
   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
@@ -129,7 +133,22 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
     }
 
   parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class);
-  return parent_class->pre_paint (effect);
+  if (parent_class->pre_paint (effect))
+    {
+      ClutterOffscreenEffect *offscreen_effect =
+        CLUTTER_OFFSCREEN_EFFECT (effect);
+      CoglHandle texture;
+
+      texture = clutter_offscreen_effect_get_texture (offscreen_effect);
+      self->tex_width = cogl_texture_get_width (texture);
+      self->tex_height = cogl_texture_get_height (texture);
+
+      cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
 static void
@@ -140,11 +159,6 @@ clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect)
   CoglHandle texture;
   guint8 paint_opacity;
 
-  if (self->factor_uniform > -1)
-    cogl_pipeline_set_uniform_1f (self->pipeline,
-                                  self->factor_uniform,
-                                  self->factor);
-
   texture = clutter_offscreen_effect_get_texture (effect);
   cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
 
@@ -221,6 +235,15 @@ clutter_desaturate_effect_get_property (GObject    *gobject,
 }
 
 static void
+update_factor_uniform (ClutterDesaturateEffect *self)
+{
+  if (self->factor_uniform > -1)
+    cogl_pipeline_set_uniform_1f (self->pipeline,
+                                  self->factor_uniform,
+                                  self->factor);
+}
+
+static void
 clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass)
 {
   ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
@@ -286,6 +309,8 @@ clutter_desaturate_effect_init (ClutterDesaturateEffect *self)
     cogl_pipeline_get_uniform_location (self->pipeline, "factor");
 
   self->factor = 1.0;
+
+  update_factor_uniform (self);
 }
 
 /**
@@ -329,6 +354,7 @@ clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect,
   if (fabsf (effect->factor - factor) >= 0.00001)
     {
       effect->factor = factor;
+      update_factor_uniform (effect);
 
       clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
 



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