Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / test / alphamap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "utils.h"
4
5 #define WIDTH 48
6 #define HEIGHT 48
7
8 static const pixman_format_code_t formats[] =
9 {
10     PIXMAN_a8r8g8b8,
11     PIXMAN_a2r10g10b10,
12     PIXMAN_a4r4g4b4,
13     PIXMAN_a8
14 };
15
16 static const pixman_format_code_t alpha_formats[] =
17 {
18     PIXMAN_null,
19     PIXMAN_a8,
20     PIXMAN_a2r10g10b10,
21     PIXMAN_a4r4g4b4
22 };
23
24 static const int origins[] =
25 {
26     0, 10, -100
27 };
28
29 static void
30 on_destroy (pixman_image_t *image, void *data)
31 {
32     uint32_t *bits = pixman_image_get_data (image);
33
34     fence_free (bits);
35 }
36
37 static pixman_image_t *
38 make_image (pixman_format_code_t format)
39 {
40     uint32_t *bits;
41     uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
42     pixman_image_t *image;
43
44     bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
45
46     image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
47
48     if (image && bits)
49         pixman_image_set_destroy_function (image, on_destroy, NULL);
50
51     return image;
52 }
53
54 static uint8_t
55 get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
56 {
57     uint8_t *bits;
58     uint8_t r;
59
60     if (image->common.alpha_map)
61     {
62         if (x - orig_x >= 0 && x - orig_x < WIDTH &&
63             y - orig_y >= 0 && y - orig_y < HEIGHT)
64         {
65             image = (pixman_image_t *)image->common.alpha_map;
66
67             x -= orig_x;
68             y -= orig_y;
69         }
70         else
71         {
72             return 0;
73         }
74     }
75
76     bits = (uint8_t *)image->bits.bits;
77
78     if (image->bits.format == PIXMAN_a8)
79     {
80         r = bits[y * WIDTH + x];
81     }
82     else if (image->bits.format == PIXMAN_a2r10g10b10)
83     {
84         r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
85         r |= r << 2;
86         r |= r << 4;
87     }
88     else if (image->bits.format == PIXMAN_a8r8g8b8)
89     {
90         r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
91     }
92     else if (image->bits.format == PIXMAN_a4r4g4b4)
93     {
94         r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
95         r |= r << 4;
96     }
97     else
98     {
99         assert (0);
100     }
101
102     return r;
103 }
104
105 static uint16_t
106 get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
107 {
108     uint8_t *bits;
109     uint16_t r;
110
111     bits = (uint8_t *)image->bits.bits;
112
113     if (image->bits.format == PIXMAN_a8)
114     {
115         r = 0x00;
116     }
117     else if (image->bits.format == PIXMAN_a2r10g10b10)
118     {
119         r = ((uint32_t *)bits)[y * WIDTH + x] >> 14;
120         r &= 0xffc0;
121         r |= (r >> 10);
122     }
123     else if (image->bits.format == PIXMAN_a8r8g8b8)
124     {
125         r = ((uint32_t *)bits)[y * WIDTH + x] >> 16;
126         r &= 0xff;
127         r |= r << 8;
128     }
129     else if (image->bits.format == PIXMAN_a4r4g4b4)
130     {
131         r = ((uint16_t *)bits)[y * WIDTH + x] >> 8;
132         r &= 0xf;
133         r |= r << 4;
134         r |= r << 8;
135     }
136     else
137     {
138         assert (0);
139     }
140
141     return r;
142 }
143
144 static int
145 run_test (int s, int d, int sa, int da, int soff, int doff)
146 {
147     pixman_format_code_t sf = formats[s];
148     pixman_format_code_t df = formats[d];
149     pixman_format_code_t saf = alpha_formats[sa];
150     pixman_format_code_t daf = alpha_formats[da];
151     pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha;
152     pixman_transform_t t1;
153     int j, k;
154     int n_alpha_bits, n_red_bits;
155
156     soff = origins[soff];
157     doff = origins[doff];
158
159     n_alpha_bits = PIXMAN_FORMAT_A (df);
160     if (daf != PIXMAN_null)
161         n_alpha_bits = PIXMAN_FORMAT_A (daf);
162
163     n_red_bits = PIXMAN_FORMAT_R (df);
164
165     /* Source */
166     src = make_image (sf);
167     if (saf != PIXMAN_null)
168     {
169         alpha = make_image (saf);
170         pixman_image_set_alpha_map (src, alpha, soff, soff);
171         pixman_image_unref (alpha);
172     }
173
174     /* Destination */
175     orig_dst = make_image (df);
176     dst = make_image (df);
177     pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
178                             0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
179
180     if (daf != PIXMAN_null)
181     {
182         orig_alpha = make_image (daf);
183         alpha = make_image (daf);
184
185         pixman_image_composite (PIXMAN_OP_SRC, orig_alpha, NULL, alpha,
186                                 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
187
188         pixman_image_set_alpha_map (orig_dst, orig_alpha, doff, doff);
189         pixman_image_set_alpha_map (dst, alpha, doff, doff);
190
191         pixman_image_unref (orig_alpha);
192         pixman_image_unref (alpha);
193     }
194
195     /* Transformations, repeats and filters on destinations should be ignored,
196      * so just set some random ones.
197      */
198     pixman_transform_init_identity (&t1);
199     pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
200     pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
201     pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
202
203     pixman_image_set_transform (dst, &t1);
204     pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0);
205     pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT);
206
207     pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst,
208                             0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
209
210     for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j)
211     {
212         for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
213         {
214             uint8_t sa, da, oda, refa;
215             uint16_t sr, dr, odr, refr;
216
217             sa = get_alpha (src, k, j, soff, soff);
218             da = get_alpha (dst, k, j, doff, doff);
219             oda = get_alpha (orig_dst, k, j, doff, doff);
220
221             if (sa + oda > 255)
222                 refa = 255;
223             else
224                 refa = sa + oda;
225
226             if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits))
227             {
228                 printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
229                         k, j, refa, da, sa, oda);
230
231                 printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
232                         format_name (sf),
233                         format_name (saf),
234                         soff, soff,
235                         format_name (df),
236                         format_name (daf),
237                         doff, doff);
238                 return 1;
239             }
240
241             /* There are cases where we go through the 8 bit compositing
242              * path even with 10bpc formats. This results in incorrect
243              * results here, so only do the red check for narrow formats
244              */
245             if (n_red_bits <= 8)
246             {
247                 sr = get_red (src, k, j, soff, soff);
248                 dr = get_red (dst, k, j, doff, doff);
249                 odr = get_red (orig_dst, k, j, doff, doff);
250
251                 if (sr + odr > 0xffff)
252                     refr = 0xffff;
253                 else
254                     refr = sr + odr;
255
256                 if (abs ((dr >> (16 - n_red_bits)) - (refr >> (16 - n_red_bits))) > 1)
257                 {
258                     printf ("%d red bits\n", n_red_bits);
259                     printf ("\nWrong red value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
260                             k, j, refr, dr, sr, odr);
261
262                     printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
263                             format_name (sf),
264                             format_name (saf),
265                             soff, soff,
266                             format_name (df),
267                             format_name (daf),
268                             doff, doff);
269                     return 1;
270                 }
271             }
272         }
273     }
274
275     pixman_image_set_alpha_map (src, NULL, 0, 0);
276     pixman_image_set_alpha_map (dst, NULL, 0, 0);
277     pixman_image_set_alpha_map (orig_dst, NULL, 0, 0);
278
279     pixman_image_unref (src);
280     pixman_image_unref (dst);
281     pixman_image_unref (orig_dst);
282
283     return 0;
284 }
285
286 int
287 main (int argc, char **argv)
288 {
289     int i, j, a, b, x, y;
290
291     prng_srand (0);
292
293     for (i = 0; i < ARRAY_LENGTH (formats); ++i)
294     {
295         for (j = 0; j < ARRAY_LENGTH (formats); ++j)
296         {
297             for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a)
298             {
299                 for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b)
300                 {
301                     for (x = 0; x < ARRAY_LENGTH (origins); ++x)
302                     {
303                         for (y = 0; y < ARRAY_LENGTH (origins); ++y)
304                         {
305                             if (run_test (i, j, a, b, x, y) != 0)
306                                 return 1;
307                         }
308                     }
309                 }
310             }
311         }
312     }
313
314     return 0;
315 }