diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2016-10-01 10:17:45 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2016-10-01 10:17:45 +0000 |
commit | 6e29ee4062908ba8e6124bf8b3a2083e1b2d3e36 (patch) | |
tree | e254d752e6bbd8d1b208522c3a952e16f2167f29 /lib/pixman/test | |
parent | aa49994dd96792e111dc00188e3c73a2e20b9780 (diff) |
Update to pixman 0.34.0.
Diffstat (limited to 'lib/pixman/test')
-rw-r--r-- | lib/pixman/test/Makefile.in | 187 | ||||
-rw-r--r-- | lib/pixman/test/Makefile.sources | 62 | ||||
-rw-r--r-- | lib/pixman/test/affine-bench.c | 448 | ||||
-rw-r--r-- | lib/pixman/test/blitters-test.c | 20 | ||||
-rw-r--r-- | lib/pixman/test/check-formats.c | 176 | ||||
-rw-r--r-- | lib/pixman/test/composite.c | 11 | ||||
-rw-r--r-- | lib/pixman/test/cover-test.c | 449 | ||||
-rw-r--r-- | lib/pixman/test/fence-image-self-test.c | 239 | ||||
-rw-r--r-- | lib/pixman/test/lowlevel-blt-bench.c | 513 | ||||
-rw-r--r-- | lib/pixman/test/pixel-test.c | 2780 | ||||
-rw-r--r-- | lib/pixman/test/radial-invalid.c | 54 | ||||
-rw-r--r-- | lib/pixman/test/scaling-test.c | 66 | ||||
-rw-r--r-- | lib/pixman/test/solid-test.c | 353 | ||||
-rw-r--r-- | lib/pixman/test/thread-test.c | 29 | ||||
-rw-r--r-- | lib/pixman/test/tolerance-test.c | 360 | ||||
-rw-r--r-- | lib/pixman/test/utils.c | 786 | ||||
-rw-r--r-- | lib/pixman/test/utils.h | 34 |
17 files changed, 5992 insertions, 575 deletions
diff --git a/lib/pixman/test/Makefile.in b/lib/pixman/test/Makefile.in index d7fa0d297..4461a93b9 100644 --- a/lib/pixman/test/Makefile.in +++ b/lib/pixman/test/Makefile.in @@ -74,20 +74,25 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am__EXEEXT_1 = prng-test$(EXEEXT) a1-trap-test$(EXEEXT) \ - pdf-op-test$(EXEEXT) region-test$(EXEEXT) \ - region-translate-test$(EXEEXT) combiner-test$(EXEEXT) \ - pixel-test$(EXEEXT) fetch-test$(EXEEXT) rotate-test$(EXEEXT) \ - oob-test$(EXEEXT) infinite-loop$(EXEEXT) trap-crasher$(EXEEXT) \ - alpha-loop$(EXEEXT) thread-test$(EXEEXT) \ - scaling-crash-test$(EXEEXT) scaling-helpers-test$(EXEEXT) \ - gradient-crash-test$(EXEEXT) region-contains-test$(EXEEXT) \ - alphamap$(EXEEXT) matrix-test$(EXEEXT) stress-test$(EXEEXT) \ - composite-traps-test$(EXEEXT) blitters-test$(EXEEXT) \ - glyph-test$(EXEEXT) scaling-test$(EXEEXT) affine-test$(EXEEXT) \ - composite$(EXEEXT) +am__EXEEXT_1 = oob-test$(EXEEXT) infinite-loop$(EXEEXT) \ + trap-crasher$(EXEEXT) fence-image-self-test$(EXEEXT) \ + region-translate-test$(EXEEXT) fetch-test$(EXEEXT) \ + a1-trap-test$(EXEEXT) prng-test$(EXEEXT) \ + radial-invalid$(EXEEXT) pdf-op-test$(EXEEXT) \ + region-test$(EXEEXT) combiner-test$(EXEEXT) \ + scaling-crash-test$(EXEEXT) alpha-loop$(EXEEXT) \ + scaling-helpers-test$(EXEEXT) thread-test$(EXEEXT) \ + rotate-test$(EXEEXT) alphamap$(EXEEXT) \ + gradient-crash-test$(EXEEXT) pixel-test$(EXEEXT) \ + matrix-test$(EXEEXT) composite-traps-test$(EXEEXT) \ + region-contains-test$(EXEEXT) glyph-test$(EXEEXT) \ + solid-test$(EXEEXT) stress-test$(EXEEXT) cover-test$(EXEEXT) \ + blitters-test$(EXEEXT) affine-test$(EXEEXT) \ + scaling-test$(EXEEXT) composite$(EXEEXT) \ + tolerance-test$(EXEEXT) am__EXEEXT_2 = lowlevel-blt-bench$(EXEEXT) radial-perf-test$(EXEEXT) \ - check-formats$(EXEEXT) scaling-bench$(EXEEXT) + check-formats$(EXEEXT) scaling-bench$(EXEEXT) \ + affine-bench$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) a1_trap_test_SOURCES = a1-trap-test.c a1_trap_test_OBJECTS = a1-trap-test.$(OBJEXT) @@ -96,6 +101,12 @@ am__DEPENDENCIES_1 = a1_trap_test_DEPENDENCIES = libutils.la \ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) +affine_bench_SOURCES = affine-bench.c +affine_bench_OBJECTS = affine-bench.$(OBJEXT) +affine_bench_LDADD = $(LDADD) +affine_bench_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) affine_test_SOURCES = affine-test.c affine_test_OBJECTS = affine-test.$(OBJEXT) affine_test_LDADD = $(LDADD) @@ -144,6 +155,18 @@ composite_traps_test_LDADD = $(LDADD) composite_traps_test_DEPENDENCIES = libutils.la \ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) +cover_test_SOURCES = cover-test.c +cover_test_OBJECTS = cover-test.$(OBJEXT) +cover_test_LDADD = $(LDADD) +cover_test_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +fence_image_self_test_SOURCES = fence-image-self-test.c +fence_image_self_test_OBJECTS = fence-image-self-test.$(OBJEXT) +fence_image_self_test_LDADD = $(LDADD) +fence_image_self_test_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) fetch_test_SOURCES = fetch-test.c fetch_test_OBJECTS = fetch-test.$(OBJEXT) fetch_test_LDADD = $(LDADD) @@ -204,6 +227,12 @@ prng_test_LDADD = $(LDADD) prng_test_DEPENDENCIES = libutils.la \ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) +radial_invalid_SOURCES = radial-invalid.c +radial_invalid_OBJECTS = radial-invalid.$(OBJEXT) +radial_invalid_LDADD = $(LDADD) +radial_invalid_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) radial_perf_test_SOURCES = radial-perf-test.c radial_perf_test_OBJECTS = radial-perf-test.$(OBJEXT) radial_perf_test_LDADD = $(LDADD) @@ -258,6 +287,12 @@ scaling_test_LDADD = $(LDADD) scaling_test_DEPENDENCIES = libutils.la \ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) +solid_test_SOURCES = solid-test.c +solid_test_OBJECTS = solid-test.$(OBJEXT) +solid_test_LDADD = $(LDADD) +solid_test_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) stress_test_SOURCES = stress-test.c stress_test_OBJECTS = stress-test.$(OBJEXT) stress_test_LDADD = $(LDADD) @@ -270,6 +305,12 @@ thread_test_LDADD = $(LDADD) thread_test_DEPENDENCIES = libutils.la \ $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) +tolerance_test_SOURCES = tolerance-test.c +tolerance_test_OBJECTS = tolerance-test.$(OBJEXT) +tolerance_test_LDADD = $(LDADD) +tolerance_test_DEPENDENCIES = libutils.la \ + $(top_builddir)/pixman/libpixman-1.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) trap_crasher_SOURCES = trap-crasher.c trap_crasher_OBJECTS = trap-crasher.$(OBJEXT) trap_crasher_LDADD = $(LDADD) @@ -310,26 +351,30 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-test.c \ - alpha-loop.c alphamap.c blitters-test.c check-formats.c \ - combiner-test.c composite.c composite-traps-test.c \ +SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-bench.c \ + affine-test.c alpha-loop.c alphamap.c blitters-test.c \ + check-formats.c combiner-test.c composite.c \ + composite-traps-test.c cover-test.c fence-image-self-test.c \ fetch-test.c glyph-test.c gradient-crash-test.c \ infinite-loop.c lowlevel-blt-bench.c matrix-test.c oob-test.c \ - pdf-op-test.c pixel-test.c prng-test.c radial-perf-test.c \ - region-contains-test.c region-test.c region-translate-test.c \ - rotate-test.c scaling-bench.c scaling-crash-test.c \ - scaling-helpers-test.c scaling-test.c stress-test.c \ - thread-test.c trap-crasher.c -DIST_SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-test.c \ - alpha-loop.c alphamap.c blitters-test.c check-formats.c \ - combiner-test.c composite.c composite-traps-test.c \ + pdf-op-test.c pixel-test.c prng-test.c radial-invalid.c \ + radial-perf-test.c region-contains-test.c region-test.c \ + region-translate-test.c rotate-test.c scaling-bench.c \ + scaling-crash-test.c scaling-helpers-test.c scaling-test.c \ + solid-test.c stress-test.c thread-test.c tolerance-test.c \ + trap-crasher.c +DIST_SOURCES = $(libutils_la_SOURCES) a1-trap-test.c affine-bench.c \ + affine-test.c alpha-loop.c alphamap.c blitters-test.c \ + check-formats.c combiner-test.c composite.c \ + composite-traps-test.c cover-test.c fence-image-self-test.c \ fetch-test.c glyph-test.c gradient-crash-test.c \ infinite-loop.c lowlevel-blt-bench.c matrix-test.c oob-test.c \ - pdf-op-test.c pixel-test.c prng-test.c radial-perf-test.c \ - region-contains-test.c region-test.c region-translate-test.c \ - rotate-test.c scaling-bench.c scaling-crash-test.c \ - scaling-helpers-test.c scaling-test.c stress-test.c \ - thread-test.c trap-crasher.c + pdf-op-test.c pixel-test.c prng-test.c radial-invalid.c \ + radial-perf-test.c region-contains-test.c region-test.c \ + region-translate-test.c rotate-test.c scaling-bench.c \ + scaling-crash-test.c scaling-helpers-test.c scaling-test.c \ + solid-test.c stress-test.c thread-test.c tolerance-test.c \ + trap-crasher.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -491,33 +536,38 @@ top_srcdir = @top_srcdir@ # Tests (sorted by expected completion time) TESTPROGRAMS = \ - prng-test \ - a1-trap-test \ - pdf-op-test \ - region-test \ - region-translate-test \ - combiner-test \ - pixel-test \ - fetch-test \ - rotate-test \ - oob-test \ - infinite-loop \ - trap-crasher \ - alpha-loop \ - thread-test \ - scaling-crash-test \ - scaling-helpers-test \ - gradient-crash-test \ - region-contains-test \ - alphamap \ - matrix-test \ - stress-test \ - composite-traps-test \ - blitters-test \ - glyph-test \ - scaling-test \ - affine-test \ - composite \ + oob-test \ + infinite-loop \ + trap-crasher \ + fence-image-self-test \ + region-translate-test \ + fetch-test \ + a1-trap-test \ + prng-test \ + radial-invalid \ + pdf-op-test \ + region-test \ + combiner-test \ + scaling-crash-test \ + alpha-loop \ + scaling-helpers-test \ + thread-test \ + rotate-test \ + alphamap \ + gradient-crash-test \ + pixel-test \ + matrix-test \ + composite-traps-test \ + region-contains-test \ + glyph-test \ + solid-test \ + stress-test \ + cover-test \ + blitters-test \ + affine-test \ + scaling-test \ + composite \ + tolerance-test \ $(NULL) @@ -527,6 +577,7 @@ OTHERPROGRAMS = \ radial-perf-test \ check-formats \ scaling-bench \ + affine-bench \ $(NULL) @@ -607,6 +658,9 @@ clean-noinstPROGRAMS: a1-trap-test$(EXEEXT): $(a1_trap_test_OBJECTS) $(a1_trap_test_DEPENDENCIES) $(EXTRA_a1_trap_test_DEPENDENCIES) @rm -f a1-trap-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(a1_trap_test_OBJECTS) $(a1_trap_test_LDADD) $(LIBS) +affine-bench$(EXEEXT): $(affine_bench_OBJECTS) $(affine_bench_DEPENDENCIES) $(EXTRA_affine_bench_DEPENDENCIES) + @rm -f affine-bench$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(affine_bench_OBJECTS) $(affine_bench_LDADD) $(LIBS) affine-test$(EXEEXT): $(affine_test_OBJECTS) $(affine_test_DEPENDENCIES) $(EXTRA_affine_test_DEPENDENCIES) @rm -f affine-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(affine_test_OBJECTS) $(affine_test_LDADD) $(LIBS) @@ -631,6 +685,12 @@ composite$(EXEEXT): $(composite_OBJECTS) $(composite_DEPENDENCIES) $(EXTRA_compo composite-traps-test$(EXEEXT): $(composite_traps_test_OBJECTS) $(composite_traps_test_DEPENDENCIES) $(EXTRA_composite_traps_test_DEPENDENCIES) @rm -f composite-traps-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(composite_traps_test_OBJECTS) $(composite_traps_test_LDADD) $(LIBS) +cover-test$(EXEEXT): $(cover_test_OBJECTS) $(cover_test_DEPENDENCIES) $(EXTRA_cover_test_DEPENDENCIES) + @rm -f cover-test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(cover_test_OBJECTS) $(cover_test_LDADD) $(LIBS) +fence-image-self-test$(EXEEXT): $(fence_image_self_test_OBJECTS) $(fence_image_self_test_DEPENDENCIES) $(EXTRA_fence_image_self_test_DEPENDENCIES) + @rm -f fence-image-self-test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fence_image_self_test_OBJECTS) $(fence_image_self_test_LDADD) $(LIBS) fetch-test$(EXEEXT): $(fetch_test_OBJECTS) $(fetch_test_DEPENDENCIES) $(EXTRA_fetch_test_DEPENDENCIES) @rm -f fetch-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fetch_test_OBJECTS) $(fetch_test_LDADD) $(LIBS) @@ -661,6 +721,9 @@ pixel-test$(EXEEXT): $(pixel_test_OBJECTS) $(pixel_test_DEPENDENCIES) $(EXTRA_pi prng-test$(EXEEXT): $(prng_test_OBJECTS) $(prng_test_DEPENDENCIES) $(EXTRA_prng_test_DEPENDENCIES) @rm -f prng-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(prng_test_OBJECTS) $(prng_test_LDADD) $(LIBS) +radial-invalid$(EXEEXT): $(radial_invalid_OBJECTS) $(radial_invalid_DEPENDENCIES) $(EXTRA_radial_invalid_DEPENDENCIES) + @rm -f radial-invalid$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(radial_invalid_OBJECTS) $(radial_invalid_LDADD) $(LIBS) radial-perf-test$(EXEEXT): $(radial_perf_test_OBJECTS) $(radial_perf_test_DEPENDENCIES) $(EXTRA_radial_perf_test_DEPENDENCIES) @rm -f radial-perf-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(radial_perf_test_OBJECTS) $(radial_perf_test_LDADD) $(LIBS) @@ -688,12 +751,18 @@ scaling-helpers-test$(EXEEXT): $(scaling_helpers_test_OBJECTS) $(scaling_helpers scaling-test$(EXEEXT): $(scaling_test_OBJECTS) $(scaling_test_DEPENDENCIES) $(EXTRA_scaling_test_DEPENDENCIES) @rm -f scaling-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(scaling_test_OBJECTS) $(scaling_test_LDADD) $(LIBS) +solid-test$(EXEEXT): $(solid_test_OBJECTS) $(solid_test_DEPENDENCIES) $(EXTRA_solid_test_DEPENDENCIES) + @rm -f solid-test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(solid_test_OBJECTS) $(solid_test_LDADD) $(LIBS) stress-test$(EXEEXT): $(stress_test_OBJECTS) $(stress_test_DEPENDENCIES) $(EXTRA_stress_test_DEPENDENCIES) @rm -f stress-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(stress_test_OBJECTS) $(stress_test_LDADD) $(LIBS) thread-test$(EXEEXT): $(thread_test_OBJECTS) $(thread_test_DEPENDENCIES) $(EXTRA_thread_test_DEPENDENCIES) @rm -f thread-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(thread_test_OBJECTS) $(thread_test_LDADD) $(LIBS) +tolerance-test$(EXEEXT): $(tolerance_test_OBJECTS) $(tolerance_test_DEPENDENCIES) $(EXTRA_tolerance_test_DEPENDENCIES) + @rm -f tolerance-test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tolerance_test_OBJECTS) $(tolerance_test_LDADD) $(LIBS) trap-crasher$(EXEEXT): $(trap_crasher_OBJECTS) $(trap_crasher_DEPENDENCIES) $(EXTRA_trap_crasher_DEPENDENCIES) @rm -f trap-crasher$(EXEEXT) $(AM_V_CCLD)$(LINK) $(trap_crasher_OBJECTS) $(trap_crasher_LDADD) $(LIBS) @@ -705,6 +774,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a1-trap-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affine-bench.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affine-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha-loop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alphamap.Po@am__quote@ @@ -713,6 +783,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/combiner-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/composite-traps-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/composite.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cover-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fence-image-self-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyph-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gradient-crash-test.Po@am__quote@ @@ -723,6 +795,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdf-op-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixel-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prng-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radial-invalid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radial-perf-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region-contains-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region-test.Po@am__quote@ @@ -732,8 +805,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scaling-crash-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scaling-helpers-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scaling-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solid-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stress-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tolerance-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trap-crasher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils-prng.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ diff --git a/lib/pixman/test/Makefile.sources b/lib/pixman/test/Makefile.sources index 2ae5d9f8d..5d55e676a 100644 --- a/lib/pixman/test/Makefile.sources +++ b/lib/pixman/test/Makefile.sources @@ -1,32 +1,37 @@ # Tests (sorted by expected completion time) -TESTPROGRAMS = \ - prng-test \ - a1-trap-test \ - pdf-op-test \ - region-test \ - region-translate-test \ - combiner-test \ - pixel-test \ - fetch-test \ - rotate-test \ - oob-test \ - infinite-loop \ - trap-crasher \ - alpha-loop \ - thread-test \ - scaling-crash-test \ - scaling-helpers-test \ - gradient-crash-test \ - region-contains-test \ - alphamap \ - matrix-test \ - stress-test \ - composite-traps-test \ - blitters-test \ - glyph-test \ - scaling-test \ - affine-test \ - composite \ +TESTPROGRAMS = \ + oob-test \ + infinite-loop \ + trap-crasher \ + fence-image-self-test \ + region-translate-test \ + fetch-test \ + a1-trap-test \ + prng-test \ + radial-invalid \ + pdf-op-test \ + region-test \ + combiner-test \ + scaling-crash-test \ + alpha-loop \ + scaling-helpers-test \ + thread-test \ + rotate-test \ + alphamap \ + gradient-crash-test \ + pixel-test \ + matrix-test \ + composite-traps-test \ + region-contains-test \ + glyph-test \ + solid-test \ + stress-test \ + cover-test \ + blitters-test \ + affine-test \ + scaling-test \ + composite \ + tolerance-test \ $(NULL) # Other programs @@ -35,6 +40,7 @@ OTHERPROGRAMS = \ radial-perf-test \ check-formats \ scaling-bench \ + affine-bench \ $(NULL) # Utility functions diff --git a/lib/pixman/test/affine-bench.c b/lib/pixman/test/affine-bench.c new file mode 100644 index 000000000..86bf46ef7 --- /dev/null +++ b/lib/pixman/test/affine-bench.c @@ -0,0 +1,448 @@ +/* + * Copyright © 2014 RISC OS Open Ltd + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holders make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Ben Avison (bavison@riscosopen.org) + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdint.h> +#include "utils.h" + +#ifdef HAVE_GETTIMEOFDAY +#include <sys/time.h> +#else +#include <time.h> +#endif + +#define WIDTH 1920 +#define HEIGHT 1080 + +/* How much data to read to flush all cached data to RAM */ +#define MAX_L2CACHE_SIZE (8 * 1024 * 1024) + +#define PAGE_SIZE (4 * 1024) + +struct bench_info +{ + pixman_op_t op; + pixman_transform_t transform; + pixman_image_t *src_image; + pixman_image_t *mask_image; + pixman_image_t *dest_image; + int32_t src_x; + int32_t src_y; +}; + +typedef struct bench_info bench_info_t; + +struct box_48_16 +{ + pixman_fixed_48_16_t x1; + pixman_fixed_48_16_t y1; + pixman_fixed_48_16_t x2; + pixman_fixed_48_16_t y2; +}; + +typedef struct box_48_16 box_48_16_t; + +/* This function is copied verbatim from pixman.c. */ +static pixman_bool_t +compute_transformed_extents (pixman_transform_t *transform, + const pixman_box32_t *extents, + box_48_16_t *transformed) +{ + pixman_fixed_48_16_t tx1, ty1, tx2, ty2; + pixman_fixed_t x1, y1, x2, y2; + int i; + + x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2; + y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2; + x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2; + y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2; + + if (!transform) + { + transformed->x1 = x1; + transformed->y1 = y1; + transformed->x2 = x2; + transformed->y2 = y2; + + return TRUE; + } + + tx1 = ty1 = INT64_MAX; + tx2 = ty2 = INT64_MIN; + + for (i = 0; i < 4; ++i) + { + pixman_fixed_48_16_t tx, ty; + pixman_vector_t v; + + v.vector[0] = (i & 0x01)? x1 : x2; + v.vector[1] = (i & 0x02)? y1 : y2; + v.vector[2] = pixman_fixed_1; + + if (!pixman_transform_point (transform, &v)) + return FALSE; + + tx = (pixman_fixed_48_16_t)v.vector[0]; + ty = (pixman_fixed_48_16_t)v.vector[1]; + + if (tx < tx1) + tx1 = tx; + if (ty < ty1) + ty1 = ty; + if (tx > tx2) + tx2 = tx; + if (ty > ty2) + ty2 = ty; + } + + transformed->x1 = tx1; + transformed->y1 = ty1; + transformed->x2 = tx2; + transformed->y2 = ty2; + + return TRUE; +} + +static void +create_image (uint32_t width, + uint32_t height, + pixman_format_code_t format, + pixman_filter_t filter, + uint32_t **bits, + pixman_image_t **image) +{ + uint32_t stride = (width * PIXMAN_FORMAT_BPP (format) + 31) / 32 * 4; + + *bits = aligned_malloc (PAGE_SIZE, stride * height); + memset (*bits, 0xCC, stride * height); + *image = pixman_image_create_bits (format, width, height, *bits, stride); + pixman_image_set_repeat (*image, PIXMAN_REPEAT_NORMAL); + pixman_image_set_filter (*image, filter, NULL, 0); +} + +/* This needs to match the shortest cacheline length we expect to encounter */ +#define CACHE_CLEAN_INCREMENT 32 + +static void +flush_cache (void) +{ + static const char clean_space[MAX_L2CACHE_SIZE]; + volatile const char *x = clean_space; + const char *clean_end = clean_space + sizeof clean_space; + + while (x < clean_end) + { + (void) *x; + x += CACHE_CLEAN_INCREMENT; + } +} + +/* Obtain current time in microseconds modulo 2^32 */ +uint32_t +gettimei (void) +{ +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + + gettimeofday (&tv, NULL); + return tv.tv_sec * 1000000 + tv.tv_usec; +#else + return (uint64_t) clock () * 1000000 / CLOCKS_PER_SEC; +#endif +} + +static void +pixman_image_composite_wrapper (const pixman_composite_info_t *info) +{ + pixman_image_composite (info->op, + info->src_image, info->mask_image, info->dest_image, + info->src_x, info->src_y, + info->mask_x, info->mask_y, + info->dest_x, info->dest_y, + info->width, info->height); +} + +static void +pixman_image_composite_empty (const pixman_composite_info_t *info) +{ + pixman_image_composite (info->op, + info->src_image, info->mask_image, info->dest_image, + info->src_x, info->src_y, + info->mask_x, info->mask_y, + info->dest_x, info->dest_y, + 1, 1); +} + +static void +bench (const bench_info_t *bi, + uint32_t max_n, + uint32_t max_time, + uint32_t *ret_n, + uint32_t *ret_time, + void (*func) (const pixman_composite_info_t *info)) +{ + uint32_t n = 0; + uint32_t t0; + uint32_t t1; + uint32_t x = 0; + pixman_transform_t t; + pixman_composite_info_t info; + + t = bi->transform; + info.op = bi->op; + info.src_image = bi->src_image; + info.mask_image = bi->mask_image; + info.dest_image = bi->dest_image; + info.src_x = 0; + info.src_y = 0; + info.mask_x = 0; + info.mask_y = 0; + /* info.dest_x set below */ + info.dest_y = 0; + info.width = WIDTH; + info.height = HEIGHT; + + t0 = gettimei (); + + do + { + + if (++x >= 64) + x = 0; + + info.dest_x = 63 - x; + + t.matrix[0][2] = pixman_int_to_fixed (bi->src_x + x); + t.matrix[1][2] = pixman_int_to_fixed (bi->src_y); + pixman_image_set_transform (bi->src_image, &t); + + if (bi->mask_image) + pixman_image_set_transform (bi->mask_image, &t); + + func (&info); + t1 = gettimei (); + } + while (++n < max_n && (t1 - t0) < max_time); + + if (ret_n) + *ret_n = n; + + *ret_time = t1 - t0; +} + +int +parse_fixed_argument (char *arg, pixman_fixed_t *value) +{ + char *tailptr; + + *value = pixman_double_to_fixed (strtod (arg, &tailptr)); + + return *tailptr == '\0'; +} + +int +parse_arguments (int argc, + char *argv[], + pixman_transform_t *t, + pixman_op_t *op, + pixman_format_code_t *src_format, + pixman_format_code_t *mask_format, + pixman_format_code_t *dest_format) +{ + if (!parse_fixed_argument (*argv, &t->matrix[0][0])) + return 0; + + if (*++argv == NULL) + return 1; + + if (!parse_fixed_argument (*argv, &t->matrix[0][1])) + return 0; + + if (*++argv == NULL) + return 1; + + if (!parse_fixed_argument (*argv, &t->matrix[1][0])) + return 0; + + if (*++argv == NULL) + return 1; + + if (!parse_fixed_argument (*argv, &t->matrix[1][1])) + return 0; + + if (*++argv == NULL) + return 1; + + *op = operator_from_string (*argv); + if (*op == PIXMAN_OP_NONE) + return 0; + + if (*++argv == NULL) + return 1; + + *src_format = format_from_string (*argv); + if (*src_format == PIXMAN_null) + return 0; + + ++argv; + if (argv[0] && argv[1]) + { + *mask_format = format_from_string (*argv); + if (*mask_format == PIXMAN_null) + return 0; + ++argv; + } + if (*argv) + { + *dest_format = format_from_string (*argv); + if (*dest_format == PIXMAN_null) + return 0; + } + return 1; +} + +static void +run_benchmark (const bench_info_t *bi) +{ + uint32_t n; /* number of iterations in at least 5 seconds */ + uint32_t t1; /* time taken to do n iterations, microseconds */ + uint32_t t2; /* calling overhead for n iterations, microseconds */ + + flush_cache (); + bench (bi, UINT32_MAX, 5000000, &n, &t1, pixman_image_composite_wrapper); + bench (bi, n, UINT32_MAX, NULL, &t2, pixman_image_composite_empty); + + /* The result indicates the output rate in megapixels/second */ + printf ("%6.2f\n", (double) n * WIDTH * HEIGHT / (t1 - t2)); +} + + +int +main (int argc, char *argv[]) +{ + bench_info_t binfo; + pixman_filter_t filter = PIXMAN_FILTER_NEAREST; + pixman_format_code_t src_format = PIXMAN_a8r8g8b8; + pixman_format_code_t mask_format = 0; + pixman_format_code_t dest_format = PIXMAN_a8r8g8b8; + pixman_box32_t dest_box = { 0, 0, WIDTH, HEIGHT }; + box_48_16_t transformed = { 0 }; + int32_t xmin, ymin, xmax, ymax; + uint32_t *src, *mask, *dest; + + binfo.op = PIXMAN_OP_SRC; + binfo.mask_image = NULL; + pixman_transform_init_identity (&binfo.transform); + + ++argv; + if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'n') + { + filter = PIXMAN_FILTER_NEAREST; + ++argv; + --argc; + } + + if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'b') + { + filter = PIXMAN_FILTER_BILINEAR; + ++argv; + --argc; + } + + if (argc == 1 || + !parse_arguments (argc, argv, &binfo.transform, &binfo.op, + &src_format, &mask_format, &dest_format)) + { + printf ("Usage: affine-bench [-n] [-b] axx [axy] [ayx] [ayy] [combine type]\n"); + printf (" [src format] [mask format] [dest format]\n"); + printf (" -n : nearest scaling (default)\n"); + printf (" -b : bilinear scaling\n"); + printf (" axx : x_out:x_in factor\n"); + printf (" axy : x_out:y_in factor (default 0)\n"); + printf (" ayx : y_out:x_in factor (default 0)\n"); + printf (" ayy : y_out:y_in factor (default 1)\n"); + printf (" combine type : src, over, in etc (default src)\n"); + printf (" src format : a8r8g8b8, r5g6b5 etc (default a8r8g8b8)\n"); + printf (" mask format : as for src format, but no mask used if omitted\n"); + printf (" dest format : as for src format (default a8r8g8b8)\n"); + printf ("The output is a single number in megapixels/second.\n"); + + return EXIT_FAILURE; + } + + /* Compute required extents for source and mask image so they qualify + * for COVER fast paths and get the flags in pixman.c:analyze_extent(). + * These computations are for FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, + * but at the same time they also allow COVER_CLIP_NEAREST. + */ + compute_transformed_extents (&binfo.transform, &dest_box, &transformed); + xmin = pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2); + ymin = pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2); + xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2); + ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2); + /* Note: + * The upper limits can be reduced to the following when fetchers + * are guaranteed to not access pixels with zero weight. This concerns + * particularly all bilinear samplers. + * + * xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e); + * ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e); + * This is equivalent to subtracting 0.5 and rounding up, rather than + * subtracting 0.5, rounding down and adding 1. + */ + binfo.src_x = -xmin; + binfo.src_y = -ymin; + + /* Always over-allocate width by 64 pixels for all src, mask and dst, + * so that we can iterate over an x-offset 0..63 in bench (). + * This is similar to lowlevel-blt-bench, which uses the same method + * to hit different cacheline misalignments. + */ + create_image (xmax - xmin + 64, ymax - ymin + 1, src_format, filter, + &src, &binfo.src_image); + + if (mask_format) + { + create_image (xmax - xmin + 64, ymax - ymin + 1, mask_format, filter, + &mask, &binfo.mask_image); + + if ((PIXMAN_FORMAT_R(mask_format) || + PIXMAN_FORMAT_G(mask_format) || + PIXMAN_FORMAT_B(mask_format))) + { + pixman_image_set_component_alpha (binfo.mask_image, 1); + } + } + + create_image (WIDTH + 64, HEIGHT, dest_format, filter, + &dest, &binfo.dest_image); + + run_benchmark (&binfo); + + return EXIT_SUCCESS; +} diff --git a/lib/pixman/test/blitters-test.c b/lib/pixman/test/blitters-test.c index ea03f475d..026f4b006 100644 --- a/lib/pixman/test/blitters-test.c +++ b/lib/pixman/test/blitters-test.c @@ -122,6 +122,15 @@ static pixman_op_t op_list[] = { PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_XOR, PIXMAN_OP_ADD, + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, +#if 0 /* these use floating point math and are not always bitexact on different platforms */ PIXMAN_OP_SATURATE, PIXMAN_OP_DISJOINT_CLEAR, PIXMAN_OP_DISJOINT_SRC, @@ -147,17 +156,8 @@ static pixman_op_t op_list[] = { PIXMAN_OP_CONJOINT_ATOP, PIXMAN_OP_CONJOINT_ATOP_REVERSE, PIXMAN_OP_CONJOINT_XOR, - PIXMAN_OP_MULTIPLY, - PIXMAN_OP_SCREEN, - PIXMAN_OP_OVERLAY, - PIXMAN_OP_DARKEN, - PIXMAN_OP_LIGHTEN, PIXMAN_OP_COLOR_DODGE, PIXMAN_OP_COLOR_BURN, - PIXMAN_OP_HARD_LIGHT, - PIXMAN_OP_DIFFERENCE, - PIXMAN_OP_EXCLUSION, -#if 0 /* these use floating point math and are not always bitexact on different platforms */ PIXMAN_OP_SOFT_LIGHT, PIXMAN_OP_HSL_HUE, PIXMAN_OP_HSL_SATURATION, @@ -394,6 +394,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main("blitters", 2000000, - 0xE0A07495, + 0xCC21DDF0, test_composite, argc, argv); } diff --git a/lib/pixman/test/check-formats.c b/lib/pixman/test/check-formats.c index 7edc198c1..4e2633c41 100644 --- a/lib/pixman/test/check-formats.c +++ b/lib/pixman/test/check-formats.c @@ -104,182 +104,6 @@ check_op (pixman_op_t op, return retval; } -static const pixman_op_t op_list[] = -{ - PIXMAN_OP_CLEAR, - PIXMAN_OP_SRC, - PIXMAN_OP_DST, - PIXMAN_OP_OVER, - PIXMAN_OP_OVER_REVERSE, - PIXMAN_OP_IN, - PIXMAN_OP_IN_REVERSE, - PIXMAN_OP_OUT, - PIXMAN_OP_OUT_REVERSE, - PIXMAN_OP_ATOP, - PIXMAN_OP_ATOP_REVERSE, - PIXMAN_OP_XOR, - PIXMAN_OP_ADD, - PIXMAN_OP_SATURATE, - - PIXMAN_OP_DISJOINT_CLEAR, - PIXMAN_OP_DISJOINT_SRC, - PIXMAN_OP_DISJOINT_DST, - PIXMAN_OP_DISJOINT_OVER, - PIXMAN_OP_DISJOINT_OVER_REVERSE, - PIXMAN_OP_DISJOINT_IN, - PIXMAN_OP_DISJOINT_IN_REVERSE, - PIXMAN_OP_DISJOINT_OUT, - PIXMAN_OP_DISJOINT_OUT_REVERSE, - PIXMAN_OP_DISJOINT_ATOP, - PIXMAN_OP_DISJOINT_ATOP_REVERSE, - PIXMAN_OP_DISJOINT_XOR, - - PIXMAN_OP_CONJOINT_CLEAR, - PIXMAN_OP_CONJOINT_SRC, - PIXMAN_OP_CONJOINT_DST, - PIXMAN_OP_CONJOINT_OVER, - PIXMAN_OP_CONJOINT_OVER_REVERSE, - PIXMAN_OP_CONJOINT_IN, - PIXMAN_OP_CONJOINT_IN_REVERSE, - PIXMAN_OP_CONJOINT_OUT, - PIXMAN_OP_CONJOINT_OUT_REVERSE, - PIXMAN_OP_CONJOINT_ATOP, - PIXMAN_OP_CONJOINT_ATOP_REVERSE, - PIXMAN_OP_CONJOINT_XOR, -}; - -static const pixman_format_code_t format_list[] = -{ - PIXMAN_a8r8g8b8, - PIXMAN_x8r8g8b8, - PIXMAN_a8b8g8r8, - PIXMAN_x8b8g8r8, - PIXMAN_b8g8r8a8, - PIXMAN_b8g8r8x8, - PIXMAN_r8g8b8a8, - PIXMAN_r8g8b8x8, - PIXMAN_x14r6g6b6, - PIXMAN_x2r10g10b10, - PIXMAN_a2r10g10b10, - PIXMAN_x2b10g10r10, - PIXMAN_a2b10g10r10, - PIXMAN_a8r8g8b8_sRGB, - PIXMAN_r8g8b8, - PIXMAN_b8g8r8, - PIXMAN_r5g6b5, - PIXMAN_b5g6r5, - PIXMAN_a1r5g5b5, - PIXMAN_x1r5g5b5, - PIXMAN_a1b5g5r5, - PIXMAN_x1b5g5r5, - PIXMAN_a4r4g4b4, - PIXMAN_x4r4g4b4, - PIXMAN_a4b4g4r4, - PIXMAN_x4b4g4r4, - PIXMAN_a8, - PIXMAN_r3g3b2, - PIXMAN_b2g3r3, - PIXMAN_a2r2g2b2, - PIXMAN_a2b2g2r2, - PIXMAN_x4a4, - PIXMAN_a4, - PIXMAN_r1g2b1, - PIXMAN_b1g2r1, - PIXMAN_a1r1g1b1, - PIXMAN_a1b1g1r1, - PIXMAN_a1, -}; - -static pixman_format_code_t -format_from_string (const char *s) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH (format_list); ++i) - { - if (strcasecmp (format_name (format_list[i]), s) == 0) - return format_list[i]; - } - - return PIXMAN_null; -} - -static void -emit (const char *s, int *n_chars) -{ - *n_chars += printf ("%s,", s); - if (*n_chars > 60) - { - printf ("\n "); - *n_chars = 0; - } - else - { - printf (" "); - (*n_chars)++; - } -} - -static void -list_formats (void) -{ - int n_chars; - int i; - - printf ("Formats:\n "); - - n_chars = 0; - for (i = 0; i < ARRAY_LENGTH (format_list); ++i) - emit (format_name (format_list[i]), &n_chars); - - printf ("\n\n"); -} - -static void -list_operators (void) -{ - char short_name [128] = { 0 }; - int i, n_chars; - - printf ("Operators:\n "); - - n_chars = 0; - for (i = 0; i < ARRAY_LENGTH (op_list); ++i) - { - pixman_op_t op = op_list[i]; - int j; - - snprintf (short_name, sizeof (short_name) - 1, "%s", - operator_name (op) + strlen ("PIXMAN_OP_")); - - for (j = 0; short_name[j] != '\0'; ++j) - short_name[j] = tolower (short_name[j]); - - emit (short_name, &n_chars); - } - - printf ("\n\n"); -} - -static pixman_op_t -operator_from_string (const char *s) -{ - char full_name[128] = { 0 }; - int i; - - snprintf (full_name, (sizeof full_name) - 1, "PIXMAN_OP_%s", s); - - for (i = 0; i < ARRAY_LENGTH (op_list); ++i) - { - pixman_op_t op = op_list[i]; - - if (strcasecmp (operator_name (op), full_name) == 0) - return op; - } - - return PIXMAN_OP_NONE; -} - int main (int argc, char **argv) { diff --git a/lib/pixman/test/composite.c b/lib/pixman/test/composite.c index 9e51a8f65..594c69772 100644 --- a/lib/pixman/test/composite.c +++ b/lib/pixman/test/composite.c @@ -299,17 +299,6 @@ composite_test (image_t *dst, } } - if (mask) - { - if (component_alpha && PIXMAN_FORMAT_R (mask->format) == 0) - { - /* Ax component-alpha masks expand alpha into - * all color channels. - */ - tmsk.r = tmsk.g = tmsk.b = tmsk.a; - } - } - if (PIXMAN_FORMAT_TYPE (dst->format) == PIXMAN_TYPE_ARGB_SRGB) { tdst.r = convert_linear_to_srgb (tdst.r); diff --git a/lib/pixman/test/cover-test.c b/lib/pixman/test/cover-test.c new file mode 100644 index 000000000..83e2972d9 --- /dev/null +++ b/lib/pixman/test/cover-test.c @@ -0,0 +1,449 @@ +/* + * Copyright © 2015 RISC OS Open Ltd + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holders make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Ben Avison (bavison@riscosopen.org) + * + */ + +/* + * This test aims to verify both numerical correctness and the honouring of + * array bounds for scaled plots (both nearest-neighbour and bilinear) at or + * close to the boundary conditions for applicability of "cover" type fast paths + * and iter fetch routines. + * + * It has a secondary purpose: by setting the env var EXACT (to any value) it + * will only test plots that are exactly on the boundary condition. This makes + * it possible to ensure that "cover" routines are being used to the maximum, + * although this requires the use of a debugger or code instrumentation to + * verify. + */ + +#include "utils.h" +#include <stdlib.h> +#include <stdio.h> + +/* Approximate limits for random scale factor generation - these ensure we can + * get at least 8x reduction and 8x enlargement. + */ +#define LOG2_MAX_FACTOR (3) + +/* 1/sqrt(2) (or sqrt(0.5), or 2^-0.5) as a 0.32 fixed-point number */ +#define INV_SQRT_2_0POINT32_FIXED (0xB504F334u) + +/* The largest increment that can be generated by random_scale_factor(). + * This occurs when the "mantissa" part is 0xFFFFFFFF and the "exponent" + * part is -LOG2_MAX_FACTOR. + */ +#define MAX_INC ((pixman_fixed_t) \ + (INV_SQRT_2_0POINT32_FIXED >> (31 - 16 - LOG2_MAX_FACTOR))) + +/* Minimum source width (in pixels) based on a typical page size of 4K and + * maximum colour depth of 32bpp. + */ +#define MIN_SRC_WIDTH (4096 / 4) + +/* Derive the destination width so that at max increment we fit within source */ +#define DST_WIDTH (MIN_SRC_WIDTH * pixman_fixed_1 / MAX_INC) + +/* Calculate heights the other way round. + * No limits due to page alignment here. + */ +#define DST_HEIGHT 3 +#define SRC_HEIGHT ((DST_HEIGHT * MAX_INC + pixman_fixed_1 - 1) / pixman_fixed_1) + +/* At the time of writing, all the scaled fast paths use SRC, OVER or ADD + * Porter-Duff operators. XOR is included in the list to ensure good + * representation of iter scanline fetch routines. + */ +static const pixman_op_t op_list[] = { + PIXMAN_OP_SRC, + PIXMAN_OP_OVER, + PIXMAN_OP_ADD, + PIXMAN_OP_XOR, +}; + +/* At the time of writing, all the scaled fast paths use a8r8g8b8, x8r8g8b8 + * or r5g6b5, or red-blue swapped versions of the same. When a mask channel is + * used, it is always a8 (and so implicitly not component alpha). a1r5g5b5 is + * included because it is the only other format to feature in any iters. */ +static const pixman_format_code_t img_fmt_list[] = { + PIXMAN_a8r8g8b8, + PIXMAN_x8r8g8b8, + PIXMAN_r5g6b5, + PIXMAN_a1r5g5b5 +}; + +/* This is a flag reflecting the environment variable EXACT. It can be used + * to ensure that source coordinates corresponding exactly to the "cover" limits + * are used, rather than any "near misses". This can, for example, be used in + * conjunction with a debugger to ensure that only COVER fast paths are used. + */ +static int exact; + +static pixman_image_t * +create_src_image (pixman_format_code_t fmt) +{ + pixman_image_t *tmp_img, *img; + + /* We need the left-most and right-most MIN_SRC_WIDTH pixels to have + * predictable values, even though fence_image_create_bits() may allocate + * an image somewhat larger than that, by an amount that varies depending + * upon the page size on the current platform. The solution is to create a + * temporary non-fenced image that is exactly MIN_SRC_WIDTH wide and blit it + * into the fenced image. + */ + tmp_img = pixman_image_create_bits (fmt, MIN_SRC_WIDTH, SRC_HEIGHT, + NULL, 0); + if (tmp_img == NULL) + return NULL; + + img = fence_image_create_bits (fmt, MIN_SRC_WIDTH, SRC_HEIGHT, TRUE); + if (img == NULL) + { + pixman_image_unref (tmp_img); + return NULL; + } + + prng_randmemset (tmp_img->bits.bits, + tmp_img->bits.rowstride * SRC_HEIGHT * sizeof (uint32_t), + 0); + image_endian_swap (tmp_img); + + pixman_image_composite (PIXMAN_OP_SRC, tmp_img, NULL, img, + 0, 0, 0, 0, 0, 0, + MIN_SRC_WIDTH, SRC_HEIGHT); + pixman_image_composite (PIXMAN_OP_SRC, tmp_img, NULL, img, + 0, 0, 0, 0, img->bits.width - MIN_SRC_WIDTH, 0, + MIN_SRC_WIDTH, SRC_HEIGHT); + + pixman_image_unref (tmp_img); + + return img; +} + +static pixman_fixed_t +random_scale_factor(void) +{ + /* Get a random number with top bit set. */ + uint32_t f = prng_rand () | 0x80000000u; + + /* In log(2) space, this is still approximately evenly spread between 31 + * and 32. Divide by sqrt(2) to centre the distribution on 2^31. + */ + f = ((uint64_t) f * INV_SQRT_2_0POINT32_FIXED) >> 32; + + /* Now shift right (ie divide by an integer power of 2) to spread the + * distribution between centres at 2^(16 +/- LOG2_MAX_FACTOR). + */ + f >>= 31 - 16 + prng_rand_n (2 * LOG2_MAX_FACTOR + 1) - LOG2_MAX_FACTOR; + + return f; +} + +static pixman_fixed_t +calc_translate (int dst_size, + int src_size, + pixman_fixed_t scale, + pixman_bool_t low_align, + pixman_bool_t bilinear) +{ + pixman_fixed_t ref_src, ref_dst, scaled_dst; + + if (low_align) + { + ref_src = bilinear ? pixman_fixed_1 / 2 : pixman_fixed_e; + ref_dst = pixman_fixed_1 / 2; + } + else + { + ref_src = pixman_int_to_fixed (src_size) - + bilinear * pixman_fixed_1 / 2; + ref_dst = pixman_int_to_fixed (dst_size) - pixman_fixed_1 / 2; + } + + scaled_dst = ((uint64_t) ref_dst * scale + pixman_fixed_1 / 2) / + pixman_fixed_1; + + /* We need the translation to be set such that when ref_dst is fed through + * the transformation matrix, we get ref_src as the result. + */ + return ref_src - scaled_dst; +} + +static pixman_fixed_t +random_offset (void) +{ + pixman_fixed_t offset = 0; + + /* Ensure we test the exact case quite a lot */ + if (prng_rand_n (2)) + return offset; + + /* What happens when we are close to the edge of the first + * interpolation step? + */ + if (prng_rand_n (2)) + offset += (pixman_fixed_1 >> BILINEAR_INTERPOLATION_BITS) - 16; + + /* Try fine-grained variations */ + offset += prng_rand_n (32); + + /* Test in both directions */ + if (prng_rand_n (2)) + offset = -offset; + + return offset; +} + +static void +check_transform (pixman_image_t *dst_img, + pixman_image_t *src_img, + pixman_transform_t *transform, + pixman_bool_t bilinear) +{ + pixman_vector_t v1, v2; + + v1.vector[0] = pixman_fixed_1 / 2; + v1.vector[1] = pixman_fixed_1 / 2; + v1.vector[2] = pixman_fixed_1; + assert (pixman_transform_point (transform, &v1)); + + v2.vector[0] = pixman_int_to_fixed (dst_img->bits.width) - + pixman_fixed_1 / 2; + v2.vector[1] = pixman_int_to_fixed (dst_img->bits.height) - + pixman_fixed_1 / 2; + v2.vector[2] = pixman_fixed_1; + assert (pixman_transform_point (transform, &v2)); + + if (bilinear) + { + assert (v1.vector[0] >= pixman_fixed_1 / 2); + assert (v1.vector[1] >= pixman_fixed_1 / 2); + assert (v2.vector[0] <= pixman_int_to_fixed (src_img->bits.width) - + pixman_fixed_1 / 2); + assert (v2.vector[1] <= pixman_int_to_fixed (src_img->bits.height) - + pixman_fixed_1 / 2); + } + else + { + assert (v1.vector[0] >= pixman_fixed_e); + assert (v1.vector[1] >= pixman_fixed_e); + assert (v2.vector[0] <= pixman_int_to_fixed (src_img->bits.width)); + assert (v2.vector[1] <= pixman_int_to_fixed (src_img->bits.height)); + } +} + +static uint32_t +test_cover (int testnum, int verbose) +{ + pixman_fixed_t x_scale, y_scale; + pixman_bool_t left_align, top_align; + pixman_bool_t bilinear; + pixman_filter_t filter; + pixman_op_t op; + size_t src_fmt_index; + pixman_format_code_t src_fmt, dst_fmt, mask_fmt; + pixman_image_t *src_img, *dst_img, *mask_img; + pixman_transform_t src_transform, mask_transform; + pixman_fixed_t fuzz[4]; + uint32_t crc32; + + /* We allocate one fenced image for each pixel format up-front. This is to + * avoid spending a lot of time on memory management rather than on testing + * Pixman optimisations. We need one per thread because the transformation + * matrices and filtering are properties of the source and mask images. + */ + static pixman_image_t *src_imgs[ARRAY_LENGTH (img_fmt_list)]; + static pixman_image_t *mask_bits_img; + static pixman_bool_t fence_images_created; +#ifdef USE_OPENMP +#pragma omp threadprivate (src_imgs) +#pragma omp threadprivate (mask_bits_img) +#pragma omp threadprivate (fence_images_created) +#endif + + if (!fence_images_created) + { + int i; + + prng_srand (0); + + for (i = 0; i < ARRAY_LENGTH (img_fmt_list); i++) + src_imgs[i] = create_src_image (img_fmt_list[i]); + + mask_bits_img = create_src_image (PIXMAN_a8); + + fence_images_created = TRUE; + } + + prng_srand (testnum); + + x_scale = random_scale_factor (); + y_scale = random_scale_factor (); + left_align = prng_rand_n (2); + top_align = prng_rand_n (2); + bilinear = prng_rand_n (2); + filter = bilinear ? PIXMAN_FILTER_BILINEAR : PIXMAN_FILTER_NEAREST; + + op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; + + dst_fmt = img_fmt_list[prng_rand_n (ARRAY_LENGTH (img_fmt_list))]; + dst_img = pixman_image_create_bits (dst_fmt, DST_WIDTH, DST_HEIGHT, + NULL, 0); + prng_randmemset (dst_img->bits.bits, + dst_img->bits.rowstride * DST_HEIGHT * sizeof (uint32_t), + 0); + image_endian_swap (dst_img); + + src_fmt_index = prng_rand_n (ARRAY_LENGTH (img_fmt_list)); + src_fmt = img_fmt_list[src_fmt_index]; + src_img = src_imgs[src_fmt_index]; + pixman_image_set_filter (src_img, filter, NULL, 0); + pixman_transform_init_scale (&src_transform, x_scale, y_scale); + src_transform.matrix[0][2] = calc_translate (dst_img->bits.width, + src_img->bits.width, + x_scale, left_align, bilinear); + src_transform.matrix[1][2] = calc_translate (dst_img->bits.height, + src_img->bits.height, + y_scale, top_align, bilinear); + + if (prng_rand_n (2)) + { + /* No mask */ + mask_fmt = PIXMAN_null; + mask_img = NULL; + } + else if (prng_rand_n (2)) + { + /* a8 bitmap mask */ + mask_fmt = PIXMAN_a8; + mask_img = mask_bits_img; + pixman_image_set_filter (mask_img, filter, NULL, 0); + pixman_transform_init_scale (&mask_transform, x_scale, y_scale); + mask_transform.matrix[0][2] = calc_translate (dst_img->bits.width, + mask_img->bits.width, + x_scale, left_align, + bilinear); + mask_transform.matrix[1][2] = calc_translate (dst_img->bits.height, + mask_img->bits.height, + y_scale, top_align, + bilinear); + } + else + { + /* Solid mask */ + pixman_color_t color; + memset (&color, 0xAA, sizeof color); + mask_fmt = PIXMAN_solid; + mask_img = pixman_image_create_solid_fill (&color); + } + + if (!exact) + { + int i = 0; + + while (i < 4) + fuzz[i++] = random_offset (); + + src_transform.matrix[0][2] += fuzz[0]; + src_transform.matrix[1][2] += fuzz[1]; + mask_transform.matrix[0][2] += fuzz[2]; + mask_transform.matrix[1][2] += fuzz[3]; + } + + pixman_image_set_transform (src_img, &src_transform); + if (mask_fmt == PIXMAN_a8) + pixman_image_set_transform (mask_img, &mask_transform); + + if (verbose) + { + printf ("op=%s\n", operator_name (op)); + printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n", + format_name (src_fmt), format_name (dst_fmt), + format_name (mask_fmt)); + printf ("x_scale=0x%08X, y_scale=0x%08X, align %s/%s, %s\n", + x_scale, y_scale, + left_align ? "left" : "right", top_align ? "top" : "bottom", + bilinear ? "bilinear" : "nearest"); + + if (!exact) + { + int i = 0; + + printf ("fuzz factors"); + while (i < 4) + printf (" %d", fuzz[i++]); + printf ("\n"); + } + } + + if (exact) + { + check_transform (dst_img, src_img, &src_transform, bilinear); + if (mask_fmt == PIXMAN_a8) + check_transform (dst_img, mask_img, &mask_transform, bilinear); + } + + pixman_image_composite (op, src_img, mask_img, dst_img, + 0, 0, 0, 0, 0, 0, + dst_img->bits.width, dst_img->bits.height); + + if (verbose) + print_image (dst_img); + + crc32 = compute_crc32_for_image (0, dst_img); + + pixman_image_unref (dst_img); + if (mask_fmt == PIXMAN_solid) + pixman_image_unref (mask_img); + + return crc32; +} + +#if BILINEAR_INTERPOLATION_BITS == 7 +#define CHECKSUM_FUZZ 0x6B56F607 +#define CHECKSUM_EXACT 0xA669F4A3 +#elif BILINEAR_INTERPOLATION_BITS == 4 +#define CHECKSUM_FUZZ 0x83119ED0 +#define CHECKSUM_EXACT 0x0D3382CD +#else +#define CHECKSUM_FUZZ 0x00000000 +#define CHECKSUM_EXACT 0x00000000 +#endif + +int +main (int argc, const char *argv[]) +{ + unsigned long page_size; + + page_size = fence_get_page_size (); + if (page_size == 0 || page_size > 16 * 1024) + return 77; /* automake SKIP */ + + exact = getenv ("EXACT") != NULL; + if (exact) + printf ("Doing plots that are exactly aligned to boundaries\n"); + + return fuzzer_test_main ("cover", 2000000, + exact ? CHECKSUM_EXACT : CHECKSUM_FUZZ, + test_cover, argc, argv); +} diff --git a/lib/pixman/test/fence-image-self-test.c b/lib/pixman/test/fence-image-self-test.c new file mode 100644 index 000000000..c80b3cf31 --- /dev/null +++ b/lib/pixman/test/fence-image-self-test.c @@ -0,0 +1,239 @@ +/* + * Copyright © 2015 Raspberry Pi Foundation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holders make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "utils.h" + + +#if FENCE_MALLOC_ACTIVE && defined (HAVE_SIGACTION) + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + +pixman_bool_t verbose; + +static void +segv_handler (int sig, siginfo_t *si, void *unused) +{ + _exit (EXIT_SUCCESS); +} + +static void +die (const char *msg, int err) +{ + if (err) + perror (msg); + else + fprintf (stderr, "%s\n", msg); + + abort (); +} + +static void +prinfo (const char *fmt, ...) +{ + va_list ap; + + if (!verbose) + return; + + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); +} + +static void +do_expect_signal (void (*fn)(void *), void *data) +{ + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sigemptyset (&sa.sa_mask); + sa.sa_sigaction = segv_handler; + if (sigaction (SIGSEGV, &sa, NULL) == -1) + die ("sigaction failed", errno); + if (sigaction (SIGBUS, &sa, NULL) == -1) + die ("sigaction failed", errno); + + (*fn)(data); + + _exit (EXIT_FAILURE); +} + +/* Check that calling fn(data) causes a segmentation fault. + * + * You cannot portably return from a SIGSEGV handler in any way, + * so we fork, and do the test in the child process. Child's + * exit status will reflect the result. Its SEGV handler causes it + * to exit with success, and return failure otherwise. + */ +static pixman_bool_t +expect_signal (void (*fn)(void *), void *data) +{ + pid_t pid, wp; + int status; + + pid = fork (); + if (pid == -1) + die ("fork failed", errno); + + if (pid == 0) + do_expect_signal (fn, data); /* never returns */ + + wp = waitpid (pid, &status, 0); + if (wp != pid) + die ("waitpid did not work", wp == -1 ? errno : 0); + + if (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_SUCCESS) + return TRUE; + + return FALSE; +} + +static void +read_u8 (void *data) +{ + volatile uint8_t *p = data; + + *p; +} + +static pixman_bool_t +test_read_fault (uint8_t *p, int offset) +{ + prinfo ("*(uint8_t *)(%p + %d)", p, offset); + + if (expect_signal (read_u8, p + offset)) + { + prinfo ("\tsignal OK\n"); + + return TRUE; + } + + prinfo ("\tFAILED\n"); + + return FALSE; +} + +static void +test_read_ok (uint8_t *p, int offset) +{ + prinfo ("*(uint8_t *)(%p + %d)", p, offset); + + /* If fails, SEGV. */ + read_u8 (p + offset); + + prinfo ("\tOK\n"); +} + +static pixman_bool_t +test_read_faults (pixman_image_t *image) +{ + pixman_bool_t ok = TRUE; + pixman_format_code_t format = pixman_image_get_format (image); + int width = pixman_image_get_width (image); + int height = pixman_image_get_height (image); + int stride = pixman_image_get_stride (image); + uint8_t *p = (void *)pixman_image_get_data (image); + int row_bytes = width * PIXMAN_FORMAT_BPP (format) / 8; + + prinfo ("%s %dx%d, row %d B, stride %d B:\n", + format_name (format), width, height, row_bytes, stride); + + assert (height > 3); + + test_read_ok (p, 0); + test_read_ok (p, row_bytes - 1); + test_read_ok (p, stride); + test_read_ok (p, stride + row_bytes - 1); + test_read_ok (p, 2 * stride); + test_read_ok (p, 2 * stride + row_bytes - 1); + test_read_ok (p, 3 * stride); + test_read_ok (p, (height - 1) * stride + row_bytes - 1); + + ok &= test_read_fault (p, -1); + ok &= test_read_fault (p, row_bytes); + ok &= test_read_fault (p, stride - 1); + ok &= test_read_fault (p, stride + row_bytes); + ok &= test_read_fault (p, 2 * stride - 1); + ok &= test_read_fault (p, 2 * stride + row_bytes); + ok &= test_read_fault (p, 3 * stride - 1); + ok &= test_read_fault (p, height * stride); + + return ok; +} + +static pixman_bool_t +test_image_faults (pixman_format_code_t format, int min_width, int height) +{ + pixman_bool_t ok; + pixman_image_t *image; + + image = fence_image_create_bits (format, min_width, height, TRUE); + ok = test_read_faults (image); + pixman_image_unref (image); + + return ok; +} + +int +main (int argc, char **argv) +{ + pixman_bool_t ok = TRUE; + + if (getenv ("VERBOSE") != NULL) + verbose = TRUE; + + ok &= test_image_faults (PIXMAN_a8r8g8b8, 7, 5); + ok &= test_image_faults (PIXMAN_r8g8b8, 7, 5); + ok &= test_image_faults (PIXMAN_r5g6b5, 7, 5); + ok &= test_image_faults (PIXMAN_a8, 7, 5); + ok &= test_image_faults (PIXMAN_a4, 7, 5); + ok &= test_image_faults (PIXMAN_a1, 7, 5); + + if (ok) + return EXIT_SUCCESS; + + return EXIT_FAILURE; +} + +#else /* FENCE_MALLOC_ACTIVE */ + +int +main (int argc, char **argv) +{ + /* Automake return code for test SKIP. */ + return 77; +} + +#endif /* FENCE_MALLOC_ACTIVE */ diff --git a/lib/pixman/test/lowlevel-blt-bench.c b/lib/pixman/test/lowlevel-blt-bench.c index 1049e21e7..28ff66991 100644 --- a/lib/pixman/test/lowlevel-blt-bench.c +++ b/lib/pixman/test/lowlevel-blt-bench.c @@ -55,7 +55,7 @@ uint32_t *dst; uint32_t *src; uint32_t *mask; -double bandwidth = 0; +double bandwidth = 0.0; double bench_memcpy () @@ -90,6 +90,7 @@ bench_memcpy () static pixman_bool_t use_scaling = FALSE; static pixman_filter_t filter = PIXMAN_FILTER_NEAREST; +static pixman_bool_t use_csv_output = FALSE; /* nearly 1x scale factor */ static pixman_transform_t m = @@ -165,7 +166,7 @@ call_func (pixman_composite_func_t func, func (0, &info); } -void +double noinline bench_L (pixman_op_t op, pixman_image_t * src_img, @@ -204,9 +205,11 @@ bench_L (pixman_op_t op, call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 63 - x, 0, width, lines_count); } qx = q; + + return (double)n * lines_count * width; } -void +double noinline bench_M (pixman_op_t op, pixman_image_t * src_img, @@ -224,6 +227,8 @@ bench_M (pixman_op_t op, x = 0; call_func (func, op, src_img, mask_img, dst_img, x, 0, x, 0, 1, 0, WIDTH - 64, HEIGHT); } + + return (double)n * (WIDTH - 64) * HEIGHT; } double @@ -366,15 +371,24 @@ bench_RT (pixman_op_t op, return pix_cnt; } +static double +Mpx_per_sec (double pix_cnt, double t1, double t2, double t3) +{ + double overhead = t2 - t1; + double testtime = t3 - t2; + + return pix_cnt / (testtime - overhead) / 1e6; +} + void -bench_composite (char * testname, - int src_fmt, - int src_flags, - int op, - int mask_fmt, - int mask_flags, - int dst_fmt, - double npix) +bench_composite (const char *testname, + int src_fmt, + int src_flags, + int op, + int mask_fmt, + int mask_flags, + int dst_fmt, + double npix) { pixman_image_t * src_img; pixman_image_t * dst_img; @@ -461,9 +475,9 @@ bench_composite (char * testname, dst, XWIDTH * 4); - - printf ("%24s %c", testname, func != pixman_image_composite_wrapper ? - '-' : '='); + if (!use_csv_output) + printf ("%24s %c", testname, func != pixman_image_composite_wrapper ? + '-' : '='); memcpy (dst, src, BUFSIZE); memcpy (src, dst, BUFSIZE); @@ -476,13 +490,15 @@ bench_composite (char * testname, n = 1 + npix / (l1test_width * 8); t1 = gettime (); #if EXCLUDE_OVERHEAD - bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, 1); + pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, 1); #endif t2 = gettime (); - bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, 1); + pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, 1); t3 = gettime (); - printf (" L1:%7.2f", (double)n * l1test_width * 1 / - ((t3 - t2) - (t2 - t1)) / 1000000.); + if (use_csv_output) + printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" L1:%7.2f", Mpx_per_sec (pix_cnt, t1, t2, t3)); fflush (stdout); memcpy (dst, src, BUFSIZE); @@ -495,13 +511,15 @@ bench_composite (char * testname, n = 1 + npix / (l1test_width * nlines); t1 = gettime (); #if EXCLUDE_OVERHEAD - bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, nlines); + pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, nlines); #endif t2 = gettime (); - bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, nlines); + pix_cnt = bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, nlines); t3 = gettime (); - printf (" L2:%7.2f", (double)n * l1test_width * nlines / - ((t3 - t2) - (t2 - t1)) / 1000000.); + if (use_csv_output) + printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" L2:%7.2f", Mpx_per_sec (pix_cnt, t1, t2, t3)); fflush (stdout); memcpy (dst, src, BUFSIZE); @@ -510,14 +528,16 @@ bench_composite (char * testname, n = 1 + npix / (WIDTH * HEIGHT); t1 = gettime (); #if EXCLUDE_OVERHEAD - bench_M (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty); + pix_cnt = bench_M (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty); #endif t2 = gettime (); - bench_M (op, src_img, mask_img, dst_img, n, func); + pix_cnt = bench_M (op, src_img, mask_img, dst_img, n, func); t3 = gettime (); - printf (" M:%6.2f (%6.2f%%)", - ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1))) / 1000000., - ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) ); + if (use_csv_output) + printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" M:%6.2f (%6.2f%%)", Mpx_per_sec (pix_cnt, t1, t2, t3), + (pix_cnt / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) ); fflush (stdout); memcpy (dst, src, BUFSIZE); @@ -531,7 +551,10 @@ bench_composite (char * testname, t2 = gettime (); pix_cnt = bench_HT (op, src_img, mask_img, dst_img, n, func); t3 = gettime (); - printf (" HT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.); + if (use_csv_output) + printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" HT:%6.2f", Mpx_per_sec (pix_cnt, t1, t2, t3)); fflush (stdout); memcpy (dst, src, BUFSIZE); @@ -545,7 +568,10 @@ bench_composite (char * testname, t2 = gettime (); pix_cnt = bench_VT (op, src_img, mask_img, dst_img, n, func); t3 = gettime (); - printf (" VT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.); + if (use_csv_output) + printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" VT:%6.2f", Mpx_per_sec (pix_cnt, t1, t2, t3)); fflush (stdout); memcpy (dst, src, BUFSIZE); @@ -559,7 +585,10 @@ bench_composite (char * testname, t2 = gettime (); pix_cnt = bench_R (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT); t3 = gettime (); - printf (" R:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.); + if (use_csv_output) + printf ("%g,", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" R:%6.2f", Mpx_per_sec (pix_cnt, t1, t2, t3)); fflush (stdout); memcpy (dst, src, BUFSIZE); @@ -573,7 +602,10 @@ bench_composite (char * testname, t2 = gettime (); pix_cnt = bench_RT (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT); t3 = gettime (); - printf (" RT:%6.2f (%4.0fKops/s)\n", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000., (double) n / ((t3 - t2) * 1000)); + if (use_csv_output) + printf ("%g\n", Mpx_per_sec (pix_cnt, t1, t2, t3)); + else + printf (" RT:%6.2f (%4.0fKops/s)\n", Mpx_per_sec (pix_cnt, t1, t2, t3), (double) n / ((t3 - t2) * 1000)); if (mask_img) { pixman_image_unref (mask_img); @@ -587,17 +619,20 @@ bench_composite (char * testname, #define PIXMAN_OP_OUT_REV (PIXMAN_OP_OUT_REVERSE) -struct +struct test_entry { - char *testname; - int src_fmt; - int src_flags; - int op; - int mask_fmt; - int mask_flags; - int dst_fmt; -} -tests_tbl[] = + const char *testname; + int src_fmt; + int src_flags; + int op; + int mask_fmt; + int mask_flags; + int dst_fmt; +}; + +typedef struct test_entry test_entry_t; + +static const test_entry_t tests_tbl[] = { { "add_8_8_8", PIXMAN_a8, 0, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 }, { "add_n_8_8", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 }, @@ -713,51 +748,292 @@ tests_tbl[] = { "outrev_n_8888_1555_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a1r5g5b5 }, { "outrev_n_8888_x888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_x8r8g8b8 }, { "outrev_n_8888_8888_ca", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a8r8g8b8 }, - { "over_reverse_n_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_OVER_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 }, + { "over_reverse_n_8888", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_OVER_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 }, + { "in_reverse_8888_8888", PIXMAN_a8r8g8b8, 0, PIXMAN_OP_IN_REVERSE, PIXMAN_null, 0, PIXMAN_a8r8g8b8 }, { "pixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8r8g8b8 }, { "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 }, }; -int -main (int argc, char *argv[]) +static const test_entry_t special_patterns[] = +{ + { "add_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x2r10g10b10 }, + { "add_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r10g10b10 }, + { "src_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x2r10g10b10 }, + { "src_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r10g10b10 }, + { "src_0888_8888_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 }, + { "src_0888_0565_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 }, + { "src_n_8", PIXMAN_a8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8 }, + { "pixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8r8g8b8 }, + { "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 }, +}; + +/* Returns the sub-string's end pointer in string. */ +static const char * +copy_sub_string (char *buf, + const char *string, + const char *scan_from, + const char *end) { - double x; + const char *delim; + size_t n; + + delim = strchr (scan_from, '_'); + if (!delim) + delim = end; + + n = delim - string; + strncpy(buf, string, n); + buf[n] = '\0'; + + return delim; +} + +static pixman_op_t +parse_longest_operator (char *buf, const char **strp, const char *end) +{ + const char *p = *strp; + const char *sub_end; + const char *best_end = p; + pixman_op_t best_op = PIXMAN_OP_NONE; + pixman_op_t op; + + while (p < end) + { + sub_end = copy_sub_string (buf, *strp, p, end); + op = operator_from_string (buf); + p = sub_end + 1; + + if (op != PIXMAN_OP_NONE) + { + best_end = p; + best_op = op; + } + } + + *strp = best_end; + return best_op; +} + +static pixman_format_code_t +parse_format (char *buf, const char **p, const char *end) +{ + pixman_format_code_t format; + const char *delim; + + if (*p >= end) + return PIXMAN_null; + + delim = copy_sub_string (buf, *p, *p, end); + format = format_from_string (buf); + + if (format != PIXMAN_null) + *p = delim + 1; + + return format; +} + +static int +parse_test_pattern (test_entry_t *test, const char *pattern) +{ + const char *p = pattern; + const char *end = pattern + strlen (pattern); + char buf[1024]; + pixman_format_code_t format[3]; int i; - const char *pattern = NULL; - for (i = 1; i < argc; i++) + + if (strlen (pattern) > sizeof (buf) - 1) + return -1; + + /* Special cases that the parser cannot produce. */ + for (i = 0; i < ARRAY_LENGTH (special_patterns); i++) { - if (argv[i][0] == '-') - { - if (strchr (argv[i] + 1, 'b')) - { - use_scaling = TRUE; - filter = PIXMAN_FILTER_BILINEAR; - } - else if (strchr (argv[i] + 1, 'n')) - { - use_scaling = TRUE; - filter = PIXMAN_FILTER_NEAREST; - } - } - else - { - pattern = argv[i]; - } + if (strcmp (pattern, special_patterns[i].testname) == 0) + { + *test = special_patterns[i]; + return 0; + } } - if (!pattern) + test->testname = pattern; + + /* Extract operator, may contain delimiters, + * so take the longest string that matches. + */ + test->op = parse_longest_operator (buf, &p, end); + if (test->op == PIXMAN_OP_NONE) + return -1; + + /* extract up to three pixel formats */ + format[0] = parse_format (buf, &p, end); + format[1] = parse_format (buf, &p, end); + format[2] = parse_format (buf, &p, end); + + if (format[0] == PIXMAN_null || format[1] == PIXMAN_null) + return -1; + + /* recognize CA flag */ + test->mask_flags = 0; + if (p < end) { - printf ("Usage: lowlevel-blt-bench [-b] [-n] pattern\n"); - printf (" -n : benchmark nearest scaling\n"); - printf (" -b : benchmark bilinear scaling\n"); - return 1; + if (strcmp (p, "ca") == 0) + test->mask_flags |= CA_FLAG; + else + return -1; /* trailing garbage */ } - src = aligned_malloc (4096, BUFSIZE * 3); - memset (src, 0xCC, BUFSIZE * 3); - dst = src + (BUFSIZE / 4); - mask = dst + (BUFSIZE / 4); + test->src_fmt = format[0]; + if (format[2] == PIXMAN_null) + { + test->mask_fmt = PIXMAN_null; + test->dst_fmt = format[1]; + } + else + { + test->mask_fmt = format[1]; + test->dst_fmt = format[2]; + } + + test->src_flags = 0; + if (test->src_fmt == PIXMAN_solid) + { + test->src_fmt = PIXMAN_a8r8g8b8; + test->src_flags |= SOLID_FLAG; + } + + if (test->mask_fmt == PIXMAN_solid) + { + if (test->mask_flags & CA_FLAG) + test->mask_fmt = PIXMAN_a8r8g8b8; + else + test->mask_fmt = PIXMAN_a8; + + test->mask_flags |= SOLID_FLAG; + } + + return 0; +} +static int +check_int (int got, int expected, const char *name, const char *field) +{ + if (got == expected) + return 0; + + printf ("%s: %s failure: expected %d, got %d.\n", + name, field, expected, got); + + return 1; +} + +static int +check_format (int got, int expected, const char *name, const char *field) +{ + if (got == expected) + return 0; + + printf ("%s: %s failure: expected %s (%#x), got %s (%#x).\n", + name, field, + format_name (expected), expected, + format_name (got), got); + + return 1; +} + +static void +parser_self_test (void) +{ + const test_entry_t *ent; + test_entry_t test; + int fails = 0; + int i; + + for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++) + { + ent = &tests_tbl[i]; + + if (parse_test_pattern (&test, ent->testname) < 0) + { + printf ("parsing failed for '%s'\n", ent->testname); + fails++; + continue; + } + + fails += check_format (test.src_fmt, ent->src_fmt, + ent->testname, "src_fmt"); + fails += check_format (test.mask_fmt, ent->mask_fmt, + ent->testname, "mask_fmt"); + fails += check_format (test.dst_fmt, ent->dst_fmt, + ent->testname, "dst_fmt"); + fails += check_int (test.src_flags, ent->src_flags, + ent->testname, "src_flags"); + fails += check_int (test.mask_flags, ent->mask_flags, + ent->testname, "mask_flags"); + fails += check_int (test.op, ent->op, ent->testname, "op"); + } + + if (fails) + { + printf ("Parser self-test failed.\n"); + exit (EXIT_FAILURE); + } + + if (!use_csv_output) + printf ("Parser self-test complete.\n"); +} + +static void +print_test_details (const test_entry_t *test) +{ + printf ("%s: %s, src %s%s, mask %s%s%s, dst %s\n", + test->testname, + operator_name (test->op), + format_name (test->src_fmt), + test->src_flags & SOLID_FLAG ? " solid" : "", + format_name (test->mask_fmt), + test->mask_flags & SOLID_FLAG ? " solid" : "", + test->mask_flags & CA_FLAG ? " CA" : "", + format_name (test->dst_fmt)); +} + +static void +run_one_test (const char *pattern, double bandwidth_, pixman_bool_t prdetails) +{ + test_entry_t test; + + if (parse_test_pattern (&test, pattern) < 0) + { + printf ("Error: Could not parse the test pattern '%s'.\n", pattern); + return; + } + + if (prdetails) + { + print_test_details (&test); + printf ("---\n"); + } + + bench_composite (pattern, + test.src_fmt, + test.src_flags, + test.op, + test.mask_fmt, + test.mask_flags, + test.dst_fmt, + bandwidth_ / 8); +} + +static void +run_default_tests (double bandwidth_) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++) + run_one_test (tests_tbl[i].testname, bandwidth_, FALSE); +} + +static void +print_explanation (void) +{ printf ("Benchmark for a set of most commonly used functions\n"); printf ("---\n"); printf ("All results are presented in millions of pixels per second\n"); @@ -785,9 +1061,14 @@ main (int argc, char *argv[]) printf ("RT - as R, but %dx%d average sized rectangles are copied\n", TINYWIDTH, TINYWIDTH); printf ("---\n"); - bandwidth = x = bench_memcpy (); +} + +static void +print_speed_scaling (double bw) +{ printf ("reference memcpy speed = %.1fMB/s (%.1fMP/s for 32bpp fills)\n", - x / 1000000., x / 4000000); + bw / 1000000., bw / 4000000); + if (use_scaling) { printf ("---\n"); @@ -798,23 +1079,85 @@ main (int argc, char *argv[]) else printf ("UNKNOWN scaling\n"); } + printf ("---\n"); +} - for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++) +static void +usage (const char *progname) +{ + printf ("Usage: %s [-b] [-n] [-c] [-m M] pattern\n", progname); + printf (" -n : benchmark nearest scaling\n"); + printf (" -b : benchmark bilinear scaling\n"); + printf (" -c : print output as CSV data\n"); + printf (" -m M : set reference memcpy speed to M MB/s instead of measuring it\n"); +} + +int +main (int argc, char *argv[]) +{ + int i; + const char *pattern = NULL; + + for (i = 1; i < argc; i++) { - if (strcmp (pattern, "all") == 0 || strcmp (tests_tbl[i].testname, pattern) == 0) + if (argv[i][0] == '-') { - bench_composite (tests_tbl[i].testname, - tests_tbl[i].src_fmt, - tests_tbl[i].src_flags, - tests_tbl[i].op, - tests_tbl[i].mask_fmt, - tests_tbl[i].mask_flags, - tests_tbl[i].dst_fmt, - bandwidth/8); + if (strchr (argv[i] + 1, 'b')) + { + use_scaling = TRUE; + filter = PIXMAN_FILTER_BILINEAR; + } + else if (strchr (argv[i] + 1, 'n')) + { + use_scaling = TRUE; + filter = PIXMAN_FILTER_NEAREST; + } + + if (strchr (argv[i] + 1, 'c')) + use_csv_output = TRUE; + + if (strcmp (argv[i], "-m") == 0 && i + 1 < argc) + bandwidth = atof (argv[++i]) * 1e6; } + else + { + if (pattern) + { + pattern = NULL; + printf ("Error: extra arguments given.\n"); + break; + } + pattern = argv[i]; + } + } + + if (!pattern) + { + usage (argv[0]); + return 1; } + parser_self_test (); + + src = aligned_malloc (4096, BUFSIZE * 3); + memset (src, 0xCC, BUFSIZE * 3); + dst = src + (BUFSIZE / 4); + mask = dst + (BUFSIZE / 4); + + if (!use_csv_output) + print_explanation (); + + if (bandwidth < 1.0) + bandwidth = bench_memcpy (); + if (!use_csv_output) + print_speed_scaling (bandwidth); + + if (strcmp (pattern, "all") == 0) + run_default_tests (bandwidth); + else + run_one_test (pattern, bandwidth, !use_csv_output); + free (src); return 0; } diff --git a/lib/pixman/test/pixel-test.c b/lib/pixman/test/pixel-test.c index 8c525d202..7dc0eff3f 100644 --- a/lib/pixman/test/pixel-test.c +++ b/lib/pixman/test/pixel-test.c @@ -33,68 +33,2764 @@ struct pixel_combination_t pixman_op_t op; pixman_format_code_t src_format; uint32_t src_pixel; + pixman_format_code_t mask_format; + uint32_t mask_pixel; pixman_format_code_t dest_format; uint32_t dest_pixel; }; static const pixel_combination_t regressions[] = { + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffc3ff, + PIXMAN_a8, 0x7b, + PIXMAN_a8r8g8b8, 0xff00c300, + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb5, + PIXMAN_a4r4g4b4, 0xe3ff, + PIXMAN_a2r2g2b2, 0x2e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa6, + PIXMAN_a8r8g8b8, 0x2b00ff00, + PIXMAN_a4r4g4b4, 0x7e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x27000013, + PIXMAN_a2r2g2b2, 0x80, + PIXMAN_a4r4g4b4, 0x9d + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xe6f7, + PIXMAN_a2r2g2b2, 0xad, + PIXMAN_a4r4g4b4, 0x71 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xff4f70ff, + PIXMAN_r5g6b5, 0xb828, + PIXMAN_a8r8g8b8, 0xcac400 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa9, + PIXMAN_a4r4g4b4, 0x41c2, + PIXMAN_a8r8g8b8, 0xffff2b + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x89, + PIXMAN_a8r8g8b8, 0x977cff61, + PIXMAN_a4r4g4b4, 0x36 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x81, + PIXMAN_r5g6b5, 0x6f9e, + PIXMAN_a4r4g4b4, 0x1eb + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb5, + PIXMAN_a4r4g4b4, 0xe247, + PIXMAN_a8r8g8b8, 0xffbaff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x97, + PIXMAN_a2r2g2b2, 0x9d, + PIXMAN_a2r2g2b2, 0x21 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb4, + PIXMAN_a2r2g2b2, 0x90, + PIXMAN_a8r8g8b8, 0xc0fd5c + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xdf00ff70, + PIXMAN_a8r8g8b8, 0x2597ff27, + PIXMAN_a4r4g4b4, 0xf3 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb7, + PIXMAN_r3g3b2, 0xb1, + PIXMAN_a8r8g8b8, 0x9f4bcc + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xf39e, + PIXMAN_r5g6b5, 0x34, + PIXMAN_a8r8g8b8, 0xf6ae00 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x3aff1dff, + PIXMAN_a2r2g2b2, 0x64, + PIXMAN_a8r8g8b8, 0x94ffb4 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa4, + PIXMAN_a2r2g2b2, 0x8a, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa5, + PIXMAN_a4r4g4b4, 0x1a, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb4, + PIXMAN_a2r2g2b2, 0xca, + PIXMAN_a4r4g4b4, 0x7b + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xbd, + PIXMAN_a4r4g4b4, 0xff37, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x96, + PIXMAN_a2r2g2b2, 0xbb, + PIXMAN_a8r8g8b8, 0x96ffff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x89, + PIXMAN_r3g3b2, 0x92, + PIXMAN_a4r4g4b4, 0xa8c + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xa95b, + PIXMAN_a2r2g2b2, 0x68, + PIXMAN_a8r8g8b8, 0x38ff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x90, + PIXMAN_a8r8g8b8, 0x53bd00ef, + PIXMAN_a8r8g8b8, 0xff0003 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1f5ffff, + PIXMAN_r3g3b2, 0x22, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x10000b6, + PIXMAN_a8r8g8b8, 0x9645, + PIXMAN_r5g6b5, 0x6 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x172ff00, + PIXMAN_a4r4g4b4, 0xff61, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x281ffc8, + PIXMAN_r5g6b5, 0x39b8, + PIXMAN_r5g6b5, 0x13 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100a2ff, + PIXMAN_a4r4g4b4, 0x6500, + PIXMAN_a2r2g2b2, 0x5 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff51, + PIXMAN_r5g6b5, 0x52ff, + PIXMAN_a2r2g2b2, 0x14 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x150d500, + PIXMAN_a8r8g8b8, 0x6200b7ff, + PIXMAN_a8r8g8b8, 0x1f5200 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2a9a700, + PIXMAN_a8r8g8b8, 0xf7003400, + PIXMAN_a8r8g8b8, 0x2200 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r5g6b5, 0x81ff, + PIXMAN_r5g6b5, 0x1f + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ff00ff, + PIXMAN_r5g6b5, 0x3f00, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3ff1aa4, + PIXMAN_a4r4g4b4, 0x2200, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x280ff2c, + PIXMAN_r3g3b2, 0xc6, + PIXMAN_a8r8g8b8, 0xfdfd44fe + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x13aff1d, + PIXMAN_a2r2g2b2, 0x4b, + PIXMAN_r5g6b5, 0x12a1 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ffff88, + PIXMAN_a8r8g8b8, 0xff3a49, + PIXMAN_r5g6b5, 0xf7df + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1009700, + PIXMAN_a2r2g2b2, 0x56, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1aacbff, + PIXMAN_a4r4g4b4, 0x84, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x100b1ff, + PIXMAN_a2r2g2b2, 0xf5, + PIXMAN_a8r8g8b8, 0xfea89cff + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_r5g6b5, 0x6800, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x10064ff, + PIXMAN_r3g3b2, 0x61, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1bb00ff, + PIXMAN_r5g6b5, 0x76b5, + PIXMAN_a4r4g4b4, 0x500 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ffff41, + PIXMAN_r5g6b5, 0x7100, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff1231, + PIXMAN_a8r8g8b8, 0x381089, + PIXMAN_r5g6b5, 0x38a5 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x16e5c49, + PIXMAN_a8r8g8b8, 0x4dfa3694, + PIXMAN_a8r8g8b8, 0x211c16 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x134ff62, + PIXMAN_a2r2g2b2, 0x14, + PIXMAN_r3g3b2, 0x8 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x300ffeb, + PIXMAN_r3g3b2, 0xc7, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x3ff8bff, + PIXMAN_r3g3b2, 0x3e, + PIXMAN_a8r8g8b8, 0x3008baa + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_a4r4g4b4, 0x3466, + PIXMAN_a4r4g4b4, 0x406 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ddc027, + PIXMAN_a4r4g4b4, 0x7d00, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a8r8g8b8, 0xc92cfb52, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff116a, + PIXMAN_a4r4g4b4, 0x6000, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r5g6b5, 0x2f95, + PIXMAN_r5g6b5, 0x795 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a4r4g4b4, 0x354a, + PIXMAN_r5g6b5, 0x3180 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1d7ff00, + PIXMAN_a4r4g4b4, 0xd6ff, + PIXMAN_a8r8g8b8, 0xffff0700 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1bc5db7, + PIXMAN_r5g6b5, 0x944f, + PIXMAN_a4r4g4b4, 0xff05 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x185ffd9, + PIXMAN_a2r2g2b2, 0x9c, + PIXMAN_r5g6b5, 0x3c07 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1fa7f61, + PIXMAN_a8r8g8b8, 0xff31ff00, + PIXMAN_r3g3b2, 0xd2 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1c4ff00, + PIXMAN_r3g3b2, 0xb, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ff00ff, + PIXMAN_a8r8g8b8, 0x3f3caeda, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff68ff, + PIXMAN_a4r4g4b4, 0x8046, + PIXMAN_r5g6b5, 0xec + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ff28, + PIXMAN_a8r8g8b8, 0x4c00, + PIXMAN_r5g6b5, 0x260 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_a4r4g4b4, 0xd92a, + PIXMAN_a8r8g8b8, 0x2200 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100289a, + PIXMAN_a8r8g8b8, 0x74ffb8ff, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1baff00, + PIXMAN_r5g6b5, 0x4e9d, + PIXMAN_r5g6b5, 0x3000 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1fcffad, + PIXMAN_r5g6b5, 0x42d7, + PIXMAN_a8r8g8b8, 0x1c6ffe5 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x183ff00, + PIXMAN_r3g3b2, 0x7e, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x2ff0076, + PIXMAN_a8r8g8b8, 0x2a0000, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3d8bbff, + PIXMAN_r5g6b5, 0x6900, + PIXMAN_a8r8g8b8, 0x35b0000 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x14f00ff, + PIXMAN_r5g6b5, 0xd48, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x28c72df, + PIXMAN_a8r8g8b8, 0xff5cff31, + PIXMAN_a4r4g4b4, 0x2 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffffff, + PIXMAN_a8r8g8b8, 0xffad8020, + PIXMAN_r5g6b5, 0x4 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_a2r2g2b2, 0x76, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1005d00, + PIXMAN_r5g6b5, 0x7b04, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x3cdfc3e, + PIXMAN_a8r8g8b8, 0x69ec21d3, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r5g6b5, 0x30ff, + PIXMAN_r5g6b5, 0x60ff + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x532fff4, + PIXMAN_r5g6b5, 0xcb, + PIXMAN_r5g6b5, 0xd9a1 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r3g3b2, 0x5f, + PIXMAN_a2r2g2b2, 0x10 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a8r8g8b8, 0xffd60052, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff6491, + PIXMAN_a8r8g8b8, 0x1e53ff00, + PIXMAN_r5g6b5, 0x1862 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_r3g3b2, 0xc7, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x29d0fff, + PIXMAN_a4r4g4b4, 0x25ff, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x141760a, + PIXMAN_a4r4g4b4, 0x7ec2, + PIXMAN_a4r4g4b4, 0x130 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1abedff, + PIXMAN_a8r8g8b8, 0x75520068, + PIXMAN_r3g3b2, 0x87 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a8r8g8b8, 0xff00e652, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x16006075, + PIXMAN_r5g6b5, 0xc00, + PIXMAN_a8r8g8b8, 0x27f0900 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x200ff00, + PIXMAN_a8r8g8b8, 0xd1b83f57, + PIXMAN_a4r4g4b4, 0xff75 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14000c4, + PIXMAN_a4r4g4b4, 0x96, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff00d1, + PIXMAN_r3g3b2, 0x79, + PIXMAN_a2r2g2b2, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff00dc, + PIXMAN_a4r4g4b4, 0xc5ff, + PIXMAN_a2r2g2b2, 0x10 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffb2, + PIXMAN_a8r8g8b8, 0x4cff5700, + PIXMAN_r3g3b2, 0x48 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1327482, + PIXMAN_a8r8g8b8, 0x247ff, + PIXMAN_a8r8g8b8, 0x82 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1d0ff00, + PIXMAN_r3g3b2, 0xc9, + PIXMAN_r5g6b5, 0x240 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x13d35ff, + PIXMAN_a2r2g2b2, 0x6d, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffc6b2, + PIXMAN_a8r8g8b8, 0x5abe8e3c, + PIXMAN_r5g6b5, 0x5a27 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x15700ff, + PIXMAN_r3g3b2, 0xdd, + PIXMAN_a8r8g8b8, 0x55 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff11ff, + PIXMAN_r3g3b2, 0x30, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_a2r2g2b2, 0x6d, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1421d5f, + PIXMAN_a4r4g4b4, 0xff85, + PIXMAN_a8r8g8b8, 0x1420f00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1d2ffff, + PIXMAN_r5g6b5, 0xfc, + PIXMAN_r5g6b5, 0x1c + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffff42, + PIXMAN_a4r4g4b4, 0x7100, + PIXMAN_a4r4g4b4, 0x771 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x25ae3d4, + PIXMAN_a8r8g8b8, 0x39ffc99a, + PIXMAN_a8r8g8b8, 0x14332f + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0643, + PIXMAN_a8r8g8b8, 0x4c000000, + PIXMAN_r5g6b5, 0x4802 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1966a00, + PIXMAN_r3g3b2, 0x46, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x387ff59, + PIXMAN_r5g6b5, 0x512c, + PIXMAN_r5g6b5, 0x120 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1f7ffb0, + PIXMAN_r5g6b5, 0x63b8, + PIXMAN_a8r8g8b8, 0x1000089 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x185841c, + PIXMAN_a2r2g2b2, 0x5c, + PIXMAN_a8r8g8b8, 0x8400 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffc3ff, + PIXMAN_a8r8g8b8, 0xff7b, + PIXMAN_a8r8g8b8, 0xff00c300 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff7500, + PIXMAN_a2r2g2b2, 0x47, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1002361, + PIXMAN_a2r2g2b2, 0x7e, + PIXMAN_r5g6b5, 0x64 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x10000b6, + PIXMAN_a8r8g8b8, 0x59004463, + PIXMAN_a4r4g4b4, 0xffa7 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff5a49, + PIXMAN_a8r8g8b8, 0xff3fff2b, + PIXMAN_a8r8g8b8, 0x13f000c + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x3ffecfc, + PIXMAN_r3g3b2, 0x3c, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1630044, + PIXMAN_a2r2g2b2, 0x63, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1d2ff58, + PIXMAN_a8r8g8b8, 0x8f77ff, + PIXMAN_a4r4g4b4, 0x705 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14dffff, + PIXMAN_a2r2g2b2, 0x9a, + PIXMAN_a8r8g8b8, 0x1a0000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff92, + PIXMAN_a4r4g4b4, 0x540c, + PIXMAN_r5g6b5, 0x2a6 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a4r4g4b4, 0xddd5, + PIXMAN_a4r4g4b4, 0xdd0 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r5g6b5, 0xff8c, + PIXMAN_a4r4g4b4, 0xff0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r3g3b2, 0x66, + PIXMAN_r5g6b5, 0x7d1f + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_a4r4g4b4, 0xff5b, + PIXMAN_a8r8g8b8, 0x5500 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ed2dff, + PIXMAN_r5g6b5, 0x7ae7, + PIXMAN_r3g3b2, 0xce + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1b13205, + PIXMAN_a8r8g8b8, 0x35ffff00, + PIXMAN_r5g6b5, 0x2040 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1e60dff, + PIXMAN_a4r4g4b4, 0x760f, + PIXMAN_a2r2g2b2, 0x11 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a4r4g4b4, 0x3, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a8r8g8b8, 0x6600, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x30000fa, + PIXMAN_a4r4g4b4, 0x23b7, + PIXMAN_a8r8g8b8, 0x21 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r3g3b2, 0x60, + PIXMAN_r3g3b2, 0x60 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3b31b30, + PIXMAN_r3g3b2, 0x2e, + PIXMAN_a8r8g8b8, 0x3000c20 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x160ffff, + PIXMAN_a4r4g4b4, 0xff42, + PIXMAN_r3g3b2, 0xed + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x172ffff, + PIXMAN_a4r4g4b4, 0x5100, + PIXMAN_r3g3b2, 0x29 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x16300ff, + PIXMAN_a4r4g4b4, 0x5007, + PIXMAN_a8r8g8b8, 0x77 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ffff3a, + PIXMAN_a8r8g8b8, 0x26640083, + PIXMAN_a4r4g4b4, 0x220 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x106ff60, + PIXMAN_r5g6b5, 0xdce, + PIXMAN_a8r8g8b8, 0x100ba00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100e7ff, + PIXMAN_r5g6b5, 0xa00, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2b500f1, + PIXMAN_a4r4g4b4, 0x7339, + PIXMAN_a8r8g8b8, 0x1000091 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_a4r4g4b4, 0xc863, + PIXMAN_r5g6b5, 0x6 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1ffffca, + PIXMAN_a8r8g8b8, 0x8b4cf000, + PIXMAN_r3g3b2, 0xd2 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1fffe00, + PIXMAN_r3g3b2, 0x88, + PIXMAN_r3g3b2, 0x8 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x16f0000, + PIXMAN_a2r2g2b2, 0x59, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x377ff43, + PIXMAN_a4r4g4b4, 0x2a, + PIXMAN_a8r8g8b8, 0x2d + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x11dffff, + PIXMAN_r3g3b2, 0xcb, + PIXMAN_r3g3b2, 0x8 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r5g6b5, 0xbdab, + PIXMAN_a4r4g4b4, 0xbb0 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff3343, + PIXMAN_a8r8g8b8, 0x7a00ffff, + PIXMAN_a2r2g2b2, 0xd + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ebff4b, + PIXMAN_r3g3b2, 0x26, + PIXMAN_r3g3b2, 0x24 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2c1b3ff, + PIXMAN_a8r8g8b8, 0x3000152a, + PIXMAN_r3g3b2, 0x24 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1a7ffff, + PIXMAN_r3g3b2, 0x9, + PIXMAN_r5g6b5, 0x24a + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x4ff00ec, + PIXMAN_a8r8g8b8, 0x1da4961e, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff25ff, + PIXMAN_a8r8g8b8, 0x64b0ff00, + PIXMAN_r5g6b5, 0x606c + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1fd62ff, + PIXMAN_a4r4g4b4, 0x76b1, + PIXMAN_r5g6b5, 0x716e + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x194ffde, + PIXMAN_r5g6b5, 0x47ff, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x108ffff, + PIXMAN_a8r8g8b8, 0xffffff66, + PIXMAN_r5g6b5, 0xff0c + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x5ffffff, + PIXMAN_r5g6b5, 0xdf, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ad31, + PIXMAN_a2r2g2b2, 0xc5, + PIXMAN_a4r4g4b4, 0x31 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff34, + PIXMAN_a8r8g8b8, 0x6a57c491, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1fffff1, + PIXMAN_r3g3b2, 0xaf, + PIXMAN_r5g6b5, 0xb01e + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff67ff, + PIXMAN_a4r4g4b4, 0x50ff, + PIXMAN_a8r8g8b8, 0x552255 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x11bffff, + PIXMAN_r5g6b5, 0xef0c, + PIXMAN_r5g6b5, 0xc + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x16cf37d, + PIXMAN_a4r4g4b4, 0xc561, + PIXMAN_r5g6b5, 0x2301 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffff9c, + PIXMAN_a4r4g4b4, 0x2700, + PIXMAN_a8r8g8b8, 0xffff + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x200f322, + PIXMAN_a8r8g8b8, 0xff3c7e, + PIXMAN_r5g6b5, 0x2 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1f14a33, + PIXMAN_a8r8g8b8, 0x26cff79, + PIXMAN_r3g3b2, 0xf9 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x11d922c, + PIXMAN_r3g3b2, 0xab, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a2r2g2b2, 0xf5, + PIXMAN_r3g3b2, 0x9 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x18697ff, + PIXMAN_a4r4g4b4, 0x5700, + PIXMAN_r5g6b5, 0xfa6d + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x12000fc, + PIXMAN_a2r2g2b2, 0x41, + PIXMAN_a8r8g8b8, 0xb0054 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x100ccff, + PIXMAN_a4r4g4b4, 0x657e, + PIXMAN_r5g6b5, 0x3b1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff1f, + PIXMAN_a2r2g2b2, 0xa6, + PIXMAN_r5g6b5, 0x2a0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x11fff82, + PIXMAN_a4r4g4b4, 0xff94, + PIXMAN_a8r8g8b8, 0x1010123 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x154bd19, + PIXMAN_a4r4g4b4, 0xb600, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_r5g6b5, 0x8e, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x21aff00, + PIXMAN_r5g6b5, 0x71ff, + PIXMAN_r3g3b2, 0xf2 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ad00a7, + PIXMAN_a4r4g4b4, 0x23, + PIXMAN_a8r8g8b8, 0x21 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_r5g6b5, 0xb343, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x3ffa500, + PIXMAN_a8r8g8b8, 0x1af5b4, + PIXMAN_a8r8g8b8, 0xff1abc00 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ffff11, + PIXMAN_a8r8g8b8, 0x9f334f, + PIXMAN_a8r8g8b8, 0x9f0005 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2c75971, + PIXMAN_a4r4g4b4, 0x3900, + PIXMAN_a4r4g4b4, 0x211 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff49, + PIXMAN_a8r8g8b8, 0x813dc25e, + PIXMAN_r5g6b5, 0x667d + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a4r4g4b4, 0x4bff, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x20ebcff, + PIXMAN_r5g6b5, 0xc9ff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_r5g6b5, 0x51ff, + PIXMAN_r3g3b2, 0x44 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffd158, + PIXMAN_a8r8g8b8, 0x7d88ffce, + PIXMAN_r3g3b2, 0x6c + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1425e21, + PIXMAN_a2r2g2b2, 0xa5, + PIXMAN_r5g6b5, 0xe1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14b00ff, + PIXMAN_a8r8g8b8, 0xbe95004b, + PIXMAN_r5g6b5, 0x9 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14fc0cd, + PIXMAN_a8r8g8b8, 0x2d12b78b, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff8230, + PIXMAN_a2r2g2b2, 0x4c, + PIXMAN_r3g3b2, 0x44 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff31ff, + PIXMAN_a2r2g2b2, 0x14, + PIXMAN_a8r8g8b8, 0x551000 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x17800ff, + PIXMAN_a4r4g4b4, 0x22, + PIXMAN_a8r8g8b8, 0x22 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x14500ff, + PIXMAN_a4r4g4b4, 0x6400, + PIXMAN_r5g6b5, 0xff78 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff9d, + PIXMAN_r3g3b2, 0xcd, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x3ff00ff, + PIXMAN_a4r4g4b4, 0xf269, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff28b8, + PIXMAN_a4r4g4b4, 0x33ff, + PIXMAN_r5g6b5, 0x3000 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1006278, + PIXMAN_a8r8g8b8, 0x8a7f18, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffcb00, + PIXMAN_a4r4g4b4, 0x7900, + PIXMAN_a2r2g2b2, 0x14 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x115ff00, + PIXMAN_a8r8g8b8, 0x508d, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x3ff30b5, + PIXMAN_r5g6b5, 0x2e60, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x182fffb, + PIXMAN_r3g3b2, 0x1, + PIXMAN_a8r8g8b8, 0x1000054 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x16fff00, + PIXMAN_r5g6b5, 0x7bc0, + PIXMAN_a8r8g8b8, 0x367900 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1d95dd8, + PIXMAN_a4r4g4b4, 0xfff5, + PIXMAN_r5g6b5, 0xff09 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff3cdc, + PIXMAN_a8r8g8b8, 0x3bda45ff, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x13900f8, + PIXMAN_a8r8g8b8, 0x7e00ffff, + PIXMAN_a4r4g4b4, 0xff00 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x10ea9ff, + PIXMAN_a8r8g8b8, 0xff34ff22, + PIXMAN_r5g6b5, 0xff52 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2002e99, + PIXMAN_a4r4g4b4, 0x3000, + PIXMAN_r5g6b5, 0x43 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_r5g6b5, 0x19ff, + PIXMAN_r3g3b2, 0x3 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_a8r8g8b8, 0xffff4251, + PIXMAN_a2r2g2b2, 0x4 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x121c9ff, + PIXMAN_a4r4g4b4, 0xd2, + PIXMAN_a4r4g4b4, 0x2 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff4d, + PIXMAN_a2r2g2b2, 0x5e, + PIXMAN_a2r2g2b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x29ab4ff, + PIXMAN_r3g3b2, 0x47, + PIXMAN_a8r8g8b8, 0x1900 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffc1ac, + PIXMAN_a8r8g8b8, 0xee4ed0ac, + PIXMAN_a8r8g8b8, 0x1009d74 + }, + { PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_a8r8g8b8, 0x269dffdc, + PIXMAN_a8r8g8b8, 0xff0b00e0, + PIXMAN_a8r8g8b8, 0x2a200ff + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffffff, + PIXMAN_a4r4g4b4, 0x3200, + PIXMAN_r3g3b2, 0x24 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ffed, + PIXMAN_a8r8g8b8, 0x67004eff, + PIXMAN_a2r2g2b2, 0x5 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2fffd6a, + PIXMAN_a8r8g8b8, 0xc9003bff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x253ff00, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x13600ad, + PIXMAN_r5g6b5, 0x35ae, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffa8ff, + PIXMAN_a8r8g8b8, 0xff5f00, + PIXMAN_r3g3b2, 0xe0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x10067ff, + PIXMAN_a4r4g4b4, 0x450d, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1ff01ff, + PIXMAN_r3g3b2, 0x77, + PIXMAN_r5g6b5, 0x6800 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x11da4ff, + PIXMAN_r5g6b5, 0x83c9, + PIXMAN_a4r4g4b4, 0x44 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffd4ff, + PIXMAN_r3g3b2, 0xaa, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_a8r8g8b8, 0x71002a, + PIXMAN_a4r4g4b4, 0x700 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1d7ffff, + PIXMAN_r5g6b5, 0x3696, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffffc8, + PIXMAN_r5g6b5, 0xe900, + PIXMAN_a8r8g8b8, 0x2000 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff004a, + PIXMAN_r3g3b2, 0x48, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x3ffe969, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x300ff73, + PIXMAN_r5g6b5, 0xff, + PIXMAN_a8r8g8b8, 0x3000073 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff93ff, + PIXMAN_a8r8g8b8, 0x61fc7d2b, + PIXMAN_a4r4g4b4, 0x2 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x11bffff, + PIXMAN_a4r4g4b4, 0xffb4, + PIXMAN_r5g6b5, 0x8 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1e9e100, + PIXMAN_a2r2g2b2, 0x56, + PIXMAN_a2r2g2b2, 0x14 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x3ffb656, + PIXMAN_r3g3b2, 0x4, + PIXMAN_a4r4g4b4, 0xff99 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_r3g3b2, 0x68, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1006dff, + PIXMAN_a2r2g2b2, 0x5d, + PIXMAN_a8r8g8b8, 0xff00ff55 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x11c00cb, + PIXMAN_a2r2g2b2, 0x44, + PIXMAN_a4r4g4b4, 0x4 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1d0ff86, + PIXMAN_r3g3b2, 0x5c, + PIXMAN_a8r8g8b8, 0x3c0000 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2f25fff, + PIXMAN_r3g3b2, 0x36, + PIXMAN_a8r8g8b8, 0x2a444aa + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x134af85, + PIXMAN_r3g3b2, 0x29, + PIXMAN_r5g6b5, 0xf300 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x13398af, + PIXMAN_r3g3b2, 0xa5, + PIXMAN_a4r4g4b4, 0x13 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff57ff, + PIXMAN_a4r4g4b4, 0x252c, + PIXMAN_r3g3b2, 0x40 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x115ffff, + PIXMAN_r5g6b5, 0xffe3, + PIXMAN_r5g6b5, 0x3303 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_r5g6b5, 0x6300, + PIXMAN_r3g3b2, 0x6c + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x4ccff9c, + PIXMAN_r5g6b5, 0xcc, + PIXMAN_a8r8g8b8, 0x400003d + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffc6dd, + PIXMAN_r5g6b5, 0x9bff, + PIXMAN_r5g6b5, 0x5bff + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x14fff95, + PIXMAN_r3g3b2, 0x46, + PIXMAN_a8r8g8b8, 0x1000063 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1e6b700, + PIXMAN_r5g6b5, 0xc1ff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff54, + PIXMAN_a8r8g8b8, 0x2e00ff, + PIXMAN_r5g6b5, 0x2800 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3ffffff, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1003550, + PIXMAN_r5g6b5, 0xffcc, + PIXMAN_r5g6b5, 0x1e0 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffff74, + PIXMAN_r3g3b2, 0x28, + PIXMAN_a8r8g8b8, 0xfe2f49d7 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1e35100, + PIXMAN_r3g3b2, 0x57, + PIXMAN_r5g6b5, 0x4000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x268ffa3, + PIXMAN_a4r4g4b4, 0x30, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x35700f8, + PIXMAN_r5g6b5, 0xa4, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x3ce1dff, + PIXMAN_r5g6b5, 0x2a5e, + PIXMAN_a8r8g8b8, 0x210000 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x494a7ff, + PIXMAN_a8r8g8b8, 0x1bffe400, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x10026d9, + PIXMAN_a8r8g8b8, 0xec00621f, + PIXMAN_r5g6b5, 0x63 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff99, + PIXMAN_a8r8g8b8, 0xf334ff, + PIXMAN_a4r4g4b4, 0x30 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffc200, + PIXMAN_a8r8g8b8, 0x1e0000ff, + PIXMAN_a8r8g8b8, 0x1e1700 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_r3g3b2, 0x4b, + PIXMAN_r5g6b5, 0x4818 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2e800ff, + PIXMAN_a4r4g4b4, 0xd3, + PIXMAN_a4r4g4b4, 0xec + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x19a001f, + PIXMAN_r3g3b2, 0x76, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1cb00c3, + PIXMAN_a4r4g4b4, 0x5cff, + PIXMAN_r5g6b5, 0x4008 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_r3g3b2, 0x2a, + PIXMAN_r5g6b5, 0xc5fb + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a8r8g8b8, 0xea005a88, + PIXMAN_r3g3b2, 0xb3 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffea, + PIXMAN_a4r4g4b4, 0x54eb, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x179ffff, + PIXMAN_r3g3b2, 0xa4, + PIXMAN_a8r8g8b8, 0x2400 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x17ad226, + PIXMAN_r3g3b2, 0xa4, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff01, + PIXMAN_a2r2g2b2, 0x25, + PIXMAN_a4r4g4b4, 0x50 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x20000ff, + PIXMAN_a8r8g8b8, 0x2b00c127, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x200ff96, + PIXMAN_a4r4g4b4, 0x2300, + PIXMAN_r3g3b2, 0x6 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r3g3b2, 0x87, + PIXMAN_r5g6b5, 0x5bc8 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1fffff2, + PIXMAN_r3g3b2, 0x7e, + PIXMAN_a2r2g2b2, 0xe + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1ff8b00, + PIXMAN_a4r4g4b4, 0xd500, + PIXMAN_r3g3b2, 0x40 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a8r8g8b8, 0x1bff38, + PIXMAN_a4r4g4b4, 0xf0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x158ff39, + PIXMAN_a4r4g4b4, 0x75dd, + PIXMAN_a8r8g8b8, 0xdd31 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1009b70, + PIXMAN_a4r4g4b4, 0xff40, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x12fb43f, + PIXMAN_a4r4g4b4, 0x69ff, + PIXMAN_a2r2g2b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff95, + PIXMAN_a2r2g2b2, 0x84, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x200d188, + PIXMAN_r5g6b5, 0xde6, + PIXMAN_r5g6b5, 0x3 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2c70000, + PIXMAN_r5g6b5, 0x24fa, + PIXMAN_a8r8g8b8, 0x21a0000 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ff24, + PIXMAN_a4r4g4b4, 0x835, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x10000cd, + PIXMAN_a2r2g2b2, 0x7f, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x379ffff, + PIXMAN_a8r8g8b8, 0x23ffff00, + PIXMAN_r5g6b5, 0x4eda + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x172e3ff, + PIXMAN_r3g3b2, 0xa6, + PIXMAN_r5g6b5, 0x100 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100f5ad, + PIXMAN_a4r4g4b4, 0x7908, + PIXMAN_a2r2g2b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100fff9, + PIXMAN_a2r2g2b2, 0xf1, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1abff00, + PIXMAN_r5g6b5, 0x31ff, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x112ffd1, + PIXMAN_r3g3b2, 0x9, + PIXMAN_a2r2g2b2, 0xdd + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ffbf, + PIXMAN_r3g3b2, 0x2c, + PIXMAN_a4r4g4b4, 0x60 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffb7ff, + PIXMAN_r3g3b2, 0x6b, + PIXMAN_a4r4g4b4, 0x630 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x20005ff, + PIXMAN_a4r4g4b4, 0x8462, + PIXMAN_r5g6b5, 0xb1e8 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff5b00, + PIXMAN_r5g6b5, 0x70ff, + PIXMAN_r3g3b2, 0x60 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffffc3, + PIXMAN_r3g3b2, 0x39, + PIXMAN_a8r8g8b8, 0x200db41 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x306ffff, + PIXMAN_a8r8g8b8, 0xdcffff1f, + PIXMAN_a8r8g8b8, 0x306ff00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x193daff, + PIXMAN_a8r8g8b8, 0x69000000, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x2a200ff, + PIXMAN_a8r8g8b8, 0x183aff00, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100f1a5, + PIXMAN_a8r8g8b8, 0xb5fc21ff, + PIXMAN_r5g6b5, 0xfe00 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1630019, + PIXMAN_a8r8g8b8, 0x6affc400, + PIXMAN_r5g6b5, 0x56ff + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff8bc2, + PIXMAN_r3g3b2, 0xee, + PIXMAN_r5g6b5, 0x1c0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x260ffff, + PIXMAN_a4r4g4b4, 0x3f00, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x169ffed, + PIXMAN_a8r8g8b8, 0xffffff3f, + PIXMAN_a8r8g8b8, 0x169ff00 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x154c181, + PIXMAN_a4r4g4b4, 0x5100, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1e09c00, + PIXMAN_r5g6b5, 0xca00, + PIXMAN_a4r4g4b4, 0xb00 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff8dff, + PIXMAN_a8r8g8b8, 0x610038ff, + PIXMAN_a8r8g8b8, 0x1001f02 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1e400ff, + PIXMAN_a4r4g4b4, 0x66bd, + PIXMAN_r3g3b2, 0x68 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x25362ff, + PIXMAN_a4r4g4b4, 0x31ff, + PIXMAN_a8r8g8b8, 0x111433 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3ad0039, + PIXMAN_r3g3b2, 0x26, + PIXMAN_a8r8g8b8, 0x3000026 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2e442ef, + PIXMAN_r3g3b2, 0x32, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1720000, + PIXMAN_a8r8g8b8, 0x55fdea00, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x14bb0d7, + PIXMAN_a8r8g8b8, 0x7fffff47, + PIXMAN_a2r2g2b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x13dffff, + PIXMAN_a8r8g8b8, 0xa3860672, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x120495a, + PIXMAN_a4r4g4b4, 0x407e, + PIXMAN_a8r8g8b8, 0x54 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff8fff, + PIXMAN_a2r2g2b2, 0x29, + PIXMAN_r5g6b5, 0xa + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100a31a, + PIXMAN_a4r4g4b4, 0xde4c, + PIXMAN_a4r4g4b4, 0x1 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1d4008c, + PIXMAN_r3g3b2, 0x79, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_a4r4g4b4, 0x7de4, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1b27e62, + PIXMAN_a4r4g4b4, 0x7941, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x300ff00, + PIXMAN_a8r8g8b8, 0xfcff255e, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ff00b8, + PIXMAN_a8r8g8b8, 0x19ff718d, + PIXMAN_r5g6b5, 0x1802 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x235ff13, + PIXMAN_a8r8g8b8, 0x34bcd9ff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1006400, + PIXMAN_a4r4g4b4, 0x7000, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff8bff, + PIXMAN_a4r4g4b4, 0xfff4, + PIXMAN_a4r4g4b4, 0xf80 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x24630ff, + PIXMAN_a8r8g8b8, 0x1f00000b, + PIXMAN_a8r8g8b8, 0x9061f + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff8a00, + PIXMAN_a8r8g8b8, 0x79ffab00, + PIXMAN_r5g6b5, 0x7a00 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x19807ff, + PIXMAN_a4r4g4b4, 0x6794, + PIXMAN_a8r8g8b8, 0xff002e00 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x10000da, + PIXMAN_a4r4g4b4, 0xf864, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffffde, + PIXMAN_a2r2g2b2, 0x94, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x200c800, + PIXMAN_r5g6b5, 0xe9d4, + PIXMAN_a8r8g8b8, 0x2c00 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff00c9, + PIXMAN_r3g3b2, 0x4c, + PIXMAN_r5g6b5, 0x4800 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x122d5ff, + PIXMAN_r5g6b5, 0x418b, + PIXMAN_a4r4g4b4, 0x25 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff55, + PIXMAN_a2r2g2b2, 0x1c, + PIXMAN_a8r8g8b8, 0xff00 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x135ffff, + PIXMAN_r5g6b5, 0x39c4, + PIXMAN_r5g6b5, 0xb7 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100d2c3, + PIXMAN_r3g3b2, 0x2a, + PIXMAN_a8r8g8b8, 0x3c00 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x17268ff, + PIXMAN_a8r8g8b8, 0x7c00ffff, + PIXMAN_r5g6b5, 0x318f + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_r3g3b2, 0x68, + PIXMAN_r3g3b2, 0xb4 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r5g6b5, 0xff86, + PIXMAN_a8r8g8b8, 0x200f300 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x18a23ff, + PIXMAN_a2r2g2b2, 0x44, + PIXMAN_a4r4g4b4, 0x205 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x16bff23, + PIXMAN_a8r8g8b8, 0x31fd00ff, + PIXMAN_r3g3b2, 0x7 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x137d1ff, + PIXMAN_a4r4g4b4, 0x56c1, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff5bff, + PIXMAN_a4r4g4b4, 0xfff4, + PIXMAN_a4r4g4b4, 0xf50 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x15c6b00, + PIXMAN_a8r8g8b8, 0x7d008a, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x12091ff, + PIXMAN_a8r8g8b8, 0xb74cff6b, + PIXMAN_a2r2g2b2, 0x8 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff5bff, + PIXMAN_a8r8g8b8, 0xff6ddce8, + PIXMAN_a2r2g2b2, 0x10 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a4r4g4b4, 0xffb7, + PIXMAN_a4r4g4b4, 0xb0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x173ffff, + PIXMAN_r5g6b5, 0xff2c, + PIXMAN_a4r4g4b4, 0x6 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x17102ff, + PIXMAN_a8r8g8b8, 0x955bff66, + PIXMAN_a8r8g8b8, 0x280066 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x3c7ff24, + PIXMAN_r5g6b5, 0xc4, + PIXMAN_r5g6b5, 0x163 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100c2a6, + PIXMAN_r5g6b5, 0xa9b9, + PIXMAN_a4r4g4b4, 0x8 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x26049ff, + PIXMAN_a4r4g4b4, 0xb2, + PIXMAN_r5g6b5, 0x8904 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2f100ff, + PIXMAN_r3g3b2, 0x30, + PIXMAN_a8r8g8b8, 0x2220100 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffff88, + PIXMAN_r3g3b2, 0x7e, + PIXMAN_r3g3b2, 0x60 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x153ffab, + PIXMAN_a8r8g8b8, 0xfd10725a, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff00d2, + PIXMAN_r5g6b5, 0xff6b, + PIXMAN_a8r8g8b8, 0x101014a + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100d965, + PIXMAN_a8r8g8b8, 0xff007b00, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ec0000, + PIXMAN_r5g6b5, 0x6fff, + PIXMAN_r5g6b5, 0x6000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x19d59a2, + PIXMAN_a8r8g8b8, 0x4a00ff7a, + PIXMAN_a8r8g8b8, 0x2e1a2f + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1eb0000, + PIXMAN_a4r4g4b4, 0x72bc, + PIXMAN_r5g6b5, 0x1800 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a4r4g4b4, 0xc034, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x195ff15, + PIXMAN_a4r4g4b4, 0xb7b1, + PIXMAN_r5g6b5, 0x4000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffdf94, + PIXMAN_a4r4g4b4, 0x78, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x26f00ff, + PIXMAN_a4r4g4b4, 0xff93, + PIXMAN_r5g6b5, 0x1dd2 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ff3fc5, + PIXMAN_r3g3b2, 0x2f, + PIXMAN_a8r8g8b8, 0x240000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff696e, + PIXMAN_a4r4g4b4, 0x22ff, + PIXMAN_r5g6b5, 0x34d + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x10033d9, + PIXMAN_a8r8g8b8, 0x38650000, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a4r4g4b4, 0x2070, + PIXMAN_r5g6b5, 0x2100 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1008746, + PIXMAN_a8r8g8b8, 0xb56971, + PIXMAN_r5g6b5, 0xc25c + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x144d200, + PIXMAN_a4r4g4b4, 0xff42, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffffd0, + PIXMAN_r5g6b5, 0x5b00, + PIXMAN_r3g3b2, 0x4c + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a8r8g8b8, 0xff006f, + PIXMAN_r5g6b5, 0xd + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x10666ff, + PIXMAN_a4r4g4b4, 0x39b2, + PIXMAN_r5g6b5, 0xa6 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x11a007d, + PIXMAN_r3g3b2, 0xf9, + PIXMAN_a8r8g8b8, 0x11a0000 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1eb90ee, + PIXMAN_r5g6b5, 0xd, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff42d5, + PIXMAN_a4r4g4b4, 0x3400, + PIXMAN_r3g3b2, 0x40 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1dfff00, + PIXMAN_a8r8g8b8, 0x3ffff9d2, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff6500, + PIXMAN_a2r2g2b2, 0x56, + PIXMAN_r3g3b2, 0x44 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x119ffe6, + PIXMAN_r3g3b2, 0x8d, + PIXMAN_a4r4g4b4, 0xff00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100cd00, + PIXMAN_r5g6b5, 0x33ff, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x569ffd7, + PIXMAN_r5g6b5, 0x8cc, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100876a, + PIXMAN_a8r8g8b8, 0x575447a5, + PIXMAN_r5g6b5, 0x164 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x12d00ff, + PIXMAN_a4r4g4b4, 0x3fff, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff953b, + PIXMAN_a4r4g4b4, 0x2914, + PIXMAN_r5g6b5, 0x20a1 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffead4, + PIXMAN_a8r8g8b8, 0xff00ea4e, + PIXMAN_r3g3b2, 0x5a + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff6400, + PIXMAN_a2r2g2b2, 0x99, + PIXMAN_r5g6b5, 0xa620 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x17b0084, + PIXMAN_r3g3b2, 0xbd, + PIXMAN_a4r4g4b4, 0x500 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x4f90bbb, + PIXMAN_a8r8g8b8, 0xff00d21f, + PIXMAN_a8r8g8b8, 0xfb00fc4a + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffbb1d, + PIXMAN_a8r8g8b8, 0x2dff79ff, + PIXMAN_r5g6b5, 0x2c0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a2r2g2b2, 0x43, + PIXMAN_a4r4g4b4, 0x6f + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1f000ff, + PIXMAN_a4r4g4b4, 0xb393, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1c60020, + PIXMAN_a8r8g8b8, 0x6bffffff, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1727d00, + PIXMAN_a2r2g2b2, 0x67, + PIXMAN_a4r4g4b4, 0x400 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x14a5194, + PIXMAN_a4r4g4b4, 0xd7ff, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x20003fa, + PIXMAN_a4r4g4b4, 0x24ff, + PIXMAN_a8r8g8b8, 0xffff1550 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1a6ff83, + PIXMAN_a4r4g4b4, 0xf400, + PIXMAN_r5g6b5, 0x2800 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffcf00, + PIXMAN_r5g6b5, 0x71ff, + PIXMAN_a4r4g4b4, 0x30 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x333ffff, + PIXMAN_a4r4g4b4, 0x2c00, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1c2ffe8, + PIXMAN_r5g6b5, 0xc200, + PIXMAN_a8r8g8b8, 0xfeca41ff + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a2r2g2b2, 0x47, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a8r8g8b8, 0x3aa0102 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffeb00, + PIXMAN_a4r4g4b4, 0xb493, + PIXMAN_a4r4g4b4, 0x400 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2afffff, + PIXMAN_r5g6b5, 0xcb, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x183ff00, + PIXMAN_r3g3b2, 0x87, + PIXMAN_r5g6b5, 0xae91 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x3ffff00, + PIXMAN_a4r4g4b4, 0x2ba4, + PIXMAN_r5g6b5, 0x2100 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x215cbc2, + PIXMAN_a4r4g4b4, 0xafd3, + PIXMAN_a8r8g8b8, 0x115b000 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1853f65, + PIXMAN_a8r8g8b8, 0xc68cdc41, + PIXMAN_r5g6b5, 0x3 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x3ffff8f, + PIXMAN_a4r4g4b4, 0x8824, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x28e08e6, + PIXMAN_a8r8g8b8, 0x2cffff31, + PIXMAN_r5g6b5, 0x1805 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1b500be, + PIXMAN_r5g6b5, 0xd946, + PIXMAN_r5g6b5, 0x9800 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x133ffb3, + PIXMAN_a2r2g2b2, 0x42, + PIXMAN_a8r8g8b8, 0x11553c + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x21aff81, + PIXMAN_r3g3b2, 0xc7, + PIXMAN_r5g6b5, 0x120 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x12e004f, + PIXMAN_a4r4g4b4, 0xf617, + PIXMAN_a4r4g4b4, 0x102 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x164861f, + PIXMAN_r3g3b2, 0x4e, + PIXMAN_r5g6b5, 0x19c0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0eff, + PIXMAN_a8r8g8b8, 0xff5c00aa, + PIXMAN_r5g6b5, 0x5800 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1e4c60f, + PIXMAN_a8r8g8b8, 0x38ff0e0c, + PIXMAN_a4r4g4b4, 0xff2a + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_a8r8g8b8, 0x9f3d6700, + PIXMAN_r5g6b5, 0xf3ff + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x205ffd0, + PIXMAN_a8r8g8b8, 0xffc22b3b, + PIXMAN_a8r8g8b8, 0x2040000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0059, + PIXMAN_r5g6b5, 0x74ff, + PIXMAN_a8r8g8b8, 0x1730101 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x29affb8, + PIXMAN_r5g6b5, 0xff, + PIXMAN_a8r8g8b8, 0x2d25cff + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff8b, + PIXMAN_a4r4g4b4, 0xff7b, + PIXMAN_r5g6b5, 0x3a0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x2a86ad7, + PIXMAN_a4r4g4b4, 0xdc22, + PIXMAN_a8r8g8b8, 0x2860000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x3ff00ff, + PIXMAN_r3g3b2, 0x33, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1e50063, + PIXMAN_a8r8g8b8, 0x35ff95d7, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ffe6ff, + PIXMAN_a8r8g8b8, 0x153ef297, + PIXMAN_r5g6b5, 0x6d2 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x34ffeff, + PIXMAN_a4r4g4b4, 0x2e, + PIXMAN_r5g6b5, 0x1d + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ffeada, + PIXMAN_r5g6b5, 0xabc6, + PIXMAN_a8r8g8b8, 0xfd15b256 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_a8r8g8b8, 0xcff3f32, + PIXMAN_a8r8g8b8, 0x3f00 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1e1b0f1, + PIXMAN_a8r8g8b8, 0xff63ff54, + PIXMAN_r3g3b2, 0x5d + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ffff23, + PIXMAN_a8r8g8b8, 0x380094ff, + PIXMAN_r5g6b5, 0x3a4b + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a4r4g4b4, 0x1000, + PIXMAN_r5g6b5, 0xca, + PIXMAN_a8r8g8b8, 0x3434500 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x195ffe5, + PIXMAN_a4r4g4b4, 0x3a29, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x139007a, + PIXMAN_a4r4g4b4, 0x4979, + PIXMAN_r5g6b5, 0x84 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa9, + PIXMAN_a4r4g4b4, 0xfa18, + PIXMAN_a8r8g8b8, 0xabff67ff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x94, + PIXMAN_a4r4g4b4, 0x5109, + PIXMAN_a8r8g8b8, 0x3affffff + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r5g6b5, 0xd038, + PIXMAN_r5g6b5, 0xff00, + PIXMAN_r5g6b5, 0xf9a5 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x543128ff, + PIXMAN_a8r8g8b8, 0x7029ff, + PIXMAN_a8r8g8b8, 0x316b1d7 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r5g6b5, 0x53ff, + PIXMAN_r5g6b5, 0x72ff, + PIXMAN_a8r8g8b8, 0xffffdeff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x5b00002b, + PIXMAN_a4r4g4b4, 0xc3, + PIXMAN_a8r8g8b8, 0x23530be + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xcefc0041, + PIXMAN_a8r8g8b8, 0xf60d02, + PIXMAN_a8r8g8b8, 0x1f2ffe5 + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0xffdb, + PIXMAN_r5g6b5, 0xc700, + PIXMAN_r5g6b5, 0x654 + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0xffc6, + PIXMAN_r5g6b5, 0xff09, + PIXMAN_r5g6b5, 0xfe58 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x95, + PIXMAN_r5g6b5, 0x1b4a, + PIXMAN_a8r8g8b8, 0xab234cff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x95, + PIXMAN_a4r4g4b4, 0x5e99, + PIXMAN_a8r8g8b8, 0x3b1c1cdd + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r5g6b5, 0x22, + PIXMAN_r5g6b5, 0xd00, + PIXMAN_r5g6b5, 0xfbb1 + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0xffc8, + PIXMAN_a8r8g8b8, 0xa1a3ffff, + PIXMAN_r5g6b5, 0x44a + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xffff7cff, + PIXMAN_r5g6b5, 0x900, + PIXMAN_a8r8g8b8, 0xffff94ec + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa7, + PIXMAN_r5g6b5, 0xff, + PIXMAN_a8r8g8b8, 0xaa00cffe + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x85, + PIXMAN_r5g6b5, 0xffb3, + PIXMAN_a8r8g8b8, 0xaaffff4a + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x3500a118, + PIXMAN_a4r4g4b4, 0x9942, + PIXMAN_a8r8g8b8, 0x01ff405e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb5, + PIXMAN_x4a4, 0xe, + PIXMAN_a8r8g8b8, 0xffbaff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xe872, + PIXMAN_x2r10g10b10, 0xa648ff00, + PIXMAN_a2r10g10b10, 0x14ff00e8, + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x4d2db34, + PIXMAN_a8, 0x19, + PIXMAN_r5g6b5, 0x9700, + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x2ff0076, + PIXMAN_a8r8g8b8, 0x2a0000, + PIXMAN_r3g3b2, 0x0, + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x14f00ff, + PIXMAN_r5g6b5, 0xd48, + PIXMAN_a4r4g4b4, 0x0, + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3d8bbff, + PIXMAN_r5g6b5, 0x6900, + PIXMAN_a8r8g8b8, 0x0, + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff00ff, + PIXMAN_a4r4g4b4, 0x2300, + PIXMAN_r3g3b2, 0x0, + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x4d2db34, + PIXMAN_a8r8g8b8, 0xff0019ff, + PIXMAN_r5g6b5, 0x9700, + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ac05, + PIXMAN_r3g3b2, 0xef, + PIXMAN_a2r2g2b2, 0xff, + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xbf, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x7e + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x33 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a8r8g8b8, 0x84c4ffd7, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xffddff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xff6e56, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x20ff1ade + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a4r4g4b4, 0xfe0, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xbdff + }, + { PIXMAN_OP_SCREEN, + PIXMAN_a8r8g8b8, 0x9671ff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x43 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x39ff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x1968 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a4r4g4b4, 0x4247, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xd8ffff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xff00, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x79 + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r3g3b2, 0xe0, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x39 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xfff8, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xff + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0x75fc, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x11ff, + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r3g3b2, 0x52, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xc627 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x9f2b, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x4b00e7f5 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0x00dfff5c, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x5e0f, + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_a8r8g8b8, 0xff00121b, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x3776 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r5g6b5, 0x03e0, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x01003c00, + }, { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 0x0f00c300, + PIXMAN_null, 0x00, PIXMAN_x14r6g6b6, 0x003c0, }, { PIXMAN_OP_DISJOINT_XOR, PIXMAN_a4r4g4b4, 0xd0c0, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x5300ea00, }, { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 0x20c6bf00, + PIXMAN_null, 0x00, PIXMAN_r5g6b5, 0xb9ff }, { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 0x204ac7ff, + PIXMAN_null, 0x00, PIXMAN_r5g6b5, 0xc1ff }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0xffc3, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x102d00dd }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0x1f00, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x1bdf0c89 }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0xf9d2, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x1076bcf7 }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0x00c3, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x1bfe9ae5 }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0x09ff, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x0b00c16c }, { PIXMAN_OP_DISJOINT_ATOP, PIXMAN_a2r2g2b2, 0xbc, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x9efff1ff }, { PIXMAN_OP_DISJOINT_ATOP, PIXMAN_a4r4g4b4, 0xae5f, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0xf215b675 }, { PIXMAN_OP_DISJOINT_ATOP_REVERSE, PIXMAN_a8r8g8b8, 0xce007980, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x80ffe4ad }, { PIXMAN_OP_DISJOINT_XOR, PIXMAN_a8r8g8b8, 0xb8b07bea, + PIXMAN_null, 0x00, PIXMAN_a4r4g4b4, 0x939c }, { PIXMAN_OP_CONJOINT_ATOP_REVERSE, PIXMAN_r5g6b5, 0x0063, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x10bb1ed7, }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xbf, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x7e + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xffffff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xff3fffff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r3g3b2, 0x38, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x5b + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_a8r8g8b8, 0x2e9effff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x77 + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x33 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0xd0089ff, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xb1 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_r3g3b2, 0x8a, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xcd0004 + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_a8r8g8b8, 0xffff1e3a, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xcf00 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a8r8g8b8, 0x84c4ffd7, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xffddff + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_a4r4g4b4, 0xfd75, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x7f + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_r3g3b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x63ff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xff6e56, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x20ff1ade + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a4r4g4b4, 0xfe0, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xbdff + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_r5g6b5, 0x9799, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x8d + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a8r8g8b8, 0xe8ff1c33, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x6200 + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_a8r8g8b8, 0x22ffffff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x63 + }, + { PIXMAN_OP_SCREEN, + PIXMAN_a8r8g8b8, 0x9671ff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x43 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a2r2g2b2, 0x83, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xff + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_r3g3b2, 0x0, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x97 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r5g6b5, 0xb900, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x6800ff00 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a4r4g4b4, 0xff, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0x8e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xff00, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0xbc + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0xfffe, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x90 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_r3g3b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xc35f + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x39ff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a2r2g2b2, 0x1e, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xbaff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xb4ffff26, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xff + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_a4r4g4b4, 0xe3ff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x878b + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0xff700044, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x6 + }, + { PIXMAN_OP_DARKEN, + PIXMAN_a2r2g2b2, 0xb6, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xcd00 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a2r2g2b2, 0xfe, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x12 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xb1ff006c, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xff7c + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r3g3b2, 0x4e, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x3c + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x1968 + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r3g3b2, 0xe7, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x8cced6ac + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xa500, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x1bff009d + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0x45ff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x32 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a2r2g2b2, 0x18, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xdc00 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a4r4g4b4, 0x4247, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xd8ffff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xff00, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x79 + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r3g3b2, 0xf, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x9fff00ff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0x93, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a2r2g2b2, 0xa3, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xca + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r3g3b2, 0xe0, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x39 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r3g3b2, 0x16, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x98ffff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_r3g3b2, 0x96, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x225f6c + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a4r4g4b4, 0x12c7, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xb100 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xffda91, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0x6a + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xfff8, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xf0ff48ca + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xf1ff, + PIXMAN_r5g6b5, 0x6eff, + PIXMAN_a8r8g8b8, 0xffffff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xf1ff, + PIXMAN_a8, 0xdf, + PIXMAN_a8r8g8b8, 0xffffff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xf1ff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xffffff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xb867, + PIXMAN_a4r4g4b4, 0x82d9, + PIXMAN_a8r8g8b8, 0xffc5, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xa9f5, + PIXMAN_r5g6b5, 0xadff, + PIXMAN_a8r8g8b8, 0xffff00, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x4900, + PIXMAN_r5g6b5, 0x865c, + PIXMAN_a8r8g8b8, 0xebff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xd9ff, + PIXMAN_a8r8g8b8, 0xffffffff, + PIXMAN_a8r8g8b8, 0x8ff0d, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x41ff, + PIXMAN_a4r4g4b4, 0xcff, + PIXMAN_a8r8g8b8, 0xe1ff00, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x91ff, + PIXMAN_a2r2g2b2, 0xf3, + PIXMAN_a8r8g8b8, 0xe4ffb4, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xb9ff, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_a8r8g8b8, 0xffff, + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0x473affff, + PIXMAN_r5g6b5, 0x2b00, + PIXMAN_r5g6b5, 0x1ff, + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0xe4ff, + PIXMAN_r3g3b2, 0xff, + PIXMAN_r5g6b5, 0x89ff, + }, }; static void @@ -159,35 +2855,59 @@ access (pixman_image_t *image, int x, int y) } static pixman_bool_t -verify (int test_no, const pixel_combination_t *combination, int size) +verify (int test_no, const pixel_combination_t *combination, int size, + pixman_bool_t component_alpha) { - pixman_image_t *src, *dest; - pixel_checker_t src_checker, dest_checker; - color_t source_color, dest_color, reference_color; + pixman_image_t *src, *mask, *dest; + pixel_checker_t src_checker, mask_checker, dest_checker; + color_t source_color, mask_color, dest_color, reference_color; + pixman_bool_t have_mask = (combination->mask_format != PIXMAN_null); pixman_bool_t result = TRUE; int i, j; /* Compute reference color */ pixel_checker_init (&src_checker, combination->src_format); + if (have_mask) + pixel_checker_init (&mask_checker, combination->mask_format); pixel_checker_init (&dest_checker, combination->dest_format); + pixel_checker_convert_pixel_to_color ( &src_checker, combination->src_pixel, &source_color); + if (combination->mask_format != PIXMAN_null) + { + pixel_checker_convert_pixel_to_color ( + &mask_checker, combination->mask_pixel, &mask_color); + } pixel_checker_convert_pixel_to_color ( &dest_checker, combination->dest_pixel, &dest_color); + do_composite (combination->op, - &source_color, NULL, &dest_color, - &reference_color, FALSE); + &source_color, + have_mask? &mask_color : NULL, + &dest_color, + &reference_color, component_alpha); src = pixman_image_create_bits ( combination->src_format, size, size, NULL, -1); + if (have_mask) + { + mask = pixman_image_create_bits ( + combination->mask_format, size, size, NULL, -1); + + pixman_image_set_component_alpha (mask, component_alpha); + } dest = pixman_image_create_bits ( combination->dest_format, size, size, NULL, -1); fill (src, combination->src_pixel); + if (have_mask) + fill (mask, combination->mask_pixel); fill (dest, combination->dest_pixel); pixman_image_composite32 ( - combination->op, src, NULL, dest, 0, 0, 0, 0, 0, 0, size, size); + combination->op, src, + have_mask ? mask : NULL, + dest, 0, 0, 0, 0, 0, 0, size, size); for (j = 0; j < size; ++j) { @@ -200,9 +2920,13 @@ verify (int test_no, const pixel_combination_t *combination, int size) { printf ("----------- Test %d failed ----------\n", test_no); - printf (" operator: %s\n", operator_name (combination->op)); + printf (" operator: %s (%s)\n", operator_name (combination->op), + have_mask? component_alpha ? "component alpha" : "unified alpha" : "no mask"); printf (" src format: %s\n", format_name (combination->src_format)); + if (have_mask != PIXMAN_null) + printf (" mask format: %s\n", format_name (combination->mask_format)); printf (" dest format: %s\n", format_name (combination->dest_format)); + printf (" - source ARGB: %f %f %f %f (pixel: %8x)\n", source_color.a, source_color.r, source_color.g, source_color.b, combination->src_pixel); @@ -210,6 +2934,16 @@ verify (int test_no, const pixel_combination_t *combination, int size) &a, &r, &g, &b); printf (" %8d %8d %8d %8d\n", a, r, g, b); + if (have_mask) + { + printf (" - mask ARGB: %f %f %f %f (pixel: %8x)\n", + mask_color.a, mask_color.r, mask_color.g, mask_color.b, + combination->mask_pixel); + pixel_checker_split_pixel (&mask_checker, combination->mask_pixel, + &a, &r, &g, &b); + printf (" %8d %8d %8d %8d\n", a, r, g, b); + } + printf (" - dest ARGB: %f %f %f %f (pixel: %8x)\n", dest_color.a, dest_color.r, dest_color.g, dest_color.b, combination->dest_pixel); @@ -248,19 +2982,41 @@ main (int argc, char **argv) { int result = 0; int i, j; + int lo, hi; + + if (argc > 1) + { + lo = atoi (argv[1]); + hi = lo + 1; + } + else + { + lo = 0; + hi = ARRAY_LENGTH (regressions); + } - for (i = 0; i < ARRAY_LENGTH (regressions); ++i) + for (i = lo; i < hi; ++i) { const pixel_combination_t *combination = &(regressions[i]); for (j = 1; j < 34; ++j) { - if (!verify (i, combination, j)) + int k, ca; + + ca = combination->mask_format == PIXMAN_null ? 1 : 2; + + for (k = 0; k < ca; ++k) { - result = 1; - break; + if (!verify (i, combination, j, k)) + { + result = 1; + goto next_regression; + } } } + + next_regression: + ; } return result; diff --git a/lib/pixman/test/radial-invalid.c b/lib/pixman/test/radial-invalid.c new file mode 100644 index 000000000..ec85fe320 --- /dev/null +++ b/lib/pixman/test/radial-invalid.c @@ -0,0 +1,54 @@ +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "utils.h" + +#define WIDTH 100 +#define HEIGHT 100 + +int +main () +{ + pixman_image_t *radial; + pixman_image_t *dest = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, WIDTH, HEIGHT, NULL, -1); + + static const pixman_transform_t xform = + { + { { 0x346f7, 0x0, 0x0 }, + { 0x0, 0x346f7, 0x0 }, + { 0x0, 0x0, 0x10000 } + }, + }; + + static const pixman_gradient_stop_t stops[] = + { + { 0xde61, { 0x4481, 0x96e8, 0x1e6a, 0x29e1 } }, + { 0xfdd5, { 0xfa10, 0xcc26, 0xbc43, 0x1eb7 } }, + { 0xfe1e, { 0xd257, 0x5bac, 0x6fc2, 0xa33b } }, + }; + + static const pixman_point_fixed_t inner = { 0x320000, 0x320000 }; + static const pixman_point_fixed_t outer = { 0x320000, 0x3cb074 }; + + enable_divbyzero_exceptions (); + enable_invalid_exceptions (); + + radial = pixman_image_create_radial_gradient ( + &inner, + &outer, + 0xab074, /* inner radius */ + 0x0, /* outer radius */ + stops, sizeof (stops) / sizeof (stops[0])); + + pixman_image_set_repeat (radial, PIXMAN_REPEAT_REFLECT); + pixman_image_set_transform (radial, &xform); + + pixman_image_composite ( + PIXMAN_OP_OVER, + radial, NULL, dest, + 0, 0, 0, 0, + 0, 0, WIDTH, HEIGHT); + + return 0; +} diff --git a/lib/pixman/test/scaling-test.c b/lib/pixman/test/scaling-test.c index e2f7fa9f4..0ece61110 100644 --- a/lib/pixman/test/scaling-test.c +++ b/lib/pixman/test/scaling-test.c @@ -73,7 +73,7 @@ test_composite (int testnum, pixman_op_t op; pixman_repeat_t repeat = PIXMAN_REPEAT_NONE; pixman_repeat_t mask_repeat = PIXMAN_REPEAT_NONE; - pixman_format_code_t src_fmt, dst_fmt; + pixman_format_code_t src_fmt, mask_fmt, dst_fmt; uint32_t * srcbuf; uint32_t * dstbuf; uint32_t * maskbuf; @@ -145,6 +145,7 @@ test_composite (int testnum, prng_randmemset (dstbuf, dst_stride * dst_height, 0); src_fmt = get_format (src_bpp); + mask_fmt = PIXMAN_a8; dst_fmt = get_format (dst_bpp); if (prng_rand_n (2)) @@ -169,7 +170,7 @@ test_composite (int testnum, src_fmt, src_width, src_height, srcbuf, src_stride); mask_img = pixman_image_create_bits ( - PIXMAN_a8, mask_width, mask_height, maskbuf, mask_stride); + mask_fmt, mask_width, mask_height, maskbuf, mask_stride); dst_img = pixman_image_create_bits ( dst_fmt, dst_width, dst_height, dstbuf, dst_stride); @@ -255,21 +256,6 @@ test_composite (int testnum, else pixman_image_set_filter (mask_img, PIXMAN_FILTER_BILINEAR, NULL, 0); - if (verbose) - { - printf ("src_fmt=%s, dst_fmt=%s\n", - format_name (src_fmt), format_name (dst_fmt)); - printf ("op=%s, scale_x=%d, scale_y=%d, repeat=%d\n", - operator_name (op), scale_x, scale_y, repeat); - printf ("translate_x=%d, translate_y=%d\n", - translate_x, translate_y); - printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", - src_width, src_height, dst_width, dst_height); - printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", - src_x, src_y, dst_x, dst_y); - printf ("w=%d, h=%d\n", w, h); - } - if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; @@ -352,10 +338,45 @@ test_composite (int testnum, } if (prng_rand_n (2) == 0) - pixman_image_composite (op, src_img, NULL, dst_img, - src_x, src_y, 0, 0, dst_x, dst_y, w, h); - else - pixman_image_composite (op, src_img, mask_img, dst_img, + { + mask_fmt = PIXMAN_null; + pixman_image_unref (mask_img); + mask_img = NULL; + mask_x = 0; + mask_y = 0; + } + + if (verbose) + { + printf ("op=%s, src_fmt=%s, mask_fmt=%s, dst_fmt=%s\n", + operator_name (op), format_name (src_fmt), + format_name (mask_fmt), format_name (dst_fmt)); + printf ("scale_x=%d, scale_y=%d, repeat=%d, filter=%d\n", + scale_x, scale_y, repeat, src_img->common.filter); + printf ("translate_x=%d, translate_y=%d\n", + translate_x, translate_y); + if (mask_fmt != PIXMAN_null) + { + printf ("mask_scale_x=%d, mask_scale_y=%d, " + "mask_repeat=%d, mask_filter=%d\n", + mask_scale_x, mask_scale_y, mask_repeat, + mask_img->common.filter); + printf ("mask_translate_x=%d, mask_translate_y=%d\n", + mask_translate_x, mask_translate_y); + } + printf ("src_width=%d, src_height=%d, src_x=%d, src_y=%d\n", + src_width, src_height, src_x, src_y); + if (mask_fmt != PIXMAN_null) + { + printf ("mask_width=%d, mask_height=%d, mask_x=%d, mask_y=%d\n", + mask_width, mask_height, mask_x, mask_y); + } + printf ("dst_width=%d, dst_height=%d, dst_x=%d, dst_y=%d\n", + dst_width, dst_height, dst_x, dst_y); + printf ("w=%d, h=%d\n", w, h); + } + + pixman_image_composite (op, src_img, mask_img, dst_img, src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h); crc32 = compute_crc32_for_image (0, dst_img); @@ -364,7 +385,8 @@ test_composite (int testnum, print_image (dst_img); pixman_image_unref (src_img); - pixman_image_unref (mask_img); + if (mask_img != NULL) + pixman_image_unref (mask_img); pixman_image_unref (dst_img); if (src_stride < 0) diff --git a/lib/pixman/test/solid-test.c b/lib/pixman/test/solid-test.c new file mode 100644 index 000000000..c6ea39770 --- /dev/null +++ b/lib/pixman/test/solid-test.c @@ -0,0 +1,353 @@ +/* + * Copyright © 2015 RISC OS Open Ltd + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holders make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Ben Avison (bavison@riscosopen.org) + * + */ + +#include "utils.h" +#include <stdlib.h> +#include <stdio.h> + +#define WIDTH 32 +#define HEIGHT 32 + +static const pixman_op_t op_list[] = { + PIXMAN_OP_SRC, + PIXMAN_OP_OVER, + PIXMAN_OP_ADD, + PIXMAN_OP_CLEAR, + PIXMAN_OP_SRC, + PIXMAN_OP_DST, + PIXMAN_OP_OVER, + PIXMAN_OP_OVER_REVERSE, + PIXMAN_OP_IN, + PIXMAN_OP_IN_REVERSE, + PIXMAN_OP_OUT, + PIXMAN_OP_OUT_REVERSE, + PIXMAN_OP_ATOP, + PIXMAN_OP_ATOP_REVERSE, + PIXMAN_OP_XOR, + PIXMAN_OP_ADD, + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, +#if 0 /* these use floating point math and are not always bitexact on different platforms */ + PIXMAN_OP_SATURATE, + PIXMAN_OP_DISJOINT_CLEAR, + PIXMAN_OP_DISJOINT_SRC, + PIXMAN_OP_DISJOINT_DST, + PIXMAN_OP_DISJOINT_OVER, + PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_OP_DISJOINT_IN, + PIXMAN_OP_DISJOINT_IN_REVERSE, + PIXMAN_OP_DISJOINT_OUT, + PIXMAN_OP_DISJOINT_OUT_REVERSE, + PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_OP_DISJOINT_XOR, + PIXMAN_OP_CONJOINT_CLEAR, + PIXMAN_OP_CONJOINT_SRC, + PIXMAN_OP_CONJOINT_DST, + PIXMAN_OP_CONJOINT_OVER, + PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_OP_CONJOINT_IN, + PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_OP_CONJOINT_OUT, + PIXMAN_OP_CONJOINT_OUT_REVERSE, + PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_OP_CONJOINT_XOR, + PIXMAN_OP_COLOR_DODGE, + PIXMAN_OP_COLOR_BURN, + PIXMAN_OP_SOFT_LIGHT, + PIXMAN_OP_HSL_HUE, + PIXMAN_OP_HSL_SATURATION, + PIXMAN_OP_HSL_COLOR, + PIXMAN_OP_HSL_LUMINOSITY, +#endif +}; + +/* The first eight format in the list are by far the most widely + * used formats, so we test those more than the others + */ +#define N_MOST_LIKELY_FORMATS 8 + +static const pixman_format_code_t img_fmt_list[] = { + PIXMAN_a8r8g8b8, + PIXMAN_a8b8g8r8, + PIXMAN_x8r8g8b8, + PIXMAN_x8b8g8r8, + PIXMAN_r5g6b5, + PIXMAN_b5g6r5, + PIXMAN_a8, + PIXMAN_a1, + PIXMAN_r3g3b2, + PIXMAN_b8g8r8a8, + PIXMAN_b8g8r8x8, + PIXMAN_r8g8b8a8, + PIXMAN_r8g8b8x8, + PIXMAN_x14r6g6b6, + PIXMAN_r8g8b8, + PIXMAN_b8g8r8, +#if 0 /* These are going to use floating point in the near future */ + PIXMAN_x2r10g10b10, + PIXMAN_a2r10g10b10, + PIXMAN_x2b10g10r10, + PIXMAN_a2b10g10r10, +#endif + PIXMAN_a1r5g5b5, + PIXMAN_x1r5g5b5, + PIXMAN_a1b5g5r5, + PIXMAN_x1b5g5r5, + PIXMAN_a4r4g4b4, + PIXMAN_x4r4g4b4, + PIXMAN_a4b4g4r4, + PIXMAN_x4b4g4r4, + PIXMAN_r3g3b2, + PIXMAN_b2g3r3, + PIXMAN_a2r2g2b2, + PIXMAN_a2b2g2r2, + PIXMAN_c8, + PIXMAN_g8, + PIXMAN_x4c4, + PIXMAN_x4g4, + PIXMAN_c4, + PIXMAN_g4, + PIXMAN_g1, + PIXMAN_x4a4, + PIXMAN_a4, + PIXMAN_r1g2b1, + PIXMAN_b1g2r1, + PIXMAN_a1r1g1b1, + PIXMAN_a1b1g1r1, + PIXMAN_null +}; + +static const pixman_format_code_t mask_fmt_list[] = { + PIXMAN_a8r8g8b8, + PIXMAN_a8, + PIXMAN_a4, + PIXMAN_a1, + PIXMAN_null +}; + +static pixman_indexed_t rgb_palette[9]; +static pixman_indexed_t y_palette[9]; + +static pixman_format_code_t +random_format (const pixman_format_code_t *allowed_formats) +{ + int n = 0; + + while (allowed_formats[n] != PIXMAN_null) + n++; + + if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0) + n = N_MOST_LIKELY_FORMATS; + + return allowed_formats[prng_rand_n (n)]; +} + +static pixman_image_t * +create_multi_pixel_image (const pixman_format_code_t *allowed_formats, + uint32_t *buffer, + pixman_format_code_t *used_fmt) +{ + pixman_format_code_t fmt; + pixman_image_t *img; + int stride; + + fmt = random_format (allowed_formats); + stride = (WIDTH * PIXMAN_FORMAT_BPP (fmt) + 31) / 32 * 4; + img = pixman_image_create_bits (fmt, WIDTH, HEIGHT, buffer, stride); + + if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR) + pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)])); + else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY) + pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)])); + + prng_randmemset (buffer, WIDTH * HEIGHT * 4, 0); + image_endian_swap (img); + + if (used_fmt) + *used_fmt = fmt; + + return img; +} + +static pixman_image_t * +create_solid_image (const pixman_format_code_t *allowed_formats, + uint32_t *buffer, + pixman_format_code_t *used_fmt) +{ + if (prng_rand_n (2)) + { + /* Use a repeating 1x1 bitmap image for solid */ + pixman_format_code_t fmt; + pixman_image_t *img, *dummy_img; + uint32_t bpp, dummy_buf; + + fmt = random_format (allowed_formats); + bpp = PIXMAN_FORMAT_BPP (fmt); + img = pixman_image_create_bits (fmt, 1, 1, buffer, 4); + pixman_image_set_repeat (img, PIXMAN_REPEAT_NORMAL); + + if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR) + pixman_image_set_indexed (img, &(rgb_palette[bpp])); + else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY) + pixman_image_set_indexed (img, &(y_palette[bpp])); + + /* Force the flags to be calculated for image with initial + * bitmap contents of 0 or 2^bpp-1 by plotting from it into a + * separate throwaway image. It is simplest to write all 0s + * or all 1s to the first word irrespective of the colour + * depth even though we actually only care about the first + * pixel since the stride has to be a whole number of words. + */ + *buffer = prng_rand_n (2) ? 0xFFFFFFFFu : 0; + dummy_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, 1, 1, + &dummy_buf, 4); + pixman_image_composite (PIXMAN_OP_SRC, img, NULL, dummy_img, + 0, 0, 0, 0, 0, 0, 1, 1); + pixman_image_unref (dummy_img); + + /* Now set the bitmap contents to a random value */ + prng_randmemset (buffer, 4, 0); + image_endian_swap (img); + + if (used_fmt) + *used_fmt = fmt; + + return img; + } + else + { + /* Use a native solid image */ + pixman_color_t color; + pixman_image_t *img; + + color.alpha = prng_rand_n (UINT16_MAX + 1); + color.red = prng_rand_n (UINT16_MAX + 1); + color.green = prng_rand_n (UINT16_MAX + 1); + color.blue = prng_rand_n (UINT16_MAX + 1); + img = pixman_image_create_solid_fill (&color); + + if (used_fmt) + *used_fmt = PIXMAN_solid; + + return img; + } +} + +static uint32_t +test_solid (int testnum, int verbose) +{ + pixman_op_t op; + uint32_t src_buf[WIDTH * HEIGHT]; + uint32_t dst_buf[WIDTH * HEIGHT]; + uint32_t mask_buf[WIDTH * HEIGHT]; + pixman_image_t *src_img; + pixman_image_t *dst_img; + pixman_image_t *mask_img = NULL; + pixman_format_code_t src_fmt, dst_fmt, mask_fmt = PIXMAN_null; + pixman_bool_t ca = 0; + uint32_t crc32; + + prng_srand (testnum); + + op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; + + dst_img = create_multi_pixel_image (img_fmt_list, dst_buf, &dst_fmt); + switch (prng_rand_n (3)) + { + case 0: /* Solid source, no mask */ + src_img = create_solid_image (img_fmt_list, src_buf, &src_fmt); + break; + case 1: /* Solid source, bitmap mask */ + src_img = create_solid_image (img_fmt_list, src_buf, &src_fmt); + mask_img = create_multi_pixel_image (mask_fmt_list, mask_buf, &mask_fmt); + break; + case 2: /* Bitmap image, solid mask */ + src_img = create_multi_pixel_image (img_fmt_list, src_buf, &src_fmt); + mask_img = create_solid_image (mask_fmt_list, mask_buf, &mask_fmt); + break; + default: + abort (); + } + + if (mask_img) + { + ca = prng_rand_n (2); + pixman_image_set_component_alpha (mask_img, ca); + } + + if (verbose) + { + printf ("op=%s\n", operator_name (op)); + printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n", + format_name (src_fmt), format_name (dst_fmt), + format_name (mask_fmt)); + printf ("src_size=%u, mask_size=%u, component_alpha=%u\n", + src_fmt == PIXMAN_solid ? 1 : src_img->bits.width, + !mask_img || mask_fmt == PIXMAN_solid ? 1 : mask_img->bits.width, + ca); + } + + pixman_image_composite (op, src_img, mask_img, dst_img, + 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); + + if (verbose) + print_image (dst_img); + + crc32 = compute_crc32_for_image (0, dst_img); + + pixman_image_unref (src_img); + pixman_image_unref (dst_img); + if (mask_img) + pixman_image_unref (mask_img); + + return crc32; +} + +int +main (int argc, const char *argv[]) +{ + int i; + + prng_srand (0); + + for (i = 1; i <= 8; i++) + { + initialize_palette (&(rgb_palette[i]), i, TRUE); + initialize_palette (&(y_palette[i]), i, FALSE); + } + + return fuzzer_test_main ("solid", 500000, + 0xC30FD380, + test_solid, argc, argv); +} diff --git a/lib/pixman/test/thread-test.c b/lib/pixman/test/thread-test.c index 0b07b269d..1c2f0407a 100644 --- a/lib/pixman/test/thread-test.c +++ b/lib/pixman/test/thread-test.c @@ -38,38 +38,11 @@ static const pixman_op_t operators[] = PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_XOR, PIXMAN_OP_ADD, - PIXMAN_OP_SATURATE, - PIXMAN_OP_DISJOINT_CLEAR, - PIXMAN_OP_DISJOINT_SRC, - PIXMAN_OP_DISJOINT_DST, - PIXMAN_OP_DISJOINT_OVER, - PIXMAN_OP_DISJOINT_OVER_REVERSE, - PIXMAN_OP_DISJOINT_IN, - PIXMAN_OP_DISJOINT_IN_REVERSE, - PIXMAN_OP_DISJOINT_OUT, - PIXMAN_OP_DISJOINT_OUT_REVERSE, - PIXMAN_OP_DISJOINT_ATOP, - PIXMAN_OP_DISJOINT_ATOP_REVERSE, - PIXMAN_OP_DISJOINT_XOR, - PIXMAN_OP_CONJOINT_CLEAR, - PIXMAN_OP_CONJOINT_SRC, - PIXMAN_OP_CONJOINT_DST, - PIXMAN_OP_CONJOINT_OVER, - PIXMAN_OP_CONJOINT_OVER_REVERSE, - PIXMAN_OP_CONJOINT_IN, - PIXMAN_OP_CONJOINT_IN_REVERSE, - PIXMAN_OP_CONJOINT_OUT, - PIXMAN_OP_CONJOINT_OUT_REVERSE, - PIXMAN_OP_CONJOINT_ATOP, - PIXMAN_OP_CONJOINT_ATOP_REVERSE, - PIXMAN_OP_CONJOINT_XOR, PIXMAN_OP_MULTIPLY, PIXMAN_OP_SCREEN, PIXMAN_OP_OVERLAY, PIXMAN_OP_DARKEN, PIXMAN_OP_LIGHTEN, - PIXMAN_OP_COLOR_DODGE, - PIXMAN_OP_COLOR_BURN, PIXMAN_OP_HARD_LIGHT, PIXMAN_OP_DIFFERENCE, PIXMAN_OP_EXCLUSION, @@ -183,7 +156,7 @@ main (void) crc32 = compute_crc32 (0, crc32s, sizeof crc32s); -#define EXPECTED 0xE299B18E +#define EXPECTED 0x82C4D9FB if (crc32 != EXPECTED) { diff --git a/lib/pixman/test/tolerance-test.c b/lib/pixman/test/tolerance-test.c new file mode 100644 index 000000000..320bb7fe0 --- /dev/null +++ b/lib/pixman/test/tolerance-test.c @@ -0,0 +1,360 @@ +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <float.h> +#include <math.h> +#include "utils.h" + +#define MAX_WIDTH 16 +#define MAX_HEIGHT 16 +#define MAX_STRIDE 4 + +static const pixman_format_code_t formats[] = +{ + PIXMAN_a2r10g10b10, + PIXMAN_x2r10g10b10, + PIXMAN_a8r8g8b8, + PIXMAN_a4r4g4b4, + PIXMAN_a2r2g2b2, + PIXMAN_r5g6b5, + PIXMAN_r3g3b2, +}; + +static const pixman_op_t operators[] = +{ + PIXMAN_OP_CLEAR, + PIXMAN_OP_SRC, + PIXMAN_OP_DST, + PIXMAN_OP_OVER, + PIXMAN_OP_OVER_REVERSE, + PIXMAN_OP_IN, + PIXMAN_OP_IN_REVERSE, + PIXMAN_OP_OUT, + PIXMAN_OP_OUT_REVERSE, + PIXMAN_OP_ATOP, + PIXMAN_OP_ATOP_REVERSE, + PIXMAN_OP_XOR, + PIXMAN_OP_ADD, + PIXMAN_OP_SATURATE, + + PIXMAN_OP_DISJOINT_CLEAR, + PIXMAN_OP_DISJOINT_SRC, + PIXMAN_OP_DISJOINT_DST, + PIXMAN_OP_DISJOINT_OVER, + PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_OP_DISJOINT_IN, + PIXMAN_OP_DISJOINT_IN_REVERSE, + PIXMAN_OP_DISJOINT_OUT, + PIXMAN_OP_DISJOINT_OUT_REVERSE, + PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_OP_DISJOINT_XOR, + + PIXMAN_OP_CONJOINT_CLEAR, + PIXMAN_OP_CONJOINT_SRC, + PIXMAN_OP_CONJOINT_DST, + PIXMAN_OP_CONJOINT_OVER, + PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_OP_CONJOINT_IN, + PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_OP_CONJOINT_OUT, + PIXMAN_OP_CONJOINT_OUT_REVERSE, + PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_OP_CONJOINT_XOR, + + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_COLOR_DODGE, + PIXMAN_OP_COLOR_BURN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_SOFT_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, +}; + +#define RANDOM_ELT(array) \ + (array[prng_rand_n (ARRAY_LENGTH (array))]) + +static void +free_bits (pixman_image_t *image, void *data) +{ + free (image->bits.bits); +} + +static pixman_image_t * +create_image (pixman_image_t **clone) +{ + pixman_format_code_t format = RANDOM_ELT (formats); + pixman_image_t *image; + int width = prng_rand_n (MAX_WIDTH); + int height = prng_rand_n (MAX_HEIGHT); + int stride = ((width * (PIXMAN_FORMAT_BPP (format) / 8)) + 3) & ~3; + uint32_t *bytes = malloc (stride * height); + + prng_randmemset (bytes, stride * height, RANDMEMSET_MORE_00_AND_FF); + + image = pixman_image_create_bits ( + format, width, height, bytes, stride); + + pixman_image_set_destroy_function (image, free_bits, NULL); + + assert (image); + + if (clone) + { + uint32_t *bytes_dup = malloc (stride * height); + + memcpy (bytes_dup, bytes, stride * height); + + *clone = pixman_image_create_bits ( + format, width, height, bytes_dup, stride); + + pixman_image_set_destroy_function (*clone, free_bits, NULL); + } + + return image; +} + +static pixman_bool_t +access (pixman_image_t *image, int x, int y, uint32_t *pixel) +{ + int bytes_per_pixel; + int stride; + uint8_t *location; + + if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height) + return FALSE; + + bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8; + stride = image->bits.rowstride * 4; + + location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel; + + if (bytes_per_pixel == 4) + *pixel = *(uint32_t *)location; + else if (bytes_per_pixel == 2) + *pixel = *(uint16_t *)location; + else if (bytes_per_pixel == 1) + *pixel = *(uint8_t *)location; + else + assert (0); + + return TRUE; +} + +static void +get_color (pixel_checker_t *checker, + pixman_image_t *image, + int x, int y, + color_t *color, + uint32_t *pixel) +{ + if (!access (image, x, y, pixel)) + { + color->a = 0.0; + color->r = 0.0; + color->g = 0.0; + color->b = 0.0; + } + else + { + pixel_checker_convert_pixel_to_color ( + checker, *pixel, color); + } +} + +static pixman_bool_t +verify (int test_no, + pixman_op_t op, + pixman_image_t *source, + pixman_image_t *mask, + pixman_image_t *dest, + pixman_image_t *orig_dest, + int x, int y, + int width, int height, + pixman_bool_t component_alpha) +{ + pixel_checker_t dest_checker, src_checker, mask_checker; + int i, j; + + pixel_checker_init (&src_checker, source->bits.format); + pixel_checker_init (&dest_checker, dest->bits.format); + pixel_checker_init (&mask_checker, mask->bits.format); + + assert (dest->bits.format == orig_dest->bits.format); + + for (j = y; j < y + height; ++j) + { + for (i = x; i < x + width; ++i) + { + color_t src_color, mask_color, orig_dest_color, result; + uint32_t dest_pixel, orig_dest_pixel, src_pixel, mask_pixel; + + access (dest, i, j, &dest_pixel); + + get_color (&src_checker, + source, i - x, j - y, + &src_color, &src_pixel); + + get_color (&mask_checker, + mask, i - x, j - y, + &mask_color, &mask_pixel); + + get_color (&dest_checker, + orig_dest, i, j, + &orig_dest_color, &orig_dest_pixel); + + do_composite (op, + &src_color, &mask_color, &orig_dest_color, + &result, component_alpha); + + if (!pixel_checker_check (&dest_checker, dest_pixel, &result)) + { + int a, r, g, b; + + printf ("--------- Test 0x%x failed ---------\n", test_no); + + printf (" operator: %s (%s alpha)\n", operator_name (op), + component_alpha? "component" : "unified"); + printf (" dest_x, dest_y: %d %d\n", x, y); + printf (" width, height: %d %d\n", width, height); + printf (" source: format: %-14s size: %2d x %2d\n", + format_name (source->bits.format), + source->bits.width, source->bits.height); + printf (" mask: format: %-14s size: %2d x %2d\n", + format_name (mask->bits.format), + mask->bits.width, mask->bits.height); + printf (" dest: format: %-14s size: %2d x %2d\n", + format_name (dest->bits.format), + dest->bits.width, dest->bits.height); + printf (" -- Failed pixel: (%d, %d) --\n", i, j); + printf (" source ARGB: %f %f %f %f (pixel: %x)\n", + src_color.a, src_color.r, src_color.g, src_color.b, + src_pixel); + printf (" mask ARGB: %f %f %f %f (pixel: %x)\n", + mask_color.a, mask_color.r, mask_color.g, mask_color.b, + mask_pixel); + printf (" dest ARGB: %f %f %f %f (pixel: %x)\n", + orig_dest_color.a, orig_dest_color.r, orig_dest_color.g, orig_dest_color.b, + orig_dest_pixel); + printf (" expected ARGB: %f %f %f %f\n", + result.a, result.r, result.g, result.b); + + pixel_checker_get_min (&dest_checker, &result, &a, &r, &g, &b); + printf (" min acceptable: %8d %8d %8d %8d\n", a, r, g, b); + + pixel_checker_split_pixel (&dest_checker, dest_pixel, &a, &r, &g, &b); + printf (" got: %8d %8d %8d %8d (pixel: %x)\n", a, r, g, b, dest_pixel); + + pixel_checker_get_max (&dest_checker, &result, &a, &r, &g, &b); + printf (" max acceptable: %8d %8d %8d %8d\n", a, r, g, b); + printf ("\n"); + printf (" { %s,\n", operator_name (op)); + printf (" PIXMAN_%s,\t0x%x,\n", format_name (source->bits.format), src_pixel); + printf (" PIXMAN_%s,\t0x%x,\n", format_name (mask->bits.format), mask_pixel); + printf (" PIXMAN_%s,\t0x%x\n", format_name (dest->bits.format), orig_dest_pixel); + printf (" },\n"); + return FALSE; + } + } + } + + return TRUE; +} + +static pixman_bool_t +do_check (int i) +{ + pixman_image_t *source, *dest, *mask; + pixman_op_t op; + int x, y, width, height; + pixman_image_t *dest_copy; + pixman_bool_t result = TRUE; + pixman_bool_t component_alpha; + + prng_srand (i); + op = RANDOM_ELT (operators); + x = prng_rand_n (MAX_WIDTH); + y = prng_rand_n (MAX_HEIGHT); + width = prng_rand_n (MAX_WIDTH) + 4; + height = prng_rand_n (MAX_HEIGHT) + 4; + + source = create_image (NULL); + mask = create_image (NULL); + dest = create_image (&dest_copy); + + if (x >= dest->bits.width) + x = dest->bits.width / 2; + if (y >= dest->bits.height) + y = dest->bits.height / 2; + if (x + width > dest->bits.width) + width = dest->bits.width - x; + if (y + height > dest->bits.height) + height = dest->bits.height - y; + + component_alpha = prng_rand_n (2); + + pixman_image_set_component_alpha (mask, component_alpha); + + pixman_image_composite32 (op, source, mask, dest, + 0, 0, 0, 0, + x, y, width, height); + + if (!verify (i, op, source, mask, dest, dest_copy, + x, y, width, height, component_alpha)) + { + result = FALSE; + } + + pixman_image_unref (source); + pixman_image_unref (mask); + pixman_image_unref (dest); + pixman_image_unref (dest_copy); + + return result; +} + +#define N_TESTS 10000000 + +int +main (int argc, const char *argv[]) +{ + int i; + int result = 0; + + if (argc == 2) + { + if (strcmp (argv[1], "--forever") == 0) + { + uint32_t n; + + prng_srand (time (0)); + + n = prng_rand(); + + for (;;) + do_check (n++); + } + else + { + do_check (strtol (argv[1], NULL, 0)); + } + } + else + { +#ifdef USE_OPENMP +# pragma omp parallel for default(none) reduction(|:result) +#endif + for (i = 0; i < N_TESTS; ++i) + { + if (!do_check (i)) + result |= 1; + } + } + + return result; +} diff --git a/lib/pixman/test/utils.c b/lib/pixman/test/utils.c index ebe0ccc09..f8e42a5d3 100644 --- a/lib/pixman/test/utils.c +++ b/lib/pixman/test/utils.c @@ -4,6 +4,9 @@ #include <math.h> #include <signal.h> #include <stdlib.h> +#include <float.h> +#include <ctype.h> +#include <limits.h> #ifdef HAVE_GETTIMEOFDAY #include <sys/time.h> @@ -27,6 +30,8 @@ #include <png.h> #endif +#define ROUND_UP(x, mult) (((x) + (mult) - 1) / (mult) * (mult)) + /* Random number generator state */ @@ -375,7 +380,16 @@ typedef struct int n_bytes; } info_t; -#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP) +#if FENCE_MALLOC_ACTIVE + +unsigned long +fence_get_page_size () +{ + /* You can fake a page size here, if you want to test e.g. 64 kB + * pages on a 4 kB page system. Just put a multiplier below. + */ + return getpagesize (); +} /* This is apparently necessary on at least OS X */ #ifndef MAP_ANONYMOUS @@ -385,7 +399,7 @@ typedef struct void * fence_malloc (int64_t len) { - unsigned long page_size = getpagesize(); + unsigned long page_size = fence_get_page_size (); unsigned long page_mask = page_size - 1; uint32_t n_payload_bytes = (len + page_mask) & ~page_mask; uint32_t n_bytes = @@ -434,7 +448,7 @@ fence_malloc (int64_t len) void fence_free (void *data) { - uint32_t page_size = getpagesize(); + uint32_t page_size = fence_get_page_size (); uint8_t *payload = data; uint8_t *leading_protected = payload - N_LEADING_PROTECTED * page_size; uint8_t *initial_page = leading_protected - page_size; @@ -443,7 +457,98 @@ fence_free (void *data) munmap (info->addr, info->n_bytes); } -#else +static void +fence_image_destroy (pixman_image_t *image, void *data) +{ + fence_free (data); +} + +/* Create an image with fence pages. + * + * Creates an image, where the data area is allocated with fence_malloc (). + * Each row has an additional page in the stride. + * + * min_width is only a minimum width for the image. The width is aligned up + * for the row size to be divisible by both page size and pixel size. + * + * If stride_fence is true, the additional page on each row will be + * armed to cause SIGSEGV or SIGBUS on all accesses. This should catch + * all accesses outside the valid row pixels. + */ +pixman_image_t * +fence_image_create_bits (pixman_format_code_t format, + int min_width, + int height, + pixman_bool_t stride_fence) +{ + unsigned page_size = fence_get_page_size (); + unsigned page_mask = page_size - 1; + unsigned bitspp = PIXMAN_FORMAT_BPP (format); + unsigned bits_boundary; + unsigned row_bits; + int width; /* pixels */ + unsigned stride; /* bytes */ + void *pixels; + pixman_image_t *image; + int i; + + /* must be power of two */ + assert (page_size && (page_size & page_mask) == 0); + + if (bitspp < 1 || min_width < 1 || height < 1) + abort (); + + /* least common multiple between page size * 8 and bitspp */ + bits_boundary = bitspp; + while (! (bits_boundary & 1)) + bits_boundary >>= 1; + bits_boundary *= page_size * 8; + + /* round up to bits_boundary */ + row_bits = ROUND_UP ( (unsigned)min_width * bitspp, bits_boundary); + width = row_bits / bitspp; + + stride = row_bits / 8; + if (stride_fence) + stride += page_size; /* add fence page */ + + if (UINT_MAX / stride < (unsigned)height) + abort (); + + pixels = fence_malloc (stride * (unsigned)height); + if (!pixels) + return NULL; + + if (stride_fence) + { + uint8_t *guard = (uint8_t *)pixels + stride - page_size; + + /* arm row end fence pages */ + for (i = 0; i < height; i++) + { + if (mprotect (guard + i * stride, page_size, PROT_NONE) == -1) + goto out_fail; + } + } + + assert (width >= min_width); + + image = pixman_image_create_bits_no_clear (format, width, height, + pixels, stride); + if (!image) + goto out_fail; + + pixman_image_set_destroy_function (image, fence_image_destroy, pixels); + + return image; + +out_fail: + fence_free (pixels); + + return NULL; +} + +#else /* FENCE_MALLOC_ACTIVE */ void * fence_malloc (int64_t len) @@ -457,7 +562,25 @@ fence_free (void *data) free (data); } -#endif +pixman_image_t * +fence_image_create_bits (pixman_format_code_t format, + int min_width, + int height, + pixman_bool_t stride_fence) +{ + return pixman_image_create_bits (format, min_width, height, NULL, 0); + /* Implicitly allocated storage does not need a destroy function + * to get freed on refcount hitting zero. + */ +} + +unsigned long +fence_get_page_size () +{ + return 0; +} + +#endif /* FENCE_MALLOC_ACTIVE */ uint8_t * make_random_bytes (int n_bytes) @@ -843,9 +966,21 @@ enable_divbyzero_exceptions (void) { #ifdef HAVE_FENV_H #ifdef HAVE_FEENABLEEXCEPT +#ifdef HAVE_FEDIVBYZERO feenableexcept (FE_DIVBYZERO); #endif #endif +#endif +} + +void +enable_invalid_exceptions (void) +{ +#ifdef HAVE_FENV_H +#ifdef HAVE_FEENABLEEXCEPT + feenableexcept (FE_INVALID); +#endif +#endif } void * @@ -937,71 +1072,332 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb) } } +struct operator_entry { + pixman_op_t op; + const char *name; + pixman_bool_t is_alias; +}; + +typedef struct operator_entry operator_entry_t; + +static const operator_entry_t op_list[] = +{ +#define ENTRY(op) \ + { PIXMAN_OP_##op, "PIXMAN_OP_" #op, FALSE } +#define ALIAS(op, nam) \ + { PIXMAN_OP_##op, nam, TRUE } + + /* operator_name () will return the first hit in this table, + * so keep the list properly ordered between entries and aliases. + * Aliases are not listed by list_operators (). + */ + + ENTRY (CLEAR), + ENTRY (SRC), + ENTRY (DST), + ENTRY (OVER), + ENTRY (OVER_REVERSE), + ALIAS (OVER_REVERSE, "overrev"), + ENTRY (IN), + ENTRY (IN_REVERSE), + ALIAS (IN_REVERSE, "inrev"), + ENTRY (OUT), + ENTRY (OUT_REVERSE), + ALIAS (OUT_REVERSE, "outrev"), + ENTRY (ATOP), + ENTRY (ATOP_REVERSE), + ALIAS (ATOP_REVERSE, "atoprev"), + ENTRY (XOR), + ENTRY (ADD), + ENTRY (SATURATE), + + ENTRY (DISJOINT_CLEAR), + ENTRY (DISJOINT_SRC), + ENTRY (DISJOINT_DST), + ENTRY (DISJOINT_OVER), + ENTRY (DISJOINT_OVER_REVERSE), + ENTRY (DISJOINT_IN), + ENTRY (DISJOINT_IN_REVERSE), + ENTRY (DISJOINT_OUT), + ENTRY (DISJOINT_OUT_REVERSE), + ENTRY (DISJOINT_ATOP), + ENTRY (DISJOINT_ATOP_REVERSE), + ENTRY (DISJOINT_XOR), + + ENTRY (CONJOINT_CLEAR), + ENTRY (CONJOINT_SRC), + ENTRY (CONJOINT_DST), + ENTRY (CONJOINT_OVER), + ENTRY (CONJOINT_OVER_REVERSE), + ENTRY (CONJOINT_IN), + ENTRY (CONJOINT_IN_REVERSE), + ENTRY (CONJOINT_OUT), + ENTRY (CONJOINT_OUT_REVERSE), + ENTRY (CONJOINT_ATOP), + ENTRY (CONJOINT_ATOP_REVERSE), + ENTRY (CONJOINT_XOR), + + ENTRY (MULTIPLY), + ENTRY (SCREEN), + ENTRY (OVERLAY), + ENTRY (DARKEN), + ENTRY (LIGHTEN), + ENTRY (COLOR_DODGE), + ENTRY (COLOR_BURN), + ENTRY (HARD_LIGHT), + ENTRY (SOFT_LIGHT), + ENTRY (DIFFERENCE), + ENTRY (EXCLUSION), + ENTRY (HSL_HUE), + ENTRY (HSL_SATURATION), + ENTRY (HSL_COLOR), + ENTRY (HSL_LUMINOSITY), + + ALIAS (NONE, "<invalid operator 'none'>") + +#undef ENTRY +#undef ALIAS +}; + +struct format_entry +{ + pixman_format_code_t format; + const char *name; + pixman_bool_t is_alias; +}; + +typedef struct format_entry format_entry_t; + +static const format_entry_t format_list[] = +{ +#define ENTRY(f) \ + { PIXMAN_##f, #f, FALSE } +#define ALIAS(f, nam) \ + { PIXMAN_##f, nam, TRUE } + + /* format_name () will return the first hit in this table, + * so keep the list properly ordered between entries and aliases. + * Aliases are not listed by list_formats (). + */ + +/* 32bpp formats */ + ENTRY (a8r8g8b8), + ALIAS (a8r8g8b8, "8888"), + ENTRY (x8r8g8b8), + ALIAS (x8r8g8b8, "x888"), + ENTRY (a8b8g8r8), + ENTRY (x8b8g8r8), + ENTRY (b8g8r8a8), + ENTRY (b8g8r8x8), + ENTRY (r8g8b8a8), + ENTRY (r8g8b8x8), + ENTRY (x14r6g6b6), + ENTRY (x2r10g10b10), + ALIAS (x2r10g10b10, "2x10"), + ENTRY (a2r10g10b10), + ALIAS (a2r10g10b10, "2a10"), + ENTRY (x2b10g10r10), + ENTRY (a2b10g10r10), + +/* sRGB formats */ + ENTRY (a8r8g8b8_sRGB), + +/* 24bpp formats */ + ENTRY (r8g8b8), + ALIAS (r8g8b8, "0888"), + ENTRY (b8g8r8), + +/* 16 bpp formats */ + ENTRY (r5g6b5), + ALIAS (r5g6b5, "0565"), + ENTRY (b5g6r5), + + ENTRY (a1r5g5b5), + ALIAS (a1r5g5b5, "1555"), + ENTRY (x1r5g5b5), + ENTRY (a1b5g5r5), + ENTRY (x1b5g5r5), + ENTRY (a4r4g4b4), + ALIAS (a4r4g4b4, "4444"), + ENTRY (x4r4g4b4), + ENTRY (a4b4g4r4), + ENTRY (x4b4g4r4), + +/* 8bpp formats */ + ENTRY (a8), + ALIAS (a8, "8"), + ENTRY (r3g3b2), + ENTRY (b2g3r3), + ENTRY (a2r2g2b2), + ALIAS (a2r2g2b2, "2222"), + ENTRY (a2b2g2r2), + + ALIAS (c8, "x4c4 / c8"), + /* ENTRY (c8), */ + ALIAS (g8, "x4g4 / g8"), + /* ENTRY (g8), */ + + ENTRY (x4a4), + + /* These format codes are identical to c8 and g8, respectively. */ + /* ENTRY (x4c4), */ + /* ENTRY (x4g4), */ + +/* 4 bpp formats */ + ENTRY (a4), + ENTRY (r1g2b1), + ENTRY (b1g2r1), + ENTRY (a1r1g1b1), + ENTRY (a1b1g1r1), + + ALIAS (c4, "c4"), + /* ENTRY (c4), */ + ALIAS (g4, "g4"), + /* ENTRY (g4), */ + +/* 1bpp formats */ + ENTRY (a1), + + ALIAS (g1, "g1"), + /* ENTRY (g1), */ + +/* YUV formats */ + ALIAS (yuy2, "yuy2"), + /* ENTRY (yuy2), */ + ALIAS (yv12, "yv12"), + /* ENTRY (yv12), */ + +/* Fake formats, not in pixman_format_code_t enum */ + ALIAS (null, "null"), + ALIAS (solid, "solid"), + ALIAS (solid, "n"), + ALIAS (pixbuf, "pixbuf"), + ALIAS (rpixbuf, "rpixbuf"), + ALIAS (unknown, "unknown"), + +#undef ENTRY +#undef ALIAS +}; + +pixman_format_code_t +format_from_string (const char *s) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (format_list); ++i) + { + const format_entry_t *ent = &format_list[i]; + + if (strcasecmp (ent->name, s) == 0) + return ent->format; + } + + return PIXMAN_null; +} + +static void +emit (const char *s, int *n_chars) +{ + *n_chars += printf ("%s,", s); + if (*n_chars > 60) + { + printf ("\n "); + *n_chars = 0; + } + else + { + printf (" "); + (*n_chars)++; + } +} + +void +list_formats (void) +{ + int n_chars; + int i; + + printf ("Formats:\n "); + + n_chars = 0; + for (i = 0; i < ARRAY_LENGTH (format_list); ++i) + { + const format_entry_t *ent = &format_list[i]; + + if (ent->is_alias) + continue; + + emit (ent->name, &n_chars); + } + + printf ("\n\n"); +} + +void +list_operators (void) +{ + char short_name [128] = { 0 }; + int i, n_chars; + + printf ("Operators:\n "); + + n_chars = 0; + for (i = 0; i < ARRAY_LENGTH (op_list); ++i) + { + const operator_entry_t *ent = &op_list[i]; + int j; + + if (ent->is_alias) + continue; + + snprintf (short_name, sizeof (short_name) - 1, "%s", + ent->name + strlen ("PIXMAN_OP_")); + + for (j = 0; short_name[j] != '\0'; ++j) + short_name[j] = tolower (short_name[j]); + + emit (short_name, &n_chars); + } + + printf ("\n\n"); +} + +pixman_op_t +operator_from_string (const char *s) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (op_list); ++i) + { + const operator_entry_t *ent = &op_list[i]; + + if (ent->is_alias) + { + if (strcasecmp (ent->name, s) == 0) + return ent->op; + } + else + { + if (strcasecmp (ent->name + strlen ("PIXMAN_OP_"), s) == 0) + return ent->op; + } + } + + return PIXMAN_OP_NONE; +} + const char * operator_name (pixman_op_t op) { - switch (op) + int i; + + for (i = 0; i < ARRAY_LENGTH (op_list); ++i) { - case PIXMAN_OP_CLEAR: return "PIXMAN_OP_CLEAR"; - case PIXMAN_OP_SRC: return "PIXMAN_OP_SRC"; - case PIXMAN_OP_DST: return "PIXMAN_OP_DST"; - case PIXMAN_OP_OVER: return "PIXMAN_OP_OVER"; - case PIXMAN_OP_OVER_REVERSE: return "PIXMAN_OP_OVER_REVERSE"; - case PIXMAN_OP_IN: return "PIXMAN_OP_IN"; - case PIXMAN_OP_IN_REVERSE: return "PIXMAN_OP_IN_REVERSE"; - case PIXMAN_OP_OUT: return "PIXMAN_OP_OUT"; - case PIXMAN_OP_OUT_REVERSE: return "PIXMAN_OP_OUT_REVERSE"; - case PIXMAN_OP_ATOP: return "PIXMAN_OP_ATOP"; - case PIXMAN_OP_ATOP_REVERSE: return "PIXMAN_OP_ATOP_REVERSE"; - case PIXMAN_OP_XOR: return "PIXMAN_OP_XOR"; - case PIXMAN_OP_ADD: return "PIXMAN_OP_ADD"; - case PIXMAN_OP_SATURATE: return "PIXMAN_OP_SATURATE"; - - case PIXMAN_OP_DISJOINT_CLEAR: return "PIXMAN_OP_DISJOINT_CLEAR"; - case PIXMAN_OP_DISJOINT_SRC: return "PIXMAN_OP_DISJOINT_SRC"; - case PIXMAN_OP_DISJOINT_DST: return "PIXMAN_OP_DISJOINT_DST"; - case PIXMAN_OP_DISJOINT_OVER: return "PIXMAN_OP_DISJOINT_OVER"; - case PIXMAN_OP_DISJOINT_OVER_REVERSE: return "PIXMAN_OP_DISJOINT_OVER_REVERSE"; - case PIXMAN_OP_DISJOINT_IN: return "PIXMAN_OP_DISJOINT_IN"; - case PIXMAN_OP_DISJOINT_IN_REVERSE: return "PIXMAN_OP_DISJOINT_IN_REVERSE"; - case PIXMAN_OP_DISJOINT_OUT: return "PIXMAN_OP_DISJOINT_OUT"; - case PIXMAN_OP_DISJOINT_OUT_REVERSE: return "PIXMAN_OP_DISJOINT_OUT_REVERSE"; - case PIXMAN_OP_DISJOINT_ATOP: return "PIXMAN_OP_DISJOINT_ATOP"; - case PIXMAN_OP_DISJOINT_ATOP_REVERSE: return "PIXMAN_OP_DISJOINT_ATOP_REVERSE"; - case PIXMAN_OP_DISJOINT_XOR: return "PIXMAN_OP_DISJOINT_XOR"; - - case PIXMAN_OP_CONJOINT_CLEAR: return "PIXMAN_OP_CONJOINT_CLEAR"; - case PIXMAN_OP_CONJOINT_SRC: return "PIXMAN_OP_CONJOINT_SRC"; - case PIXMAN_OP_CONJOINT_DST: return "PIXMAN_OP_CONJOINT_DST"; - case PIXMAN_OP_CONJOINT_OVER: return "PIXMAN_OP_CONJOINT_OVER"; - case PIXMAN_OP_CONJOINT_OVER_REVERSE: return "PIXMAN_OP_CONJOINT_OVER_REVERSE"; - case PIXMAN_OP_CONJOINT_IN: return "PIXMAN_OP_CONJOINT_IN"; - case PIXMAN_OP_CONJOINT_IN_REVERSE: return "PIXMAN_OP_CONJOINT_IN_REVERSE"; - case PIXMAN_OP_CONJOINT_OUT: return "PIXMAN_OP_CONJOINT_OUT"; - case PIXMAN_OP_CONJOINT_OUT_REVERSE: return "PIXMAN_OP_CONJOINT_OUT_REVERSE"; - case PIXMAN_OP_CONJOINT_ATOP: return "PIXMAN_OP_CONJOINT_ATOP"; - case PIXMAN_OP_CONJOINT_ATOP_REVERSE: return "PIXMAN_OP_CONJOINT_ATOP_REVERSE"; - case PIXMAN_OP_CONJOINT_XOR: return "PIXMAN_OP_CONJOINT_XOR"; - - case PIXMAN_OP_MULTIPLY: return "PIXMAN_OP_MULTIPLY"; - case PIXMAN_OP_SCREEN: return "PIXMAN_OP_SCREEN"; - case PIXMAN_OP_OVERLAY: return "PIXMAN_OP_OVERLAY"; - case PIXMAN_OP_DARKEN: return "PIXMAN_OP_DARKEN"; - case PIXMAN_OP_LIGHTEN: return "PIXMAN_OP_LIGHTEN"; - case PIXMAN_OP_COLOR_DODGE: return "PIXMAN_OP_COLOR_DODGE"; - case PIXMAN_OP_COLOR_BURN: return "PIXMAN_OP_COLOR_BURN"; - case PIXMAN_OP_HARD_LIGHT: return "PIXMAN_OP_HARD_LIGHT"; - case PIXMAN_OP_SOFT_LIGHT: return "PIXMAN_OP_SOFT_LIGHT"; - case PIXMAN_OP_DIFFERENCE: return "PIXMAN_OP_DIFFERENCE"; - case PIXMAN_OP_EXCLUSION: return "PIXMAN_OP_EXCLUSION"; - case PIXMAN_OP_HSL_HUE: return "PIXMAN_OP_HSL_HUE"; - case PIXMAN_OP_HSL_SATURATION: return "PIXMAN_OP_HSL_SATURATION"; - case PIXMAN_OP_HSL_COLOR: return "PIXMAN_OP_HSL_COLOR"; - case PIXMAN_OP_HSL_LUMINOSITY: return "PIXMAN_OP_HSL_LUMINOSITY"; - - case PIXMAN_OP_NONE: - return "<invalid operator 'none'>"; - }; + const operator_entry_t *ent = &op_list[i]; + + if (ent->op == op) + return ent->name; + } return "<unknown operator>"; } @@ -1009,95 +1405,164 @@ operator_name (pixman_op_t op) const char * format_name (pixman_format_code_t format) { - switch (format) + int i; + + for (i = 0; i < ARRAY_LENGTH (format_list); ++i) { -/* 32bpp formats */ - case PIXMAN_a8r8g8b8: return "a8r8g8b8"; - case PIXMAN_x8r8g8b8: return "x8r8g8b8"; - case PIXMAN_a8b8g8r8: return "a8b8g8r8"; - case PIXMAN_x8b8g8r8: return "x8b8g8r8"; - case PIXMAN_b8g8r8a8: return "b8g8r8a8"; - case PIXMAN_b8g8r8x8: return "b8g8r8x8"; - case PIXMAN_r8g8b8a8: return "r8g8b8a8"; - case PIXMAN_r8g8b8x8: return "r8g8b8x8"; - case PIXMAN_x14r6g6b6: return "x14r6g6b6"; - case PIXMAN_x2r10g10b10: return "x2r10g10b10"; - case PIXMAN_a2r10g10b10: return "a2r10g10b10"; - case PIXMAN_x2b10g10r10: return "x2b10g10r10"; - case PIXMAN_a2b10g10r10: return "a2b10g10r10"; + const format_entry_t *ent = &format_list[i]; -/* sRGB formats */ - case PIXMAN_a8r8g8b8_sRGB: return "a8r8g8b8_sRGB"; + if (ent->format == format) + return ent->name; + } -/* 24bpp formats */ - case PIXMAN_r8g8b8: return "r8g8b8"; - case PIXMAN_b8g8r8: return "b8g8r8"; - -/* 16bpp formats */ - case PIXMAN_r5g6b5: return "r5g6b5"; - case PIXMAN_b5g6r5: return "b5g6r5"; - - case PIXMAN_a1r5g5b5: return "a1r5g5b5"; - case PIXMAN_x1r5g5b5: return "x1r5g5b5"; - case PIXMAN_a1b5g5r5: return "a1b5g5r5"; - case PIXMAN_x1b5g5r5: return "x1b5g5r5"; - case PIXMAN_a4r4g4b4: return "a4r4g4b4"; - case PIXMAN_x4r4g4b4: return "x4r4g4b4"; - case PIXMAN_a4b4g4r4: return "a4b4g4r4"; - case PIXMAN_x4b4g4r4: return "x4b4g4r4"; + return "<unknown format>"; +}; -/* 8bpp formats */ - case PIXMAN_a8: return "a8"; - case PIXMAN_r3g3b2: return "r3g3b2"; - case PIXMAN_b2g3r3: return "b2g3r3"; - case PIXMAN_a2r2g2b2: return "a2r2g2b2"; - case PIXMAN_a2b2g2r2: return "a2b2g2r2"; - -#if 0 - case PIXMAN_x4c4: return "x4c4"; - case PIXMAN_g8: return "g8"; -#endif - case PIXMAN_c8: return "x4c4 / c8"; - case PIXMAN_x4g4: return "x4g4 / g8"; +#define IS_ZERO(f) (-DBL_MIN < (f) && (f) < DBL_MIN) - case PIXMAN_x4a4: return "x4a4"; +typedef double (* blend_func_t) (double as, double s, double ad, double d); -/* 4bpp formats */ - case PIXMAN_a4: return "a4"; - case PIXMAN_r1g2b1: return "r1g2b1"; - case PIXMAN_b1g2r1: return "b1g2r1"; - case PIXMAN_a1r1g1b1: return "a1r1g1b1"; - case PIXMAN_a1b1g1r1: return "a1b1g1r1"; +static force_inline double +blend_multiply (double sa, double s, double da, double d) +{ + return d * s; +} - case PIXMAN_c4: return "c4"; - case PIXMAN_g4: return "g4"; +static force_inline double +blend_screen (double sa, double s, double da, double d) +{ + return d * sa + s * da - s * d; +} -/* 1bpp formats */ - case PIXMAN_a1: return "a1"; +static force_inline double +blend_overlay (double sa, double s, double da, double d) +{ + if (2 * d < da) + return 2 * s * d; + else + return sa * da - 2 * (da - d) * (sa - s); +} - case PIXMAN_g1: return "g1"; +static force_inline double +blend_darken (double sa, double s, double da, double d) +{ + s = s * da; + d = d * sa; -/* YUV formats */ - case PIXMAN_yuy2: return "yuy2"; - case PIXMAN_yv12: return "yv12"; - }; + if (s > d) + return d; + else + return s; +} - /* Fake formats. - * - * This is separate switch to prevent GCC from complaining - * that the values are not in the pixman_format_code_t enum. - */ - switch ((uint32_t)format) +static force_inline double +blend_lighten (double sa, double s, double da, double d) +{ + s = s * da; + d = d * sa; + + if (s > d) + return s; + else + return d; +} + +static force_inline double +blend_color_dodge (double sa, double s, double da, double d) +{ + if (IS_ZERO (d)) + return 0.0f; + else if (d * sa >= sa * da - s * da) + return sa * da; + else if (IS_ZERO (sa - s)) + return sa * da; + else + return sa * sa * d / (sa - s); +} + +static force_inline double +blend_color_burn (double sa, double s, double da, double d) +{ + if (d >= da) + return sa * da; + else if (sa * (da - d) >= s * da) + return 0.0f; + else if (IS_ZERO (s)) + return 0.0f; + else + return sa * (da - sa * (da - d) / s); +} + +static force_inline double +blend_hard_light (double sa, double s, double da, double d) +{ + if (2 * s < sa) + return 2 * s * d; + else + return sa * da - 2 * (da - d) * (sa - s); +} + +static force_inline double +blend_soft_light (double sa, double s, double da, double d) +{ + if (2 * s <= sa) { - case PIXMAN_null: return "null"; - case PIXMAN_solid: return "solid"; - case PIXMAN_pixbuf: return "pixbuf"; - case PIXMAN_rpixbuf: return "rpixbuf"; - case PIXMAN_unknown: return "unknown"; - }; + if (IS_ZERO (da)) + return d * sa; + else + return d * sa - d * (da - d) * (sa - 2 * s) / da; + } + else + { + if (IS_ZERO (da)) + { + return d * sa; + } + else + { + if (4 * d <= da) + return d * sa + (2 * s - sa) * d * ((16 * d / da - 12) * d / da + 3); + else + return d * sa + (sqrt (d * da) - d) * (2 * s - sa); + } + } +} - return "<unknown format>"; -}; +static force_inline double +blend_difference (double sa, double s, double da, double d) +{ + double dsa = d * sa; + double sda = s * da; + + if (sda < dsa) + return dsa - sda; + else + return sda - dsa; +} + +static force_inline double +blend_exclusion (double sa, double s, double da, double d) +{ + return s * da + d * sa - 2 * d * s; +} + +static double +clamp (double d) +{ + if (d > 1.0) + return 1.0; + else if (d < 0.0) + return 0.0; + else + return d; +} + +static double +blend_channel (double as, double s, double ad, double d, + blend_func_t blend) +{ + return clamp ((1 - ad) * s + (1 - as) * d + blend (as, s, ad, d)); +} static double calc_op (pixman_op_t op, double src, double dst, double srca, double dsta) @@ -1336,6 +1801,21 @@ do_composite (pixman_op_t op, { color_t srcval, srcalpha; + static const blend_func_t blend_funcs[] = + { + blend_multiply, + blend_screen, + blend_overlay, + blend_darken, + blend_lighten, + blend_color_dodge, + blend_color_burn, + blend_hard_light, + blend_soft_light, + blend_difference, + blend_exclusion, + }; + if (mask == NULL) { srcval = *src; @@ -1370,10 +1850,22 @@ do_composite (pixman_op_t op, srcalpha.a = src->a * mask->a; } - result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a); - result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a); - result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a); - result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a); + if (op >= PIXMAN_OP_MULTIPLY) + { + blend_func_t func = blend_funcs[op - PIXMAN_OP_MULTIPLY]; + + result->a = srcalpha.a + dst->a - srcalpha.a * dst->a; + result->r = blend_channel (srcalpha.r, srcval.r, dst->a, dst->r, func); + result->g = blend_channel (srcalpha.g, srcval.g, dst->a, dst->g, func); + result->b = blend_channel (srcalpha.b, srcval.b, dst->a, dst->b, func); + } + else + { + result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a); + result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a); + result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a); + result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a); + } } static double @@ -1580,7 +2072,7 @@ get_limits (const pixel_checker_t *checker, double limit, /* The acceptable deviation in units of [0.0, 1.0] */ -#define DEVIATION (0.0064) +#define DEVIATION (0.0128) void pixel_checker_get_max (const pixel_checker_t *checker, color_t *color, diff --git a/lib/pixman/test/utils.h b/lib/pixman/test/utils.h index ebb14d9e4..e299d1d06 100644 --- a/lib/pixman/test/utils.h +++ b/lib/pixman/test/utils.h @@ -86,6 +86,17 @@ is_little_endian (void) void image_endian_swap (pixman_image_t *img); +#if defined (HAVE_MPROTECT) && defined (HAVE_GETPAGESIZE) && \ + defined (HAVE_SYS_MMAN_H) && defined (HAVE_MMAP) +/* fence_malloc and friends have working fence implementation. + * Without this, fence_malloc still allocs but does not catch + * out-of-bounds accesses. + */ +#define FENCE_MALLOC_ACTIVE 1 +#else +#define FENCE_MALLOC_ACTIVE 0 +#endif + /* Allocate memory that is bounded by protected pages, * so that out-of-bounds access will cause segfaults */ @@ -95,6 +106,16 @@ fence_malloc (int64_t len); void fence_free (void *data); +pixman_image_t * +fence_image_create_bits (pixman_format_code_t format, + int min_width, + int height, + pixman_bool_t stride_fence); + +/* Return the page size if FENCE_MALLOC_ACTIVE, or zero otherwise */ +unsigned long +fence_get_page_size (); + /* Generate n_bytes random bytes in fence_malloced memory */ uint8_t * make_random_bytes (int n_bytes); @@ -120,6 +141,7 @@ fail_after (int seconds, const char *msg); /* If possible, enable traps for floating point exceptions */ void enable_divbyzero_exceptions(void); +void enable_invalid_exceptions(void); /* Converts a8r8g8b8 pixels to pixels that * - are not premultiplied, @@ -186,6 +208,18 @@ convert_linear_to_srgb (double component); void initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb); +pixman_format_code_t +format_from_string (const char *s); + +void +list_formats (void); + +void +list_operators (void); + +pixman_op_t +operator_from_string (const char *s); + const char * operator_name (pixman_op_t op); |