aboutsummaryrefslogtreecommitdiff
path: root/pixman/test
diff options
context:
space:
mode:
Diffstat (limited to 'pixman/test')
-rw-r--r--pixman/test/Makefile.sources1
-rw-r--r--pixman/test/blitters-test.c31
-rw-r--r--pixman/test/glyph-test.c331
-rw-r--r--pixman/test/utils.c101
-rw-r--r--pixman/test/utils.h7
5 files changed, 440 insertions, 31 deletions
diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources
index 99eb705af..fad8c6f69 100644
--- a/pixman/test/Makefile.sources
+++ b/pixman/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/pixman/test/blitters-test.c b/pixman/test/blitters-test.c
index feea308c2..6a3cc8649 100644
--- a/pixman/test/blitters-test.c
+++ b/pixman/test/blitters-test.c
@@ -83,39 +83,10 @@ free_random_image (uint32_t initcrc,
pixman_format_code_t fmt)
{
uint32_t crc32 = 0;
- int stride = pixman_image_get_stride (img);
uint32_t *data = pixman_image_get_data (img);
- int height = pixman_image_get_height (img);
if (fmt != PIXMAN_null)
- {
- /* mask unused 'x' part */
- if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
- PIXMAN_FORMAT_DEPTH (fmt) != 0)
- {
- int i;
- uint32_t *data = pixman_image_get_data (img);
- uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
-
- if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
- PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
- {
- mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
- }
-
- for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++)
- mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
-
- for (i = 0; i < stride * height / 4; i++)
- data[i] &= mask;
- }
-
- /* swap endiannes in order to provide identical results on both big
- * and litte endian systems
- */
- image_endian_swap (img);
- crc32 = compute_crc32 (initcrc, data, stride * height);
- }
+ crc32 = compute_crc32_for_image (initcrc, img);
pixman_image_unref (img);
free (data);
diff --git a/pixman/test/glyph-test.c b/pixman/test/glyph-test.c
new file mode 100644
index 000000000..9ff2a2bd4
--- /dev/null
+++ b/pixman/test/glyph-test.c
@@ -0,0 +1,331 @@
+#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;
+
+ color.alpha = lcg_rand_u32();
+ color.red = lcg_rand_u32();
+ color.green = lcg_rand_u32();
+ color.blue = 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)
+ {
+ int src_x = lcg_rand_n (300) - 150;
+ int src_y = lcg_rand_n (300) - 150;
+ int mask_x = lcg_rand_n (64) - 32;
+ int mask_y = lcg_rand_n (64) - 32;
+ int dest_x = lcg_rand_n (64) - 32;
+ int dest_y = lcg_rand_n (64) - 32;
+ int width = lcg_rand_n (64);
+ int height = lcg_rand_n (64);
+ pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
+ pixman_format_code_t format = random_format (glyph_formats);
+
+ pixman_composite_glyphs (
+ op,
+ source, dest, format,
+ src_x, src_y,
+ mask_x, mask_y,
+ dest_x, dest_y,
+ width, height,
+ cache, 4 * n_glyphs, glyphs);
+ }
+ else
+ {
+ pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
+ int src_x = lcg_rand_n (300) - 150;
+ int src_y = lcg_rand_n (300) - 150;
+ int dest_x = lcg_rand_n (64) - 32;
+ int dest_y = lcg_rand_n (64) - 32;
+
+ pixman_composite_glyphs_no_mask (
+ op, source, dest,
+ src_x, src_y,
+ dest_x, dest_y,
+ 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,
+ 0xA2B67F99,
+ test_glyphs, argc, argv);
+}
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index c1bf6dc2c..0abc32c66 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -135,6 +135,107 @@ compute_crc32 (uint32_t in_crc32,
return (crc32 ^ 0xFFFFFFFF);
}
+static uint32_t
+compute_crc32_for_image_internal (uint32_t crc32,
+ pixman_image_t *img,
+ pixman_bool_t remove_alpha,
+ pixman_bool_t remove_rgb)
+{
+ pixman_format_code_t fmt = pixman_image_get_format (img);
+ uint32_t *data = pixman_image_get_data (img);
+ int stride = pixman_image_get_stride (img);
+ int height = pixman_image_get_height (img);
+ uint32_t mask = 0xffffffff;
+ int i;
+
+ /* mask unused 'x' part */
+ if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
+ PIXMAN_FORMAT_DEPTH (fmt) != 0)
+ {
+ uint32_t m = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
+ PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
+ {
+ m <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
+ }
+
+ mask &= m;
+ }
+
+ /* mask alpha channel */
+ if (remove_alpha && PIXMAN_FORMAT_A (fmt))
+ {
+ uint32_t m;
+
+ if (PIXMAN_FORMAT_BPP (fmt) == 32)
+ m = 0xffffffff;
+ else
+ m = (1 << PIXMAN_FORMAT_BPP (fmt)) - 1;
+
+ m >>= PIXMAN_FORMAT_A (fmt);
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
+ PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA ||
+ PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_A)
+ {
+ /* Alpha is at the bottom of the pixel */
+ m <<= PIXMAN_FORMAT_A (fmt);
+ }
+
+ mask &= m;
+ }
+
+ /* mask rgb channels */
+ if (remove_rgb && PIXMAN_FORMAT_RGB (fmt))
+ {
+ uint32_t m = ((uint32_t)~0) >> (32 - PIXMAN_FORMAT_BPP (fmt));
+ uint32_t size = PIXMAN_FORMAT_R (fmt) + PIXMAN_FORMAT_G (fmt) + PIXMAN_FORMAT_B (fmt);
+
+ m &= ~((1 << size) - 1);
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
+ PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
+ {
+ /* RGB channels are at the top of the pixel */
+ m >>= size;
+ }
+
+ mask &= m;
+ }
+
+ for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++)
+ mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
+
+ for (i = 0; i < stride * height / 4; i++)
+ data[i] &= mask;
+
+ /* swap endiannes in order to provide identical results on both big
+ * and litte endian systems
+ */
+ image_endian_swap (img);
+
+ return compute_crc32 (crc32, data, stride * height);
+}
+
+uint32_t
+compute_crc32_for_image (uint32_t crc32,
+ pixman_image_t *img)
+{
+ if (img->common.alpha_map)
+ {
+ crc32 = compute_crc32_for_image_internal (crc32, img, TRUE, FALSE);
+ crc32 = compute_crc32_for_image_internal (
+ crc32, (pixman_image_t *)img->common.alpha_map, FALSE, TRUE);
+ }
+ else
+ {
+ crc32 = compute_crc32_for_image_internal (crc32, img, FALSE, FALSE);
+ }
+
+ return crc32;
+}
+
pixman_bool_t
is_little_endian (void)
{
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index 01af316d2..ac2decd11 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -63,7 +63,12 @@ compute_crc32 (uint32_t in_crc32,
const void *buf,
size_t buf_len);
-/* Returns TRUE if running on a little endian system */
+uint32_t
+compute_crc32_for_image (uint32_t in_crc32,
+ pixman_image_t *image);
+
+/* Returns TRUE if running on a little endian system
+ */
pixman_bool_t
is_little_endian (void);