|
1 #ifdef HAVE_CONFIG_H |
|
2 #include <config.h> |
|
3 #endif |
|
4 |
|
5 #include <math.h> |
|
6 #include <string.h> |
|
7 |
|
8 #include "pixman-private.h" |
|
9 |
|
10 #include "pixman-combine32.h" |
|
11 |
|
12 static force_inline uint32_t |
|
13 combine_mask (const uint32_t src, const uint32_t mask) |
|
14 { |
|
15 uint32_t s, m; |
|
16 |
|
17 m = mask >> A_SHIFT; |
|
18 |
|
19 if (!m) |
|
20 return 0; |
|
21 s = src; |
|
22 |
|
23 UN8x4_MUL_UN8 (s, m); |
|
24 |
|
25 return s; |
|
26 } |
|
27 |
|
28 static void |
|
29 combine_src_u (pixman_implementation_t *imp, |
|
30 pixman_op_t op, |
|
31 uint32_t * dest, |
|
32 const uint32_t * src, |
|
33 const uint32_t * mask, |
|
34 int width) |
|
35 { |
|
36 int i; |
|
37 |
|
38 if (!mask) |
|
39 memcpy (dest, src, width * sizeof (uint16_t)); |
|
40 else |
|
41 { |
|
42 uint16_t *d = (uint16_t*)dest; |
|
43 uint16_t *src16 = (uint16_t*)src; |
|
44 for (i = 0; i < width; ++i) |
|
45 { |
|
46 if ((*mask & 0xff000000) == 0xff000000) { |
|
47 // it's likely worth special casing |
|
48 // fully opaque because it avoids |
|
49 // the cost of conversion as well the multiplication |
|
50 *(d + i) = *src16; |
|
51 } else { |
|
52 // the mask is still 32bits |
|
53 uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); |
|
54 *(d + i) = convert_8888_to_0565(s); |
|
55 } |
|
56 mask++; |
|
57 src16++; |
|
58 } |
|
59 } |
|
60 |
|
61 } |
|
62 |
|
63 static void |
|
64 combine_over_u (pixman_implementation_t *imp, |
|
65 pixman_op_t op, |
|
66 uint32_t * dest, |
|
67 const uint32_t * src, |
|
68 const uint32_t * mask, |
|
69 int width) |
|
70 { |
|
71 int i; |
|
72 |
|
73 if (!mask) |
|
74 memcpy (dest, src, width * sizeof (uint16_t)); |
|
75 else |
|
76 { |
|
77 uint16_t *d = (uint16_t*)dest; |
|
78 uint16_t *src16 = (uint16_t*)src; |
|
79 for (i = 0; i < width; ++i) |
|
80 { |
|
81 if ((*mask & 0xff000000) == 0xff000000) { |
|
82 // it's likely worth special casing |
|
83 // fully opaque because it avoids |
|
84 // the cost of conversion as well the multiplication |
|
85 *(d + i) = *src16; |
|
86 } else if ((*mask & 0xff000000) == 0x00000000) { |
|
87 // keep the dest the same |
|
88 } else { |
|
89 // the mask is still 32bits |
|
90 uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); |
|
91 uint32_t ia = ALPHA_8 (~s); |
|
92 uint32_t d32 = convert_0565_to_8888(*(d + i)); |
|
93 UN8x4_MUL_UN8_ADD_UN8x4 (d32, ia, s); |
|
94 *(d + i) = convert_8888_to_0565(d32); |
|
95 } |
|
96 mask++; |
|
97 src16++; |
|
98 } |
|
99 } |
|
100 |
|
101 } |
|
102 |
|
103 |
|
104 void |
|
105 _pixman_setup_combiner_functions_16 (pixman_implementation_t *imp) |
|
106 { |
|
107 int i; |
|
108 for (i = 0; i < PIXMAN_N_OPERATORS; i++) { |
|
109 imp->combine_16[i] = NULL; |
|
110 } |
|
111 imp->combine_16[PIXMAN_OP_SRC] = combine_src_u; |
|
112 imp->combine_16[PIXMAN_OP_OVER] = combine_over_u; |
|
113 } |
|
114 |