gfx/cairo/libpixman/src/pixman-combine64.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* WARNING: This file is generated by combine.pl from combine.inc.
     2    Please edit one of those files rather than this one. */
     4 #line 1 "pixman-combine.c.template"
     5 #ifdef HAVE_CONFIG_H
     6 #include <config.h>
     7 #endif
     9 #include <math.h>
    10 #include <string.h>
    12 #include "pixman-private.h"
    14 #include "pixman-combine64.h"
    16 /*** per channel helper functions ***/
    18 static void
    19 combine_mask_ca (uint64_t *src, uint64_t *mask)
    20 {
    21     uint64_t a = *mask;
    23     uint64_t x;
    24     uint32_t xa;
    26     if (!a)
    27     {
    28 	*(src) = 0;
    29 	return;
    30     }
    32     x = *(src);
    33     if (a == ~0)
    34     {
    35 	x = x >> A_SHIFT;
    36 	x |= x << G_SHIFT;
    37 	x |= x << R_SHIFT;
    38 	*(mask) = x;
    39 	return;
    40     }
    42     xa = x >> A_SHIFT;
    43     UN16x4_MUL_UN16x4 (x, a);
    44     *(src) = x;
    46     UN16x4_MUL_UN16 (a, xa);
    47     *(mask) = a;
    48 }
    50 static void
    51 combine_mask_value_ca (uint64_t *src, const uint64_t *mask)
    52 {
    53     uint64_t a = *mask;
    54     uint64_t x;
    56     if (!a)
    57     {
    58 	*(src) = 0;
    59 	return;
    60     }
    62     if (a == ~0)
    63 	return;
    65     x = *(src);
    66     UN16x4_MUL_UN16x4 (x, a);
    67     *(src) = x;
    68 }
    70 static void
    71 combine_mask_alpha_ca (const uint64_t *src, uint64_t *mask)
    72 {
    73     uint64_t a = *(mask);
    74     uint64_t x;
    76     if (!a)
    77 	return;
    79     x = *(src) >> A_SHIFT;
    80     if (x == MASK)
    81 	return;
    83     if (a == ~0)
    84     {
    85 	x |= x << G_SHIFT;
    86 	x |= x << R_SHIFT;
    87 	*(mask) = x;
    88 	return;
    89     }
    91     UN16x4_MUL_UN16 (a, x);
    92     *(mask) = a;
    93 }
    95 /*
    96  * There are two ways of handling alpha -- either as a single unified value or
    97  * a separate value for each component, hence each macro must have two
    98  * versions.  The unified alpha version has a 'U' at the end of the name,
    99  * the component version has a 'C'.  Similarly, functions which deal with
   100  * this difference will have two versions using the same convention.
   101  */
   103 /*
   104  * All of the composing functions
   105  */
   107 static force_inline uint64_t
   108 combine_mask (const uint64_t *src, const uint64_t *mask, int i)
   109 {
   110     uint64_t s, m;
   112     if (mask)
   113     {
   114 	m = *(mask + i) >> A_SHIFT;
   116 	if (!m)
   117 	    return 0;
   118     }
   120     s = *(src + i);
   122     if (mask)
   123 	UN16x4_MUL_UN16 (s, m);
   125     return s;
   126 }
   128 static void
   129 combine_clear (pixman_implementation_t *imp,
   130                pixman_op_t              op,
   131                uint64_t *                dest,
   132                const uint64_t *          src,
   133                const uint64_t *          mask,
   134                int                      width)
   135 {
   136     memset (dest, 0, width * sizeof(uint64_t));
   137 }
   139 static void
   140 combine_dst (pixman_implementation_t *imp,
   141 	     pixman_op_t	      op,
   142 	     uint64_t *		      dest,
   143 	     const uint64_t *	      src,
   144 	     const uint64_t *          mask,
   145 	     int		      width)
   146 {
   147     return;
   148 }
   150 static void
   151 combine_src_u (pixman_implementation_t *imp,
   152                pixman_op_t              op,
   153                uint64_t *                dest,
   154                const uint64_t *          src,
   155                const uint64_t *          mask,
   156                int                      width)
   157 {
   158     int i;
   160     if (!mask)
   161 	memcpy (dest, src, width * sizeof (uint64_t));
   162     else
   163     {
   164 	for (i = 0; i < width; ++i)
   165 	{
   166 	    uint64_t s = combine_mask (src, mask, i);
   168 	    *(dest + i) = s;
   169 	}
   170     }
   171 }
   173 /* if the Src is opaque, call combine_src_u */
   174 static void
   175 combine_over_u (pixman_implementation_t *imp,
   176                 pixman_op_t              op,
   177                 uint64_t *                dest,
   178                 const uint64_t *          src,
   179                 const uint64_t *          mask,
   180                 int                      width)
   181 {
   182     int i;
   184     for (i = 0; i < width; ++i)
   185     {
   186 	uint64_t s = combine_mask (src, mask, i);
   187 	uint64_t d = *(dest + i);
   188 	uint64_t ia = ALPHA_16 (~s);
   190 	UN16x4_MUL_UN16_ADD_UN16x4 (d, ia, s);
   191 	*(dest + i) = d;
   192     }
   193 }
   195 /* if the Dst is opaque, this is a noop */
   196 static void
   197 combine_over_reverse_u (pixman_implementation_t *imp,
   198                         pixman_op_t              op,
   199                         uint64_t *                dest,
   200                         const uint64_t *          src,
   201                         const uint64_t *          mask,
   202                         int                      width)
   203 {
   204     int i;
   206     for (i = 0; i < width; ++i)
   207     {
   208 	uint64_t s = combine_mask (src, mask, i);
   209 	uint64_t d = *(dest + i);
   210 	uint64_t ia = ALPHA_16 (~*(dest + i));
   211 	UN16x4_MUL_UN16_ADD_UN16x4 (s, ia, d);
   212 	*(dest + i) = s;
   213     }
   214 }
   216 /* if the Dst is opaque, call combine_src_u */
   217 static void
   218 combine_in_u (pixman_implementation_t *imp,
   219               pixman_op_t              op,
   220               uint64_t *                dest,
   221               const uint64_t *          src,
   222               const uint64_t *          mask,
   223               int                      width)
   224 {
   225     int i;
   227     for (i = 0; i < width; ++i)
   228     {
   229 	uint64_t s = combine_mask (src, mask, i);
   230 	uint64_t a = ALPHA_16 (*(dest + i));
   231 	UN16x4_MUL_UN16 (s, a);
   232 	*(dest + i) = s;
   233     }
   234 }
   236 /* if the Src is opaque, this is a noop */
   237 static void
   238 combine_in_reverse_u (pixman_implementation_t *imp,
   239                       pixman_op_t              op,
   240                       uint64_t *                dest,
   241                       const uint64_t *          src,
   242                       const uint64_t *          mask,
   243                       int                      width)
   244 {
   245     int i;
   247     for (i = 0; i < width; ++i)
   248     {
   249 	uint64_t s = combine_mask (src, mask, i);
   250 	uint64_t d = *(dest + i);
   251 	uint64_t a = ALPHA_16 (s);
   252 	UN16x4_MUL_UN16 (d, a);
   253 	*(dest + i) = d;
   254     }
   255 }
   257 /* if the Dst is opaque, call combine_clear */
   258 static void
   259 combine_out_u (pixman_implementation_t *imp,
   260                pixman_op_t              op,
   261                uint64_t *                dest,
   262                const uint64_t *          src,
   263                const uint64_t *          mask,
   264                int                      width)
   265 {
   266     int i;
   268     for (i = 0; i < width; ++i)
   269     {
   270 	uint64_t s = combine_mask (src, mask, i);
   271 	uint64_t a = ALPHA_16 (~*(dest + i));
   272 	UN16x4_MUL_UN16 (s, a);
   273 	*(dest + i) = s;
   274     }
   275 }
   277 /* if the Src is opaque, call combine_clear */
   278 static void
   279 combine_out_reverse_u (pixman_implementation_t *imp,
   280                        pixman_op_t              op,
   281                        uint64_t *                dest,
   282                        const uint64_t *          src,
   283                        const uint64_t *          mask,
   284                        int                      width)
   285 {
   286     int i;
   288     for (i = 0; i < width; ++i)
   289     {
   290 	uint64_t s = combine_mask (src, mask, i);
   291 	uint64_t d = *(dest + i);
   292 	uint64_t a = ALPHA_16 (~s);
   293 	UN16x4_MUL_UN16 (d, a);
   294 	*(dest + i) = d;
   295     }
   296 }
   298 /* if the Src is opaque, call combine_in_u */
   299 /* if the Dst is opaque, call combine_over_u */
   300 /* if both the Src and Dst are opaque, call combine_src_u */
   301 static void
   302 combine_atop_u (pixman_implementation_t *imp,
   303                 pixman_op_t              op,
   304                 uint64_t *                dest,
   305                 const uint64_t *          src,
   306                 const uint64_t *          mask,
   307                 int                      width)
   308 {
   309     int i;
   311     for (i = 0; i < width; ++i)
   312     {
   313 	uint64_t s = combine_mask (src, mask, i);
   314 	uint64_t d = *(dest + i);
   315 	uint64_t dest_a = ALPHA_16 (d);
   316 	uint64_t src_ia = ALPHA_16 (~s);
   318 	UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (s, dest_a, d, src_ia);
   319 	*(dest + i) = s;
   320     }
   321 }
   323 /* if the Src is opaque, call combine_over_reverse_u */
   324 /* if the Dst is opaque, call combine_in_reverse_u */
   325 /* if both the Src and Dst are opaque, call combine_dst_u */
   326 static void
   327 combine_atop_reverse_u (pixman_implementation_t *imp,
   328                         pixman_op_t              op,
   329                         uint64_t *                dest,
   330                         const uint64_t *          src,
   331                         const uint64_t *          mask,
   332                         int                      width)
   333 {
   334     int i;
   336     for (i = 0; i < width; ++i)
   337     {
   338 	uint64_t s = combine_mask (src, mask, i);
   339 	uint64_t d = *(dest + i);
   340 	uint64_t src_a = ALPHA_16 (s);
   341 	uint64_t dest_ia = ALPHA_16 (~d);
   343 	UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (s, dest_ia, d, src_a);
   344 	*(dest + i) = s;
   345     }
   346 }
   348 /* if the Src is opaque, call combine_over_u */
   349 /* if the Dst is opaque, call combine_over_reverse_u */
   350 /* if both the Src and Dst are opaque, call combine_clear */
   351 static void
   352 combine_xor_u (pixman_implementation_t *imp,
   353                pixman_op_t              op,
   354                uint64_t *                dest,
   355                const uint64_t *          src,
   356                const uint64_t *          mask,
   357                int                      width)
   358 {
   359     int i;
   361     for (i = 0; i < width; ++i)
   362     {
   363 	uint64_t s = combine_mask (src, mask, i);
   364 	uint64_t d = *(dest + i);
   365 	uint64_t src_ia = ALPHA_16 (~s);
   366 	uint64_t dest_ia = ALPHA_16 (~d);
   368 	UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (s, dest_ia, d, src_ia);
   369 	*(dest + i) = s;
   370     }
   371 }
   373 static void
   374 combine_add_u (pixman_implementation_t *imp,
   375                pixman_op_t              op,
   376                uint64_t *                dest,
   377                const uint64_t *          src,
   378                const uint64_t *          mask,
   379                int                      width)
   380 {
   381     int i;
   383     for (i = 0; i < width; ++i)
   384     {
   385 	uint64_t s = combine_mask (src, mask, i);
   386 	uint64_t d = *(dest + i);
   387 	UN16x4_ADD_UN16x4 (d, s);
   388 	*(dest + i) = d;
   389     }
   390 }
   392 /* if the Src is opaque, call combine_add_u */
   393 /* if the Dst is opaque, call combine_add_u */
   394 /* if both the Src and Dst are opaque, call combine_add_u */
   395 static void
   396 combine_saturate_u (pixman_implementation_t *imp,
   397                     pixman_op_t              op,
   398                     uint64_t *                dest,
   399                     const uint64_t *          src,
   400                     const uint64_t *          mask,
   401                     int                      width)
   402 {
   403     int i;
   405     for (i = 0; i < width; ++i)
   406     {
   407 	uint64_t s = combine_mask (src, mask, i);
   408 	uint64_t d = *(dest + i);
   409 	uint32_t sa, da;
   411 	sa = s >> A_SHIFT;
   412 	da = ~d >> A_SHIFT;
   413 	if (sa > da)
   414 	{
   415 	    sa = DIV_UN16 (da, sa);
   416 	    UN16x4_MUL_UN16 (s, sa);
   417 	}
   418 	;
   419 	UN16x4_ADD_UN16x4 (d, s);
   420 	*(dest + i) = d;
   421     }
   422 }
   424 /*
   425  * PDF blend modes:
   426  * The following blend modes have been taken from the PDF ISO 32000
   427  * specification, which at this point in time is available from
   428  * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
   429  * The relevant chapters are 11.3.5 and 11.3.6.
   430  * The formula for computing the final pixel color given in 11.3.6 is:
   431  * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
   432  * with B() being the blend function.
   433  * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs
   434  *
   435  * These blend modes should match the SVG filter draft specification, as
   436  * it has been designed to mirror ISO 32000. Note that at the current point
   437  * no released draft exists that shows this, as the formulas have not been
   438  * updated yet after the release of ISO 32000.
   439  *
   440  * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
   441  * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
   442  * argument. Note that this implementation operates on premultiplied colors,
   443  * while the PDF specification does not. Therefore the code uses the formula
   444  * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
   445  */
   447 /*
   448  * Multiply
   449  * B(Dca, ad, Sca, as) = Dca.Sca
   450  */
   452 static void
   453 combine_multiply_u (pixman_implementation_t *imp,
   454                     pixman_op_t              op,
   455                     uint64_t *                dest,
   456                     const uint64_t *          src,
   457                     const uint64_t *          mask,
   458                     int                      width)
   459 {
   460     int i;
   462     for (i = 0; i < width; ++i)
   463     {
   464 	uint64_t s = combine_mask (src, mask, i);
   465 	uint64_t d = *(dest + i);
   466 	uint64_t ss = s;
   467 	uint64_t src_ia = ALPHA_16 (~s);
   468 	uint64_t dest_ia = ALPHA_16 (~d);
   470 	UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (ss, dest_ia, d, src_ia);
   471 	UN16x4_MUL_UN16x4 (d, s);
   472 	UN16x4_ADD_UN16x4 (d, ss);
   474 	*(dest + i) = d;
   475     }
   476 }
   478 static void
   479 combine_multiply_ca (pixman_implementation_t *imp,
   480                      pixman_op_t              op,
   481                      uint64_t *                dest,
   482                      const uint64_t *          src,
   483                      const uint64_t *          mask,
   484                      int                      width)
   485 {
   486     int i;
   488     for (i = 0; i < width; ++i)
   489     {
   490 	uint64_t m = *(mask + i);
   491 	uint64_t s = *(src + i);
   492 	uint64_t d = *(dest + i);
   493 	uint64_t r = d;
   494 	uint64_t dest_ia = ALPHA_16 (~d);
   496 	combine_mask_value_ca (&s, &m);
   498 	UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (r, ~m, s, dest_ia);
   499 	UN16x4_MUL_UN16x4 (d, s);
   500 	UN16x4_ADD_UN16x4 (r, d);
   502 	*(dest + i) = r;
   503     }
   504 }
   506 #define PDF_SEPARABLE_BLEND_MODE(name)					\
   507     static void								\
   508     combine_ ## name ## _u (pixman_implementation_t *imp,		\
   509 			    pixman_op_t              op,		\
   510                             uint64_t *                dest,		\
   511 			    const uint64_t *          src,		\
   512 			    const uint64_t *          mask,		\
   513 			    int                      width)		\
   514     {									\
   515 	int i;								\
   516 	for (i = 0; i < width; ++i) {					\
   517 	    uint64_t s = combine_mask (src, mask, i);			\
   518 	    uint64_t d = *(dest + i);					\
   519 	    uint16_t sa = ALPHA_16 (s);					\
   520 	    uint16_t isa = ~sa;						\
   521 	    uint16_t da = ALPHA_16 (d);					\
   522 	    uint16_t ida = ~da;						\
   523 	    uint64_t result;						\
   524 									\
   525 	    result = d;							\
   526 	    UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (result, isa, s, ida);	\
   527 	    								\
   528 	    *(dest + i) = result +					\
   529 		(DIV_ONE_UN16 (sa * (uint64_t)da) << A_SHIFT) +		\
   530 		(blend_ ## name (RED_16 (d), da, RED_16 (s), sa) << R_SHIFT) + \
   531 		(blend_ ## name (GREEN_16 (d), da, GREEN_16 (s), sa) << G_SHIFT) + \
   532 		(blend_ ## name (BLUE_16 (d), da, BLUE_16 (s), sa));	\
   533 	}								\
   534     }									\
   535     									\
   536     static void								\
   537     combine_ ## name ## _ca (pixman_implementation_t *imp,		\
   538 			     pixman_op_t              op,		\
   539                              uint64_t *                dest,		\
   540 			     const uint64_t *          src,		\
   541 			     const uint64_t *          mask,		\
   542 			     int                     width)		\
   543     {									\
   544 	int i;								\
   545 	for (i = 0; i < width; ++i) {					\
   546 	    uint64_t m = *(mask + i);					\
   547 	    uint64_t s = *(src + i);					\
   548 	    uint64_t d = *(dest + i);					\
   549 	    uint16_t da = ALPHA_16 (d);					\
   550 	    uint16_t ida = ~da;						\
   551 	    uint64_t result;						\
   552             								\
   553 	    combine_mask_value_ca (&s, &m);				\
   554             								\
   555 	    result = d;							\
   556 	    UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (result, ~m, s, ida);     \
   557             								\
   558 	    result +=							\
   559 	        (DIV_ONE_UN16 (ALPHA_16 (m) * (uint64_t)da) << A_SHIFT) +	\
   560 	        (blend_ ## name (RED_16 (d), da, RED_16 (s), RED_16 (m)) << R_SHIFT) + \
   561 	        (blend_ ## name (GREEN_16 (d), da, GREEN_16 (s), GREEN_16 (m)) << G_SHIFT) + \
   562 	        (blend_ ## name (BLUE_16 (d), da, BLUE_16 (s), BLUE_16 (m))); \
   563 	    								\
   564 	    *(dest + i) = result;					\
   565 	}								\
   566     }
   568 /*
   569  * Screen
   570  * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca
   571  */
   572 static inline uint64_t
   573 blend_screen (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   574 {
   575     return DIV_ONE_UN16 (sca * da + dca * sa - sca * dca);
   576 }
   578 PDF_SEPARABLE_BLEND_MODE (screen)
   580 /*
   581  * Overlay
   582  * B(Dca, Da, Sca, Sa) =
   583  *   if 2.Dca < Da
   584  *     2.Sca.Dca
   585  *   otherwise
   586  *     Sa.Da - 2.(Da - Dca).(Sa - Sca)
   587  */
   588 static inline uint64_t
   589 blend_overlay (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   590 {
   591     uint64_t rca;
   593     if (2 * dca < da)
   594 	rca = 2 * sca * dca;
   595     else
   596 	rca = sa * da - 2 * (da - dca) * (sa - sca);
   597     return DIV_ONE_UN16 (rca);
   598 }
   600 PDF_SEPARABLE_BLEND_MODE (overlay)
   602 /*
   603  * Darken
   604  * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa)
   605  */
   606 static inline uint64_t
   607 blend_darken (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   608 {
   609     uint64_t s, d;
   611     s = sca * da;
   612     d = dca * sa;
   613     return DIV_ONE_UN16 (s > d ? d : s);
   614 }
   616 PDF_SEPARABLE_BLEND_MODE (darken)
   618 /*
   619  * Lighten
   620  * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa)
   621  */
   622 static inline uint64_t
   623 blend_lighten (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   624 {
   625     uint64_t s, d;
   627     s = sca * da;
   628     d = dca * sa;
   629     return DIV_ONE_UN16 (s > d ? s : d);
   630 }
   632 PDF_SEPARABLE_BLEND_MODE (lighten)
   634 /*
   635  * Color dodge
   636  * B(Dca, Da, Sca, Sa) =
   637  *   if Dca == 0
   638  *     0
   639  *   if Sca == Sa
   640  *     Sa.Da
   641  *   otherwise
   642  *     Sa.Da. min (1, Dca / Da / (1 - Sca/Sa))
   643  */
   644 static inline uint64_t
   645 blend_color_dodge (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   646 {
   647     if (sca >= sa)
   648     {
   649 	return dca == 0 ? 0 : DIV_ONE_UN16 (sa * da);
   650     }
   651     else
   652     {
   653 	uint64_t rca = dca * sa / (sa - sca);
   654 	return DIV_ONE_UN16 (sa * MIN (rca, da));
   655     }
   656 }
   658 PDF_SEPARABLE_BLEND_MODE (color_dodge)
   660 /*
   661  * Color burn
   662  * B(Dca, Da, Sca, Sa) =
   663  *   if Dca == Da
   664  *     Sa.Da
   665  *   if Sca == 0
   666  *     0
   667  *   otherwise
   668  *     Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca))
   669  */
   670 static inline uint64_t
   671 blend_color_burn (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   672 {
   673     if (sca == 0)
   674     {
   675 	return dca < da ? 0 : DIV_ONE_UN16 (sa * da);
   676     }
   677     else
   678     {
   679 	uint64_t rca = (da - dca) * sa / sca;
   680 	return DIV_ONE_UN16 (sa * (MAX (rca, da) - rca));
   681     }
   682 }
   684 PDF_SEPARABLE_BLEND_MODE (color_burn)
   686 /*
   687  * Hard light
   688  * B(Dca, Da, Sca, Sa) =
   689  *   if 2.Sca < Sa
   690  *     2.Sca.Dca
   691  *   otherwise
   692  *     Sa.Da - 2.(Da - Dca).(Sa - Sca)
   693  */
   694 static inline uint64_t
   695 blend_hard_light (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   696 {
   697     if (2 * sca < sa)
   698 	return DIV_ONE_UN16 (2 * sca * dca);
   699     else
   700 	return DIV_ONE_UN16 (sa * da - 2 * (da - dca) * (sa - sca));
   701 }
   703 PDF_SEPARABLE_BLEND_MODE (hard_light)
   705 /*
   706  * Soft light
   707  * B(Dca, Da, Sca, Sa) =
   708  *   if (2.Sca <= Sa)
   709  *     Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa))
   710  *   otherwise if Dca.4 <= Da
   711  *     Dca.(Sa + (2.Sca - Sa).((16.Dca/Da - 12).Dca/Da + 3)
   712  *   otherwise
   713  *     (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa))
   714  */
   715 static inline uint64_t
   716 blend_soft_light (uint64_t dca_org,
   717 		  uint64_t da_org,
   718 		  uint64_t sca_org,
   719 		  uint64_t sa_org)
   720 {
   721     double dca = dca_org * (1.0 / MASK);
   722     double da = da_org * (1.0 / MASK);
   723     double sca = sca_org * (1.0 / MASK);
   724     double sa = sa_org * (1.0 / MASK);
   725     double rca;
   727     if (2 * sca < sa)
   728     {
   729 	if (da == 0)
   730 	    rca = dca * sa;
   731 	else
   732 	    rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da;
   733     }
   734     else if (da == 0)
   735     {
   736 	rca = 0;
   737     }
   738     else if (4 * dca <= da)
   739     {
   740 	rca = dca * sa +
   741 	    (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3);
   742     }
   743     else
   744     {
   745 	rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa);
   746     }
   747     return rca * MASK + 0.5;
   748 }
   750 PDF_SEPARABLE_BLEND_MODE (soft_light)
   752 /*
   753  * Difference
   754  * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da)
   755  */
   756 static inline uint64_t
   757 blend_difference (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   758 {
   759     uint64_t dcasa = dca * sa;
   760     uint64_t scada = sca * da;
   762     if (scada < dcasa)
   763 	return DIV_ONE_UN16 (dcasa - scada);
   764     else
   765 	return DIV_ONE_UN16 (scada - dcasa);
   766 }
   768 PDF_SEPARABLE_BLEND_MODE (difference)
   770 /*
   771  * Exclusion
   772  * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca)
   773  */
   775 /* This can be made faster by writing it directly and not using
   776  * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
   778 static inline uint64_t
   779 blend_exclusion (uint64_t dca, uint64_t da, uint64_t sca, uint64_t sa)
   780 {
   781     return DIV_ONE_UN16 (sca * da + dca * sa - 2 * dca * sca);
   782 }
   784 PDF_SEPARABLE_BLEND_MODE (exclusion)
   786 #undef PDF_SEPARABLE_BLEND_MODE
   788 /*
   789  * PDF nonseperable blend modes are implemented using the following functions
   790  * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid
   791  * and min value of the red, green and blue components.
   792  *
   793  * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
   794  *
   795  * clip_color (C):
   796  *   l = LUM (C)
   797  *   min = Cmin
   798  *   max = Cmax
   799  *   if n < 0.0
   800  *     C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) )
   801  *   if x > 1.0
   802  *     C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) )
   803  *   return C
   804  *
   805  * set_lum (C, l):
   806  *   d = l – LUM (C)
   807  *   C += d
   808  *   return clip_color (C)
   809  *
   810  * SAT (C) = CH_MAX (C) - CH_MIN (C)
   811  *
   812  * set_sat (C, s):
   813  *  if Cmax > Cmin
   814  *    Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
   815  *    Cmax = s
   816  *  else
   817  *    Cmid = Cmax = 0.0
   818  *  Cmin = 0.0
   819  *  return C
   820  */
   822 /* For premultiplied colors, we need to know what happens when C is
   823  * multiplied by a real number. LUM and SAT are linear:
   824  *
   825  *    LUM (r × C) = r × LUM (C)		SAT (r * C) = r * SAT (C)
   826  *
   827  * If we extend clip_color with an extra argument a and change
   828  *
   829  *        if x >= 1.0
   830  *
   831  * into
   832  *
   833  *        if x >= a
   834  *
   835  * then clip_color is also linear:
   836  *
   837  *    r * clip_color (C, a) = clip_color (r_c, ra);
   838  *
   839  * for positive r.
   840  *
   841  * Similarly, we can extend set_lum with an extra argument that is just passed
   842  * on to clip_color:
   843  *
   844  *   r * set_lum ( C, l, a)
   845  *
   846  *   = r × clip_color ( C + l - LUM (C), a)
   847  *
   848  *   = clip_color ( r * C + r × l - r * LUM (C), r * a)
   849  *
   850  *   = set_lum ( r * C, r * l, r * a)
   851  *
   852  * Finally, set_sat:
   853  *
   854  *    r * set_sat (C, s) = set_sat (x * C, r * s)
   855  *
   856  * The above holds for all non-zero x, because the x'es in the fraction for
   857  * C_mid cancel out. Specifically, it holds for x = r:
   858  *
   859  *    r * set_sat (C, s) = set_sat (r_c, rs)
   860  *
   861  */
   863 /* So, for the non-separable PDF blend modes, we have (using s, d for
   864  * non-premultiplied colors, and S, D for premultiplied:
   865  *
   866  *   Color:
   867  *
   868  *     a_s * a_d * B(s, d)
   869  *   = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1)
   870  *   = set_lum (S * a_d, a_s * LUM (D), a_s * a_d)
   871  *
   872  *
   873  *   Luminosity:
   874  *
   875  *     a_s * a_d * B(s, d)
   876  *   = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1)
   877  *   = set_lum (a_s * D, a_d * LUM(S), a_s * a_d)
   878  *
   879  *
   880  *   Saturation:
   881  *
   882  *     a_s * a_d * B(s, d)
   883  *   = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1)
   884  *   = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)),
   885  *                                        a_s * LUM (D), a_s * a_d)
   886  *   = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d))
   887  *
   888  *   Hue:
   889  *
   890  *     a_s * a_d * B(s, d)
   891  *   = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
   892  *   = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
   893  *
   894  */
   896 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
   897 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
   898 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
   899 #define SAT(c) (CH_MAX (c) - CH_MIN (c))
   901 #define PDF_NON_SEPARABLE_BLEND_MODE(name)				\
   902     static void								\
   903     combine_ ## name ## _u (pixman_implementation_t *imp,		\
   904 			    pixman_op_t op,				\
   905                             uint64_t *dest,				\
   906 			    const uint64_t *src,				\
   907 			    const uint64_t *mask,			\
   908 			    int width)					\
   909     {									\
   910 	int i;								\
   911 	for (i = 0; i < width; ++i)					\
   912 	{								\
   913 	    uint64_t s = combine_mask (src, mask, i);			\
   914 	    uint64_t d = *(dest + i);					\
   915 	    uint16_t sa = ALPHA_16 (s);					\
   916 	    uint16_t isa = ~sa;						\
   917 	    uint16_t da = ALPHA_16 (d);					\
   918 	    uint16_t ida = ~da;						\
   919 	    uint64_t result;						\
   920 	    uint64_t sc[3], dc[3], c[3];					\
   921             								\
   922 	    result = d;							\
   923 	    UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (result, isa, s, ida);	\
   924 	    dc[0] = RED_16 (d);						\
   925 	    sc[0] = RED_16 (s);						\
   926 	    dc[1] = GREEN_16 (d);					\
   927 	    sc[1] = GREEN_16 (s);					\
   928 	    dc[2] = BLUE_16 (d);						\
   929 	    sc[2] = BLUE_16 (s);						\
   930 	    blend_ ## name (c, dc, da, sc, sa);				\
   931             								\
   932 	    *(dest + i) = result +					\
   933 		(DIV_ONE_UN16 (sa * (uint64_t)da) << A_SHIFT) +		\
   934 		(DIV_ONE_UN16 (c[0]) << R_SHIFT) +			\
   935 		(DIV_ONE_UN16 (c[1]) << G_SHIFT) +			\
   936 		(DIV_ONE_UN16 (c[2]));					\
   937 	}								\
   938     }
   940 static void
   941 set_lum (uint64_t dest[3], uint64_t src[3], uint64_t sa, uint64_t lum)
   942 {
   943     double a, l, min, max;
   944     double tmp[3];
   946     a = sa * (1.0 / MASK);
   948     l = lum * (1.0 / MASK);
   949     tmp[0] = src[0] * (1.0 / MASK);
   950     tmp[1] = src[1] * (1.0 / MASK);
   951     tmp[2] = src[2] * (1.0 / MASK);
   953     l = l - LUM (tmp);
   954     tmp[0] += l;
   955     tmp[1] += l;
   956     tmp[2] += l;
   958     /* clip_color */
   959     l = LUM (tmp);
   960     min = CH_MIN (tmp);
   961     max = CH_MAX (tmp);
   963     if (min < 0)
   964     {
   965 	if (l - min == 0.0)
   966 	{
   967 	    tmp[0] = 0;
   968 	    tmp[1] = 0;
   969 	    tmp[2] = 0;
   970 	}
   971 	else
   972 	{
   973 	    tmp[0] = l + (tmp[0] - l) * l / (l - min);
   974 	    tmp[1] = l + (tmp[1] - l) * l / (l - min);
   975 	    tmp[2] = l + (tmp[2] - l) * l / (l - min);
   976 	}
   977     }
   978     if (max > a)
   979     {
   980 	if (max - l == 0.0)
   981 	{
   982 	    tmp[0] = a;
   983 	    tmp[1] = a;
   984 	    tmp[2] = a;
   985 	}
   986 	else
   987 	{
   988 	    tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
   989 	    tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
   990 	    tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
   991 	}
   992     }
   994     dest[0] = tmp[0] * MASK + 0.5;
   995     dest[1] = tmp[1] * MASK + 0.5;
   996     dest[2] = tmp[2] * MASK + 0.5;
   997 }
   999 static void
  1000 set_sat (uint64_t dest[3], uint64_t src[3], uint64_t sat)
  1002     int id[3];
  1003     uint64_t min, max;
  1005     if (src[0] > src[1])
  1007 	if (src[0] > src[2])
  1009 	    id[0] = 0;
  1010 	    if (src[1] > src[2])
  1012 		id[1] = 1;
  1013 		id[2] = 2;
  1015 	    else
  1017 		id[1] = 2;
  1018 		id[2] = 1;
  1021 	else
  1023 	    id[0] = 2;
  1024 	    id[1] = 0;
  1025 	    id[2] = 1;
  1028     else
  1030 	if (src[0] > src[2])
  1032 	    id[0] = 1;
  1033 	    id[1] = 0;
  1034 	    id[2] = 2;
  1036 	else
  1038 	    id[2] = 0;
  1039 	    if (src[1] > src[2])
  1041 		id[0] = 1;
  1042 		id[1] = 2;
  1044 	    else
  1046 		id[0] = 2;
  1047 		id[1] = 1;
  1052     max = dest[id[0]];
  1053     min = dest[id[2]];
  1054     if (max > min)
  1056 	dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
  1057 	dest[id[0]] = sat;
  1058 	dest[id[2]] = 0;
  1060     else
  1062 	dest[0] = dest[1] = dest[2] = 0;
  1066 /*
  1067  * Hue:
  1068  * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
  1069  */
  1070 static inline void
  1071 blend_hsl_hue (uint64_t c[3],
  1072                uint64_t dc[3],
  1073                uint64_t da,
  1074                uint64_t sc[3],
  1075                uint64_t sa)
  1077     c[0] = sc[0] * da;
  1078     c[1] = sc[1] * da;
  1079     c[2] = sc[2] * da;
  1080     set_sat (c, c, SAT (dc) * sa);
  1081     set_lum (c, c, sa * da, LUM (dc) * sa);
  1084 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
  1086 /*
  1087  * Saturation:
  1088  * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb))
  1089  */
  1090 static inline void
  1091 blend_hsl_saturation (uint64_t c[3],
  1092                       uint64_t dc[3],
  1093                       uint64_t da,
  1094                       uint64_t sc[3],
  1095                       uint64_t sa)
  1097     c[0] = dc[0] * sa;
  1098     c[1] = dc[1] * sa;
  1099     c[2] = dc[2] * sa;
  1100     set_sat (c, c, SAT (sc) * da);
  1101     set_lum (c, c, sa * da, LUM (dc) * sa);
  1104 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
  1106 /*
  1107  * Color:
  1108  * B(Cb, Cs) = set_lum (Cs, LUM (Cb))
  1109  */
  1110 static inline void
  1111 blend_hsl_color (uint64_t c[3],
  1112                  uint64_t dc[3],
  1113                  uint64_t da,
  1114                  uint64_t sc[3],
  1115                  uint64_t sa)
  1117     c[0] = sc[0] * da;
  1118     c[1] = sc[1] * da;
  1119     c[2] = sc[2] * da;
  1120     set_lum (c, c, sa * da, LUM (dc) * sa);
  1123 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
  1125 /*
  1126  * Luminosity:
  1127  * B(Cb, Cs) = set_lum (Cb, LUM (Cs))
  1128  */
  1129 static inline void
  1130 blend_hsl_luminosity (uint64_t c[3],
  1131                       uint64_t dc[3],
  1132                       uint64_t da,
  1133                       uint64_t sc[3],
  1134                       uint64_t sa)
  1136     c[0] = dc[0] * sa;
  1137     c[1] = dc[1] * sa;
  1138     c[2] = dc[2] * sa;
  1139     set_lum (c, c, sa * da, LUM (sc) * da);
  1142 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
  1144 #undef SAT
  1145 #undef LUM
  1146 #undef CH_MAX
  1147 #undef CH_MIN
  1148 #undef PDF_NON_SEPARABLE_BLEND_MODE
  1150 /* All of the disjoint/conjoint composing functions
  1152  * The four entries in the first column indicate what source contributions
  1153  * come from each of the four areas of the picture -- areas covered by neither
  1154  * A nor B, areas covered only by A, areas covered only by B and finally
  1155  * areas covered by both A and B.
  1157  * Disjoint			Conjoint
  1158  * Fa		Fb		Fa		Fb
  1159  * (0,0,0,0)	0		0		0		0
  1160  * (0,A,0,A)	1		0		1		0
  1161  * (0,0,B,B)	0		1		0		1
  1162  * (0,A,B,A)	1		min((1-a)/b,1)	1		max(1-a/b,0)
  1163  * (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
  1164  * (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
  1165  * (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
  1166  * (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
  1167  * (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
  1168  * (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
  1169  * (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
  1170  * (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
  1172  * See  http://marc.info/?l=xfree-render&m=99792000027857&w=2  for more
  1173  * information about these operators.
  1174  */
  1176 #define COMBINE_A_OUT 1
  1177 #define COMBINE_A_IN  2
  1178 #define COMBINE_B_OUT 4
  1179 #define COMBINE_B_IN  8
  1181 #define COMBINE_CLEAR   0
  1182 #define COMBINE_A       (COMBINE_A_OUT | COMBINE_A_IN)
  1183 #define COMBINE_B       (COMBINE_B_OUT | COMBINE_B_IN)
  1184 #define COMBINE_A_OVER  (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN)
  1185 #define COMBINE_B_OVER  (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN)
  1186 #define COMBINE_A_ATOP  (COMBINE_B_OUT | COMBINE_A_IN)
  1187 #define COMBINE_B_ATOP  (COMBINE_A_OUT | COMBINE_B_IN)
  1188 #define COMBINE_XOR     (COMBINE_A_OUT | COMBINE_B_OUT)
  1190 /* portion covered by a but not b */
  1191 static uint16_t
  1192 combine_disjoint_out_part (uint16_t a, uint16_t b)
  1194     /* min (1, (1-b) / a) */
  1196     b = ~b;                 /* 1 - b */
  1197     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
  1198 	return MASK;        /* 1 */
  1199     return DIV_UN16 (b, a);     /* (1-b) / a */
  1202 /* portion covered by both a and b */
  1203 static uint16_t
  1204 combine_disjoint_in_part (uint16_t a, uint16_t b)
  1206     /* max (1-(1-b)/a,0) */
  1207     /*  = - min ((1-b)/a - 1, 0) */
  1208     /*  = 1 - min (1, (1-b)/a) */
  1210     b = ~b;                 /* 1 - b */
  1211     if (b >= a)             /* 1 - b >= a -> (1-b)/a >= 1 */
  1212 	return 0;           /* 1 - 1 */
  1213     return ~DIV_UN16(b, a);    /* 1 - (1-b) / a */
  1216 /* portion covered by a but not b */
  1217 static uint16_t
  1218 combine_conjoint_out_part (uint16_t a, uint16_t b)
  1220     /* max (1-b/a,0) */
  1221     /* = 1-min(b/a,1) */
  1223     /* min (1, (1-b) / a) */
  1225     if (b >= a)             /* b >= a -> b/a >= 1 */
  1226 	return 0x00;        /* 0 */
  1227     return ~DIV_UN16(b, a);    /* 1 - b/a */
  1230 /* portion covered by both a and b */
  1231 static uint16_t
  1232 combine_conjoint_in_part (uint16_t a, uint16_t b)
  1234     /* min (1,b/a) */
  1236     if (b >= a)             /* b >= a -> b/a >= 1 */
  1237 	return MASK;        /* 1 */
  1238     return DIV_UN16 (b, a);     /* b/a */
  1241 #define GET_COMP(v, i)   ((uint32_t) (uint16_t) ((v) >> i))
  1243 #define ADD(x, y, i, t)							\
  1244     ((t) = GET_COMP (x, i) + GET_COMP (y, i),				\
  1245      (uint64_t) ((uint16_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i))
  1247 #define GENERIC(x, y, i, ax, ay, t, u, v)				\
  1248     ((t) = (MUL_UN16 (GET_COMP (y, i), ay, (u)) +			\
  1249             MUL_UN16 (GET_COMP (x, i), ax, (v))),			\
  1250      (uint64_t) ((uint16_t) ((t) |					\
  1251                            (0 - ((t) >> G_SHIFT)))) << (i))
  1253 static void
  1254 combine_disjoint_general_u (uint64_t *      dest,
  1255                             const uint64_t *src,
  1256                             const uint64_t *mask,
  1257                             int            width,
  1258                             uint16_t        combine)
  1260     int i;
  1262     for (i = 0; i < width; ++i)
  1264 	uint64_t s = combine_mask (src, mask, i);
  1265 	uint64_t d = *(dest + i);
  1266 	uint64_t m, n, o, p;
  1267 	uint32_t Fa, Fb, t, u, v;
  1268 	uint16_t sa = s >> A_SHIFT;
  1269 	uint16_t da = d >> A_SHIFT;
  1271 	switch (combine & COMBINE_A)
  1273 	default:
  1274 	    Fa = 0;
  1275 	    break;
  1277 	case COMBINE_A_OUT:
  1278 	    Fa = combine_disjoint_out_part (sa, da);
  1279 	    break;
  1281 	case COMBINE_A_IN:
  1282 	    Fa = combine_disjoint_in_part (sa, da);
  1283 	    break;
  1285 	case COMBINE_A:
  1286 	    Fa = MASK;
  1287 	    break;
  1290 	switch (combine & COMBINE_B)
  1292 	default:
  1293 	    Fb = 0;
  1294 	    break;
  1296 	case COMBINE_B_OUT:
  1297 	    Fb = combine_disjoint_out_part (da, sa);
  1298 	    break;
  1300 	case COMBINE_B_IN:
  1301 	    Fb = combine_disjoint_in_part (da, sa);
  1302 	    break;
  1304 	case COMBINE_B:
  1305 	    Fb = MASK;
  1306 	    break;
  1308 	m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
  1309 	n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
  1310 	o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
  1311 	p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
  1312 	s = m | n | o | p;
  1313 	*(dest + i) = s;
  1317 static void
  1318 combine_disjoint_over_u (pixman_implementation_t *imp,
  1319                          pixman_op_t              op,
  1320                          uint64_t *                dest,
  1321                          const uint64_t *          src,
  1322                          const uint64_t *          mask,
  1323                          int                      width)
  1325     int i;
  1327     for (i = 0; i < width; ++i)
  1329 	uint64_t s = combine_mask (src, mask, i);
  1330 	uint32_t a = s >> A_SHIFT;
  1332 	if (s != 0x00)
  1334 	    uint64_t d = *(dest + i);
  1335 	    a = combine_disjoint_out_part (d >> A_SHIFT, a);
  1336 	    UN16x4_MUL_UN16_ADD_UN16x4 (d, a, s);
  1338 	    *(dest + i) = d;
  1343 static void
  1344 combine_disjoint_in_u (pixman_implementation_t *imp,
  1345                        pixman_op_t              op,
  1346                        uint64_t *                dest,
  1347                        const uint64_t *          src,
  1348                        const uint64_t *          mask,
  1349                        int                      width)
  1351     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
  1354 static void
  1355 combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
  1356                                pixman_op_t              op,
  1357                                uint64_t *                dest,
  1358                                const uint64_t *          src,
  1359                                const uint64_t *          mask,
  1360                                int                      width)
  1362     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
  1365 static void
  1366 combine_disjoint_out_u (pixman_implementation_t *imp,
  1367                         pixman_op_t              op,
  1368                         uint64_t *                dest,
  1369                         const uint64_t *          src,
  1370                         const uint64_t *          mask,
  1371                         int                      width)
  1373     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
  1376 static void
  1377 combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
  1378                                 pixman_op_t              op,
  1379                                 uint64_t *                dest,
  1380                                 const uint64_t *          src,
  1381                                 const uint64_t *          mask,
  1382                                 int                      width)
  1384     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
  1387 static void
  1388 combine_disjoint_atop_u (pixman_implementation_t *imp,
  1389                          pixman_op_t              op,
  1390                          uint64_t *                dest,
  1391                          const uint64_t *          src,
  1392                          const uint64_t *          mask,
  1393                          int                      width)
  1395     combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
  1398 static void
  1399 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
  1400                                  pixman_op_t              op,
  1401                                  uint64_t *                dest,
  1402                                  const uint64_t *          src,
  1403                                  const uint64_t *          mask,
  1404                                  int                      width)
  1406     combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
  1409 static void
  1410 combine_disjoint_xor_u (pixman_implementation_t *imp,
  1411                         pixman_op_t              op,
  1412                         uint64_t *                dest,
  1413                         const uint64_t *          src,
  1414                         const uint64_t *          mask,
  1415                         int                      width)
  1417     combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
  1420 static void
  1421 combine_conjoint_general_u (uint64_t *      dest,
  1422                             const uint64_t *src,
  1423                             const uint64_t *mask,
  1424                             int            width,
  1425                             uint16_t        combine)
  1427     int i;
  1429     for (i = 0; i < width; ++i)
  1431 	uint64_t s = combine_mask (src, mask, i);
  1432 	uint64_t d = *(dest + i);
  1433 	uint64_t m, n, o, p;
  1434 	uint32_t Fa, Fb, t, u, v;
  1435 	uint16_t sa = s >> A_SHIFT;
  1436 	uint16_t da = d >> A_SHIFT;
  1438 	switch (combine & COMBINE_A)
  1440 	default:
  1441 	    Fa = 0;
  1442 	    break;
  1444 	case COMBINE_A_OUT:
  1445 	    Fa = combine_conjoint_out_part (sa, da);
  1446 	    break;
  1448 	case COMBINE_A_IN:
  1449 	    Fa = combine_conjoint_in_part (sa, da);
  1450 	    break;
  1452 	case COMBINE_A:
  1453 	    Fa = MASK;
  1454 	    break;
  1457 	switch (combine & COMBINE_B)
  1459 	default:
  1460 	    Fb = 0;
  1461 	    break;
  1463 	case COMBINE_B_OUT:
  1464 	    Fb = combine_conjoint_out_part (da, sa);
  1465 	    break;
  1467 	case COMBINE_B_IN:
  1468 	    Fb = combine_conjoint_in_part (da, sa);
  1469 	    break;
  1471 	case COMBINE_B:
  1472 	    Fb = MASK;
  1473 	    break;
  1476 	m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
  1477 	n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
  1478 	o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
  1479 	p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
  1481 	s = m | n | o | p;
  1483 	*(dest + i) = s;
  1487 static void
  1488 combine_conjoint_over_u (pixman_implementation_t *imp,
  1489                          pixman_op_t              op,
  1490                          uint64_t *                dest,
  1491                          const uint64_t *          src,
  1492                          const uint64_t *          mask,
  1493                          int                      width)
  1495     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
  1498 static void
  1499 combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
  1500                                  pixman_op_t              op,
  1501                                  uint64_t *                dest,
  1502                                  const uint64_t *          src,
  1503                                  const uint64_t *          mask,
  1504                                  int                      width)
  1506     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
  1509 static void
  1510 combine_conjoint_in_u (pixman_implementation_t *imp,
  1511                        pixman_op_t              op,
  1512                        uint64_t *                dest,
  1513                        const uint64_t *          src,
  1514                        const uint64_t *          mask,
  1515                        int                      width)
  1517     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
  1520 static void
  1521 combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
  1522                                pixman_op_t              op,
  1523                                uint64_t *                dest,
  1524                                const uint64_t *          src,
  1525                                const uint64_t *          mask,
  1526                                int                      width)
  1528     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
  1531 static void
  1532 combine_conjoint_out_u (pixman_implementation_t *imp,
  1533                         pixman_op_t              op,
  1534                         uint64_t *                dest,
  1535                         const uint64_t *          src,
  1536                         const uint64_t *          mask,
  1537                         int                      width)
  1539     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
  1542 static void
  1543 combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
  1544                                 pixman_op_t              op,
  1545                                 uint64_t *                dest,
  1546                                 const uint64_t *          src,
  1547                                 const uint64_t *          mask,
  1548                                 int                      width)
  1550     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
  1553 static void
  1554 combine_conjoint_atop_u (pixman_implementation_t *imp,
  1555                          pixman_op_t              op,
  1556                          uint64_t *                dest,
  1557                          const uint64_t *          src,
  1558                          const uint64_t *          mask,
  1559                          int                      width)
  1561     combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
  1564 static void
  1565 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp,
  1566                                  pixman_op_t              op,
  1567                                  uint64_t *                dest,
  1568                                  const uint64_t *          src,
  1569                                  const uint64_t *          mask,
  1570                                  int                      width)
  1572     combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
  1575 static void
  1576 combine_conjoint_xor_u (pixman_implementation_t *imp,
  1577                         pixman_op_t              op,
  1578                         uint64_t *                dest,
  1579                         const uint64_t *          src,
  1580                         const uint64_t *          mask,
  1581                         int                      width)
  1583     combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
  1586 /************************************************************************/
  1587 /*********************** Per Channel functions **************************/
  1588 /************************************************************************/
  1590 static void
  1591 combine_clear_ca (pixman_implementation_t *imp,
  1592                   pixman_op_t              op,
  1593                   uint64_t *                dest,
  1594                   const uint64_t *          src,
  1595                   const uint64_t *          mask,
  1596                   int                      width)
  1598     memset (dest, 0, width * sizeof(uint64_t));
  1601 static void
  1602 combine_src_ca (pixman_implementation_t *imp,
  1603                 pixman_op_t              op,
  1604                 uint64_t *                dest,
  1605                 const uint64_t *          src,
  1606                 const uint64_t *          mask,
  1607                 int                      width)
  1609     int i;
  1611     for (i = 0; i < width; ++i)
  1613 	uint64_t s = *(src + i);
  1614 	uint64_t m = *(mask + i);
  1616 	combine_mask_value_ca (&s, &m);
  1618 	*(dest + i) = s;
  1622 static void
  1623 combine_over_ca (pixman_implementation_t *imp,
  1624                  pixman_op_t              op,
  1625                  uint64_t *                dest,
  1626                  const uint64_t *          src,
  1627                  const uint64_t *          mask,
  1628                  int                      width)
  1630     int i;
  1632     for (i = 0; i < width; ++i)
  1634 	uint64_t s = *(src + i);
  1635 	uint64_t m = *(mask + i);
  1636 	uint64_t a;
  1638 	combine_mask_ca (&s, &m);
  1640 	a = ~m;
  1641 	if (a)
  1643 	    uint64_t d = *(dest + i);
  1644 	    UN16x4_MUL_UN16x4_ADD_UN16x4 (d, a, s);
  1645 	    s = d;
  1648 	*(dest + i) = s;
  1652 static void
  1653 combine_over_reverse_ca (pixman_implementation_t *imp,
  1654                          pixman_op_t              op,
  1655                          uint64_t *                dest,
  1656                          const uint64_t *          src,
  1657                          const uint64_t *          mask,
  1658                          int                      width)
  1660     int i;
  1662     for (i = 0; i < width; ++i)
  1664 	uint64_t d = *(dest + i);
  1665 	uint64_t a = ~d >> A_SHIFT;
  1667 	if (a)
  1669 	    uint64_t s = *(src + i);
  1670 	    uint64_t m = *(mask + i);
  1672 	    UN16x4_MUL_UN16x4 (s, m);
  1673 	    UN16x4_MUL_UN16_ADD_UN16x4 (s, a, d);
  1675 	    *(dest + i) = s;
  1680 static void
  1681 combine_in_ca (pixman_implementation_t *imp,
  1682                pixman_op_t              op,
  1683                uint64_t *                dest,
  1684                const uint64_t *          src,
  1685                const uint64_t *          mask,
  1686                int                      width)
  1688     int i;
  1690     for (i = 0; i < width; ++i)
  1692 	uint64_t d = *(dest + i);
  1693 	uint32_t a = d >> A_SHIFT;
  1694 	uint64_t s = 0;
  1696 	if (a)
  1698 	    uint64_t m = *(mask + i);
  1700 	    s = *(src + i);
  1701 	    combine_mask_value_ca (&s, &m);
  1703 	    if (a != MASK)
  1704 		UN16x4_MUL_UN16 (s, a);
  1707 	*(dest + i) = s;
  1711 static void
  1712 combine_in_reverse_ca (pixman_implementation_t *imp,
  1713                        pixman_op_t              op,
  1714                        uint64_t *                dest,
  1715                        const uint64_t *          src,
  1716                        const uint64_t *          mask,
  1717                        int                      width)
  1719     int i;
  1721     for (i = 0; i < width; ++i)
  1723 	uint64_t s = *(src + i);
  1724 	uint64_t m = *(mask + i);
  1725 	uint64_t a;
  1727 	combine_mask_alpha_ca (&s, &m);
  1729 	a = m;
  1730 	if (a != ~0)
  1732 	    uint64_t d = 0;
  1734 	    if (a)
  1736 		d = *(dest + i);
  1737 		UN16x4_MUL_UN16x4 (d, a);
  1740 	    *(dest + i) = d;
  1745 static void
  1746 combine_out_ca (pixman_implementation_t *imp,
  1747                 pixman_op_t              op,
  1748                 uint64_t *                dest,
  1749                 const uint64_t *          src,
  1750                 const uint64_t *          mask,
  1751                 int                      width)
  1753     int i;
  1755     for (i = 0; i < width; ++i)
  1757 	uint64_t d = *(dest + i);
  1758 	uint32_t a = ~d >> A_SHIFT;
  1759 	uint64_t s = 0;
  1761 	if (a)
  1763 	    uint64_t m = *(mask + i);
  1765 	    s = *(src + i);
  1766 	    combine_mask_value_ca (&s, &m);
  1768 	    if (a != MASK)
  1769 		UN16x4_MUL_UN16 (s, a);
  1772 	*(dest + i) = s;
  1776 static void
  1777 combine_out_reverse_ca (pixman_implementation_t *imp,
  1778                         pixman_op_t              op,
  1779                         uint64_t *                dest,
  1780                         const uint64_t *          src,
  1781                         const uint64_t *          mask,
  1782                         int                      width)
  1784     int i;
  1786     for (i = 0; i < width; ++i)
  1788 	uint64_t s = *(src + i);
  1789 	uint64_t m = *(mask + i);
  1790 	uint64_t a;
  1792 	combine_mask_alpha_ca (&s, &m);
  1794 	a = ~m;
  1795 	if (a != ~0)
  1797 	    uint64_t d = 0;
  1799 	    if (a)
  1801 		d = *(dest + i);
  1802 		UN16x4_MUL_UN16x4 (d, a);
  1805 	    *(dest + i) = d;
  1810 static void
  1811 combine_atop_ca (pixman_implementation_t *imp,
  1812                  pixman_op_t              op,
  1813                  uint64_t *                dest,
  1814                  const uint64_t *          src,
  1815                  const uint64_t *          mask,
  1816                  int                      width)
  1818     int i;
  1820     for (i = 0; i < width; ++i)
  1822 	uint64_t d = *(dest + i);
  1823 	uint64_t s = *(src + i);
  1824 	uint64_t m = *(mask + i);
  1825 	uint64_t ad;
  1826 	uint32_t as = d >> A_SHIFT;
  1828 	combine_mask_ca (&s, &m);
  1830 	ad = ~m;
  1832 	UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (d, ad, s, as);
  1834 	*(dest + i) = d;
  1838 static void
  1839 combine_atop_reverse_ca (pixman_implementation_t *imp,
  1840                          pixman_op_t              op,
  1841                          uint64_t *                dest,
  1842                          const uint64_t *          src,
  1843                          const uint64_t *          mask,
  1844                          int                      width)
  1846     int i;
  1848     for (i = 0; i < width; ++i)
  1850 	uint64_t d = *(dest + i);
  1851 	uint64_t s = *(src + i);
  1852 	uint64_t m = *(mask + i);
  1853 	uint64_t ad;
  1854 	uint32_t as = ~d >> A_SHIFT;
  1856 	combine_mask_ca (&s, &m);
  1858 	ad = m;
  1860 	UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (d, ad, s, as);
  1862 	*(dest + i) = d;
  1866 static void
  1867 combine_xor_ca (pixman_implementation_t *imp,
  1868                 pixman_op_t              op,
  1869                 uint64_t *                dest,
  1870                 const uint64_t *          src,
  1871                 const uint64_t *          mask,
  1872                 int                      width)
  1874     int i;
  1876     for (i = 0; i < width; ++i)
  1878 	uint64_t d = *(dest + i);
  1879 	uint64_t s = *(src + i);
  1880 	uint64_t m = *(mask + i);
  1881 	uint64_t ad;
  1882 	uint32_t as = ~d >> A_SHIFT;
  1884 	combine_mask_ca (&s, &m);
  1886 	ad = ~m;
  1888 	UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (d, ad, s, as);
  1890 	*(dest + i) = d;
  1894 static void
  1895 combine_add_ca (pixman_implementation_t *imp,
  1896                 pixman_op_t              op,
  1897                 uint64_t *                dest,
  1898                 const uint64_t *          src,
  1899                 const uint64_t *          mask,
  1900                 int                      width)
  1902     int i;
  1904     for (i = 0; i < width; ++i)
  1906 	uint64_t s = *(src + i);
  1907 	uint64_t m = *(mask + i);
  1908 	uint64_t d = *(dest + i);
  1910 	combine_mask_value_ca (&s, &m);
  1912 	UN16x4_ADD_UN16x4 (d, s);
  1914 	*(dest + i) = d;
  1918 static void
  1919 combine_saturate_ca (pixman_implementation_t *imp,
  1920                      pixman_op_t              op,
  1921                      uint64_t *                dest,
  1922                      const uint64_t *          src,
  1923                      const uint64_t *          mask,
  1924                      int                      width)
  1926     int i;
  1928     for (i = 0; i < width; ++i)
  1930 	uint64_t s, d;
  1931 	uint32_t sa, sr, sg, sb, da;
  1932 	uint32_t t, u, v;
  1933 	uint64_t m, n, o, p;
  1935 	d = *(dest + i);
  1936 	s = *(src + i);
  1937 	m = *(mask + i);
  1939 	combine_mask_ca (&s, &m);
  1941 	sa = (m >> A_SHIFT);
  1942 	sr = (m >> R_SHIFT) & MASK;
  1943 	sg = (m >> G_SHIFT) & MASK;
  1944 	sb =  m             & MASK;
  1945 	da = ~d >> A_SHIFT;
  1947 	if (sb <= da)
  1948 	    m = ADD (s, d, 0, t);
  1949 	else
  1950 	    m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
  1952 	if (sg <= da)
  1953 	    n = ADD (s, d, G_SHIFT, t);
  1954 	else
  1955 	    n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
  1957 	if (sr <= da)
  1958 	    o = ADD (s, d, R_SHIFT, t);
  1959 	else
  1960 	    o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
  1962 	if (sa <= da)
  1963 	    p = ADD (s, d, A_SHIFT, t);
  1964 	else
  1965 	    p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
  1967 	*(dest + i) = m | n | o | p;
  1971 static void
  1972 combine_disjoint_general_ca (uint64_t *      dest,
  1973                              const uint64_t *src,
  1974                              const uint64_t *mask,
  1975                              int            width,
  1976                              uint16_t        combine)
  1978     int i;
  1980     for (i = 0; i < width; ++i)
  1982 	uint64_t s, d;
  1983 	uint64_t m, n, o, p;
  1984 	uint64_t Fa, Fb;
  1985 	uint32_t t, u, v;
  1986 	uint64_t sa;
  1987 	uint16_t da;
  1989 	s = *(src + i);
  1990 	m = *(mask + i);
  1991 	d = *(dest + i);
  1992 	da = d >> A_SHIFT;
  1994 	combine_mask_ca (&s, &m);
  1996 	sa = m;
  1998 	switch (combine & COMBINE_A)
  2000 	default:
  2001 	    Fa = 0;
  2002 	    break;
  2004 	case COMBINE_A_OUT:
  2005 	    m = (uint64_t)combine_disjoint_out_part ((uint16_t) (sa >> 0), da);
  2006 	    n = (uint64_t)combine_disjoint_out_part ((uint16_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2007 	    o = (uint64_t)combine_disjoint_out_part ((uint16_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2008 	    p = (uint64_t)combine_disjoint_out_part ((uint16_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2009 	    Fa = m | n | o | p;
  2010 	    break;
  2012 	case COMBINE_A_IN:
  2013 	    m = (uint64_t)combine_disjoint_in_part ((uint16_t) (sa >> 0), da);
  2014 	    n = (uint64_t)combine_disjoint_in_part ((uint16_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2015 	    o = (uint64_t)combine_disjoint_in_part ((uint16_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2016 	    p = (uint64_t)combine_disjoint_in_part ((uint16_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2017 	    Fa = m | n | o | p;
  2018 	    break;
  2020 	case COMBINE_A:
  2021 	    Fa = ~0;
  2022 	    break;
  2025 	switch (combine & COMBINE_B)
  2027 	default:
  2028 	    Fb = 0;
  2029 	    break;
  2031 	case COMBINE_B_OUT:
  2032 	    m = (uint64_t)combine_disjoint_out_part (da, (uint16_t) (sa >> 0));
  2033 	    n = (uint64_t)combine_disjoint_out_part (da, (uint16_t) (sa >> G_SHIFT)) << G_SHIFT;
  2034 	    o = (uint64_t)combine_disjoint_out_part (da, (uint16_t) (sa >> R_SHIFT)) << R_SHIFT;
  2035 	    p = (uint64_t)combine_disjoint_out_part (da, (uint16_t) (sa >> A_SHIFT)) << A_SHIFT;
  2036 	    Fb = m | n | o | p;
  2037 	    break;
  2039 	case COMBINE_B_IN:
  2040 	    m = (uint64_t)combine_disjoint_in_part (da, (uint16_t) (sa >> 0));
  2041 	    n = (uint64_t)combine_disjoint_in_part (da, (uint16_t) (sa >> G_SHIFT)) << G_SHIFT;
  2042 	    o = (uint64_t)combine_disjoint_in_part (da, (uint16_t) (sa >> R_SHIFT)) << R_SHIFT;
  2043 	    p = (uint64_t)combine_disjoint_in_part (da, (uint16_t) (sa >> A_SHIFT)) << A_SHIFT;
  2044 	    Fb = m | n | o | p;
  2045 	    break;
  2047 	case COMBINE_B:
  2048 	    Fb = ~0;
  2049 	    break;
  2051 	m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
  2052 	n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
  2053 	o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
  2054 	p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
  2056 	s = m | n | o | p;
  2058 	*(dest + i) = s;
  2062 static void
  2063 combine_disjoint_over_ca (pixman_implementation_t *imp,
  2064                           pixman_op_t              op,
  2065                           uint64_t *                dest,
  2066                           const uint64_t *          src,
  2067                           const uint64_t *          mask,
  2068                           int                      width)
  2070     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
  2073 static void
  2074 combine_disjoint_in_ca (pixman_implementation_t *imp,
  2075                         pixman_op_t              op,
  2076                         uint64_t *                dest,
  2077                         const uint64_t *          src,
  2078                         const uint64_t *          mask,
  2079                         int                      width)
  2081     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
  2084 static void
  2085 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
  2086                                 pixman_op_t              op,
  2087                                 uint64_t *                dest,
  2088                                 const uint64_t *          src,
  2089                                 const uint64_t *          mask,
  2090                                 int                      width)
  2092     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
  2095 static void
  2096 combine_disjoint_out_ca (pixman_implementation_t *imp,
  2097                          pixman_op_t              op,
  2098                          uint64_t *                dest,
  2099                          const uint64_t *          src,
  2100                          const uint64_t *          mask,
  2101                          int                      width)
  2103     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
  2106 static void
  2107 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
  2108                                  pixman_op_t              op,
  2109                                  uint64_t *                dest,
  2110                                  const uint64_t *          src,
  2111                                  const uint64_t *          mask,
  2112                                  int                      width)
  2114     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
  2117 static void
  2118 combine_disjoint_atop_ca (pixman_implementation_t *imp,
  2119                           pixman_op_t              op,
  2120                           uint64_t *                dest,
  2121                           const uint64_t *          src,
  2122                           const uint64_t *          mask,
  2123                           int                      width)
  2125     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
  2128 static void
  2129 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
  2130                                   pixman_op_t              op,
  2131                                   uint64_t *                dest,
  2132                                   const uint64_t *          src,
  2133                                   const uint64_t *          mask,
  2134                                   int                      width)
  2136     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
  2139 static void
  2140 combine_disjoint_xor_ca (pixman_implementation_t *imp,
  2141                          pixman_op_t              op,
  2142                          uint64_t *                dest,
  2143                          const uint64_t *          src,
  2144                          const uint64_t *          mask,
  2145                          int                      width)
  2147     combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
  2150 static void
  2151 combine_conjoint_general_ca (uint64_t *      dest,
  2152                              const uint64_t *src,
  2153                              const uint64_t *mask,
  2154                              int            width,
  2155                              uint16_t        combine)
  2157     int i;
  2159     for (i = 0; i < width; ++i)
  2161 	uint64_t s, d;
  2162 	uint64_t m, n, o, p;
  2163 	uint64_t Fa, Fb;
  2164 	uint32_t t, u, v;
  2165 	uint64_t sa;
  2166 	uint16_t da;
  2168 	s = *(src + i);
  2169 	m = *(mask + i);
  2170 	d = *(dest + i);
  2171 	da = d >> A_SHIFT;
  2173 	combine_mask_ca (&s, &m);
  2175 	sa = m;
  2177 	switch (combine & COMBINE_A)
  2179 	default:
  2180 	    Fa = 0;
  2181 	    break;
  2183 	case COMBINE_A_OUT:
  2184 	    m = (uint64_t)combine_conjoint_out_part ((uint16_t) (sa >> 0), da);
  2185 	    n = (uint64_t)combine_conjoint_out_part ((uint16_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2186 	    o = (uint64_t)combine_conjoint_out_part ((uint16_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2187 	    p = (uint64_t)combine_conjoint_out_part ((uint16_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2188 	    Fa = m | n | o | p;
  2189 	    break;
  2191 	case COMBINE_A_IN:
  2192 	    m = (uint64_t)combine_conjoint_in_part ((uint16_t) (sa >> 0), da);
  2193 	    n = (uint64_t)combine_conjoint_in_part ((uint16_t) (sa >> G_SHIFT), da) << G_SHIFT;
  2194 	    o = (uint64_t)combine_conjoint_in_part ((uint16_t) (sa >> R_SHIFT), da) << R_SHIFT;
  2195 	    p = (uint64_t)combine_conjoint_in_part ((uint16_t) (sa >> A_SHIFT), da) << A_SHIFT;
  2196 	    Fa = m | n | o | p;
  2197 	    break;
  2199 	case COMBINE_A:
  2200 	    Fa = ~0;
  2201 	    break;
  2204 	switch (combine & COMBINE_B)
  2206 	default:
  2207 	    Fb = 0;
  2208 	    break;
  2210 	case COMBINE_B_OUT:
  2211 	    m = (uint64_t)combine_conjoint_out_part (da, (uint16_t) (sa >> 0));
  2212 	    n = (uint64_t)combine_conjoint_out_part (da, (uint16_t) (sa >> G_SHIFT)) << G_SHIFT;
  2213 	    o = (uint64_t)combine_conjoint_out_part (da, (uint16_t) (sa >> R_SHIFT)) << R_SHIFT;
  2214 	    p = (uint64_t)combine_conjoint_out_part (da, (uint16_t) (sa >> A_SHIFT)) << A_SHIFT;
  2215 	    Fb = m | n | o | p;
  2216 	    break;
  2218 	case COMBINE_B_IN:
  2219 	    m = (uint64_t)combine_conjoint_in_part (da, (uint16_t) (sa >> 0));
  2220 	    n = (uint64_t)combine_conjoint_in_part (da, (uint16_t) (sa >> G_SHIFT)) << G_SHIFT;
  2221 	    o = (uint64_t)combine_conjoint_in_part (da, (uint16_t) (sa >> R_SHIFT)) << R_SHIFT;
  2222 	    p = (uint64_t)combine_conjoint_in_part (da, (uint16_t) (sa >> A_SHIFT)) << A_SHIFT;
  2223 	    Fb = m | n | o | p;
  2224 	    break;
  2226 	case COMBINE_B:
  2227 	    Fb = ~0;
  2228 	    break;
  2230 	m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
  2231 	n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
  2232 	o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
  2233 	p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
  2235 	s = m | n | o | p;
  2237 	*(dest + i) = s;
  2241 static void
  2242 combine_conjoint_over_ca (pixman_implementation_t *imp,
  2243                           pixman_op_t              op,
  2244                           uint64_t *                dest,
  2245                           const uint64_t *          src,
  2246                           const uint64_t *          mask,
  2247                           int                      width)
  2249     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
  2252 static void
  2253 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
  2254                                   pixman_op_t              op,
  2255                                   uint64_t *                dest,
  2256                                   const uint64_t *          src,
  2257                                   const uint64_t *          mask,
  2258                                   int                      width)
  2260     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
  2263 static void
  2264 combine_conjoint_in_ca (pixman_implementation_t *imp,
  2265                         pixman_op_t              op,
  2266                         uint64_t *                dest,
  2267                         const uint64_t *          src,
  2268                         const uint64_t *          mask,
  2269                         int                      width)
  2271     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
  2274 static void
  2275 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
  2276                                 pixman_op_t              op,
  2277                                 uint64_t *                dest,
  2278                                 const uint64_t *          src,
  2279                                 const uint64_t *          mask,
  2280                                 int                      width)
  2282     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
  2285 static void
  2286 combine_conjoint_out_ca (pixman_implementation_t *imp,
  2287                          pixman_op_t              op,
  2288                          uint64_t *                dest,
  2289                          const uint64_t *          src,
  2290                          const uint64_t *          mask,
  2291                          int                      width)
  2293     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
  2296 static void
  2297 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
  2298                                  pixman_op_t              op,
  2299                                  uint64_t *                dest,
  2300                                  const uint64_t *          src,
  2301                                  const uint64_t *          mask,
  2302                                  int                      width)
  2304     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
  2307 static void
  2308 combine_conjoint_atop_ca (pixman_implementation_t *imp,
  2309                           pixman_op_t              op,
  2310                           uint64_t *                dest,
  2311                           const uint64_t *          src,
  2312                           const uint64_t *          mask,
  2313                           int                      width)
  2315     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
  2318 static void
  2319 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp,
  2320                                   pixman_op_t              op,
  2321                                   uint64_t *                dest,
  2322                                   const uint64_t *          src,
  2323                                   const uint64_t *          mask,
  2324                                   int                      width)
  2326     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
  2329 static void
  2330 combine_conjoint_xor_ca (pixman_implementation_t *imp,
  2331                          pixman_op_t              op,
  2332                          uint64_t *                dest,
  2333                          const uint64_t *          src,
  2334                          const uint64_t *          mask,
  2335                          int                      width)
  2337     combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
  2340 void
  2341 _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp)
  2343     /* Unified alpha */
  2344     imp->combine_64[PIXMAN_OP_CLEAR] = combine_clear;
  2345     imp->combine_64[PIXMAN_OP_SRC] = combine_src_u;
  2346     imp->combine_64[PIXMAN_OP_DST] = combine_dst;
  2347     imp->combine_64[PIXMAN_OP_OVER] = combine_over_u;
  2348     imp->combine_64[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u;
  2349     imp->combine_64[PIXMAN_OP_IN] = combine_in_u;
  2350     imp->combine_64[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u;
  2351     imp->combine_64[PIXMAN_OP_OUT] = combine_out_u;
  2352     imp->combine_64[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u;
  2353     imp->combine_64[PIXMAN_OP_ATOP] = combine_atop_u;
  2354     imp->combine_64[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u;
  2355     imp->combine_64[PIXMAN_OP_XOR] = combine_xor_u;
  2356     imp->combine_64[PIXMAN_OP_ADD] = combine_add_u;
  2357     imp->combine_64[PIXMAN_OP_SATURATE] = combine_saturate_u;
  2359     /* Disjoint, unified */
  2360     imp->combine_64[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
  2361     imp->combine_64[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
  2362     imp->combine_64[PIXMAN_OP_DISJOINT_DST] = combine_dst;
  2363     imp->combine_64[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
  2364     imp->combine_64[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
  2365     imp->combine_64[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
  2366     imp->combine_64[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u;
  2367     imp->combine_64[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u;
  2368     imp->combine_64[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u;
  2369     imp->combine_64[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u;
  2370     imp->combine_64[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u;
  2371     imp->combine_64[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u;
  2373     /* Conjoint, unified */
  2374     imp->combine_64[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
  2375     imp->combine_64[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
  2376     imp->combine_64[PIXMAN_OP_CONJOINT_DST] = combine_dst;
  2377     imp->combine_64[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
  2378     imp->combine_64[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u;
  2379     imp->combine_64[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
  2380     imp->combine_64[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u;
  2381     imp->combine_64[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u;
  2382     imp->combine_64[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u;
  2383     imp->combine_64[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u;
  2384     imp->combine_64[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u;
  2385     imp->combine_64[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u;
  2387     imp->combine_64[PIXMAN_OP_MULTIPLY] = combine_multiply_u;
  2388     imp->combine_64[PIXMAN_OP_SCREEN] = combine_screen_u;
  2389     imp->combine_64[PIXMAN_OP_OVERLAY] = combine_overlay_u;
  2390     imp->combine_64[PIXMAN_OP_DARKEN] = combine_darken_u;
  2391     imp->combine_64[PIXMAN_OP_LIGHTEN] = combine_lighten_u;
  2392     imp->combine_64[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u;
  2393     imp->combine_64[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u;
  2394     imp->combine_64[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u;
  2395     imp->combine_64[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u;
  2396     imp->combine_64[PIXMAN_OP_DIFFERENCE] = combine_difference_u;
  2397     imp->combine_64[PIXMAN_OP_EXCLUSION] = combine_exclusion_u;
  2398     imp->combine_64[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u;
  2399     imp->combine_64[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u;
  2400     imp->combine_64[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u;
  2401     imp->combine_64[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u;
  2403     /* Component alpha combiners */
  2404     imp->combine_64_ca[PIXMAN_OP_CLEAR] = combine_clear_ca;
  2405     imp->combine_64_ca[PIXMAN_OP_SRC] = combine_src_ca;
  2406     /* dest */
  2407     imp->combine_64_ca[PIXMAN_OP_OVER] = combine_over_ca;
  2408     imp->combine_64_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca;
  2409     imp->combine_64_ca[PIXMAN_OP_IN] = combine_in_ca;
  2410     imp->combine_64_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca;
  2411     imp->combine_64_ca[PIXMAN_OP_OUT] = combine_out_ca;
  2412     imp->combine_64_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca;
  2413     imp->combine_64_ca[PIXMAN_OP_ATOP] = combine_atop_ca;
  2414     imp->combine_64_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca;
  2415     imp->combine_64_ca[PIXMAN_OP_XOR] = combine_xor_ca;
  2416     imp->combine_64_ca[PIXMAN_OP_ADD] = combine_add_ca;
  2417     imp->combine_64_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca;
  2419     /* Disjoint CA */
  2420     imp->combine_64_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
  2421     imp->combine_64_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
  2422     imp->combine_64_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst;
  2423     imp->combine_64_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
  2424     imp->combine_64_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca;
  2425     imp->combine_64_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
  2426     imp->combine_64_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca;
  2427     imp->combine_64_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca;
  2428     imp->combine_64_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca;
  2429     imp->combine_64_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca;
  2430     imp->combine_64_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca;
  2431     imp->combine_64_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca;
  2433     /* Conjoint CA */
  2434     imp->combine_64_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
  2435     imp->combine_64_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
  2436     imp->combine_64_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst;
  2437     imp->combine_64_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
  2438     imp->combine_64_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca;
  2439     imp->combine_64_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
  2440     imp->combine_64_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca;
  2441     imp->combine_64_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca;
  2442     imp->combine_64_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca;
  2443     imp->combine_64_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca;
  2444     imp->combine_64_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca;
  2445     imp->combine_64_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca;
  2447     imp->combine_64_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca;
  2448     imp->combine_64_ca[PIXMAN_OP_SCREEN] = combine_screen_ca;
  2449     imp->combine_64_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca;
  2450     imp->combine_64_ca[PIXMAN_OP_DARKEN] = combine_darken_ca;
  2451     imp->combine_64_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca;
  2452     imp->combine_64_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca;
  2453     imp->combine_64_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca;
  2454     imp->combine_64_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca;
  2455     imp->combine_64_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca;
  2456     imp->combine_64_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
  2457     imp->combine_64_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
  2459     /* It is not clear that these make sense, so make them noops for now */
  2460     imp->combine_64_ca[PIXMAN_OP_HSL_HUE] = combine_dst;
  2461     imp->combine_64_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst;
  2462     imp->combine_64_ca[PIXMAN_OP_HSL_COLOR] = combine_dst;
  2463     imp->combine_64_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst;

mercurial