composite-traps-test.c revision 6ba797d6
16ba797d6Smrg/* Based loosely on scaling-test */
26ba797d6Smrg
36ba797d6Smrg#include <assert.h>
46ba797d6Smrg#include <stdlib.h>
56ba797d6Smrg#include <stdio.h>
66ba797d6Smrg#include "utils.h"
76ba797d6Smrg
86ba797d6Smrg#define MAX_SRC_WIDTH  48
96ba797d6Smrg#define MAX_SRC_HEIGHT 48
106ba797d6Smrg#define MAX_DST_WIDTH  48
116ba797d6Smrg#define MAX_DST_HEIGHT 48
126ba797d6Smrg#define MAX_STRIDE     4
136ba797d6Smrg
146ba797d6Smrgstatic pixman_format_code_t formats[] =
156ba797d6Smrg{
166ba797d6Smrg    PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_r5g6b5, PIXMAN_a1, PIXMAN_a4
176ba797d6Smrg};
186ba797d6Smrg
196ba797d6Smrgstatic pixman_format_code_t mask_formats[] =
206ba797d6Smrg{
216ba797d6Smrg    PIXMAN_a1, PIXMAN_a4, PIXMAN_a8,
226ba797d6Smrg};
236ba797d6Smrg
246ba797d6Smrgstatic pixman_op_t operators[] =
256ba797d6Smrg{
266ba797d6Smrg    PIXMAN_OP_OVER, PIXMAN_OP_ADD, PIXMAN_OP_SRC, PIXMAN_OP_IN
276ba797d6Smrg};
286ba797d6Smrg
296ba797d6Smrg#define RANDOM_ELT(array)						\
306ba797d6Smrg    ((array)[lcg_rand_n(ARRAY_LENGTH((array)))])
316ba797d6Smrg
326ba797d6Smrgstatic void
336ba797d6Smrgdestroy_bits (pixman_image_t *image, void *data)
346ba797d6Smrg{
356ba797d6Smrg    fence_free (data);
366ba797d6Smrg}
376ba797d6Smrg
386ba797d6Smrgstatic pixman_fixed_t
396ba797d6Smrgrandom_fixed (int n)
406ba797d6Smrg{
416ba797d6Smrg    return lcg_rand_N (n << 16);
426ba797d6Smrg}
436ba797d6Smrg
446ba797d6Smrg/*
456ba797d6Smrg * Composite operation with pseudorandom images
466ba797d6Smrg */
476ba797d6Smrguint32_t
486ba797d6Smrgtest_composite (int      testnum,
496ba797d6Smrg		int      verbose)
506ba797d6Smrg{
516ba797d6Smrg    int                i;
526ba797d6Smrg    pixman_image_t *   src_img;
536ba797d6Smrg    pixman_image_t *   dst_img;
546ba797d6Smrg    pixman_region16_t  clip;
556ba797d6Smrg    int                dst_width, dst_height;
566ba797d6Smrg    int                dst_stride;
576ba797d6Smrg    int                dst_x, dst_y;
586ba797d6Smrg    int                dst_bpp;
596ba797d6Smrg    pixman_op_t        op;
606ba797d6Smrg    uint32_t *         dst_bits;
616ba797d6Smrg    uint32_t           crc32;
626ba797d6Smrg    pixman_format_code_t mask_format, dst_format;
636ba797d6Smrg    pixman_trapezoid_t *traps;
646ba797d6Smrg    int src_x, src_y;
656ba797d6Smrg    int n_traps;
666ba797d6Smrg
676ba797d6Smrg    static pixman_color_t colors[] =
686ba797d6Smrg    {
696ba797d6Smrg	{ 0xffff, 0xffff, 0xffff, 0xffff },
706ba797d6Smrg	{ 0x0000, 0x0000, 0x0000, 0x0000 },
716ba797d6Smrg	{ 0xabcd, 0xabcd, 0x0000, 0xabcd },
726ba797d6Smrg	{ 0x0000, 0x0000, 0x0000, 0xffff },
736ba797d6Smrg	{ 0x0101, 0x0101, 0x0101, 0x0101 },
746ba797d6Smrg	{ 0x7777, 0x6666, 0x5555, 0x9999 },
756ba797d6Smrg    };
766ba797d6Smrg
776ba797d6Smrg    FLOAT_REGS_CORRUPTION_DETECTOR_START ();
786ba797d6Smrg
796ba797d6Smrg    lcg_srand (testnum);
806ba797d6Smrg
816ba797d6Smrg    op = RANDOM_ELT (operators);
826ba797d6Smrg    mask_format = RANDOM_ELT (mask_formats);
836ba797d6Smrg
846ba797d6Smrg    /* Create source image */
856ba797d6Smrg
866ba797d6Smrg    if (lcg_rand_n (4) == 0)
876ba797d6Smrg    {
886ba797d6Smrg	src_img = pixman_image_create_solid_fill (
896ba797d6Smrg	    &(colors[lcg_rand_n (ARRAY_LENGTH (colors))]));
906ba797d6Smrg
916ba797d6Smrg	src_x = 10;
926ba797d6Smrg	src_y = 234;
936ba797d6Smrg    }
946ba797d6Smrg    else
956ba797d6Smrg    {
966ba797d6Smrg	pixman_format_code_t src_format = RANDOM_ELT(formats);
976ba797d6Smrg	int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
986ba797d6Smrg	int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
996ba797d6Smrg	int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
1006ba797d6Smrg	int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
1016ba797d6Smrg	uint32_t *bits;
1026ba797d6Smrg
1036ba797d6Smrg	src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
1046ba797d6Smrg	src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
1056ba797d6Smrg
1066ba797d6Smrg	src_stride = (src_stride + 3) & ~3;
1076ba797d6Smrg
1086ba797d6Smrg	bits = (uint32_t *)make_random_bytes (src_stride * src_height);
1096ba797d6Smrg
1106ba797d6Smrg	src_img = pixman_image_create_bits (
1116ba797d6Smrg	    src_format, src_width, src_height, bits, src_stride);
1126ba797d6Smrg
1136ba797d6Smrg	pixman_image_set_destroy_function (src_img, destroy_bits, bits);
1146ba797d6Smrg
1156ba797d6Smrg	if (lcg_rand_n (8) == 0)
1166ba797d6Smrg	{
1176ba797d6Smrg	    pixman_box16_t clip_boxes[2];
1186ba797d6Smrg	    int            n = lcg_rand_n (2) + 1;
1196ba797d6Smrg
1206ba797d6Smrg	    for (i = 0; i < n; i++)
1216ba797d6Smrg	    {
1226ba797d6Smrg		clip_boxes[i].x1 = lcg_rand_n (src_width);
1236ba797d6Smrg		clip_boxes[i].y1 = lcg_rand_n (src_height);
1246ba797d6Smrg		clip_boxes[i].x2 =
1256ba797d6Smrg		    clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
1266ba797d6Smrg		clip_boxes[i].y2 =
1276ba797d6Smrg		    clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
1286ba797d6Smrg
1296ba797d6Smrg		if (verbose)
1306ba797d6Smrg		{
1316ba797d6Smrg		    printf ("source clip box: [%d,%d-%d,%d]\n",
1326ba797d6Smrg			    clip_boxes[i].x1, clip_boxes[i].y1,
1336ba797d6Smrg			    clip_boxes[i].x2, clip_boxes[i].y2);
1346ba797d6Smrg		}
1356ba797d6Smrg	    }
1366ba797d6Smrg
1376ba797d6Smrg	    pixman_region_init_rects (&clip, clip_boxes, n);
1386ba797d6Smrg	    pixman_image_set_clip_region (src_img, &clip);
1396ba797d6Smrg	    pixman_image_set_source_clipping (src_img, 1);
1406ba797d6Smrg	    pixman_region_fini (&clip);
1416ba797d6Smrg	}
1426ba797d6Smrg
1436ba797d6Smrg	image_endian_swap (src_img);
1446ba797d6Smrg    }
1456ba797d6Smrg
1466ba797d6Smrg    /* Create destination image */
1476ba797d6Smrg    {
1486ba797d6Smrg	dst_format = RANDOM_ELT(formats);
1496ba797d6Smrg	dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
1506ba797d6Smrg	dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
1516ba797d6Smrg	dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
1526ba797d6Smrg	dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
1536ba797d6Smrg	dst_stride = (dst_stride + 3) & ~3;
1546ba797d6Smrg
1556ba797d6Smrg	dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);
1566ba797d6Smrg
1576ba797d6Smrg	dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
1586ba797d6Smrg	dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
1596ba797d6Smrg
1606ba797d6Smrg	dst_img = pixman_image_create_bits (
1616ba797d6Smrg	    dst_format, dst_width, dst_height, dst_bits, dst_stride);
1626ba797d6Smrg
1636ba797d6Smrg	image_endian_swap (dst_img);
1646ba797d6Smrg    }
1656ba797d6Smrg
1666ba797d6Smrg    /* Create traps */
1676ba797d6Smrg    {
1686ba797d6Smrg	int i;
1696ba797d6Smrg
1706ba797d6Smrg	n_traps = lcg_rand_n (25);
1716ba797d6Smrg	traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));
1726ba797d6Smrg
1736ba797d6Smrg	for (i = 0; i < n_traps; ++i)
1746ba797d6Smrg	{
1756ba797d6Smrg	    pixman_trapezoid_t *t = &(traps[i]);
1766ba797d6Smrg
1776ba797d6Smrg	    t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2;
1786ba797d6Smrg	    t->bottom = t->top + random_fixed (MAX_DST_HEIGHT);
1796ba797d6Smrg	    t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
1806ba797d6Smrg	    t->left.p1.y = t->top - random_fixed (50);
1816ba797d6Smrg	    t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
1826ba797d6Smrg	    t->left.p2.y = t->bottom + random_fixed (50);
1836ba797d6Smrg	    t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH);
1846ba797d6Smrg	    t->right.p1.y = t->top - random_fixed (50);
1856ba797d6Smrg	    t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH);
1866ba797d6Smrg	    t->right.p2.y = t->bottom - random_fixed (50);
1876ba797d6Smrg	}
1886ba797d6Smrg    }
1896ba797d6Smrg
1906ba797d6Smrg    if (lcg_rand_n (8) == 0)
1916ba797d6Smrg    {
1926ba797d6Smrg	pixman_box16_t clip_boxes[2];
1936ba797d6Smrg	int            n = lcg_rand_n (2) + 1;
1946ba797d6Smrg	for (i = 0; i < n; i++)
1956ba797d6Smrg	{
1966ba797d6Smrg	    clip_boxes[i].x1 = lcg_rand_n (dst_width);
1976ba797d6Smrg	    clip_boxes[i].y1 = lcg_rand_n (dst_height);
1986ba797d6Smrg	    clip_boxes[i].x2 =
1996ba797d6Smrg		clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
2006ba797d6Smrg	    clip_boxes[i].y2 =
2016ba797d6Smrg		clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
2026ba797d6Smrg
2036ba797d6Smrg	    if (verbose)
2046ba797d6Smrg	    {
2056ba797d6Smrg		printf ("destination clip box: [%d,%d-%d,%d]\n",
2066ba797d6Smrg		        clip_boxes[i].x1, clip_boxes[i].y1,
2076ba797d6Smrg		        clip_boxes[i].x2, clip_boxes[i].y2);
2086ba797d6Smrg	    }
2096ba797d6Smrg	}
2106ba797d6Smrg	pixman_region_init_rects (&clip, clip_boxes, n);
2116ba797d6Smrg	pixman_image_set_clip_region (dst_img, &clip);
2126ba797d6Smrg	pixman_region_fini (&clip);
2136ba797d6Smrg    }
2146ba797d6Smrg
2156ba797d6Smrg    pixman_composite_trapezoids (op, src_img, dst_img, mask_format,
2166ba797d6Smrg				 src_x, src_y, dst_x, dst_y, n_traps, traps);
2176ba797d6Smrg
2186ba797d6Smrg    if (dst_format == PIXMAN_x8r8g8b8)
2196ba797d6Smrg    {
2206ba797d6Smrg	/* ignore unused part */
2216ba797d6Smrg	for (i = 0; i < dst_stride * dst_height / 4; i++)
2226ba797d6Smrg	    dst_bits[i] &= 0xFFFFFF;
2236ba797d6Smrg    }
2246ba797d6Smrg
2256ba797d6Smrg    image_endian_swap (dst_img);
2266ba797d6Smrg
2276ba797d6Smrg    if (verbose)
2286ba797d6Smrg    {
2296ba797d6Smrg	int j;
2306ba797d6Smrg
2316ba797d6Smrg	for (i = 0; i < dst_height; i++)
2326ba797d6Smrg	{
2336ba797d6Smrg	    for (j = 0; j < dst_stride; j++)
2346ba797d6Smrg		printf ("%02X ", *((uint8_t *)dst_bits + i * dst_stride + j));
2356ba797d6Smrg
2366ba797d6Smrg	    printf ("\n");
2376ba797d6Smrg	}
2386ba797d6Smrg    }
2396ba797d6Smrg
2406ba797d6Smrg    crc32 = compute_crc32 (0, dst_bits, dst_stride * dst_height);
2416ba797d6Smrg
2426ba797d6Smrg    fence_free (dst_bits);
2436ba797d6Smrg
2446ba797d6Smrg    pixman_image_unref (src_img);
2456ba797d6Smrg    pixman_image_unref (dst_img);
2466ba797d6Smrg    fence_free (traps);
2476ba797d6Smrg
2486ba797d6Smrg    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
2496ba797d6Smrg    return crc32;
2506ba797d6Smrg}
2516ba797d6Smrg
2526ba797d6Smrgint
2536ba797d6Smrgmain (int argc, const char *argv[])
2546ba797d6Smrg{
2556ba797d6Smrg    return fuzzer_test_main("composite traps", 40000, 0xE3112106,
2566ba797d6Smrg			    test_composite, argc, argv);
2576ba797d6Smrg}
258