[clutter] Add a conformance test for ClutterShaderEffect



commit 3372a0233e574b6d67e9f9d83010c1891c427ad8
Author: Neil Roberts <neil linux intel com>
Date:   Thu Sep 29 20:14:26 2011 +0100

    Add a conformance test for ClutterShaderEffect
    
    This adds a simple conformance test which sets up a few shader effects
    using both the old style with clutter_shader_effect_set_source and the
    new style by overriding get_static_shader_source. The effects are then
    verified to confirm that they drew the right pixel colour.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=660512
    
    Reviewed-by: Emmanuele Bassi <ebassi linux intel com>

 tests/conform/Makefile.am          |    1 +
 tests/conform/test-conform-main.c  |    1 +
 tests/conform/test-shader-effect.c |  267 ++++++++++++++++++++++++++++++++++++
 3 files changed, 269 insertions(+), 0 deletions(-)
---
diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am
index 43c9295..c9e81d5 100644
--- a/tests/conform/Makefile.am
+++ b/tests/conform/Makefile.am
@@ -75,6 +75,7 @@ units_sources += \
 	test-pick.c 			\
 	test-texture-fbo.c		\
         test-text-cache.c               \
+	test-shader-effect.c		\
 	$(NULL)
 
 # objects tests
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
index 39d1fcd..5055772 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -134,6 +134,7 @@ main (int argc, char **argv)
   TEST_CONFORM_SIMPLE ("/actor", actor_fixed_size);
   TEST_CONFORM_SIMPLE ("/actor", actor_preferred_size);
   TEST_CONFORM_SIMPLE ("/actor", test_offscreen_redirect);
+  TEST_CONFORM_SIMPLE ("/actor", test_shader_effect);
 
   TEST_CONFORM_SIMPLE ("/invariants", test_initial_state);
   TEST_CONFORM_SIMPLE ("/invariants", test_shown_not_parented);
diff --git a/tests/conform/test-shader-effect.c b/tests/conform/test-shader-effect.c
new file mode 100644
index 0000000..916edf7
--- /dev/null
+++ b/tests/conform/test-shader-effect.c
@@ -0,0 +1,267 @@
+#include <clutter/clutter.h>
+
+#include "test-conform-common.h"
+
+/****************************************************************
+ Old style shader effect
+ This uses clutter_shader_effect_set_source
+ ****************************************************************/
+
+static const gchar
+old_shader_effect_source[] =
+  "uniform vec3 override_color;\n"
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  cogl_color_out = vec4 (override_color, 1.0);\n"
+  "}";
+
+typedef struct _FooOldShaderEffectClass
+{
+  ClutterShaderEffectClass parent_class;
+} FooOldShaderEffectClass;
+
+typedef struct _FooOldShaderEffect
+{
+  ClutterShaderEffect parent;
+} FooOldShaderEffect;
+
+G_DEFINE_TYPE (FooOldShaderEffect,
+               foo_old_shader_effect,
+               CLUTTER_TYPE_SHADER_EFFECT);
+
+static void
+foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect)
+{
+  clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
+                                           old_shader_effect_source);
+  clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
+                                     "override_color",
+                                     G_TYPE_FLOAT, 3,
+                                     1.0f, 0.0f, 0.0f);
+
+  CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)->
+    paint_target (effect);
+}
+
+static void
+foo_old_shader_effect_class_init (FooOldShaderEffectClass *klass)
+{
+  ClutterOffscreenEffectClass *offscreen_effect_class =
+    CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
+
+  offscreen_effect_class->paint_target = foo_old_shader_effect_paint_target;
+}
+
+static void
+foo_old_shader_effect_init (FooOldShaderEffect *self)
+{
+}
+
+/****************************************************************
+ New style shader effect
+ This overrides get_static_shader_source()
+ ****************************************************************/
+
+static const gchar
+new_shader_effect_source[] =
+  "uniform vec3 override_color;\n"
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  cogl_color_out = (vec4 (override_color, 1.0) +\n"
+  "                    vec4 (0.0, 0.0, 1.0, 0.0));\n"
+  "}";
+
+typedef struct _FooNewShaderEffectClass
+{
+  ClutterShaderEffectClass parent_class;
+} FooNewShaderEffectClass;
+
+typedef struct _FooNewShaderEffect
+{
+  ClutterShaderEffect parent;
+} FooNewShaderEffect;
+
+G_DEFINE_TYPE (FooNewShaderEffect,
+               foo_new_shader_effect,
+               CLUTTER_TYPE_SHADER_EFFECT);
+
+static gchar *
+foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
+{
+  static gboolean already_called = FALSE;
+
+  /* This should only be called once even though we have two actors
+     using this effect */
+  g_assert (!already_called);
+
+  already_called = TRUE;
+
+  return g_strdup (new_shader_effect_source);
+}
+
+static void
+foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect)
+{
+  clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
+                                     "override_color",
+                                     G_TYPE_FLOAT, 3,
+                                     0.0f, 1.0f, 0.0f);
+
+  CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)->
+    paint_target (effect);
+}
+
+static void
+foo_new_shader_effect_class_init (FooNewShaderEffectClass *klass)
+{
+  ClutterOffscreenEffectClass *offscreen_effect_class =
+    CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
+  ClutterShaderEffectClass *shader_effect_class =
+    CLUTTER_SHADER_EFFECT_CLASS (klass);
+
+  offscreen_effect_class->paint_target = foo_new_shader_effect_paint_target;
+
+  shader_effect_class->get_static_shader_source =
+    foo_new_shader_effect_get_static_source;
+}
+
+static void
+foo_new_shader_effect_init (FooNewShaderEffect *self)
+{
+}
+
+/****************************************************************
+ Another new style shader effect
+ This is the same but with a different shader. This is just
+ sanity check that each class gets its own copy of the private
+ data
+ ****************************************************************/
+
+static const gchar
+another_new_shader_effect_source[] =
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  cogl_color_out = vec4 (1.0, 0.0, 1.0, 1.0);\n"
+  "}";
+
+typedef struct _FooAnotherNewShaderEffectClass
+{
+  ClutterShaderEffectClass parent_class;
+} FooAnotherNewShaderEffectClass;
+
+typedef struct _FooAnotherNewShaderEffect
+{
+  ClutterShaderEffect parent;
+} FooAnotherNewShaderEffect;
+
+G_DEFINE_TYPE (FooAnotherNewShaderEffect,
+               foo_another_new_shader_effect,
+               CLUTTER_TYPE_SHADER_EFFECT);
+
+static gchar *
+foo_another_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
+{
+  return g_strdup (another_new_shader_effect_source);
+}
+
+static void
+foo_another_new_shader_effect_class_init (FooAnotherNewShaderEffectClass *klass)
+{
+  ClutterShaderEffectClass *shader_effect_class =
+    CLUTTER_SHADER_EFFECT_CLASS (klass);
+
+  shader_effect_class->get_static_shader_source =
+    foo_another_new_shader_effect_get_static_source;
+}
+
+static void
+foo_another_new_shader_effect_init (FooAnotherNewShaderEffect *self)
+{
+}
+
+/****************************************************************/
+
+static ClutterActor *
+make_actor (GType shader_type)
+{
+  ClutterActor *rect;
+  const ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
+
+  rect = clutter_rectangle_new ();
+  clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect), &white);
+  clutter_actor_set_size (rect, 50, 50);
+
+  clutter_actor_add_effect (rect, g_object_new (shader_type, NULL));
+
+  return rect;
+}
+
+static guint32
+get_pixel (int x, int y)
+{
+  guint8 data[4];
+
+  cogl_read_pixels (x, y, 1, 1,
+                    COGL_READ_PIXELS_COLOR_BUFFER,
+                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                    data);
+
+  return (((guint32) data[0] << 16) |
+          ((guint32) data[1] << 8) |
+          data[2]);
+}
+
+static void
+paint_cb (ClutterActor *stage)
+{
+  /* old shader effect */
+  g_assert_cmpint (get_pixel (50, 50), ==, 0xff0000);
+  /* new shader effect */
+  g_assert_cmpint (get_pixel (150, 50), ==, 0x00ffff);
+  /* another new shader effect */
+  g_assert_cmpint (get_pixel (250, 50), ==, 0xff00ff);
+  /* new shader effect */
+  g_assert_cmpint (get_pixel (350, 50), ==, 0x00ffff);
+
+  clutter_main_quit ();
+}
+
+void
+test_shader_effect (TestConformSimpleFixture *fixture,
+                    gconstpointer data)
+{
+  ClutterActor *stage;
+  ClutterActor *rect;
+
+  stage = clutter_stage_get_default ();
+
+  rect = make_actor (foo_old_shader_effect_get_type ());
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
+
+  rect = make_actor (foo_new_shader_effect_get_type ());
+  clutter_actor_set_x (rect, 100);
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
+
+  rect = make_actor (foo_another_new_shader_effect_get_type ());
+  clutter_actor_set_x (rect, 200);
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
+
+  rect = make_actor (foo_new_shader_effect_get_type ());
+  clutter_actor_set_x (rect, 300);
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
+
+  clutter_actor_show (stage);
+
+  g_signal_connect_after (stage, "paint", G_CALLBACK (paint_cb), NULL);
+
+  clutter_main ();
+
+  if (g_test_verbose ())
+    g_print ("OK\n");
+}



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