2 * Copyright © 2009 Nokia Corporation
3 * Copyright © 2010 Movial Creative Technologies Oy
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:
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
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.
33 #define L1CACHE_SIZE (8 * 1024)
34 #define L2CACHE_SIZE (128 * 1024)
36 /* This is applied to both L1 and L2 tests - alternatively, you could
37 * parameterise bench_L or split it into two functions. It could be
38 * read at runtime on some architectures, but it only really matters
39 * that it's a number that's an integer divisor of both cacheline
40 * lengths, and further, it only really matters for caches that don't
41 * do allocate0on-write. */
42 #define CACHELINE_LENGTH (32) /* bytes */
46 #define BUFSIZE (WIDTH * HEIGHT * 4)
52 #define EXCLUDE_OVERHEAD 1
70 memcpy (dst, src, BUFSIZE - 64);
71 memcpy (src, dst, BUFSIZE - 64);
72 n += 4 * (BUFSIZE - 64);
83 memcpy ((char *)dst + 1, (char *)src + x, BUFSIZE - 64);
84 memcpy ((char *)src + 1, (char *)dst + x, BUFSIZE - 64);
85 n -= 4 * (BUFSIZE - 64);
88 return (double)total / (t2 - t1);
91 static pixman_bool_t use_scaling = FALSE;
92 static pixman_filter_t filter = PIXMAN_FILTER_NEAREST;
94 /* nearly 1x scale factor */
95 static pixman_transform_t m =
98 { pixman_fixed_1 + 1, 0, 0 },
99 { 0, pixman_fixed_1, 0 },
100 { 0, 0, pixman_fixed_1 }
105 pixman_image_composite_wrapper (pixman_implementation_t *impl,
106 pixman_composite_info_t *info)
110 pixman_image_set_filter (info->src_image, filter, NULL, 0);
111 pixman_image_set_transform(info->src_image, &m);
113 pixman_image_composite (info->op,
114 info->src_image, info->mask_image, info->dest_image,
115 info->src_x, info->src_y,
116 info->mask_x, info->mask_y,
117 info->dest_x, info->dest_y,
118 info->width, info->height);
122 pixman_image_composite_empty (pixman_implementation_t *impl,
123 pixman_composite_info_t *info)
127 pixman_image_set_filter (info->src_image, filter, NULL, 0);
128 pixman_image_set_transform(info->src_image, &m);
130 pixman_image_composite (info->op,
131 info->src_image, info->mask_image, info->dest_image,
132 0, 0, 0, 0, 0, 0, 1, 1);
136 call_func (pixman_composite_func_t func,
138 pixman_image_t * src_image,
139 pixman_image_t * mask_image,
140 pixman_image_t * dest_image,
150 pixman_composite_info_t info;
153 info.src_image = src_image;
154 info.mask_image = mask_image;
155 info.dest_image = dest_image;
158 info.mask_x = mask_x;
159 info.mask_y = mask_y;
160 info.dest_x = dest_x;
161 info.dest_y = dest_y;
163 info.height = height;
170 bench_L (pixman_op_t op,
171 pixman_image_t * src_img,
172 pixman_image_t * mask_img,
173 pixman_image_t * dst_img,
175 pixman_composite_func_t func,
184 for (i = 0; i < n; i++)
186 /* For caches without allocate-on-write, we need to force the
187 * destination buffer back into the cache on each iteration,
188 * otherwise if they are evicted during the test, they remain
189 * uncached. This doesn't matter for tests which read the
190 * destination buffer, or for caches that do allocate-on-write,
191 * but in those cases this loop just adds constant time, which
192 * should be successfully cancelled out.
194 for (j = 0; j < lines_count; j++)
196 for (k = 0; k < width + 62; k += CACHELINE_LENGTH / sizeof *dst)
198 q += dst[j * WIDTH + k];
200 q += dst[j * WIDTH + width + 62];
204 call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 63 - x, 0, width, lines_count);
211 bench_M (pixman_op_t op,
212 pixman_image_t * src_img,
213 pixman_image_t * mask_img,
214 pixman_image_t * dst_img,
216 pixman_composite_func_t func)
221 for (i = 0; i < n; i++)
225 call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 1, 0, WIDTH - 64, HEIGHT);
231 bench_HT (pixman_op_t op,
232 pixman_image_t * src_img,
233 pixman_image_t * mask_img,
234 pixman_image_t * dst_img,
236 pixman_composite_func_t func)
244 for (i = 0; i < n; i++)
246 int w = (rand () % (TILEWIDTH * 2)) + 1;
247 int h = (rand () % (TILEWIDTH * 2)) + 1;
257 call_func (func, op, src_img, mask_img, dst_img, x, y, x, y, x, y, w, h);
266 bench_VT (pixman_op_t op,
267 pixman_image_t * src_img,
268 pixman_image_t * mask_img,
269 pixman_image_t * dst_img,
271 pixman_composite_func_t func)
279 for (i = 0; i < n; i++)
281 int w = (rand () % (TILEWIDTH * 2)) + 1;
282 int h = (rand () % (TILEWIDTH * 2)) + 1;
292 call_func (func, op, src_img, mask_img, dst_img, x, y, x, y, x, y, w, h);
301 bench_R (pixman_op_t op,
302 pixman_image_t * src_img,
303 pixman_image_t * mask_img,
304 pixman_image_t * dst_img,
306 pixman_composite_func_t func,
313 if (maxw <= TILEWIDTH * 2 || maxh <= TILEWIDTH * 2)
315 printf("error: maxw <= TILEWIDTH * 2 || maxh <= TILEWIDTH * 2\n");
320 for (i = 0; i < n; i++)
322 int w = (rand () % (TILEWIDTH * 2)) + 1;
323 int h = (rand () % (TILEWIDTH * 2)) + 1;
324 int sx = rand () % (maxw - TILEWIDTH * 2);
325 int sy = rand () % (maxh - TILEWIDTH * 2);
326 int dx = rand () % (maxw - TILEWIDTH * 2);
327 int dy = rand () % (maxh - TILEWIDTH * 2);
328 call_func (func, op, src_img, mask_img, dst_img, sx, sy, sx, sy, dx, dy, w, h);
336 bench_RT (pixman_op_t op,
337 pixman_image_t * src_img,
338 pixman_image_t * mask_img,
339 pixman_image_t * dst_img,
341 pixman_composite_func_t func,
348 if (maxw <= TINYWIDTH * 2 || maxh <= TINYWIDTH * 2)
350 printf("error: maxw <= TINYWIDTH * 2 || maxh <= TINYWIDTH * 2\n");
355 for (i = 0; i < n; i++)
357 int w = (rand () % (TINYWIDTH * 2)) + 1;
358 int h = (rand () % (TINYWIDTH * 2)) + 1;
359 int sx = rand () % (maxw - TINYWIDTH * 2);
360 int sy = rand () % (maxh - TINYWIDTH * 2);
361 int dx = rand () % (maxw - TINYWIDTH * 2);
362 int dy = rand () % (maxh - TINYWIDTH * 2);
363 call_func (func, op, src_img, mask_img, dst_img, sx, sy, sx, sy, dx, dy, w, h);
370 bench_composite (char * testname,
379 pixman_image_t * src_img;
380 pixman_image_t * dst_img;
381 pixman_image_t * mask_img;
382 pixman_image_t * xsrc_img;
383 pixman_image_t * xdst_img;
384 pixman_image_t * xmask_img;
385 double t1, t2, t3, pix_cnt;
386 int64_t n, l1test_width, nlines;
387 double bytes_per_pix = 0;
388 pixman_bool_t bench_pixbuf = FALSE;
390 pixman_composite_func_t func = pixman_image_composite_wrapper;
392 if (!(src_flags & SOLID_FLAG))
394 bytes_per_pix += (src_fmt >> 24) / 8.0;
395 src_img = pixman_image_create_bits (src_fmt,
399 xsrc_img = pixman_image_create_bits (src_fmt,
406 src_img = pixman_image_create_bits (src_fmt,
410 xsrc_img = pixman_image_create_bits (src_fmt,
414 pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
415 pixman_image_set_repeat (xsrc_img, PIXMAN_REPEAT_NORMAL);
418 bytes_per_pix += (dst_fmt >> 24) / 8.0;
419 dst_img = pixman_image_create_bits (dst_fmt,
426 if (strcmp (testname, "pixbuf") == 0 || strcmp (testname, "rpixbuf") == 0)
430 if (!(mask_flags & SOLID_FLAG) && mask_fmt != PIXMAN_null)
432 bytes_per_pix += (mask_fmt >> 24) / ((op == PIXMAN_OP_SRC) ? 8.0 : 4.0);
433 mask_img = pixman_image_create_bits (mask_fmt,
435 bench_pixbuf ? src : mask,
437 xmask_img = pixman_image_create_bits (mask_fmt,
439 bench_pixbuf ? src : mask,
442 else if (mask_fmt != PIXMAN_null)
444 mask_img = pixman_image_create_bits (mask_fmt,
448 xmask_img = pixman_image_create_bits (mask_fmt,
452 pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
453 pixman_image_set_repeat (xmask_img, PIXMAN_REPEAT_NORMAL);
455 if ((mask_flags & CA_FLAG) && mask_fmt != PIXMAN_null)
457 pixman_image_set_component_alpha (mask_img, 1);
459 xdst_img = pixman_image_create_bits (dst_fmt,
465 printf ("%24s %c", testname, func != pixman_image_composite_wrapper ?
468 memcpy (dst, src, BUFSIZE);
469 memcpy (src, dst, BUFSIZE);
471 l1test_width = L1CACHE_SIZE / 8 - 64;
472 if (l1test_width < 1)
474 if (l1test_width > WIDTH - 64)
475 l1test_width = WIDTH - 64;
476 n = 1 + npix / (l1test_width * 8);
479 bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, 1);
482 bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, 1);
484 printf (" L1:%7.2f", (double)n * l1test_width * 1 /
485 ((t3 - t2) - (t2 - t1)) / 1000000.);
488 memcpy (dst, src, BUFSIZE);
489 memcpy (src, dst, BUFSIZE);
491 nlines = (L2CACHE_SIZE / l1test_width) /
492 ((PIXMAN_FORMAT_BPP(src_fmt) + PIXMAN_FORMAT_BPP(dst_fmt)) / 8);
495 n = 1 + npix / (l1test_width * nlines);
498 bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, nlines);
501 bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, nlines);
503 printf (" L2:%7.2f", (double)n * l1test_width * nlines /
504 ((t3 - t2) - (t2 - t1)) / 1000000.);
507 memcpy (dst, src, BUFSIZE);
508 memcpy (src, dst, BUFSIZE);
510 n = 1 + npix / (WIDTH * HEIGHT);
513 bench_M (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
516 bench_M (op, src_img, mask_img, dst_img, n, func);
518 printf (" M:%6.2f (%6.2f%%)",
519 ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1))) / 1000000.,
520 ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) );
523 memcpy (dst, src, BUFSIZE);
524 memcpy (src, dst, BUFSIZE);
526 n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
529 pix_cnt = bench_HT (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
532 pix_cnt = bench_HT (op, src_img, mask_img, dst_img, n, func);
534 printf (" HT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
537 memcpy (dst, src, BUFSIZE);
538 memcpy (src, dst, BUFSIZE);
540 n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
543 pix_cnt = bench_VT (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
546 pix_cnt = bench_VT (op, src_img, mask_img, dst_img, n, func);
548 printf (" VT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
551 memcpy (dst, src, BUFSIZE);
552 memcpy (src, dst, BUFSIZE);
554 n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
557 pix_cnt = bench_R (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, WIDTH, HEIGHT);
560 pix_cnt = bench_R (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT);
562 printf (" R:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
565 memcpy (dst, src, BUFSIZE);
566 memcpy (src, dst, BUFSIZE);
568 n = 1 + npix / (16 * TINYWIDTH * TINYWIDTH);
571 pix_cnt = bench_RT (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, WIDTH, HEIGHT);
574 pix_cnt = bench_RT (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT);
576 printf (" RT:%6.2f (%4.0fKops/s)\n", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000., (double) n / ((t3 - t2) * 1000));
579 pixman_image_unref (mask_img);
580 pixman_image_unref (xmask_img);
582 pixman_image_unref (src_img);
583 pixman_image_unref (dst_img);
584 pixman_image_unref (xsrc_img);
585 pixman_image_unref (xdst_img);
588 #define PIXMAN_OP_OUT_REV (PIXMAN_OP_OUT_REVERSE)
602 { "add_8_8_8", PIXMAN_a8, 0, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 },
603 { "add_n_8_8", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 },
604 { "add_n_8_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
605 { "add_n_8_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_x8r8g8b8 },
606 { "add_n_8_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
607 { "add_n_8_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a1r5g5b5 },
608 { "add_n_8_4444", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a4r4g4b4 },
609 { "add_n_8_2222", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a2r2g2b2 },
610 { "add_n_8_2x10", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_x2r10g10b10 },
611 { "add_n_8_2a10", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a2r10g10b10 },
612 { "add_n_8", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a8 },
613 { "add_n_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
614 { "add_n_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
615 { "add_n_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_r5g6b5 },
616 { "add_n_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
617 { "add_n_4444", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a4r4g4b4 },
618 { "add_n_2222", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r2g2b2 },
619 { "add_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
620 { "add_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
621 { "add_8_8", PIXMAN_a8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a8 },
622 { "add_x888_x888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
623 { "add_8888_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
624 { "add_8888_0565", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_r5g6b5 },
625 { "add_8888_1555", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
626 { "add_8888_4444", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a4r4g4b4 },
627 { "add_8888_2222", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r2g2b2 },
628 { "add_0565_0565", PIXMAN_r5g6b5, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_r5g6b5 },
629 { "add_1555_1555", PIXMAN_a1r5g5b5, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
630 { "add_0565_2x10", PIXMAN_r5g6b5, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
631 { "add_2a10_2a10", PIXMAN_a2r10g10b10, 0, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
632 { "in_n_8_8", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_IN, PIXMAN_a8, 0, PIXMAN_a8 },
633 { "in_8_8", PIXMAN_a8, 0, PIXMAN_OP_IN, PIXMAN_null, 0, PIXMAN_a8 },
634 { "src_n_2222", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r2g2b2 },
635 { "src_n_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
636 { "src_n_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
637 { "src_n_4444", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a4r4g4b4 },
638 { "src_n_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
639 { "src_n_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
640 { "src_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
641 { "src_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
642 { "src_8888_0565", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
643 { "src_0565_8888", PIXMAN_r5g6b5, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
644 { "src_8888_4444", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a4r4g4b4 },
645 { "src_8888_2222", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r2g2b2 },
646 { "src_8888_2x10", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
647 { "src_8888_2a10", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
648 { "src_0888_0565", PIXMAN_r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
649 { "src_0888_8888", PIXMAN_r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
650 { "src_0888_x888", PIXMAN_r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
651 { "src_0888_8888_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
652 { "src_0888_0565_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
653 { "src_x888_x888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
654 { "src_x888_8888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
655 { "src_8888_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
656 { "src_0565_0565", PIXMAN_r5g6b5, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
657 { "src_1555_0565", PIXMAN_a1r5g5b5, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
658 { "src_0565_1555", PIXMAN_r5g6b5, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
659 { "src_8_8", PIXMAN_a8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8 },
660 { "src_n_8", PIXMAN_a8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8 },
661 { "src_n_8_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
662 { "src_n_8_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a1r5g5b5 },
663 { "src_n_8_4444", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a4r4g4b4 },
664 { "src_n_8_2222", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a2r2g2b2 },
665 { "src_n_8_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_x8r8g8b8 },
666 { "src_n_8_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
667 { "src_n_8_2x10", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_x2r10g10b10 },
668 { "src_n_8_2a10", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a2r10g10b10 },
669 { "src_8888_8_0565", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
670 { "src_0888_8_0565", PIXMAN_r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
671 { "src_0888_8_8888", PIXMAN_r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
672 { "src_0888_8_x888", PIXMAN_r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_x8r8g8b8 },
673 { "src_x888_8_x888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_x8r8g8b8 },
674 { "src_x888_8_8888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
675 { "src_0565_8_0565", PIXMAN_r5g6b5, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
676 { "src_1555_8_0565", PIXMAN_a1r5g5b5, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
677 { "src_0565_8_1555", PIXMAN_r5g6b5, 0, PIXMAN_OP_SRC, PIXMAN_a8, 0, PIXMAN_a1r5g5b5 },
678 { "over_n_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
679 { "over_n_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
680 { "over_n_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_r5g6b5 },
681 { "over_n_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_a1r5g5b5 },
682 { "over_8888_0565", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_r5g6b5 },
683 { "over_8888_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
684 { "over_8888_x888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
685 { "over_x888_8_0565", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
686 { "over_x888_8_8888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
687 { "over_n_8_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
688 { "over_n_8_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a1r5g5b5 },
689 { "over_n_8_4444", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a4r4g4b4 },
690 { "over_n_8_2222", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a2r2g2b2 },
691 { "over_n_8_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_x8r8g8b8 },
692 { "over_n_8_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
693 { "over_n_8_2x10", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_x2r10g10b10 },
694 { "over_n_8_2a10", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8, 0, PIXMAN_a2r10g10b10 },
695 { "over_n_8888_8888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_a8r8g8b8 },
696 { "over_n_8888_x888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_x8r8g8b8 },
697 { "over_n_8888_0565_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_r5g6b5 },
698 { "over_n_8888_1555_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_a1r5g5b5 },
699 { "over_n_8888_4444_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_a4r4g4b4 },
700 { "over_n_8888_2222_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_a2r2g2b2 },
701 { "over_n_8888_2x10_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_x2r10g10b10 },
702 { "over_n_8888_2a10_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 2, PIXMAN_a2r10g10b10 },
703 { "over_8888_n_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 1, PIXMAN_a8r8g8b8 },
704 { "over_8888_n_x888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 1, PIXMAN_x8r8g8b8 },
705 { "over_8888_n_0565", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 1, PIXMAN_r5g6b5 },
706 { "over_8888_n_1555", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 1, PIXMAN_a1r5g5b5 },
707 { "over_x888_n_8888", PIXMAN_x8r8g8b8, 0, PIXMAN_OP_OVER, PIXMAN_a8, 1, PIXMAN_a8r8g8b8 },
708 { "outrev_n_8_0565", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8, 0, PIXMAN_r5g6b5 },
709 { "outrev_n_8_1555", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8, 0, PIXMAN_a1r5g5b5 },
710 { "outrev_n_8_x888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8, 0, PIXMAN_x8r8g8b8 },
711 { "outrev_n_8_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8, 0, PIXMAN_a8r8g8b8 },
712 { "outrev_n_8888_0565_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_r5g6b5 },
713 { "outrev_n_8888_1555_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a1r5g5b5 },
714 { "outrev_n_8888_x888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_x8r8g8b8 },
715 { "outrev_n_8888_8888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a8r8g8b8 },
716 { "over_reverse_n_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 },
717 { "pixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8r8g8b8 },
718 { "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 },
722 main (int argc, char *argv[])
726 const char *pattern = NULL;
727 for (i = 1; i < argc; i++)
729 if (argv[i][0] == '-')
731 if (strchr (argv[i] + 1, 'b'))
734 filter = PIXMAN_FILTER_BILINEAR;
736 else if (strchr (argv[i] + 1, 'n'))
739 filter = PIXMAN_FILTER_NEAREST;
750 printf ("Usage: lowlevel-blt-bench [-b] [-n] pattern\n");
751 printf (" -n : benchmark nearest scaling\n");
752 printf (" -b : benchmark bilinear scaling\n");
756 src = aligned_malloc (4096, BUFSIZE * 3);
757 memset (src, 0xCC, BUFSIZE * 3);
758 dst = src + (BUFSIZE / 4);
759 mask = dst + (BUFSIZE / 4);
761 printf ("Benchmark for a set of most commonly used functions\n");
763 printf ("All results are presented in millions of pixels per second\n");
764 printf ("L1 - small Xx1 rectangle (fitting L1 cache), always blitted at the same\n");
765 printf (" memory location with small drift in horizontal direction\n");
766 printf ("L2 - small XxY rectangle (fitting L2 cache), always blitted at the same\n");
767 printf (" memory location with small drift in horizontal direction\n");
768 printf ("M - large %dx%d rectangle, always blitted at the same\n",
770 printf (" memory location with small drift in horizontal direction\n");
771 printf ("HT - random rectangles with %dx%d average size are copied from\n",
772 TILEWIDTH, TILEWIDTH);
773 printf (" one %dx%d buffer to another, traversing from left to right\n",
775 printf (" and from top to bottom\n");
776 printf ("VT - random rectangles with %dx%d average size are copied from\n",
777 TILEWIDTH, TILEWIDTH);
778 printf (" one %dx%d buffer to another, traversing from top to bottom\n",
780 printf (" and from left to right\n");
781 printf ("R - random rectangles with %dx%d average size are copied from\n",
782 TILEWIDTH, TILEWIDTH);
783 printf (" random locations of one %dx%d buffer to another\n",
785 printf ("RT - as R, but %dx%d average sized rectangles are copied\n",
786 TINYWIDTH, TINYWIDTH);
788 bandwidth = x = bench_memcpy ();
789 printf ("reference memcpy speed = %.1fMB/s (%.1fMP/s for 32bpp fills)\n",
790 x / 1000000., x / 4000000);
794 if (filter == PIXMAN_FILTER_BILINEAR)
795 printf ("BILINEAR scaling\n");
796 else if (filter == PIXMAN_FILTER_NEAREST)
797 printf ("NEAREST scaling\n");
799 printf ("UNKNOWN scaling\n");
803 for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
805 if (strcmp (pattern, "all") == 0 || strcmp (tests_tbl[i].testname, pattern) == 0)
807 bench_composite (tests_tbl[i].testname,
808 tests_tbl[i].src_fmt,
809 tests_tbl[i].src_flags,
811 tests_tbl[i].mask_fmt,
812 tests_tbl[i].mask_flags,
813 tests_tbl[i].dst_fmt,