summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--tests/conform/Makefile.am1
-rw-r--r--tests/conform/test-clutter-cairo-texture.c196
-rw-r--r--tests/conform/test-conform-main.c1
4 files changed, 199 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 5b0ff42b5..65a694870 100644
--- a/.gitignore
+++ b/.gitignore
@@ -255,6 +255,7 @@ TAGS
/tests/conform/test-cogl-texture-rectangle
/tests/conform/test-cogl-path
/tests/conform/test-cogl-wrap-modes
+/tests/conform/test-clutter-cairo-texture
/tests/conform/wrappers
/tests/micro-bench/test-text-perf
/tests/micro-bench/test-text
diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am
index fd0263a9b..5ad918d81 100644
--- a/tests/conform/Makefile.am
+++ b/tests/conform/Makefile.am
@@ -37,6 +37,7 @@ test_conformance_SOURCES = \
test-paint-opacity.c \
test-binding-pool.c \
test-clutter-text.c \
+ test-clutter-cairo-texture.c \
test-text-cache.c \
test-anchors.c \
test-model.c \
diff --git a/tests/conform/test-clutter-cairo-texture.c b/tests/conform/test-clutter-cairo-texture.c
new file mode 100644
index 000000000..a6b73c83b
--- /dev/null
+++ b/tests/conform/test-clutter-cairo-texture.c
@@ -0,0 +1,196 @@
+#include <clutter/clutter.h>
+#include <cogl/cogl.h>
+
+#include "test-conform-common.h"
+
+#define BLOCK_SIZE 16
+
+/* Number of pixels at the border of a block to skip when verifying */
+#define TEST_INSET 1
+
+static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
+
+typedef enum
+{
+ /* The first frame is drawn using clutter_cairo_texture_create. The
+ second frame is an update of the first frame using
+ clutter_cairo_texture_create_region. The states are stored like
+ this because the cairo drawing is done on idle and the validation
+ is done during paint and we need to synchronize the two */
+ TEST_BEFORE_DRAW_FIRST_FRAME,
+ TEST_BEFORE_VALIDATE_FIRST_FRAME,
+ TEST_BEFORE_DRAW_SECOND_FRAME,
+ TEST_BEFORE_VALIDATE_SECOND_FRAME,
+ TEST_DONE
+} TestProgress;
+
+typedef struct _TestState
+{
+ ClutterActor *stage;
+ ClutterActor *ct;
+ guint frame;
+ TestProgress progress;
+} TestState;
+
+static void
+validate_part (int block_x, int block_y, const ClutterColor *color)
+{
+ guint8 data[BLOCK_SIZE * BLOCK_SIZE * 4];
+ int x, y;
+
+ cogl_read_pixels (block_x * BLOCK_SIZE,
+ block_y * BLOCK_SIZE,
+ BLOCK_SIZE, BLOCK_SIZE,
+ COGL_READ_PIXELS_COLOR_BUFFER,
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+ data);
+
+ for (x = 0; x < BLOCK_SIZE - TEST_INSET * 2; x++)
+ for (y = 0; y < BLOCK_SIZE - TEST_INSET * 2; y++)
+ {
+ const guint8 *p = data + ((x + TEST_INSET) * 4 +
+ (y + TEST_INSET) * BLOCK_SIZE * 4);
+
+ g_assert_cmpint (p[0], ==, color->red);
+ g_assert_cmpint (p[1], ==, color->green);
+ g_assert_cmpint (p[2], ==, color->blue);
+ }
+}
+
+static void
+paint_cb (ClutterActor *actor, TestState *state)
+{
+ static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff };
+ static const ClutterColor green = { 0x00, 0xff, 0x00, 0xff };
+ static const ClutterColor blue = { 0x00, 0x00, 0xff, 0xff };
+
+ if (state->frame++ < 2)
+ return;
+
+ switch (state->progress)
+ {
+ case TEST_BEFORE_DRAW_FIRST_FRAME:
+ case TEST_BEFORE_DRAW_SECOND_FRAME:
+ case TEST_DONE:
+ /* Handled by the idle callback */
+ break;
+
+ case TEST_BEFORE_VALIDATE_FIRST_FRAME:
+ /* In the first frame there is a red rectangle next to a green
+ rectangle */
+ validate_part (0, 0, &red);
+ validate_part (1, 0, &green);
+
+ state->progress = TEST_BEFORE_DRAW_SECOND_FRAME;
+ break;
+
+ case TEST_BEFORE_VALIDATE_SECOND_FRAME:
+ /* The second frame is the same except the green rectangle is
+ replaced with a blue one */
+ validate_part (0, 0, &red);
+ validate_part (1, 0, &blue);
+
+ state->progress = TEST_DONE;
+ break;
+ }
+}
+
+static gboolean
+idle_cb (gpointer data)
+{
+ TestState *state = data;
+ cairo_t *cr;
+
+ if (state->frame < 2)
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (state->stage));
+ else
+ switch (state->progress)
+ {
+ case TEST_BEFORE_DRAW_FIRST_FRAME:
+ /* Draw two different colour rectangles */
+ cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (state->ct));
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ cairo_save (cr);
+ cairo_rectangle (cr, 0, 0, BLOCK_SIZE, BLOCK_SIZE);
+ cairo_clip (cr);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_rectangle (cr, BLOCK_SIZE, 0, BLOCK_SIZE, BLOCK_SIZE);
+ cairo_clip (cr);
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+
+ cairo_destroy (cr);
+
+ state->progress = TEST_BEFORE_VALIDATE_FIRST_FRAME;
+
+ break;
+
+ case TEST_BEFORE_DRAW_SECOND_FRAME:
+ /* Replace the second rectangle with a blue one */
+ cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (state->ct));
+
+ cairo_rectangle (cr, BLOCK_SIZE, 0, BLOCK_SIZE, BLOCK_SIZE);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+
+ state->progress = TEST_BEFORE_VALIDATE_SECOND_FRAME;
+
+ break;
+
+ case TEST_BEFORE_VALIDATE_FIRST_FRAME:
+ case TEST_BEFORE_VALIDATE_SECOND_FRAME:
+ /* Handled by the paint callback */
+ break;
+
+ case TEST_DONE:
+ clutter_main_quit ();
+ break;
+ }
+
+ return TRUE;
+}
+
+void
+test_clutter_cairo_texture (TestConformSimpleFixture *fixture,
+ gconstpointer data)
+{
+ TestState state;
+ unsigned int idle_source;
+ unsigned int paint_handler;
+
+ state.frame = 0;
+ state.stage = clutter_stage_get_default ();
+ state.progress = TEST_BEFORE_DRAW_FIRST_FRAME;
+
+ state.ct = clutter_cairo_texture_new (BLOCK_SIZE * 2, BLOCK_SIZE);
+ clutter_container_add_actor (CLUTTER_CONTAINER (state.stage), state.ct);
+
+ clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color);
+
+ /* We force continuous redrawing of the stage, since we need to skip
+ * the first few frames, and we wont be doing anything else that
+ * will trigger redrawing. */
+ idle_source = g_idle_add (idle_cb, &state);
+ paint_handler = g_signal_connect_after (state.stage, "paint",
+ G_CALLBACK (paint_cb), &state);
+
+ clutter_actor_show (state.stage);
+ clutter_main ();
+
+ g_signal_handler_disconnect (state.stage, paint_handler);
+ g_source_remove (idle_source);
+
+ if (g_test_verbose ())
+ g_print ("OK\n");
+}
+
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
index cecb44508..44e64d36d 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -145,6 +145,7 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/opacity", test_paint_opacity);
TEST_CONFORM_SIMPLE ("/texture", test_texture_fbo);
+ TEST_CONFORM_SIMPLE ("/texture/cairo", test_clutter_cairo_texture);
TEST_CONFORM_SIMPLE ("/path", test_path);