Line data Source code
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 0 : m = mask >> A_SHIFT;
18 :
19 0 : if (!m)
20 0 : return 0;
21 0 : s = src;
22 :
23 0 : UN8x4_MUL_UN8 (s, m);
24 :
25 0 : return s;
26 : }
27 :
28 : static void
29 0 : 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 0 : if (!mask)
39 0 : memcpy (dest, src, width * sizeof (uint16_t));
40 : else
41 : {
42 0 : uint16_t *d = (uint16_t*)dest;
43 0 : uint16_t *src16 = (uint16_t*)src;
44 0 : for (i = 0; i < width; ++i)
45 : {
46 0 : 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 0 : *(d + i) = *src16;
51 : } else {
52 : // the mask is still 32bits
53 0 : uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask);
54 0 : *(d + i) = convert_8888_to_0565(s);
55 : }
56 0 : mask++;
57 0 : src16++;
58 : }
59 : }
60 :
61 0 : }
62 :
63 : static void
64 0 : 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 0 : if (!mask)
74 0 : memcpy (dest, src, width * sizeof (uint16_t));
75 : else
76 : {
77 0 : uint16_t *d = (uint16_t*)dest;
78 0 : uint16_t *src16 = (uint16_t*)src;
79 0 : for (i = 0; i < width; ++i)
80 : {
81 0 : 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 0 : *(d + i) = *src16;
86 0 : } else if ((*mask & 0xff000000) == 0x00000000) {
87 : // keep the dest the same
88 : } else {
89 : // the mask is still 32bits
90 0 : uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask);
91 0 : uint32_t ia = ALPHA_8 (~s);
92 0 : uint32_t d32 = convert_0565_to_8888(*(d + i));
93 0 : UN8x4_MUL_UN8_ADD_UN8x4 (d32, ia, s);
94 0 : *(d + i) = convert_8888_to_0565(d32);
95 : }
96 0 : mask++;
97 0 : src16++;
98 : }
99 : }
100 :
101 0 : }
102 :
103 :
104 : void
105 1 : _pixman_setup_combiner_functions_16 (pixman_implementation_t *imp)
106 : {
107 : int i;
108 64 : for (i = 0; i < PIXMAN_N_OPERATORS; i++) {
109 63 : imp->combine_16[i] = NULL;
110 : }
111 1 : imp->combine_16[PIXMAN_OP_SRC] = combine_src_u;
112 1 : imp->combine_16[PIXMAN_OP_OVER] = combine_over_u;
113 1 : }
114 :
|