Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / test / pixel-test.c
1 /*
2  * Copyright © 2013 Soeren Sandmann
3  * Copyright © 2013 Red Hat, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 #include <stdio.h>
25 #include <stdlib.h> /* abort() */
26 #include <math.h>
27 #include <time.h>
28 #include "utils.h"
29
30 typedef struct pixel_combination_t pixel_combination_t;
31 struct pixel_combination_t
32 {
33     pixman_op_t                 op;
34     pixman_format_code_t        src_format;
35     uint32_t                    src_pixel;
36     pixman_format_code_t        dest_format;
37     uint32_t                    dest_pixel;
38 };
39
40 static const pixel_combination_t regressions[] =
41 {
42     { PIXMAN_OP_OVER,
43       PIXMAN_a8r8g8b8,  0x0f00c300,
44       PIXMAN_x14r6g6b6, 0x003c0,
45     },
46     { PIXMAN_OP_DISJOINT_XOR,
47       PIXMAN_a4r4g4b4,  0xd0c0,
48       PIXMAN_a8r8g8b8,  0x5300ea00,
49     },
50     { PIXMAN_OP_OVER,
51       PIXMAN_a8r8g8b8,  0x20c6bf00,
52       PIXMAN_r5g6b5,    0xb9ff
53     },
54     { PIXMAN_OP_OVER,
55       PIXMAN_a8r8g8b8,  0x204ac7ff,
56       PIXMAN_r5g6b5,    0xc1ff
57     },
58     { PIXMAN_OP_OVER_REVERSE,
59       PIXMAN_r5g6b5,    0xffc3,
60       PIXMAN_a8r8g8b8,  0x102d00dd
61     },
62     { PIXMAN_OP_OVER_REVERSE,
63       PIXMAN_r5g6b5,    0x1f00,
64       PIXMAN_a8r8g8b8,  0x1bdf0c89
65     },
66     { PIXMAN_OP_OVER_REVERSE,
67       PIXMAN_r5g6b5,    0xf9d2,
68       PIXMAN_a8r8g8b8,  0x1076bcf7
69     },
70     { PIXMAN_OP_OVER_REVERSE,
71       PIXMAN_r5g6b5,    0x00c3,
72       PIXMAN_a8r8g8b8,  0x1bfe9ae5
73     },
74     { PIXMAN_OP_OVER_REVERSE,
75       PIXMAN_r5g6b5,    0x09ff,
76       PIXMAN_a8r8g8b8,  0x0b00c16c
77     },
78     { PIXMAN_OP_DISJOINT_ATOP,
79       PIXMAN_a2r2g2b2,  0xbc,
80       PIXMAN_a8r8g8b8,  0x9efff1ff
81     },
82     { PIXMAN_OP_DISJOINT_ATOP,
83       PIXMAN_a4r4g4b4,  0xae5f,
84       PIXMAN_a8r8g8b8,  0xf215b675
85     },
86     { PIXMAN_OP_DISJOINT_ATOP_REVERSE,
87       PIXMAN_a8r8g8b8,  0xce007980,
88       PIXMAN_a8r8g8b8,  0x80ffe4ad
89     },
90     { PIXMAN_OP_DISJOINT_XOR,
91       PIXMAN_a8r8g8b8,  0xb8b07bea,
92       PIXMAN_a4r4g4b4,  0x939c
93     },
94     { PIXMAN_OP_CONJOINT_ATOP_REVERSE,
95       PIXMAN_r5g6b5,    0x0063,
96       PIXMAN_a8r8g8b8,  0x10bb1ed7,
97     },
98 };
99
100 static void
101 fill (pixman_image_t *image, uint32_t pixel)
102 {
103     uint8_t *data = (uint8_t *)pixman_image_get_data (image);
104     int bytes_per_pixel = PIXMAN_FORMAT_BPP (pixman_image_get_format (image)) / 8;
105     int n_bytes = pixman_image_get_stride (image) * pixman_image_get_height (image);
106     int i;
107
108     switch (bytes_per_pixel)
109     {
110     case 4:
111         for (i = 0; i < n_bytes / 4; ++i)
112             ((uint32_t *)data)[i] = pixel;
113         break;
114
115     case 2:
116         pixel &= 0xffff;
117         for (i = 0; i < n_bytes / 2; ++i)
118             ((uint16_t *)data)[i] = pixel;
119         break;
120
121     case 1:
122         pixel &= 0xff;
123         for (i = 0; i < n_bytes; ++i)
124             ((uint8_t *)data)[i] = pixel;
125         break;
126
127     default:
128         assert (0);
129         break;
130     }
131 }
132
133 static uint32_t
134 access (pixman_image_t *image, int x, int y)
135 {
136     int bytes_per_pixel;
137     int stride;
138     uint32_t result;
139     uint8_t *location;
140
141     if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height)
142         return 0;
143
144     bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
145     stride = image->bits.rowstride * 4;
146
147     location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel;
148
149     if (bytes_per_pixel == 4)
150         result = *(uint32_t *)location;
151     else if (bytes_per_pixel == 2)
152         result = *(uint16_t *)location;
153     else if (bytes_per_pixel == 1)
154         result = *(uint8_t *)location;
155     else
156         assert (0);
157
158     return result;
159 }
160
161 static pixman_bool_t
162 verify (int test_no, const pixel_combination_t *combination, int size)
163 {
164     pixman_image_t *src, *dest;
165     pixel_checker_t src_checker, dest_checker;
166     color_t source_color, dest_color, reference_color;
167     pixman_bool_t result = TRUE;
168     int i, j;
169
170     /* Compute reference color */
171     pixel_checker_init (&src_checker, combination->src_format);
172     pixel_checker_init (&dest_checker, combination->dest_format);
173     pixel_checker_convert_pixel_to_color (
174         &src_checker, combination->src_pixel, &source_color);
175     pixel_checker_convert_pixel_to_color (
176         &dest_checker, combination->dest_pixel, &dest_color);
177     do_composite (combination->op,
178                   &source_color, NULL, &dest_color,
179                   &reference_color, FALSE);
180
181     src = pixman_image_create_bits (
182         combination->src_format, size, size, NULL, -1);
183     dest = pixman_image_create_bits (
184         combination->dest_format, size, size, NULL, -1);
185
186     fill (src, combination->src_pixel);
187     fill (dest, combination->dest_pixel);
188
189     pixman_image_composite32 (
190         combination->op, src, NULL, dest, 0, 0, 0, 0, 0, 0, size, size);
191
192     for (j = 0; j < size; ++j)
193     {
194         for (i = 0; i < size; ++i)
195         {
196             uint32_t computed = access (dest, i, j);
197             int32_t a, r, g, b;
198
199             if (!pixel_checker_check (&dest_checker, computed, &reference_color))
200             {
201                 printf ("----------- Test %d failed ----------\n", test_no);
202
203                 printf ("   operator:         %s\n", operator_name (combination->op));
204                 printf ("   src format:       %s\n", format_name (combination->src_format));
205                 printf ("   dest format:      %s\n", format_name (combination->dest_format));
206                 printf (" - source ARGB:      %f  %f  %f  %f   (pixel: %8x)\n",
207                         source_color.a, source_color.r, source_color.g, source_color.b,
208                         combination->src_pixel);
209                 pixel_checker_split_pixel (&src_checker, combination->src_pixel,
210                                            &a, &r, &g, &b);
211                 printf ("                     %8d  %8d  %8d  %8d\n", a, r, g, b);
212
213                 printf (" - dest ARGB:        %f  %f  %f  %f   (pixel: %8x)\n",
214                         dest_color.a, dest_color.r, dest_color.g, dest_color.b,
215                         combination->dest_pixel);
216                 pixel_checker_split_pixel (&dest_checker, combination->dest_pixel,
217                                            &a, &r, &g, &b);
218                 printf ("                     %8d  %8d  %8d  %8d\n", a, r, g, b);
219
220                 pixel_checker_split_pixel (&dest_checker, computed, &a, &r, &g, &b);
221                 printf (" - expected ARGB:    %f  %f  %f  %f\n",
222                         reference_color.a, reference_color.r, reference_color.g, reference_color.b);
223
224                 pixel_checker_get_min (&dest_checker, &reference_color, &a, &r, &g, &b);
225                 printf ("   min acceptable:   %8d  %8d  %8d  %8d\n", a, r, g, b);
226
227                 pixel_checker_split_pixel (&dest_checker, computed, &a, &r, &g, &b);
228                 printf ("   got:              %8d  %8d  %8d  %8d   (pixel: %8x)\n", a, r, g, b, computed);
229
230                 pixel_checker_get_max (&dest_checker, &reference_color, &a, &r, &g, &b);
231                 printf ("   max acceptable:   %8d  %8d  %8d  %8d\n", a, r, g, b);
232
233                 result = FALSE;
234                 goto done;
235             }
236         }
237     }
238
239 done:
240     pixman_image_unref (src);
241     pixman_image_unref (dest);
242
243     return result;
244 }
245
246 int
247 main (int argc, char **argv)
248 {
249     int result = 0;
250     int i, j;
251
252     for (i = 0; i < ARRAY_LENGTH (regressions); ++i)
253     {
254         const pixel_combination_t *combination = &(regressions[i]);
255
256         for (j = 1; j < 34; ++j)
257         {
258             if (!verify (i, combination, j))
259             {
260                 result = 1;
261                 break;
262             }
263         }
264     }
265
266     return result;
267 }