1 /* WARNING: This file is generated by combine.pl from combine.inc.
2 Please edit one of those files rather than this one. */
3
4 #line 1 "pixman-combine.c.template"
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <math.h>
10 #include <string.h>
11
12 #include "pixman-private.h"
13
14 #include "pixman-combine64.h"
15
16 /*** per channel helper functions ***/
17
18 static void
combine_mask_ca(uint64_t * src,uint64_t * mask)19 combine_mask_ca (uint64_t *src, uint64_t *mask)
20 {
21 uint64_t a = *mask;
22
23 uint64_t x;
24 uint32_t xa;
25
26 if (!a)
27 {
28 *(src) = 0;
29 return;
30 }
31
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 }
41
42 xa = x >> A_SHIFT;
43 UN16x4_MUL_UN16x4 (x, a);
44 *(src) = x;
45
46 UN16x4_MUL_UN16 (a, xa);
47 *(mask) = a;
48 }
49
50 static void
combine_mask_value_ca(uint64_t * src,const uint64_t * mask)51 combine_mask_value_ca (uint64_t *src, const uint64_t *mask)
52 {
53 uint64_t a = *mask;
54 uint64_t x;
55
56 if (!a)
57 {
58 *(src) = 0;
59 return;
60 }
61
62 if (a == ~0)
63 return;
64
65 x = *(src);
66 UN16x4_MUL_UN16x4 (x, a);
67 *(src) = x;
68 }
69
70 static void
combine_mask_alpha_ca(const uint64_t * src,uint64_t * mask)71 combine_mask_alpha_ca (const uint64_t *src, uint64_t *mask)
72 {
73 uint64_t a = *(mask);
74 uint64_t x;
75
76 if (!a)
77 return;
78
79 x = *(src) >> A_SHIFT;
80 if (x == MASK)
81 return;
82
83 if (a == ~0)
84 {
85 x |= x << G_SHIFT;
86 x |= x << R_SHIFT;
87 *(mask) = x;
88 return;
89 }
90
91 UN16x4_MUL_UN16 (a, x);
92 *(mask) = a;
93 }
94
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 */
102
103 /*
104 * All of the composing functions
105 */
106
107 static force_inline uint64_t
combine_mask(const uint64_t * src,const uint64_t * mask,int i)108 combine_mask (const uint64_t *src, const uint64_t *mask, int i)
109 {
110 uint64_t s, m;
111
112 if (mask)
113 {
114 m = *(mask + i) >> A_SHIFT;
115
116 if (!m)
117 return 0;
118 }
119
120 s = *(src + i);
121
122 if (mask)
123 UN16x4_MUL_UN16 (s, m);
124
125 return s;
126 }
127
128 static void
combine_clear(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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 }
138
139 static void
combine_dst(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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 }
149
150 static void
combine_src_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
159
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);
167
168 *(dest + i) = s;
169 }
170 }
171 }
172
173 /* if the Src is opaque, call combine_src_u */
174 static void
combine_over_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
183
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);
189
190 UN16x4_MUL_UN16_ADD_UN16x4 (d, ia, s);
191 *(dest + i) = d;
192 }
193 }
194
195 /* if the Dst is opaque, this is a noop */
196 static void
combine_over_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
205
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 }
215
216 /* if the Dst is opaque, call combine_src_u */
217 static void
combine_in_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
226
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 }
235
236 /* if the Src is opaque, this is a noop */
237 static void
combine_in_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
246
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 }
256
257 /* if the Dst is opaque, call combine_clear */
258 static void
combine_out_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
267
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 }
276
277 /* if the Src is opaque, call combine_clear */
278 static void
combine_out_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
287
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 }
297
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
combine_atop_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
310
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);
317
318 UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (s, dest_a, d, src_ia);
319 *(dest + i) = s;
320 }
321 }
322
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
combine_atop_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
335
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);
342
343 UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (s, dest_ia, d, src_a);
344 *(dest + i) = s;
345 }
346 }
347
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
combine_xor_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
360
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);
367
368 UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (s, dest_ia, d, src_ia);
369 *(dest + i) = s;
370 }
371 }
372
373 static void
combine_add_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
382
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 }
391
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
combine_saturate_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
404
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;
410
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 }
423
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 */
446
447 /*
448 * Multiply
449 * B(Dca, ad, Sca, as) = Dca.Sca
450 */
451
452 static void
combine_multiply_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
461
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);
469
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);
473
474 *(dest + i) = d;
475 }
476 }
477
478 static void
combine_multiply_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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;
487
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);
495
496 combine_mask_value_ca (&s, &m);
497
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);
501
502 *(dest + i) = r;
503 }
504 }
505
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 }
567
568 /*
569 * Screen
570 * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca
571 */
572 static inline uint64_t
blend_screen(uint64_t dca,uint64_t da,uint64_t sca,uint64_t sa)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 }
577
PDF_SEPARABLE_BLEND_MODE(screen)578 PDF_SEPARABLE_BLEND_MODE (screen)
579
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;
592
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 }
599
PDF_SEPARABLE_BLEND_MODE(overlay)600 PDF_SEPARABLE_BLEND_MODE (overlay)
601
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;
610
611 s = sca * da;
612 d = dca * sa;
613 return DIV_ONE_UN16 (s > d ? d : s);
614 }
615
PDF_SEPARABLE_BLEND_MODE(darken)616 PDF_SEPARABLE_BLEND_MODE (darken)
617
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;
626
627 s = sca * da;
628 d = dca * sa;
629 return DIV_ONE_UN16 (s > d ? s : d);
630 }
631
PDF_SEPARABLE_BLEND_MODE(lighten)632 PDF_SEPARABLE_BLEND_MODE (lighten)
633
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 }
657
PDF_SEPARABLE_BLEND_MODE(color_dodge)658 PDF_SEPARABLE_BLEND_MODE (color_dodge)
659
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 }
683
PDF_SEPARABLE_BLEND_MODE(color_burn)684 PDF_SEPARABLE_BLEND_MODE (color_burn)
685
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 }
702
PDF_SEPARABLE_BLEND_MODE(hard_light)703 PDF_SEPARABLE_BLEND_MODE (hard_light)
704
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;
726
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 }
749
PDF_SEPARABLE_BLEND_MODE(soft_light)750 PDF_SEPARABLE_BLEND_MODE (soft_light)
751
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;
761
762 if (scada < dcasa)
763 return DIV_ONE_UN16 (dcasa - scada);
764 else
765 return DIV_ONE_UN16 (scada - dcasa);
766 }
767
PDF_SEPARABLE_BLEND_MODE(difference)768 PDF_SEPARABLE_BLEND_MODE (difference)
769
770 /*
771 * Exclusion
772 * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca)
773 */
774
775 /* This can be made faster by writing it directly and not using
776 * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
777
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 }
783
PDF_SEPARABLE_BLEND_MODE(exclusion)784 PDF_SEPARABLE_BLEND_MODE (exclusion)
785
786 #undef PDF_SEPARABLE_BLEND_MODE
787
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 */
821
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 */
862
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 */
895
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))
900
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 }
939
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];
945
946 a = sa * (1.0 / MASK);
947
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);
952
953 l = l - LUM (tmp);
954 tmp[0] += l;
955 tmp[1] += l;
956 tmp[2] += l;
957
958 /* clip_color */
959 l = LUM (tmp);
960 min = CH_MIN (tmp);
961 max = CH_MAX (tmp);
962
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 }
993
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 }
998
999 static void
set_sat(uint64_t dest[3],uint64_t src[3],uint64_t sat)1000 set_sat (uint64_t dest[3], uint64_t src[3], uint64_t sat)
1001 {
1002 int id[3];
1003 uint64_t min, max;
1004
1005 if (src[0] > src[1])
1006 {
1007 if (src[0] > src[2])
1008 {
1009 id[0] = 0;
1010 if (src[1] > src[2])
1011 {
1012 id[1] = 1;
1013 id[2] = 2;
1014 }
1015 else
1016 {
1017 id[1] = 2;
1018 id[2] = 1;
1019 }
1020 }
1021 else
1022 {
1023 id[0] = 2;
1024 id[1] = 0;
1025 id[2] = 1;
1026 }
1027 }
1028 else
1029 {
1030 if (src[0] > src[2])
1031 {
1032 id[0] = 1;
1033 id[1] = 0;
1034 id[2] = 2;
1035 }
1036 else
1037 {
1038 id[2] = 0;
1039 if (src[1] > src[2])
1040 {
1041 id[0] = 1;
1042 id[1] = 2;
1043 }
1044 else
1045 {
1046 id[0] = 2;
1047 id[1] = 1;
1048 }
1049 }
1050 }
1051
1052 max = dest[id[0]];
1053 min = dest[id[2]];
1054 if (max > min)
1055 {
1056 dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
1057 dest[id[0]] = sat;
1058 dest[id[2]] = 0;
1059 }
1060 else
1061 {
1062 dest[0] = dest[1] = dest[2] = 0;
1063 }
1064 }
1065
1066 /*
1067 * Hue:
1068 * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
1069 */
1070 static inline void
blend_hsl_hue(uint64_t c[3],uint64_t dc[3],uint64_t da,uint64_t sc[3],uint64_t sa)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)
1076 {
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);
1082 }
1083
PDF_NON_SEPARABLE_BLEND_MODE(hsl_hue)1084 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
1085
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)
1096 {
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);
1102 }
1103
PDF_NON_SEPARABLE_BLEND_MODE(hsl_saturation)1104 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
1105
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)
1116 {
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);
1121 }
1122
PDF_NON_SEPARABLE_BLEND_MODE(hsl_color)1123 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
1124
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)
1135 {
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);
1140 }
1141
PDF_NON_SEPARABLE_BLEND_MODE(hsl_luminosity)1142 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
1143
1144 #undef SAT
1145 #undef LUM
1146 #undef CH_MAX
1147 #undef CH_MIN
1148 #undef PDF_NON_SEPARABLE_BLEND_MODE
1149
1150 /* All of the disjoint/conjoint composing functions
1151 *
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.
1156 *
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)
1171 *
1172 * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more
1173 * information about these operators.
1174 */
1175
1176 #define COMBINE_A_OUT 1
1177 #define COMBINE_A_IN 2
1178 #define COMBINE_B_OUT 4
1179 #define COMBINE_B_IN 8
1180
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)
1189
1190 /* portion covered by a but not b */
1191 static uint16_t
1192 combine_disjoint_out_part (uint16_t a, uint16_t b)
1193 {
1194 /* min (1, (1-b) / a) */
1195
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 */
1200 }
1201
1202 /* portion covered by both a and b */
1203 static uint16_t
combine_disjoint_in_part(uint16_t a,uint16_t b)1204 combine_disjoint_in_part (uint16_t a, uint16_t b)
1205 {
1206 /* max (1-(1-b)/a,0) */
1207 /* = - min ((1-b)/a - 1, 0) */
1208 /* = 1 - min (1, (1-b)/a) */
1209
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 */
1214 }
1215
1216 /* portion covered by a but not b */
1217 static uint16_t
combine_conjoint_out_part(uint16_t a,uint16_t b)1218 combine_conjoint_out_part (uint16_t a, uint16_t b)
1219 {
1220 /* max (1-b/a,0) */
1221 /* = 1-min(b/a,1) */
1222
1223 /* min (1, (1-b) / a) */
1224
1225 if (b >= a) /* b >= a -> b/a >= 1 */
1226 return 0x00; /* 0 */
1227 return ~DIV_UN16(b, a); /* 1 - b/a */
1228 }
1229
1230 /* portion covered by both a and b */
1231 static uint16_t
combine_conjoint_in_part(uint16_t a,uint16_t b)1232 combine_conjoint_in_part (uint16_t a, uint16_t b)
1233 {
1234 /* min (1,b/a) */
1235
1236 if (b >= a) /* b >= a -> b/a >= 1 */
1237 return MASK; /* 1 */
1238 return DIV_UN16 (b, a); /* b/a */
1239 }
1240
1241 #define GET_COMP(v, i) ((uint32_t) (uint16_t) ((v) >> i))
1242
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))
1246
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))
1252
1253 static void
combine_disjoint_general_u(uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width,uint16_t combine)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)
1259 {
1260 int i;
1261
1262 for (i = 0; i < width; ++i)
1263 {
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;
1270
1271 switch (combine & COMBINE_A)
1272 {
1273 default:
1274 Fa = 0;
1275 break;
1276
1277 case COMBINE_A_OUT:
1278 Fa = combine_disjoint_out_part (sa, da);
1279 break;
1280
1281 case COMBINE_A_IN:
1282 Fa = combine_disjoint_in_part (sa, da);
1283 break;
1284
1285 case COMBINE_A:
1286 Fa = MASK;
1287 break;
1288 }
1289
1290 switch (combine & COMBINE_B)
1291 {
1292 default:
1293 Fb = 0;
1294 break;
1295
1296 case COMBINE_B_OUT:
1297 Fb = combine_disjoint_out_part (da, sa);
1298 break;
1299
1300 case COMBINE_B_IN:
1301 Fb = combine_disjoint_in_part (da, sa);
1302 break;
1303
1304 case COMBINE_B:
1305 Fb = MASK;
1306 break;
1307 }
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;
1314 }
1315 }
1316
1317 static void
combine_disjoint_over_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1324 {
1325 int i;
1326
1327 for (i = 0; i < width; ++i)
1328 {
1329 uint64_t s = combine_mask (src, mask, i);
1330 uint32_t a = s >> A_SHIFT;
1331
1332 if (s != 0x00)
1333 {
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);
1337
1338 *(dest + i) = d;
1339 }
1340 }
1341 }
1342
1343 static void
combine_disjoint_in_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1350 {
1351 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1352 }
1353
1354 static void
combine_disjoint_in_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1361 {
1362 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1363 }
1364
1365 static void
combine_disjoint_out_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1372 {
1373 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1374 }
1375
1376 static void
combine_disjoint_out_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1383 {
1384 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1385 }
1386
1387 static void
combine_disjoint_atop_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1394 {
1395 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1396 }
1397
1398 static void
combine_disjoint_atop_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1405 {
1406 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1407 }
1408
1409 static void
combine_disjoint_xor_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1416 {
1417 combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1418 }
1419
1420 static void
combine_conjoint_general_u(uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width,uint16_t combine)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)
1426 {
1427 int i;
1428
1429 for (i = 0; i < width; ++i)
1430 {
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;
1437
1438 switch (combine & COMBINE_A)
1439 {
1440 default:
1441 Fa = 0;
1442 break;
1443
1444 case COMBINE_A_OUT:
1445 Fa = combine_conjoint_out_part (sa, da);
1446 break;
1447
1448 case COMBINE_A_IN:
1449 Fa = combine_conjoint_in_part (sa, da);
1450 break;
1451
1452 case COMBINE_A:
1453 Fa = MASK;
1454 break;
1455 }
1456
1457 switch (combine & COMBINE_B)
1458 {
1459 default:
1460 Fb = 0;
1461 break;
1462
1463 case COMBINE_B_OUT:
1464 Fb = combine_conjoint_out_part (da, sa);
1465 break;
1466
1467 case COMBINE_B_IN:
1468 Fb = combine_conjoint_in_part (da, sa);
1469 break;
1470
1471 case COMBINE_B:
1472 Fb = MASK;
1473 break;
1474 }
1475
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);
1480
1481 s = m | n | o | p;
1482
1483 *(dest + i) = s;
1484 }
1485 }
1486
1487 static void
combine_conjoint_over_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1494 {
1495 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
1496 }
1497
1498 static void
combine_conjoint_over_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1505 {
1506 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
1507 }
1508
1509 static void
combine_conjoint_in_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1516 {
1517 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1518 }
1519
1520 static void
combine_conjoint_in_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1527 {
1528 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1529 }
1530
1531 static void
combine_conjoint_out_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1538 {
1539 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1540 }
1541
1542 static void
combine_conjoint_out_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1549 {
1550 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1551 }
1552
1553 static void
combine_conjoint_atop_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1560 {
1561 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1562 }
1563
1564 static void
combine_conjoint_atop_reverse_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1571 {
1572 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1573 }
1574
1575 static void
combine_conjoint_xor_u(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1582 {
1583 combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1584 }
1585
1586 /************************************************************************/
1587 /*********************** Per Channel functions **************************/
1588 /************************************************************************/
1589
1590 static void
combine_clear_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1597 {
1598 memset (dest, 0, width * sizeof(uint64_t));
1599 }
1600
1601 static void
combine_src_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1608 {
1609 int i;
1610
1611 for (i = 0; i < width; ++i)
1612 {
1613 uint64_t s = *(src + i);
1614 uint64_t m = *(mask + i);
1615
1616 combine_mask_value_ca (&s, &m);
1617
1618 *(dest + i) = s;
1619 }
1620 }
1621
1622 static void
combine_over_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1629 {
1630 int i;
1631
1632 for (i = 0; i < width; ++i)
1633 {
1634 uint64_t s = *(src + i);
1635 uint64_t m = *(mask + i);
1636 uint64_t a;
1637
1638 combine_mask_ca (&s, &m);
1639
1640 a = ~m;
1641 if (a)
1642 {
1643 uint64_t d = *(dest + i);
1644 UN16x4_MUL_UN16x4_ADD_UN16x4 (d, a, s);
1645 s = d;
1646 }
1647
1648 *(dest + i) = s;
1649 }
1650 }
1651
1652 static void
combine_over_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1659 {
1660 int i;
1661
1662 for (i = 0; i < width; ++i)
1663 {
1664 uint64_t d = *(dest + i);
1665 uint64_t a = ~d >> A_SHIFT;
1666
1667 if (a)
1668 {
1669 uint64_t s = *(src + i);
1670 uint64_t m = *(mask + i);
1671
1672 UN16x4_MUL_UN16x4 (s, m);
1673 UN16x4_MUL_UN16_ADD_UN16x4 (s, a, d);
1674
1675 *(dest + i) = s;
1676 }
1677 }
1678 }
1679
1680 static void
combine_in_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1687 {
1688 int i;
1689
1690 for (i = 0; i < width; ++i)
1691 {
1692 uint64_t d = *(dest + i);
1693 uint32_t a = d >> A_SHIFT;
1694 uint64_t s = 0;
1695
1696 if (a)
1697 {
1698 uint64_t m = *(mask + i);
1699
1700 s = *(src + i);
1701 combine_mask_value_ca (&s, &m);
1702
1703 if (a != MASK)
1704 UN16x4_MUL_UN16 (s, a);
1705 }
1706
1707 *(dest + i) = s;
1708 }
1709 }
1710
1711 static void
combine_in_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1718 {
1719 int i;
1720
1721 for (i = 0; i < width; ++i)
1722 {
1723 uint64_t s = *(src + i);
1724 uint64_t m = *(mask + i);
1725 uint64_t a;
1726
1727 combine_mask_alpha_ca (&s, &m);
1728
1729 a = m;
1730 if (a != ~0)
1731 {
1732 uint64_t d = 0;
1733
1734 if (a)
1735 {
1736 d = *(dest + i);
1737 UN16x4_MUL_UN16x4 (d, a);
1738 }
1739
1740 *(dest + i) = d;
1741 }
1742 }
1743 }
1744
1745 static void
combine_out_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1752 {
1753 int i;
1754
1755 for (i = 0; i < width; ++i)
1756 {
1757 uint64_t d = *(dest + i);
1758 uint32_t a = ~d >> A_SHIFT;
1759 uint64_t s = 0;
1760
1761 if (a)
1762 {
1763 uint64_t m = *(mask + i);
1764
1765 s = *(src + i);
1766 combine_mask_value_ca (&s, &m);
1767
1768 if (a != MASK)
1769 UN16x4_MUL_UN16 (s, a);
1770 }
1771
1772 *(dest + i) = s;
1773 }
1774 }
1775
1776 static void
combine_out_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1783 {
1784 int i;
1785
1786 for (i = 0; i < width; ++i)
1787 {
1788 uint64_t s = *(src + i);
1789 uint64_t m = *(mask + i);
1790 uint64_t a;
1791
1792 combine_mask_alpha_ca (&s, &m);
1793
1794 a = ~m;
1795 if (a != ~0)
1796 {
1797 uint64_t d = 0;
1798
1799 if (a)
1800 {
1801 d = *(dest + i);
1802 UN16x4_MUL_UN16x4 (d, a);
1803 }
1804
1805 *(dest + i) = d;
1806 }
1807 }
1808 }
1809
1810 static void
combine_atop_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1817 {
1818 int i;
1819
1820 for (i = 0; i < width; ++i)
1821 {
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;
1827
1828 combine_mask_ca (&s, &m);
1829
1830 ad = ~m;
1831
1832 UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (d, ad, s, as);
1833
1834 *(dest + i) = d;
1835 }
1836 }
1837
1838 static void
combine_atop_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1845 {
1846 int i;
1847
1848 for (i = 0; i < width; ++i)
1849 {
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;
1855
1856 combine_mask_ca (&s, &m);
1857
1858 ad = m;
1859
1860 UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (d, ad, s, as);
1861
1862 *(dest + i) = d;
1863 }
1864 }
1865
1866 static void
combine_xor_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1873 {
1874 int i;
1875
1876 for (i = 0; i < width; ++i)
1877 {
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;
1883
1884 combine_mask_ca (&s, &m);
1885
1886 ad = ~m;
1887
1888 UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (d, ad, s, as);
1889
1890 *(dest + i) = d;
1891 }
1892 }
1893
1894 static void
combine_add_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1901 {
1902 int i;
1903
1904 for (i = 0; i < width; ++i)
1905 {
1906 uint64_t s = *(src + i);
1907 uint64_t m = *(mask + i);
1908 uint64_t d = *(dest + i);
1909
1910 combine_mask_value_ca (&s, &m);
1911
1912 UN16x4_ADD_UN16x4 (d, s);
1913
1914 *(dest + i) = d;
1915 }
1916 }
1917
1918 static void
combine_saturate_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
1925 {
1926 int i;
1927
1928 for (i = 0; i < width; ++i)
1929 {
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;
1934
1935 d = *(dest + i);
1936 s = *(src + i);
1937 m = *(mask + i);
1938
1939 combine_mask_ca (&s, &m);
1940
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;
1946
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);
1951
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);
1956
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);
1961
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);
1966
1967 *(dest + i) = m | n | o | p;
1968 }
1969 }
1970
1971 static void
combine_disjoint_general_ca(uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width,uint16_t combine)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)
1977 {
1978 int i;
1979
1980 for (i = 0; i < width; ++i)
1981 {
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;
1988
1989 s = *(src + i);
1990 m = *(mask + i);
1991 d = *(dest + i);
1992 da = d >> A_SHIFT;
1993
1994 combine_mask_ca (&s, &m);
1995
1996 sa = m;
1997
1998 switch (combine & COMBINE_A)
1999 {
2000 default:
2001 Fa = 0;
2002 break;
2003
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;
2011
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;
2019
2020 case COMBINE_A:
2021 Fa = ~0;
2022 break;
2023 }
2024
2025 switch (combine & COMBINE_B)
2026 {
2027 default:
2028 Fb = 0;
2029 break;
2030
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;
2038
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;
2046
2047 case COMBINE_B:
2048 Fb = ~0;
2049 break;
2050 }
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);
2055
2056 s = m | n | o | p;
2057
2058 *(dest + i) = s;
2059 }
2060 }
2061
2062 static void
combine_disjoint_over_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2069 {
2070 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2071 }
2072
2073 static void
combine_disjoint_in_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2080 {
2081 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2082 }
2083
2084 static void
combine_disjoint_in_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2091 {
2092 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2093 }
2094
2095 static void
combine_disjoint_out_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2102 {
2103 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2104 }
2105
2106 static void
combine_disjoint_out_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2113 {
2114 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2115 }
2116
2117 static void
combine_disjoint_atop_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2124 {
2125 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2126 }
2127
2128 static void
combine_disjoint_atop_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2135 {
2136 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2137 }
2138
2139 static void
combine_disjoint_xor_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2146 {
2147 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2148 }
2149
2150 static void
combine_conjoint_general_ca(uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width,uint16_t combine)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)
2156 {
2157 int i;
2158
2159 for (i = 0; i < width; ++i)
2160 {
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;
2167
2168 s = *(src + i);
2169 m = *(mask + i);
2170 d = *(dest + i);
2171 da = d >> A_SHIFT;
2172
2173 combine_mask_ca (&s, &m);
2174
2175 sa = m;
2176
2177 switch (combine & COMBINE_A)
2178 {
2179 default:
2180 Fa = 0;
2181 break;
2182
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;
2190
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;
2198
2199 case COMBINE_A:
2200 Fa = ~0;
2201 break;
2202 }
2203
2204 switch (combine & COMBINE_B)
2205 {
2206 default:
2207 Fb = 0;
2208 break;
2209
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;
2217
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;
2225
2226 case COMBINE_B:
2227 Fb = ~0;
2228 break;
2229 }
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);
2234
2235 s = m | n | o | p;
2236
2237 *(dest + i) = s;
2238 }
2239 }
2240
2241 static void
combine_conjoint_over_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2248 {
2249 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2250 }
2251
2252 static void
combine_conjoint_over_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2259 {
2260 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
2261 }
2262
2263 static void
combine_conjoint_in_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2270 {
2271 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2272 }
2273
2274 static void
combine_conjoint_in_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2281 {
2282 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2283 }
2284
2285 static void
combine_conjoint_out_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2292 {
2293 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2294 }
2295
2296 static void
combine_conjoint_out_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2303 {
2304 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2305 }
2306
2307 static void
combine_conjoint_atop_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2314 {
2315 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2316 }
2317
2318 static void
combine_conjoint_atop_reverse_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2325 {
2326 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2327 }
2328
2329 static void
combine_conjoint_xor_ca(pixman_implementation_t * imp,pixman_op_t op,uint64_t * dest,const uint64_t * src,const uint64_t * mask,int width)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)
2336 {
2337 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2338 }
2339
2340 void
_pixman_setup_combiner_functions_64(pixman_implementation_t * imp)2341 _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp)
2342 {
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;
2358
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;
2372
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;
2386
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;
2402
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;
2418
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;
2432
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;
2446
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;
2458
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;
2464 }
2465
2466