Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / test / composite-traps-test.c
1 /* Based loosely on scaling-test */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include "utils.h"
6
7 #define MAX_SRC_WIDTH  48
8 #define MAX_SRC_HEIGHT 48
9 #define MAX_DST_WIDTH  48
10 #define MAX_DST_HEIGHT 48
11 #define MAX_STRIDE     4
12
13 static pixman_format_code_t formats[] =
14 {
15     PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_r5g6b5, PIXMAN_a1, PIXMAN_a4
16 };
17
18 static pixman_format_code_t mask_formats[] =
19 {
20     PIXMAN_a1, PIXMAN_a4, PIXMAN_a8,
21 };
22
23 static pixman_op_t operators[] =
24 {
25     PIXMAN_OP_OVER, PIXMAN_OP_ADD, PIXMAN_OP_SRC, PIXMAN_OP_IN
26 };
27
28 #define RANDOM_ELT(array)                                               \
29     ((array)[prng_rand_n(ARRAY_LENGTH((array)))])
30
31 static void
32 destroy_bits (pixman_image_t *image, void *data)
33 {
34     fence_free (data);
35 }
36
37 static pixman_fixed_t
38 random_fixed (int n)
39 {
40     return prng_rand_n (n << 16);
41 }
42
43 /*
44  * Composite operation with pseudorandom images
45  */
46 uint32_t
47 test_composite (int      testnum,
48                 int      verbose)
49 {
50     int                i;
51     pixman_image_t *   src_img;
52     pixman_image_t *   dst_img;
53     pixman_region16_t  clip;
54     int                dst_width, dst_height;
55     int                dst_stride;
56     int                dst_x, dst_y;
57     int                dst_bpp;
58     pixman_op_t        op;
59     uint32_t *         dst_bits;
60     uint32_t           crc32;
61     pixman_format_code_t mask_format, dst_format;
62     pixman_trapezoid_t *traps;
63     int src_x, src_y;
64     int n_traps;
65
66     static pixman_color_t colors[] =
67     {
68         { 0xffff, 0xffff, 0xffff, 0xffff },
69         { 0x0000, 0x0000, 0x0000, 0x0000 },
70         { 0xabcd, 0xabcd, 0x0000, 0xabcd },
71         { 0x0000, 0x0000, 0x0000, 0xffff },
72         { 0x0101, 0x0101, 0x0101, 0x0101 },
73         { 0x7777, 0x6666, 0x5555, 0x9999 },
74     };
75     
76     FLOAT_REGS_CORRUPTION_DETECTOR_START ();
77
78     prng_srand (testnum);
79
80     op = RANDOM_ELT (operators);
81     mask_format = RANDOM_ELT (mask_formats);
82
83     /* Create source image */
84     
85     if (prng_rand_n (4) == 0)
86     {
87         src_img = pixman_image_create_solid_fill (
88             &(colors[prng_rand_n (ARRAY_LENGTH (colors))]));
89
90         src_x = 10;
91         src_y = 234;
92     }
93     else
94     {
95         pixman_format_code_t src_format = RANDOM_ELT(formats);
96         int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
97         int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
98         int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
99         int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
100         uint32_t *bits, *orig;
101
102         src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
103         src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
104
105         src_stride = (src_stride + 3) & ~3;
106         
107         orig = bits = (uint32_t *)make_random_bytes (src_stride * src_height);
108
109         if (prng_rand_n (2) == 0)
110         {
111             bits += (src_stride / 4) * (src_height - 1);
112             src_stride = - src_stride;
113         }
114         
115         src_img = pixman_image_create_bits (
116             src_format, src_width, src_height, bits, src_stride);
117
118         pixman_image_set_destroy_function (src_img, destroy_bits, orig);
119
120         if (prng_rand_n (8) == 0)
121         {
122             pixman_box16_t clip_boxes[2];
123             int            n = prng_rand_n (2) + 1;
124             
125             for (i = 0; i < n; i++)
126             {
127                 clip_boxes[i].x1 = prng_rand_n (src_width);
128                 clip_boxes[i].y1 = prng_rand_n (src_height);
129                 clip_boxes[i].x2 =
130                     clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
131                 clip_boxes[i].y2 =
132                     clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
133                 
134                 if (verbose)
135                 {
136                     printf ("source clip box: [%d,%d-%d,%d]\n",
137                             clip_boxes[i].x1, clip_boxes[i].y1,
138                             clip_boxes[i].x2, clip_boxes[i].y2);
139                 }
140             }
141             
142             pixman_region_init_rects (&clip, clip_boxes, n);
143             pixman_image_set_clip_region (src_img, &clip);
144             pixman_image_set_source_clipping (src_img, 1);
145             pixman_region_fini (&clip);
146         }
147
148         image_endian_swap (src_img);
149     }
150
151     /* Create destination image */
152     {
153         dst_format = RANDOM_ELT(formats);
154         dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
155         dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
156         dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
157         dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
158         dst_stride = (dst_stride + 3) & ~3;
159         
160         dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);
161
162         if (prng_rand_n (2) == 0)
163         {
164             dst_bits += (dst_stride / 4) * (dst_height - 1);
165             dst_stride = - dst_stride;
166         }
167         
168         dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
169         dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
170         
171         dst_img = pixman_image_create_bits (
172             dst_format, dst_width, dst_height, dst_bits, dst_stride);
173
174         image_endian_swap (dst_img);
175     }
176
177     /* Create traps */
178     {
179         int i;
180
181         n_traps = prng_rand_n (25);
182         traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));
183
184         for (i = 0; i < n_traps; ++i)
185         {
186             pixman_trapezoid_t *t = &(traps[i]);
187             
188             t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2;
189             t->bottom = t->top + random_fixed (MAX_DST_HEIGHT);
190             t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
191             t->left.p1.y = t->top - random_fixed (50);
192             t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
193             t->left.p2.y = t->bottom + random_fixed (50);
194             t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH);
195             t->right.p1.y = t->top - random_fixed (50);
196             t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH);
197             t->right.p2.y = t->bottom - random_fixed (50);
198         }
199     }
200     
201     if (prng_rand_n (8) == 0)
202     {
203         pixman_box16_t clip_boxes[2];
204         int            n = prng_rand_n (2) + 1;
205         for (i = 0; i < n; i++)
206         {
207             clip_boxes[i].x1 = prng_rand_n (dst_width);
208             clip_boxes[i].y1 = prng_rand_n (dst_height);
209             clip_boxes[i].x2 =
210                 clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
211             clip_boxes[i].y2 =
212                 clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
213
214             if (verbose)
215             {
216                 printf ("destination clip box: [%d,%d-%d,%d]\n",
217                         clip_boxes[i].x1, clip_boxes[i].y1,
218                         clip_boxes[i].x2, clip_boxes[i].y2);
219             }
220         }
221         pixman_region_init_rects (&clip, clip_boxes, n);
222         pixman_image_set_clip_region (dst_img, &clip);
223         pixman_region_fini (&clip);
224     }
225
226     pixman_composite_trapezoids (op, src_img, dst_img, mask_format,
227                                  src_x, src_y, dst_x, dst_y, n_traps, traps);
228
229     crc32 = compute_crc32_for_image (0, dst_img);
230
231     if (verbose)
232         print_image (dst_img);
233
234     if (dst_stride < 0)
235         dst_bits += (dst_stride / 4) * (dst_height - 1);
236     
237     fence_free (dst_bits);
238     
239     pixman_image_unref (src_img);
240     pixman_image_unref (dst_img);
241     fence_free (traps);
242
243     FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
244     return crc32;
245 }
246
247 int
248 main (int argc, const char *argv[])
249 {
250     return fuzzer_test_main("composite traps", 40000, 0xAF41D210,
251                             test_composite, argc, argv);
252 }