~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to pixman/test/composite.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2005 Eric Anholt
 
3
 * Copyright © 2009 Chris Wilson
 
4
 * Copyright © 2010 Soeren Sandmann
 
5
 * Copyright © 2010 Red Hat, Inc.
 
6
 *
 
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.
 
16
 *
 
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.
 
24
 */
 
25
#include <stdio.h>
 
26
#include <stdlib.h> /* abort() */
 
27
#include <math.h>
 
28
#include <time.h>
 
29
#include "utils.h"
 
30
 
 
31
typedef struct image_t image_t;
 
32
 
 
33
static const color_t colors[] =
 
34
{
 
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 },
 
43
};
 
44
 
 
45
static uint16_t
 
46
_color_double_to_short (double d)
 
47
{
 
48
    uint32_t i;
 
49
 
 
50
    i = (uint32_t) (d * 65536);
 
51
    i -= (i >> 16);
 
52
 
 
53
    return i;
 
54
}
 
55
 
 
56
static void
 
57
compute_pixman_color (const color_t *color,
 
58
                      pixman_color_t *out)
 
59
{
 
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);
 
64
}
 
65
 
 
66
#define REPEAT 0x01000000
 
67
#define FLAGS  0xff000000
 
68
 
 
69
static const int sizes[] =
 
70
{
 
71
    0,
 
72
    1,
 
73
    1 | REPEAT,
 
74
    10
 
75
};
 
76
 
 
77
static const pixman_format_code_t formats[] =
 
78
{
 
79
    /* 32 bpp formats */
 
80
    PIXMAN_a8r8g8b8,
 
81
    PIXMAN_x8r8g8b8,
 
82
    PIXMAN_a8b8g8r8,
 
83
    PIXMAN_x8b8g8r8,
 
84
    PIXMAN_b8g8r8a8,
 
85
    PIXMAN_b8g8r8x8,
 
86
    PIXMAN_r8g8b8a8,
 
87
    PIXMAN_r8g8b8x8,
 
88
    PIXMAN_x2r10g10b10,
 
89
    PIXMAN_x2b10g10r10,
 
90
    PIXMAN_a2r10g10b10,
 
91
    PIXMAN_a2b10g10r10,
 
92
    
 
93
    /* sRGB formats */
 
94
    PIXMAN_a8r8g8b8_sRGB,
 
95
 
 
96
    /* 24 bpp formats */
 
97
    PIXMAN_r8g8b8,
 
98
    PIXMAN_b8g8r8,
 
99
    PIXMAN_r5g6b5,
 
100
    PIXMAN_b5g6r5,
 
101
 
 
102
    /* 16 bpp formats */
 
103
    PIXMAN_x1r5g5b5,
 
104
    PIXMAN_x1b5g5r5,
 
105
    PIXMAN_a1r5g5b5,
 
106
    PIXMAN_a1b5g5r5,
 
107
    PIXMAN_a4b4g4r4,
 
108
    PIXMAN_x4b4g4r4,
 
109
    PIXMAN_a4r4g4b4,
 
110
    PIXMAN_x4r4g4b4,
 
111
 
 
112
    /* 8 bpp formats */
 
113
    PIXMAN_a8,
 
114
    PIXMAN_r3g3b2,
 
115
    PIXMAN_b2g3r3,
 
116
    PIXMAN_a2r2g2b2,
 
117
    PIXMAN_a2b2g2r2,
 
118
    PIXMAN_x4a4,
 
119
 
 
120
    /* 4 bpp formats */
 
121
    PIXMAN_a4,
 
122
    PIXMAN_r1g2b1,
 
123
    PIXMAN_b1g2r1,
 
124
    PIXMAN_a1r1g1b1,
 
125
    PIXMAN_a1b1g1r1,
 
126
 
 
127
    /* 1 bpp formats */
 
128
    PIXMAN_a1,
 
129
};
 
130
 
 
131
struct image_t
 
132
{
 
133
    pixman_image_t *image;
 
134
    pixman_format_code_t format;
 
135
    const color_t *color;
 
136
    pixman_repeat_t repeat;
 
137
    int size;
 
138
};
 
139
 
 
140
static const pixman_op_t operators[] =
 
141
{
 
142
    PIXMAN_OP_CLEAR,
 
143
    PIXMAN_OP_SRC,
 
144
    PIXMAN_OP_DST,
 
145
    PIXMAN_OP_OVER,
 
146
    PIXMAN_OP_OVER_REVERSE,
 
147
    PIXMAN_OP_IN,
 
148
    PIXMAN_OP_IN_REVERSE,
 
149
    PIXMAN_OP_OUT,
 
150
    PIXMAN_OP_OUT_REVERSE,
 
151
    PIXMAN_OP_ATOP,
 
152
    PIXMAN_OP_ATOP_REVERSE,
 
153
    PIXMAN_OP_XOR,
 
154
    PIXMAN_OP_ADD,
 
155
    PIXMAN_OP_SATURATE,
 
156
 
 
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,
 
169
 
 
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,
 
182
};
 
183
 
 
184
static uint32_t
 
185
get_value (pixman_image_t *image)
 
186
{
 
187
    uint32_t value = *(uint32_t *)pixman_image_get_data (image);
 
188
 
 
189
#ifdef WORDS_BIGENDIAN
 
190
    {
 
191
        pixman_format_code_t format = pixman_image_get_format (image);
 
192
        value >>= 8 * sizeof(value) - PIXMAN_FORMAT_BPP (format);
 
193
    }
 
194
#endif
 
195
 
 
196
    return value;
 
197
}
 
198
 
 
199
static char *
 
200
describe_image (image_t *info, char *buf)
 
201
{
 
202
    if (info->size)
 
203
    {
 
204
        sprintf (buf, "%s, %dx%d%s",
 
205
                 format_name (info->format),
 
206
                 info->size, info->size,
 
207
                 info->repeat ? " R" :"");
 
208
    }
 
209
    else
 
210
    {
 
211
        sprintf (buf, "solid");
 
212
    }
 
213
 
 
214
    return buf;
 
215
}
 
216
 
 
217
static char *
 
218
describe_color (const color_t *color, char *buf)
 
219
{
 
220
    sprintf (buf, "%.3f %.3f %.3f %.3f",
 
221
             color->r, color->g, color->b, color->a);
 
222
 
 
223
    return buf;
 
224
}
 
225
 
 
226
static pixman_bool_t
 
227
composite_test (image_t *dst,
 
228
                pixman_op_t op,
 
229
                image_t *src,
 
230
                image_t *mask,
 
231
                pixman_bool_t component_alpha,
 
232
                int testno)
 
233
{
 
234
    color_t expected, tdst, tsrc, tmsk;
 
235
    pixel_checker_t checker;
 
236
 
 
237
    if (mask)
 
238
    {
 
239
        pixman_image_set_component_alpha (mask->image, component_alpha);
 
240
 
 
241
        pixman_image_composite (op, src->image, mask->image, dst->image,
 
242
                                0, 0, 0, 0, 0, 0, dst->size, dst->size);
 
243
    }
 
244
    else
 
245
    {
 
246
        pixman_image_composite (op, src->image, NULL, dst->image,
 
247
                                0, 0,
 
248
                                0, 0,
 
249
                                0, 0,
 
250
                                dst->size, dst->size);
 
251
    }
 
252
 
 
253
    tdst = *dst->color;
 
254
    tsrc = *src->color;
 
255
 
 
256
    if (mask)
 
257
    {
 
258
        tmsk = *mask->color;
 
259
    }
 
260
 
 
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.
 
265
     */
 
266
    if (src->size)
 
267
    {
 
268
        if (PIXMAN_FORMAT_TYPE (src->format) == PIXMAN_TYPE_ARGB_SRGB)
 
269
        {
 
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);
 
277
        }
 
278
        else
 
279
        {
 
280
            round_color (src->format, &tsrc);
 
281
        }
 
282
    }
 
283
 
 
284
    if (mask && mask->size)
 
285
    {
 
286
        if (PIXMAN_FORMAT_TYPE (mask->format) == PIXMAN_TYPE_ARGB_SRGB)
 
287
        {
 
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);
 
295
        }
 
296
        else
 
297
        {
 
298
            round_color (mask->format, &tmsk);
 
299
        }
 
300
    }
 
301
 
 
302
    if (mask)
 
303
    {
 
304
        if (component_alpha && PIXMAN_FORMAT_R (mask->format) == 0)
 
305
        {
 
306
            /* Ax component-alpha masks expand alpha into
 
307
             * all color channels.
 
308
             */
 
309
            tmsk.r = tmsk.g = tmsk.b = tmsk.a;
 
310
        }
 
311
    }
 
312
 
 
313
    if (PIXMAN_FORMAT_TYPE (dst->format) == PIXMAN_TYPE_ARGB_SRGB)
 
314
    {
 
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);
 
322
    }
 
323
    else
 
324
    {
 
325
        round_color (dst->format, &tdst);
 
326
    }
 
327
 
 
328
    do_composite (op,
 
329
                  &tsrc,
 
330
                  mask? &tmsk : NULL,
 
331
                  &tdst,
 
332
                  &expected,
 
333
                  component_alpha);
 
334
 
 
335
    pixel_checker_init (&checker, dst->format);
 
336
 
 
337
    if (!pixel_checker_check (&checker, get_value (dst->image), &expected))
 
338
    {
 
339
        char buf[40], buf2[40];
 
340
        int a, r, g, b;
 
341
        uint32_t pixel;
 
342
 
 
343
        printf ("---- Test %d failed ----\n", testno);
 
344
        printf ("Operator:      %s %s\n",
 
345
                operator_name (op), component_alpha ? "CA" : "");
 
346
 
 
347
        printf ("Source:        %s\n", describe_image (src, buf));
 
348
        if (mask != NULL)
 
349
            printf ("Mask:          %s\n", describe_image (mask, buf));
 
350
 
 
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));
 
356
        if (mask)
 
357
        {
 
358
            printf ("Mask color:    %s     %s\n",
 
359
                    describe_color (mask->color, buf),
 
360
                    describe_color (&tmsk, buf2));
 
361
        }
 
362
        printf ("Dest. color:   %s     %s\n",
 
363
                describe_color (dst->color, buf),
 
364
                describe_color (&tdst, buf2));
 
365
 
 
366
        pixel = get_value (dst->image);
 
367
 
 
368
        printf ("Expected:      %s\n", describe_color (&expected, buf));
 
369
 
 
370
        pixel_checker_split_pixel (&checker, pixel, &a, &r, &g, &b);
 
371
 
 
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);
 
377
 
 
378
        return FALSE;
 
379
    }
 
380
    return TRUE;
 
381
}
 
382
 
 
383
static void
 
384
image_init (image_t *info,
 
385
            int color,
 
386
            int format,
 
387
            int size)
 
388
{
 
389
    pixman_color_t fill;
 
390
 
 
391
    info->color = &colors[color];
 
392
    compute_pixman_color (info->color, &fill);
 
393
 
 
394
    info->format = formats[format];
 
395
    info->size = sizes[size] & ~FLAGS;
 
396
    info->repeat = PIXMAN_REPEAT_NONE;
 
397
 
 
398
    if (info->size)
 
399
    {
 
400
        pixman_image_t *solid;
 
401
 
 
402
        info->image = pixman_image_create_bits (info->format,
 
403
                                                info->size, info->size,
 
404
                                                NULL, 0);
 
405
 
 
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);
 
410
 
 
411
        if (sizes[size] & REPEAT)
 
412
        {
 
413
            pixman_image_set_repeat (info->image, PIXMAN_REPEAT_NORMAL);
 
414
            info->repeat = PIXMAN_REPEAT_NORMAL;
 
415
        }
 
416
    }
 
417
    else
 
418
    {
 
419
        info->image = pixman_image_create_solid_fill (&fill);
 
420
    }
 
421
}
 
422
 
 
423
static void
 
424
image_fini (image_t *info)
 
425
{
 
426
    pixman_image_unref (info->image);
 
427
}
 
428
 
 
429
static int
 
430
random_size (void)
 
431
{
 
432
    return prng_rand_n (ARRAY_LENGTH (sizes));
 
433
}
 
434
 
 
435
static int
 
436
random_color (void)
 
437
{
 
438
    return prng_rand_n (ARRAY_LENGTH (colors));
 
439
}
 
440
 
 
441
static int
 
442
random_format (void)
 
443
{
 
444
    return prng_rand_n (ARRAY_LENGTH (formats));
 
445
}
 
446
 
 
447
static pixman_bool_t
 
448
run_test (uint32_t seed)
 
449
{
 
450
    image_t src, mask, dst;
 
451
    pixman_op_t op;
 
452
    int ca;
 
453
    int ok;
 
454
 
 
455
    prng_srand (seed);
 
456
 
 
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());
 
460
 
 
461
    op = operators [prng_rand_n (ARRAY_LENGTH (operators))];
 
462
 
 
463
    ca = prng_rand_n (3);
 
464
 
 
465
    switch (ca)
 
466
    {
 
467
    case 0:
 
468
        ok = composite_test (&dst, op, &src, NULL, FALSE, seed);
 
469
        break;
 
470
    case 1:
 
471
        ok = composite_test (&dst, op, &src, &mask, FALSE, seed);
 
472
        break;
 
473
    case 2:
 
474
        ok = composite_test (&dst, op, &src, &mask,
 
475
                             mask.size? TRUE : FALSE, seed);
 
476
        break;
 
477
    default:
 
478
        ok = FALSE;
 
479
        break;
 
480
    }
 
481
 
 
482
    image_fini (&src);
 
483
    image_fini (&mask);
 
484
    image_fini (&dst);
 
485
 
 
486
    return ok;
 
487
}
 
488
 
 
489
int
 
490
main (int argc, char **argv)
 
491
{
 
492
#define N_TESTS (8 * 1024 * 1024)
 
493
    int result = 0;
 
494
    uint32_t seed;
 
495
    int32_t i;
 
496
 
 
497
    if (argc > 1)
 
498
    {
 
499
        char *end;
 
500
 
 
501
        i = strtol (argv[1], &end, 0);
 
502
 
 
503
        if (end != argv[1])
 
504
        {
 
505
            if (!run_test (i))
 
506
                return 1;
 
507
            else
 
508
                return 0;
 
509
        }
 
510
        else
 
511
        {
 
512
            printf ("Usage:\n\n   %s <number>\n\n", argv[0]);
 
513
            return -1;
 
514
        }
 
515
    }
 
516
 
 
517
    if (getenv ("PIXMAN_RANDOMIZE_TESTS"))
 
518
        seed = get_random_seed();
 
519
    else
 
520
        seed = 1;
 
521
 
 
522
#ifdef USE_OPENMP
 
523
#   pragma omp parallel for default(none) shared(result, argv, seed)
 
524
#endif
 
525
    for (i = 0; i <= N_TESTS; ++i)
 
526
    {
 
527
        if (!result && !run_test (i + seed))
 
528
        {
 
529
            printf ("Test 0x%08X failed.\n", seed + i);
 
530
 
 
531
            result = seed + i;
 
532
        }
 
533
    }
 
534
 
 
535
    return result;
 
536
}