Rev 1891 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1891 | Rev 3931 | ||
---|---|---|---|
Line 34... | Line 34... | ||
34 | #include |
34 | #include |
35 | #include |
35 | #include |
36 | #include |
36 | #include |
37 | #include |
37 | #include |
38 | #include "pixman-private.h" |
38 | #include "pixman-private.h" |
- | 39 | ||
39 | #include "pixman-combine32.h" |
40 | static pixman_bool_t |
- | 41 | general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) |
|
- | 42 | { |
|
- | 43 | pixman_image_t *image = iter->image; |
|
- | 44 | ||
- | 45 | if (image->type == LINEAR) |
|
- | 46 | _pixman_linear_gradient_iter_init (image, iter); |
|
- | 47 | else if (image->type == RADIAL) |
|
- | 48 | _pixman_radial_gradient_iter_init (image, iter); |
|
- | 49 | else if (image->type == CONICAL) |
|
- | 50 | _pixman_conical_gradient_iter_init (image, iter); |
|
- | 51 | else if (image->type == BITS) |
|
- | 52 | _pixman_bits_image_src_iter_init (image, iter); |
|
- | 53 | else if (image->type == SOLID) |
|
- | 54 | _pixman_log_error (FUNC, "Solid image not handled by noop"); |
|
- | 55 | else |
|
- | 56 | _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); |
|
- | 57 | ||
- | 58 | return TRUE; |
|
- | 59 | } |
|
- | 60 | ||
40 | #include "pixman-private.h" |
61 | static pixman_bool_t |
- | 62 | general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) |
|
- | 63 | { |
|
- | 64 | if (iter->image->type == BITS) |
|
- | 65 | { |
|
- | 66 | _pixman_bits_image_dest_iter_init (iter->image, iter); |
|
- | 67 | ||
- | 68 | return TRUE; |
|
- | 69 | } |
|
- | 70 | else |
|
- | 71 | { |
|
- | 72 | _pixman_log_error (FUNC, "Trying to write to a non-writable image"); |
|
- | 73 | ||
- | 74 | return FALSE; |
|
- | 75 | } |
|
- | 76 | } |
|
- | 77 | ||
- | 78 | typedef struct op_info_t op_info_t; |
|
- | 79 | struct op_info_t |
|
- | 80 | { |
|
- | 81 | uint8_t src, dst; |
|
- | 82 | }; |
|
- | 83 | ||
- | 84 | #define ITER_IGNORE_BOTH \ |
|
- | 85 | (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA) |
|
- | 86 | ||
- | 87 | static const op_info_t op_flags[PIXMAN_N_OPERATORS] = |
|
- | 88 | { |
|
- | 89 | /* Src Dst */ |
|
- | 90 | { ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */ |
|
- | 91 | { ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */ |
|
- | 92 | { ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */ |
|
- | 93 | { 0, ITER_LOCALIZED_ALPHA }, /* OVER */ |
|
- | 94 | { ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */ |
|
- | 95 | { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */ |
|
- | 96 | { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */ |
|
- | 97 | { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */ |
|
- | 98 | { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */ |
|
- | 99 | { 0, 0 }, /* ATOP */ |
|
- | 100 | { 0, 0 }, /* ATOP_REVERSE */ |
|
- | 101 | { 0, 0 }, /* XOR */ |
|
- | 102 | { ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */ |
|
- | 103 | { 0, 0 }, /* SATURATE */ |
|
- | 104 | }; |
|
Line 41... | Line 105... | ||
41 | 105 | ||
Line 42... | Line 106... | ||
42 | #define SCANLINE_BUFFER_LENGTH 8192 |
106 | #define SCANLINE_BUFFER_LENGTH 8192 |
43 | 107 | ||
44 | static void |
- | |
45 | general_composite_rect (pixman_implementation_t *imp, |
108 | static void |
46 | pixman_op_t op, |
- | |
47 | pixman_image_t * src, |
- | |
48 | pixman_image_t * mask, |
- | |
49 | pixman_image_t * dest, |
- | |
50 | int32_t src_x, |
- | |
51 | int32_t src_y, |
- | |
52 | int32_t mask_x, |
- | |
53 | int32_t mask_y, |
- | |
54 | int32_t dest_x, |
- | |
55 | int32_t dest_y, |
- | |
56 | int32_t width, |
109 | general_composite_rect (pixman_implementation_t *imp, |
- | 110 | pixman_composite_info_t *info) |
|
57 | int32_t height) |
111 | { |
58 | { |
112 | PIXMAN_COMPOSITE_ARGS (info); |
59 | uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8]; |
113 | uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8]; |
60 | uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; |
114 | uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; |
61 | uint8_t *src_buffer, *mask_buffer, *dest_buffer; |
115 | uint8_t *src_buffer, *mask_buffer, *dest_buffer; |
62 | fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL; |
- | |
63 | pixman_combine_32_func_t compose; |
- | |
64 | store_scanline_t store; |
116 | pixman_iter_t src_iter, mask_iter, dest_iter; |
65 | source_image_class_t src_class, mask_class; |
- | |
66 | pixman_bool_t component_alpha; |
117 | pixman_combine_32_func_t compose; |
67 | uint32_t *bits; |
118 | pixman_bool_t component_alpha; |
68 | int32_t stride; |
119 | iter_flags_t narrow, src_iter_flags; |
Line 69... | Line -... | ||
69 | int narrow, Bpp; |
- | |
70 | int i; |
120 | int Bpp; |
71 | 121 | int i; |
|
72 | narrow = |
122 | |
- | 123 | if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && |
|
- | 124 | (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && |
|
- | 125 | (dest_image->common.flags & FAST_PATH_NARROW_FORMAT)) |
|
- | 126 | { |
|
- | 127 | narrow = ITER_NARROW; |
|
- | 128 | Bpp = 4; |
|
73 | (src->common.flags & FAST_PATH_NARROW_FORMAT) && |
129 | } |
- | 130 | else |
|
- | 131 | { |
|
Line 74... | Line 132... | ||
74 | (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) && |
132 | narrow = 0; |
75 | (dest->common.flags & FAST_PATH_NARROW_FORMAT); |
133 | Bpp = 16; |
76 | Bpp = narrow ? 4 : 8; |
134 | } |
Line 85... | Line 143... | ||
85 | 143 | ||
86 | src_buffer = scanline_buffer; |
144 | src_buffer = scanline_buffer; |
87 | mask_buffer = src_buffer + width * Bpp; |
145 | mask_buffer = src_buffer + width * Bpp; |
Line 88... | Line -... | ||
88 | dest_buffer = mask_buffer + width * Bpp; |
- | |
89 | - | ||
90 | src_class = _pixman_image_classify (src, |
- | |
91 | src_x, src_y, |
- | |
92 | width, height); |
- | |
93 | - | ||
94 | mask_class = SOURCE_IMAGE_CLASS_UNKNOWN; |
146 | dest_buffer = mask_buffer + width * Bpp; |
95 | 147 | ||
96 | if (mask) |
148 | if (!narrow) |
- | 149 | { |
|
97 | { |
150 | /* To make sure there aren't any NANs in the buffers */ |
98 | mask_class = _pixman_image_classify (mask, |
151 | memset (src_buffer, 0, width * Bpp); |
99 | src_x, src_y, |
152 | memset (mask_buffer, 0, width * Bpp); |
Line 100... | Line -... | ||
100 | width, height); |
- | |
101 | } |
- | |
102 | 153 | memset (dest_buffer, 0, width * Bpp); |
|
103 | if (op == PIXMAN_OP_CLEAR) |
154 | } |
104 | fetch_src = NULL; |
- | |
105 | else if (narrow) |
- | |
Line 106... | Line -... | ||
106 | fetch_src = _pixman_image_get_scanline_32; |
- | |
107 | else |
- | |
108 | fetch_src = _pixman_image_get_scanline_64; |
- | |
109 | - | ||
110 | if (!mask || op == PIXMAN_OP_CLEAR) |
- | |
111 | fetch_mask = NULL; |
- | |
112 | else if (narrow) |
- | |
113 | fetch_mask = _pixman_image_get_scanline_32; |
- | |
114 | else |
- | |
115 | fetch_mask = _pixman_image_get_scanline_64; |
- | |
116 | - | ||
117 | if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC) |
- | |
118 | fetch_dest = NULL; |
- | |
119 | else if (narrow) |
- | |
120 | fetch_dest = _pixman_image_get_scanline_32; |
- | |
121 | else |
- | |
122 | fetch_dest = _pixman_image_get_scanline_64; |
- | |
123 | - | ||
124 | if (narrow) |
- | |
125 | store = _pixman_image_store_scanline_32; |
155 | |
126 | else |
- | |
127 | store = _pixman_image_store_scanline_64; |
156 | /* src iter */ |
128 | - | ||
129 | /* Skip the store step and composite directly into the |
- | |
130 | * destination if the output format of the compose func matches |
- | |
131 | * the destination format. |
157 | src_iter_flags = narrow | op_flags[op].src; |
132 | * |
- | |
133 | * If the destination format is a8r8g8b8 then we can always do |
- | |
134 | * this. If it is x8r8g8b8, then we can only do it if the |
- | |
135 | * operator doesn't make use of destination alpha. |
- | |
136 | */ |
- | |
137 | if ((dest->bits.format == PIXMAN_a8r8g8b8) || |
- | |
138 | (dest->bits.format == PIXMAN_x8r8g8b8 && |
- | |
139 | (op == PIXMAN_OP_OVER || |
- | |
140 | op == PIXMAN_OP_ADD || |
- | |
141 | op == PIXMAN_OP_SRC || |
- | |
142 | op == PIXMAN_OP_CLEAR || |
- | |
143 | op == PIXMAN_OP_IN_REVERSE || |
- | |
144 | op == PIXMAN_OP_OUT_REVERSE || |
- | |
145 | op == PIXMAN_OP_DST))) |
- | |
146 | { |
- | |
147 | if (narrow && |
- | |
148 | !dest->common.alpha_map && |
- | |
149 | !dest->bits.write_func) |
- | |
Line 150... | Line 158... | ||
150 | { |
158 | |
- | 159 | _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image, |
|
- | 160 | src_x, src_y, width, height, |
|
151 | store = NULL; |
161 | src_buffer, src_iter_flags, info->src_flags); |
152 | } |
- | |
153 | } |
162 | |
154 | - | ||
155 | if (!store) |
163 | /* mask iter */ |
156 | { |
164 | if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == |
157 | bits = dest->bits.bits; |
165 | (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) |
158 | stride = dest->bits.rowstride; |
- | |
159 | } |
166 | { |
Line 160... | Line 167... | ||
160 | else |
167 | /* If it doesn't matter what the source is, then it doesn't matter |
161 | { |
- | |
162 | bits = NULL; |
- | |
163 | stride = 0; |
168 | * what the mask is |
164 | } |
169 | */ |
165 | 170 | mask_image = NULL; |
|
166 | component_alpha = |
171 | } |
- | 172 | ||
- | 173 | component_alpha = |
|
- | 174 | mask_image && |
|
- | 175 | mask_image->common.type == BITS && |
|
- | 176 | mask_image->common.component_alpha && |
|
- | 177 | PIXMAN_FORMAT_RGB (mask_image->bits.format); |
|
- | 178 | ||
- | 179 | _pixman_implementation_src_iter_init ( |
|
- | 180 | imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height, |
|
Line 167... | Line -... | ||
167 | fetch_src && |
- | |
168 | fetch_mask && |
- | |
169 | mask && |
- | |
170 | mask->common.type == BITS && |
- | |
171 | mask->common.component_alpha && |
- | |
172 | PIXMAN_FORMAT_RGB (mask->bits.format); |
181 | mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB), info->mask_flags); |
173 | - | ||
174 | if (narrow) |
- | |
175 | { |
- | |
176 | if (component_alpha) |
182 | |
177 | compose = _pixman_implementation_combine_32_ca; |
- | |
178 | else |
- | |
179 | compose = _pixman_implementation_combine_32; |
- | |
180 | } |
- | |
181 | else |
- | |
182 | { |
- | |
183 | if (component_alpha) |
- | |
184 | compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca; |
- | |
185 | else |
- | |
186 | compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64; |
- | |
Line 187... | Line 183... | ||
187 | } |
183 | /* dest iter */ |
188 | 184 | _pixman_implementation_dest_iter_init ( |
|
189 | if (!compose) |
- | |
190 | return; |
- | |
191 | - | ||
192 | if (!fetch_mask) |
185 | imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height, |
193 | mask_buffer = NULL; |
- | |
194 | - | ||
195 | for (i = 0; i < height; ++i) |
- | |
196 | { |
- | |
197 | /* fill first half of scanline with source */ |
- | |
Line 198... | Line 186... | ||
198 | if (fetch_src) |
186 | dest_buffer, narrow | op_flags[op].dst, info->dest_flags); |
199 | { |
187 | |
200 | if (fetch_mask) |
188 | compose = _pixman_implementation_lookup_combiner ( |
Line 201... | Line -... | ||
201 | { |
- | |
202 | /* fetch mask before source so that fetching of |
- | |
203 | source can be optimized */ |
- | |
204 | fetch_mask (mask, mask_x, mask_y + i, |
- | |
205 | width, (void *)mask_buffer, 0); |
- | |
206 | - | ||
207 | if (mask_class == SOURCE_IMAGE_CLASS_HORIZONTAL) |
- | |
208 | fetch_mask = NULL; |
- | |
209 | } |
- | |
210 | - | ||
211 | if (src_class == SOURCE_IMAGE_CLASS_HORIZONTAL) |
- | |
212 | { |
- | |
213 | fetch_src (src, src_x, src_y + i, |
- | |
214 | width, (void *)src_buffer, 0); |
- | |
215 | fetch_src = NULL; |
- | |
216 | } |
189 | imp->toplevel, op, component_alpha, narrow); |
217 | else |
- | |
218 | { |
- | |
219 | fetch_src (src, src_x, src_y + i, |
- | |
220 | width, (void *)src_buffer, (void *)mask_buffer); |
- | |
221 | } |
- | |
222 | } |
- | |
223 | else if (fetch_mask) |
- | |
224 | { |
- | |
225 | fetch_mask (mask, mask_x, mask_y + i, |
- | |
226 | width, (void *)mask_buffer, 0); |
- | |
Line 227... | Line -... | ||
227 | } |
- | |
228 | - | ||
229 | if (store) |
- | |
230 | { |
- | |
231 | /* fill dest into second half of scanline */ |
- | |
232 | if (fetch_dest) |
- | |
233 | { |
- | |
234 | fetch_dest (dest, dest_x, dest_y + i, |
- | |
235 | width, (void *)dest_buffer, 0); |
- | |
236 | } |
190 | |
237 | - | ||
238 | /* blend */ |
- | |
239 | compose (imp->toplevel, op, |
- | |
240 | (void *)dest_buffer, |
- | |
241 | (void *)src_buffer, |
- | |
242 | (void *)mask_buffer, |
- | |
243 | width); |
- | |
244 | - | ||
245 | /* write back */ |
191 | for (i = 0; i < height; ++i) |
Line 246... | Line 192... | ||
246 | store (&(dest->bits), dest_x, dest_y + i, width, |
192 | { |
247 | (void *)dest_buffer); |
193 | uint32_t *s, *m, *d; |
248 | } |
194 | |
Line 263... | Line 209... | ||
263 | { |
209 | { |
264 | { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect }, |
210 | { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect }, |
265 | { PIXMAN_OP_NONE } |
211 | { PIXMAN_OP_NONE } |
266 | }; |
212 | }; |
Line 267... | Line -... | ||
267 | - | ||
268 | static pixman_bool_t |
- | |
269 | general_blt (pixman_implementation_t *imp, |
- | |
270 | uint32_t * src_bits, |
- | |
271 | uint32_t * dst_bits, |
- | |
272 | int src_stride, |
- | |
273 | int dst_stride, |
- | |
274 | int src_bpp, |
- | |
275 | int dst_bpp, |
- | |
276 | int src_x, |
- | |
277 | int src_y, |
- | |
278 | int dst_x, |
- | |
279 | int dst_y, |
- | |
280 | int width, |
- | |
281 | int height) |
- | |
282 | { |
- | |
283 | /* We can't blit unless we have sse2 or mmx */ |
- | |
284 | - | ||
285 | return FALSE; |
- | |
286 | } |
- | |
287 | - | ||
288 | static pixman_bool_t |
- | |
289 | general_fill (pixman_implementation_t *imp, |
- | |
290 | uint32_t * bits, |
- | |
291 | int stride, |
- | |
292 | int bpp, |
- | |
293 | int x, |
- | |
294 | int y, |
- | |
295 | int width, |
- | |
296 | int height, |
- | |
297 | uint32_t xor) |
- | |
298 | { |
- | |
299 | return FALSE; |
- | |
300 | } |
- | |
301 | 213 | ||
302 | pixman_implementation_t * |
214 | pixman_implementation_t * |
303 | _pixman_implementation_create_general (void) |
215 | _pixman_implementation_create_general (void) |
304 | { |
216 | { |
Line 305... | Line 217... | ||
305 | pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); |
217 | pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); |
306 | 218 | ||
Line 307... | Line 219... | ||
307 | _pixman_setup_combiner_functions_32 (imp); |
219 | _pixman_setup_combiner_functions_32 (imp); |
308 | _pixman_setup_combiner_functions_64 (imp); |
220 | _pixman_setup_combiner_functions_float (imp); |
Line 309... | Line 221... | ||
309 | 221 | ||
310 | imp->blt = general_blt; |
222 | imp->src_iter_init = general_src_iter_init; |