summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-05-27 18:23:20 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-05-30 18:35:57 -0400
commit139e66fc648d47bcdddc5a85fb7cd111411bfd1e (patch)
tree7990705080eece7f86736116588f042bfb0b05c8
parentddff977be811dd4edf0cef9da2c89b51ff114c98 (diff)
test: Add glyph-test
This test tests the new glyph cache and compositing API. Much of this test is intending to making sure that clipping and alpha map handling survive any optimizations that may be added to the glyph compositing.
-rw-r--r--test/Makefile.sources1
-rw-r--r--test/glyph-test.c321
2 files changed, 322 insertions, 0 deletions
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 99eb705a..fad8c6f6 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -16,6 +16,7 @@ TESTPROGRAMS = \
stress-test \
composite-traps-test \
blitters-test \
+ glyph-test \
scaling-test \
affine-test \
composite \
diff --git a/test/glyph-test.c b/test/glyph-test.c
new file mode 100644
index 00000000..430669f8
--- /dev/null
+++ b/test/glyph-test.c
@@ -0,0 +1,321 @@
+#include <stdlib.h>
+#include "utils.h"
+
+static const pixman_format_code_t glyph_formats[] =
+{
+ PIXMAN_a8r8g8b8,
+ PIXMAN_a8,
+ PIXMAN_a4,
+ PIXMAN_a1,
+ PIXMAN_x8r8g8b8,
+ PIXMAN_r3g3b2,
+ PIXMAN_null,
+};
+
+static const pixman_format_code_t formats[] =
+{
+ PIXMAN_a8r8g8b8,
+ PIXMAN_a8b8g8r8,
+ PIXMAN_x8r8g8b8,
+ PIXMAN_x8b8g8r8,
+ PIXMAN_r5g6b5,
+ PIXMAN_b5g6r5,
+ PIXMAN_a8,
+ PIXMAN_a1,
+ PIXMAN_r3g3b2,
+ PIXMAN_b8g8r8a8,
+ PIXMAN_b8g8r8x8,
+ PIXMAN_r8g8b8a8,
+ PIXMAN_r8g8b8x8,
+ PIXMAN_x14r6g6b6,
+ PIXMAN_r8g8b8,
+ PIXMAN_b8g8r8,
+ PIXMAN_x2r10g10b10,
+ PIXMAN_a2r10g10b10,
+ PIXMAN_x2b10g10r10,
+ PIXMAN_a2b10g10r10,
+ PIXMAN_a1r5g5b5,
+ PIXMAN_x1r5g5b5,
+ PIXMAN_a1b5g5r5,
+ PIXMAN_x1b5g5r5,
+ PIXMAN_a4r4g4b4,
+ PIXMAN_x4r4g4b4,
+ PIXMAN_a4b4g4r4,
+ PIXMAN_x4b4g4r4,
+ PIXMAN_r3g3b2,
+ PIXMAN_b2g3r3,
+ PIXMAN_a2r2g2b2,
+ PIXMAN_a2b2g2r2,
+ PIXMAN_x4a4,
+ PIXMAN_a4,
+ PIXMAN_r1g2b1,
+ PIXMAN_b1g2r1,
+ PIXMAN_a1r1g1b1,
+ PIXMAN_a1b1g1r1,
+ PIXMAN_null,
+};
+
+static const pixman_op_t operators[] =
+{
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_CLEAR,
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_DST,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_OVER_REVERSE,
+ PIXMAN_OP_IN,
+ PIXMAN_OP_IN_REVERSE,
+ PIXMAN_OP_OUT,
+ PIXMAN_OP_OUT_REVERSE,
+ PIXMAN_OP_ATOP,
+ PIXMAN_OP_ATOP_REVERSE,
+ PIXMAN_OP_XOR,
+ PIXMAN_OP_ADD
+};
+
+enum
+{
+ ALLOW_CLIPPED = (1 << 0),
+ ALLOW_ALPHA_MAP = (1 << 1),
+ ALLOW_SOURCE_CLIPPING = (1 << 2),
+ ALLOW_REPEAT = (1 << 3),
+ ALLOW_SOLID = (1 << 4),
+ ALLOW_FENCED_MEMORY = (1 << 5),
+};
+
+static void
+destroy_fenced (pixman_image_t *image, void *data)
+{
+ fence_free (data);
+}
+
+static void
+destroy_malloced (pixman_image_t *image, void *data)
+{
+ free (data);
+}
+
+static pixman_format_code_t
+random_format (const pixman_format_code_t *formats)
+{
+ int i;
+ i = 0;
+ while (formats[i] != PIXMAN_null)
+ ++i;
+ return formats[lcg_rand_n (i)];
+}
+
+static pixman_image_t *
+create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
+{
+ int width, height;
+ pixman_image_t *image;
+ pixman_format_code_t format;
+ uint32_t *data;
+ int bpp;
+ int stride;
+ int i;
+ pixman_image_destroy_func_t destroy;
+
+ if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0)
+ {
+ pixman_color_t color = {
+ lcg_rand_u32(),
+ lcg_rand_u32(),
+ lcg_rand_u32(),
+ lcg_rand_u32(),
+ };
+
+ return pixman_image_create_solid_fill (&color);
+ }
+
+ width = lcg_rand_n (max_size) + 1;
+ height = lcg_rand_n (max_size) + 1;
+ format = random_format (formats);
+
+ bpp = PIXMAN_FORMAT_BPP (format);
+ stride = (width * bpp + 7) / 8 + lcg_rand_n (17);
+ stride = (stride + 3) & ~3;
+
+ if (lcg_rand_n (64) == 0)
+ {
+ if (!(data = (uint32_t *)make_random_bytes (stride * height)))
+ {
+ fprintf (stderr, "Out of memory\n");
+ abort ();
+ }
+ destroy = destroy_fenced;
+ }
+ else
+ {
+ data = malloc (stride * height);
+ for (i = 0; i < height * stride / 4; ++i)
+ data[i] = lcg_rand_u32();
+
+ destroy = destroy_malloced;
+ }
+
+ image = pixman_image_create_bits (format, width, height, data, stride);
+ pixman_image_set_destroy_function (image, destroy, data);
+
+ if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0)
+ {
+ pixman_box16_t clip_boxes[8];
+ pixman_region16_t clip;
+ int n = lcg_rand_n (8) + 1;
+
+ for (i = 0; i < n; i++)
+ {
+ clip_boxes[i].x1 = lcg_rand_n (width);
+ clip_boxes[i].y1 = lcg_rand_n (height);
+ clip_boxes[i].x2 =
+ clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1);
+ clip_boxes[i].y2 =
+ clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1);
+ }
+
+ pixman_region_init_rects (&clip, clip_boxes, n);
+ pixman_image_set_clip_region (image, &clip);
+ pixman_region_fini (&clip);
+ }
+
+ if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0)
+ {
+ pixman_image_set_source_clipping (image, TRUE);
+ pixman_image_set_has_client_clip (image, TRUE);
+ }
+
+ if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0)
+ {
+ pixman_image_t *alpha_map;
+ int alpha_x, alpha_y;
+
+ alpha_x = lcg_rand_n (width);
+ alpha_y = lcg_rand_n (height);
+ alpha_map =
+ create_image (max_size, formats, (flags & ~ALLOW_ALPHA_MAP));
+ pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y);
+ pixman_image_unref (alpha_map);
+ }
+
+ if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0)
+ pixman_image_set_repeat (image, lcg_rand_n (4));
+
+ image_endian_swap (image);
+
+ return image;
+}
+
+#define KEY1(p) ((void *)(((unsigned long)p) ^ (0xa7e23dfaUL)))
+#define KEY2(p) ((void *)(((unsigned long)p) ^ (0xabcd9876UL)))
+
+#define MAX_GLYPHS 32
+
+uint32_t
+test_glyphs (int testnum, int verbose)
+{
+ pixman_image_t *glyph_images[MAX_GLYPHS];
+ pixman_glyph_t glyphs[4 * MAX_GLYPHS];
+ uint32_t crc32 = 0;
+ pixman_image_t *source, *dest;
+ int n_glyphs, i;
+ pixman_glyph_cache_t *cache;
+
+ lcg_srand (testnum);
+
+ cache = pixman_glyph_cache_create ();
+
+ source = create_image (300, formats,
+ ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
+ ALLOW_SOURCE_CLIPPING |
+ ALLOW_REPEAT | ALLOW_SOLID);
+
+ dest = create_image (128, formats,
+ ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
+ ALLOW_SOURCE_CLIPPING);
+
+ pixman_glyph_cache_freeze (cache);
+
+ n_glyphs = lcg_rand_n (MAX_GLYPHS);
+ for (i = 0; i < n_glyphs; ++i)
+ glyph_images[i] = create_image (32, glyph_formats, 0);
+
+ for (i = 0; i < 4 * n_glyphs; ++i)
+ {
+ int g = lcg_rand_n (n_glyphs);
+ pixman_image_t *glyph_img = glyph_images[g];
+ void *key1 = KEY1 (glyph_img);
+ void *key2 = KEY2 (glyph_img);
+ const void *glyph;
+
+ if (!(glyph = pixman_glyph_cache_lookup (cache, key1, key2)))
+ {
+ glyph =
+ pixman_glyph_cache_insert (cache, key1, key2, 5, 8, glyph_img);
+ }
+
+ glyphs[i].glyph = glyph;
+ glyphs[i].x = lcg_rand_n (128);
+ glyphs[i].y = lcg_rand_n (128);
+ }
+
+ if (lcg_rand_n (2) == 0)
+ {
+ pixman_composite_glyphs (
+ operators[lcg_rand_n (ARRAY_LENGTH (operators))],
+ source, dest, random_format (glyph_formats),
+ lcg_rand_n (300) - 150,
+ lcg_rand_n (300) - 150,
+ lcg_rand_n (64) - 32,
+ lcg_rand_n (64) - 32,
+ lcg_rand_n (64) - 32,
+ lcg_rand_n (64) - 32,
+ lcg_rand_n (64),
+ lcg_rand_n (64),
+ cache, 4 * n_glyphs, glyphs);
+ }
+ else
+ {
+ pixman_composite_glyphs_no_mask (
+ operators[lcg_rand_n (ARRAY_LENGTH (operators))],
+ source, dest,
+ lcg_rand_n (300) - 150,
+ lcg_rand_n (300) - 150,
+ lcg_rand_n (64) - 32,
+ lcg_rand_n (64) - 32,
+ cache, 4 * n_glyphs, glyphs);
+ }
+
+ pixman_glyph_cache_thaw (cache);
+
+ for (i = 0; i < n_glyphs; ++i)
+ {
+ pixman_image_t *img = glyph_images[i];
+ void *key1, *key2;
+
+ key1 = KEY1 (img);
+ key2 = KEY2 (img);
+
+ pixman_glyph_cache_remove (cache, key1, key2);
+ pixman_image_unref (glyph_images[i]);
+ }
+
+ crc32 = compute_crc32_for_image (0, dest);
+
+ pixman_image_unref (source);
+ pixman_image_unref (dest);
+
+ pixman_glyph_cache_destroy (cache);
+
+ return crc32;
+}
+
+int
+main (int argc, const char *argv[])
+{
+ return fuzzer_test_main ("glyph", 30000,
+ 0xCB7AEED2,
+ test_glyphs, argc, argv);
+}