2
* Copyright © 2005 Eric Anholt
3
* Copyright © 2009 Chris Wilson
4
* Copyright © 2010 Soeren Sandmann
5
* Copyright © 2010 Red Hat, Inc.
7
* Permission to use, copy, modify, distribute, and sell this software and its
8
* documentation for any purpose is hereby granted without fee, provided that
9
* the above copyright notice appear in all copies and that both that
10
* copyright notice and this permission notice appear in supporting
11
* documentation, and that the name of Eric Anholt not be used in
12
* advertising or publicity pertaining to distribution of the software without
13
* specific, written prior permission. Eric Anholt makes no
14
* representations about the suitability of this software for any purpose. It
15
* is provided "as is" without express or implied warranty.
17
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19
* EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23
* PERFORMANCE OF THIS SOFTWARE.
26
#include <stdlib.h> /* abort() */
31
typedef struct image_t image_t;
33
static const color_t colors[] =
35
{ 1.0, 1.0, 1.0, 1.0 },
36
{ 1.0, 1.0, 1.0, 0.0 },
37
{ 0.0, 0.0, 0.0, 1.0 },
38
{ 0.0, 0.0, 0.0, 0.0 },
39
{ 1.0, 0.0, 0.0, 1.0 },
40
{ 0.0, 1.0, 0.0, 1.0 },
41
{ 0.0, 0.0, 1.0, 1.0 },
42
{ 0.5, 0.0, 0.0, 0.5 },
46
_color_double_to_short (double d)
50
i = (uint32_t) (d * 65536);
57
compute_pixman_color (const color_t *color,
60
out->red = _color_double_to_short (color->r);
61
out->green = _color_double_to_short (color->g);
62
out->blue = _color_double_to_short (color->b);
63
out->alpha = _color_double_to_short (color->a);
66
#define REPEAT 0x01000000
67
#define FLAGS 0xff000000
69
static const int sizes[] =
77
static const pixman_format_code_t formats[] =
133
pixman_image_t *image;
134
pixman_format_code_t format;
135
const color_t *color;
136
pixman_repeat_t repeat;
140
static const pixman_op_t operators[] =
146
PIXMAN_OP_OVER_REVERSE,
148
PIXMAN_OP_IN_REVERSE,
150
PIXMAN_OP_OUT_REVERSE,
152
PIXMAN_OP_ATOP_REVERSE,
157
PIXMAN_OP_DISJOINT_CLEAR,
158
PIXMAN_OP_DISJOINT_SRC,
159
PIXMAN_OP_DISJOINT_DST,
160
PIXMAN_OP_DISJOINT_OVER,
161
PIXMAN_OP_DISJOINT_OVER_REVERSE,
162
PIXMAN_OP_DISJOINT_IN,
163
PIXMAN_OP_DISJOINT_IN_REVERSE,
164
PIXMAN_OP_DISJOINT_OUT,
165
PIXMAN_OP_DISJOINT_OUT_REVERSE,
166
PIXMAN_OP_DISJOINT_ATOP,
167
PIXMAN_OP_DISJOINT_ATOP_REVERSE,
168
PIXMAN_OP_DISJOINT_XOR,
170
PIXMAN_OP_CONJOINT_CLEAR,
171
PIXMAN_OP_CONJOINT_SRC,
172
PIXMAN_OP_CONJOINT_DST,
173
PIXMAN_OP_CONJOINT_OVER,
174
PIXMAN_OP_CONJOINT_OVER_REVERSE,
175
PIXMAN_OP_CONJOINT_IN,
176
PIXMAN_OP_CONJOINT_IN_REVERSE,
177
PIXMAN_OP_CONJOINT_OUT,
178
PIXMAN_OP_CONJOINT_OUT_REVERSE,
179
PIXMAN_OP_CONJOINT_ATOP,
180
PIXMAN_OP_CONJOINT_ATOP_REVERSE,
181
PIXMAN_OP_CONJOINT_XOR,
185
get_value (pixman_image_t *image)
187
uint32_t value = *(uint32_t *)pixman_image_get_data (image);
189
#ifdef WORDS_BIGENDIAN
191
pixman_format_code_t format = pixman_image_get_format (image);
192
value >>= 8 * sizeof(value) - PIXMAN_FORMAT_BPP (format);
200
describe_image (image_t *info, char *buf)
204
sprintf (buf, "%s, %dx%d%s",
205
format_name (info->format),
206
info->size, info->size,
207
info->repeat ? " R" :"");
211
sprintf (buf, "solid");
218
describe_color (const color_t *color, char *buf)
220
sprintf (buf, "%.3f %.3f %.3f %.3f",
221
color->r, color->g, color->b, color->a);
227
composite_test (image_t *dst,
231
pixman_bool_t component_alpha,
234
color_t expected, tdst, tsrc, tmsk;
235
pixel_checker_t checker;
239
pixman_image_set_component_alpha (mask->image, component_alpha);
241
pixman_image_composite (op, src->image, mask->image, dst->image,
242
0, 0, 0, 0, 0, 0, dst->size, dst->size);
246
pixman_image_composite (op, src->image, NULL, dst->image,
250
dst->size, dst->size);
261
/* It turns out that by construction all source, mask etc. colors are
262
* linear because they are made from fills, and fills are always in linear
263
* color space. However, if they have been converted to bitmaps, we need
264
* to simulate the sRGB approximation to pass the test cases.
268
if (PIXMAN_FORMAT_TYPE (src->format) == PIXMAN_TYPE_ARGB_SRGB)
270
tsrc.r = convert_linear_to_srgb (tsrc.r);
271
tsrc.g = convert_linear_to_srgb (tsrc.g);
272
tsrc.b = convert_linear_to_srgb (tsrc.b);
273
round_color (src->format, &tsrc);
274
tsrc.r = convert_srgb_to_linear (tsrc.r);
275
tsrc.g = convert_srgb_to_linear (tsrc.g);
276
tsrc.b = convert_srgb_to_linear (tsrc.b);
280
round_color (src->format, &tsrc);
284
if (mask && mask->size)
286
if (PIXMAN_FORMAT_TYPE (mask->format) == PIXMAN_TYPE_ARGB_SRGB)
288
tmsk.r = convert_linear_to_srgb (tmsk.r);
289
tmsk.g = convert_linear_to_srgb (tmsk.g);
290
tmsk.b = convert_linear_to_srgb (tmsk.b);
291
round_color (mask->format, &tmsk);
292
tmsk.r = convert_srgb_to_linear (tmsk.r);
293
tmsk.g = convert_srgb_to_linear (tmsk.g);
294
tmsk.b = convert_srgb_to_linear (tmsk.b);
298
round_color (mask->format, &tmsk);
304
if (component_alpha && PIXMAN_FORMAT_R (mask->format) == 0)
306
/* Ax component-alpha masks expand alpha into
307
* all color channels.
309
tmsk.r = tmsk.g = tmsk.b = tmsk.a;
313
if (PIXMAN_FORMAT_TYPE (dst->format) == PIXMAN_TYPE_ARGB_SRGB)
315
tdst.r = convert_linear_to_srgb (tdst.r);
316
tdst.g = convert_linear_to_srgb (tdst.g);
317
tdst.b = convert_linear_to_srgb (tdst.b);
318
round_color (dst->format, &tdst);
319
tdst.r = convert_srgb_to_linear (tdst.r);
320
tdst.g = convert_srgb_to_linear (tdst.g);
321
tdst.b = convert_srgb_to_linear (tdst.b);
325
round_color (dst->format, &tdst);
335
pixel_checker_init (&checker, dst->format);
337
if (!pixel_checker_check (&checker, get_value (dst->image), &expected))
339
char buf[40], buf2[40];
343
printf ("---- Test %d failed ----\n", testno);
344
printf ("Operator: %s %s\n",
345
operator_name (op), component_alpha ? "CA" : "");
347
printf ("Source: %s\n", describe_image (src, buf));
349
printf ("Mask: %s\n", describe_image (mask, buf));
351
printf ("Destination: %s\n\n", describe_image (dst, buf));
352
printf (" R G B A Rounded\n");
353
printf ("Source color: %s %s\n",
354
describe_color (src->color, buf),
355
describe_color (&tsrc, buf2));
358
printf ("Mask color: %s %s\n",
359
describe_color (mask->color, buf),
360
describe_color (&tmsk, buf2));
362
printf ("Dest. color: %s %s\n",
363
describe_color (dst->color, buf),
364
describe_color (&tdst, buf2));
366
pixel = get_value (dst->image);
368
printf ("Expected: %s\n", describe_color (&expected, buf));
370
pixel_checker_split_pixel (&checker, pixel, &a, &r, &g, &b);
372
printf ("Got: %5d %5d %5d %5d [pixel: 0x%08x]\n", r, g, b, a, pixel);
373
pixel_checker_get_min (&checker, &expected, &a, &r, &g, &b);
374
printf ("Min accepted: %5d %5d %5d %5d\n", r, g, b, a);
375
pixel_checker_get_max (&checker, &expected, &a, &r, &g, &b);
376
printf ("Max accepted: %5d %5d %5d %5d\n", r, g, b, a);
384
image_init (image_t *info,
391
info->color = &colors[color];
392
compute_pixman_color (info->color, &fill);
394
info->format = formats[format];
395
info->size = sizes[size] & ~FLAGS;
396
info->repeat = PIXMAN_REPEAT_NONE;
400
pixman_image_t *solid;
402
info->image = pixman_image_create_bits (info->format,
403
info->size, info->size,
406
solid = pixman_image_create_solid_fill (&fill);
407
pixman_image_composite32 (PIXMAN_OP_SRC, solid, NULL, info->image,
408
0, 0, 0, 0, 0, 0, info->size, info->size);
409
pixman_image_unref (solid);
411
if (sizes[size] & REPEAT)
413
pixman_image_set_repeat (info->image, PIXMAN_REPEAT_NORMAL);
414
info->repeat = PIXMAN_REPEAT_NORMAL;
419
info->image = pixman_image_create_solid_fill (&fill);
424
image_fini (image_t *info)
426
pixman_image_unref (info->image);
432
return prng_rand_n (ARRAY_LENGTH (sizes));
438
return prng_rand_n (ARRAY_LENGTH (colors));
444
return prng_rand_n (ARRAY_LENGTH (formats));
448
run_test (uint32_t seed)
450
image_t src, mask, dst;
457
image_init (&dst, random_color(), random_format(), 1);
458
image_init (&src, random_color(), random_format(), random_size());
459
image_init (&mask, random_color(), random_format(), random_size());
461
op = operators [prng_rand_n (ARRAY_LENGTH (operators))];
463
ca = prng_rand_n (3);
468
ok = composite_test (&dst, op, &src, NULL, FALSE, seed);
471
ok = composite_test (&dst, op, &src, &mask, FALSE, seed);
474
ok = composite_test (&dst, op, &src, &mask,
475
mask.size? TRUE : FALSE, seed);
490
main (int argc, char **argv)
492
#define N_TESTS (8 * 1024 * 1024)
501
i = strtol (argv[1], &end, 0);
512
printf ("Usage:\n\n %s <number>\n\n", argv[0]);
517
if (getenv ("PIXMAN_RANDOMIZE_TESTS"))
518
seed = get_random_seed();
523
# pragma omp parallel for default(none) shared(result, argv, seed)
525
for (i = 0; i <= N_TESTS; ++i)
527
if (!result && !run_test (i + seed))
529
printf ("Test 0x%08X failed.\n", seed + i);