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 25... | Line 25... | ||
25 | #include |
25 | #include |
26 | #endif |
26 | #endif |
27 | #include |
27 | #include |
28 | #include "pixman-private.h" |
28 | #include "pixman-private.h" |
Line 29... | Line -... | ||
29 | - | ||
30 | static void |
29 | |
31 | delegate_combine_32 (pixman_implementation_t * imp, |
30 | pixman_implementation_t * |
32 | pixman_op_t op, |
- | |
33 | uint32_t * dest, |
31 | _pixman_implementation_create (pixman_implementation_t *fallback, |
34 | const uint32_t * src, |
- | |
35 | const uint32_t * mask, |
- | |
36 | int width) |
32 | const pixman_fast_path_t *fast_paths) |
37 | { |
33 | { |
38 | _pixman_implementation_combine_32 (imp->delegate, |
- | |
39 | op, dest, src, mask, width); |
- | |
Line 40... | Line 34... | ||
40 | } |
34 | pixman_implementation_t *imp; |
41 | - | ||
42 | static void |
- | |
43 | delegate_combine_64 (pixman_implementation_t * imp, |
- | |
44 | pixman_op_t op, |
- | |
45 | uint64_t * dest, |
- | |
46 | const uint64_t * src, |
- | |
47 | const uint64_t * mask, |
- | |
48 | int width) |
- | |
49 | { |
- | |
50 | _pixman_implementation_combine_64 (imp->delegate, |
- | |
Line 51... | Line -... | ||
51 | op, dest, src, mask, width); |
- | |
52 | } |
35 | |
53 | - | ||
54 | static void |
- | |
55 | delegate_combine_32_ca (pixman_implementation_t * imp, |
- | |
56 | pixman_op_t op, |
- | |
57 | uint32_t * dest, |
- | |
58 | const uint32_t * src, |
36 | assert (fast_paths); |
59 | const uint32_t * mask, |
37 | |
- | 38 | if ((imp = malloc (sizeof (pixman_implementation_t)))) |
|
- | 39 | { |
|
- | 40 | pixman_implementation_t *d; |
|
- | 41 | ||
- | 42 | memset (imp, 0, sizeof *imp); |
|
- | 43 | ||
60 | int width) |
44 | imp->fallback = fallback; |
- | 45 | imp->fast_paths = fast_paths; |
|
- | 46 | ||
61 | { |
47 | /* Make sure the whole fallback chain has the right toplevel */ |
Line 62... | Line 48... | ||
62 | _pixman_implementation_combine_32_ca (imp->delegate, |
48 | for (d = imp; d != NULL; d = d->fallback) |
63 | op, dest, src, mask, width); |
- | |
64 | } |
- | |
65 | - | ||
66 | static void |
- | |
67 | delegate_combine_64_ca (pixman_implementation_t * imp, |
- | |
68 | pixman_op_t op, |
- | |
69 | uint64_t * dest, |
- | |
70 | const uint64_t * src, |
- | |
71 | const uint64_t * mask, |
- | |
72 | int width) |
49 | d->toplevel = imp; |
Line 73... | Line 50... | ||
73 | { |
50 | } |
- | 51 | ||
74 | _pixman_implementation_combine_64_ca (imp->delegate, |
52 | return imp; |
75 | op, dest, src, mask, width); |
- | |
76 | } |
- | |
77 | - | ||
78 | static pixman_bool_t |
- | |
79 | delegate_blt (pixman_implementation_t * imp, |
- | |
80 | uint32_t * src_bits, |
- | |
81 | uint32_t * dst_bits, |
- | |
82 | int src_stride, |
- | |
83 | int dst_stride, |
- | |
84 | int src_bpp, |
- | |
85 | int dst_bpp, |
- | |
86 | int src_x, |
- | |
87 | int src_y, |
53 | } |
- | 54 | ||
- | 55 | #define N_CACHED_FAST_PATHS 8 |
|
88 | int dst_x, |
56 | |
89 | int dst_y, |
57 | typedef struct |
90 | int width, |
58 | { |
91 | int height) |
59 | struct |
92 | { |
- | |
Line -... | Line 60... | ||
- | 60 | { |
|
- | 61 | pixman_implementation_t * imp; |
|
93 | return _pixman_implementation_blt ( |
62 | pixman_fast_path_t fast_path; |
94 | imp->delegate, src_bits, dst_bits, src_stride, dst_stride, |
63 | } cache [N_CACHED_FAST_PATHS]; |
95 | src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y, |
- | |
96 | width, height); |
- | |
97 | } |
- | |
98 | - | ||
99 | static pixman_bool_t |
- | |
100 | delegate_fill (pixman_implementation_t *imp, |
- | |
101 | uint32_t * bits, |
- | |
102 | int stride, |
64 | } cache_t; |
103 | int bpp, |
65 | |
104 | int x, |
- | |
105 | int y, |
- | |
106 | int width, |
66 | PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); |
Line -... | Line 67... | ||
- | 67 | ||
- | 68 | static void |
|
107 | int height, |
69 | dummy_composite_rect (pixman_implementation_t *imp, |
- | 70 | pixman_composite_info_t *info) |
|
- | 71 | { |
|
- | 72 | } |
|
- | 73 | ||
- | 74 | void |
|
- | 75 | _pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, |
|
108 | uint32_t xor) |
76 | pixman_op_t op, |
109 | { |
77 | pixman_format_code_t src_format, |
110 | return _pixman_implementation_fill ( |
78 | uint32_t src_flags, |
111 | imp->delegate, bits, stride, bpp, x, y, width, height, xor); |
79 | pixman_format_code_t mask_format, |
112 | } |
80 | uint32_t mask_flags, |
113 | 81 | pixman_format_code_t dest_format, |
|
Line 114... | Line 82... | ||
114 | pixman_implementation_t * |
82 | uint32_t dest_flags, |
115 | _pixman_implementation_create (pixman_implementation_t *delegate, |
- | |
116 | const pixman_fast_path_t *fast_paths) |
- | |
117 | { |
83 | pixman_implementation_t **out_imp, |
Line 118... | Line 84... | ||
118 | pixman_implementation_t *imp = malloc (sizeof (pixman_implementation_t)); |
84 | pixman_composite_func_t *out_func) |
119 | pixman_implementation_t *d; |
85 | { |
120 | int i; |
86 | pixman_implementation_t *imp; |
121 | - | ||
Line -... | Line 87... | ||
- | 87 | cache_t *cache; |
|
- | 88 | int i; |
|
122 | if (!imp) |
89 | |
- | 90 | /* Check cache for fast paths */ |
|
123 | return NULL; |
91 | cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); |
- | 92 | ||
- | 93 | for (i = 0; i < N_CACHED_FAST_PATHS; ++i) |
|
- | 94 | { |
|
- | 95 | const pixman_fast_path_t *info = &(cache->cache[i].fast_path); |
|
- | 96 | ||
- | 97 | /* Note that we check for equality here, not whether |
|
124 | 98 | * the cached fast path matches. This is to prevent |
|
- | 99 | * us from selecting an overly general fast path |
|
- | 100 | * when a more specific one would work. |
|
125 | assert (fast_paths); |
101 | */ |
- | 102 | if (info->op == op && |
|
- | 103 | info->src_format == src_format && |
|
- | 104 | info->mask_format == mask_format && |
|
- | 105 | info->dest_format == dest_format && |
|
- | 106 | info->src_flags == src_flags && |
|
Line -... | Line 107... | ||
- | 107 | info->mask_flags == mask_flags && |
|
- | 108 | info->dest_flags == dest_flags && |
|
- | 109 | info->func) |
|
- | 110 | { |
|
126 | 111 | *out_imp = cache->cache[i].imp; |
|
- | 112 | *out_func = cache->cache[i].fast_path.func; |
|
- | 113 | ||
- | 114 | goto update_cache; |
|
- | 115 | } |
|
- | 116 | } |
|
- | 117 | ||
- | 118 | for (imp = toplevel; imp != NULL; imp = imp->fallback) |
|
- | 119 | { |
|
- | 120 | const pixman_fast_path_t *info = imp->fast_paths; |
|
- | 121 | ||
- | 122 | while (info->op != PIXMAN_OP_NONE) |
|
- | 123 | { |
|
- | 124 | if ((info->op == op || info->op == PIXMAN_OP_any) && |
|
127 | /* Make sure the whole delegate chain has the right toplevel */ |
125 | /* Formats */ |
128 | imp->delegate = delegate; |
126 | ((info->src_format == src_format) || |
129 | for (d = imp; d != NULL; d = d->delegate) |
127 | (info->src_format == PIXMAN_any)) && |
130 | d->toplevel = imp; |
- | |
131 | - | ||
132 | /* Fill out function pointers with ones that just delegate |
- | |
Line 133... | Line 128... | ||
133 | */ |
128 | ((info->mask_format == mask_format) || |
- | 129 | (info->mask_format == PIXMAN_any)) && |
|
- | 130 | ((info->dest_format == dest_format) || |
|
- | 131 | (info->dest_format == PIXMAN_any)) && |
|
Line 134... | Line 132... | ||
134 | imp->blt = delegate_blt; |
132 | /* Flags */ |
135 | imp->fill = delegate_fill; |
133 | (info->src_flags & src_flags) == info->src_flags && |
Line 136... | Line 134... | ||
136 | 134 | (info->mask_flags & mask_flags) == info->mask_flags && |
|
137 | for (i = 0; i < PIXMAN_N_OPERATORS; ++i) |
- | |
138 | { |
- | |
139 | imp->combine_32[i] = delegate_combine_32; |
- | |
140 | imp->combine_64[i] = delegate_combine_64; |
- | |
141 | imp->combine_32_ca[i] = delegate_combine_32_ca; |
- | |
142 | imp->combine_64_ca[i] = delegate_combine_64_ca; |
- | |
143 | } |
135 | (info->dest_flags & dest_flags) == info->dest_flags) |
144 | - | ||
145 | imp->fast_paths = fast_paths; |
136 | { |
Line 146... | Line -... | ||
146 | - | ||
147 | return imp; |
137 | *out_imp = imp; |
148 | } |
138 | *out_func = info->func; |
- | 139 | ||
149 | 140 | /* Set i to the last spot in the cache so that the |
|
- | 141 | * move-to-front code below will work |
|
150 | void |
142 | */ |
151 | _pixman_implementation_combine_32 (pixman_implementation_t * imp, |
143 | i = N_CACHED_FAST_PATHS - 1; |
- | 144 | ||
- | 145 | goto update_cache; |
|
152 | pixman_op_t op, |
146 | } |
- | 147 | ||
- | 148 | ++info; |
|
- | 149 | } |
|
- | 150 | } |
|
153 | uint32_t * dest, |
151 | |
- | 152 | /* We should never reach this point */ |
|
- | 153 | _pixman_log_error ( |
|
- | 154 | FUNC, |
|
- | 155 | "No composite function found\n" |
|
- | 156 | "\n" |
|
- | 157 | "The most likely cause of this is that this system has issues with\n" |
|
- | 158 | "thread local storage\n"); |
|
- | 159 | ||
154 | const uint32_t * src, |
160 | *out_imp = NULL; |
- | 161 | *out_func = dummy_composite_rect; |
|
- | 162 | return; |
|
- | 163 | ||
- | 164 | update_cache: |
|
155 | const uint32_t * mask, |
165 | if (i) |
Line 156... | Line 166... | ||
156 | int width) |
166 | { |
157 | { |
167 | while (i--) |
158 | (*imp->combine_32[op]) (imp, op, dest, src, mask, width); |
168 | cache->cache[i + 1] = cache->cache[i]; |
159 | } |
169 | |
160 | 170 | cache->cache[0].imp = *out_imp; |
|
161 | void |
171 | cache->cache[0].fast_path.op = op; |
162 | _pixman_implementation_combine_64 (pixman_implementation_t * imp, |
172 | cache->cache[0].fast_path.src_format = src_format; |
163 | pixman_op_t op, |
173 | cache->cache[0].fast_path.src_flags = src_flags; |
164 | uint64_t * dest, |
- | |
165 | const uint64_t * src, |
174 | cache->cache[0].fast_path.mask_format = mask_format; |
Line 166... | Line 175... | ||
166 | const uint64_t * mask, |
175 | cache->cache[0].fast_path.mask_flags = mask_flags; |
167 | int width) |
176 | cache->cache[0].fast_path.dest_format = dest_format; |
168 | { |
177 | cache->cache[0].fast_path.dest_flags = dest_flags; |
169 | (*imp->combine_64[op]) (imp, op, dest, src, mask, width); |
- | |
170 | } |
178 | cache->cache[0].fast_path.func = *out_func; |
171 | 179 | } |
|
- | 180 | } |
|
172 | void |
181 | |
173 | _pixman_implementation_combine_32_ca (pixman_implementation_t * imp, |
182 | static void |
- | 183 | dummy_combine (pixman_implementation_t *imp, |
|
- | 184 | pixman_op_t op, |
|
- | 185 | uint32_t * pd, |
|
- | 186 | const uint32_t * ps, |
|
- | 187 | const uint32_t * pm, |
|
- | 188 | int w) |
|
- | 189 | { |
|
- | 190 | } |
|
- | 191 | ||
174 | pixman_op_t op, |
192 | pixman_combine_32_func_t |
- | 193 | _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, |
|
- | 194 | pixman_op_t op, |
|
- | 195 | pixman_bool_t component_alpha, |
|
- | 196 | pixman_bool_t narrow) |
|
- | 197 | { |
|
- | 198 | while (imp) |
|
- | 199 | { |
|
- | 200 | pixman_combine_32_func_t f = NULL; |
|
- | 201 | ||
- | 202 | switch ((narrow << 1) | component_alpha) |
|
- | 203 | { |
|
- | 204 | case 0: /* not narrow, not component alpha */ |
|
- | 205 | f = (pixman_combine_32_func_t)imp->combine_float[op]; |
|
- | 206 | break; |
|
- | 207 | ||
- | 208 | case 1: /* not narrow, component_alpha */ |
|
- | 209 | f = (pixman_combine_32_func_t)imp->combine_float_ca[op]; |
|
- | 210 | break; |
|
- | 211 | ||
- | 212 | case 2: /* narrow, not component alpha */ |
|
175 | uint32_t * dest, |
213 | f = imp->combine_32[op]; |
Line 176... | Line 214... | ||
176 | const uint32_t * src, |
214 | break; |
177 | const uint32_t * mask, |
215 | |
178 | int width) |
216 | case 3: /* narrow, component_alpha */ |
Line 199... | Line 237... | ||
199 | int dst_stride, |
237 | int dst_stride, |
200 | int src_bpp, |
238 | int src_bpp, |
201 | int dst_bpp, |
239 | int dst_bpp, |
202 | int src_x, |
240 | int src_x, |
203 | int src_y, |
241 | int src_y, |
204 | int dst_x, |
242 | int dest_x, |
205 | int dst_y, |
243 | int dest_y, |
206 | int width, |
244 | int width, |
207 | int height) |
245 | int height) |
208 | { |
246 | { |
- | 247 | while (imp) |
|
- | 248 | { |
|
- | 249 | if (imp->blt && |
|
209 | return (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride, |
250 | (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride, |
210 | src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y, |
251 | src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y, |
211 | width, height); |
252 | width, height)) |
- | 253 | { |
|
- | 254 | return TRUE; |
|
- | 255 | } |
|
- | 256 | ||
- | 257 | imp = imp->fallback; |
|
- | 258 | } |
|
- | 259 | ||
- | 260 | return FALSE; |
|
212 | } |
261 | } |
Line 213... | Line 262... | ||
213 | 262 | ||
214 | pixman_bool_t |
263 | pixman_bool_t |
215 | _pixman_implementation_fill (pixman_implementation_t *imp, |
264 | _pixman_implementation_fill (pixman_implementation_t *imp, |
Line 218... | Line 267... | ||
218 | int bpp, |
267 | int bpp, |
219 | int x, |
268 | int x, |
220 | int y, |
269 | int y, |
221 | int width, |
270 | int width, |
222 | int height, |
271 | int height, |
223 | uint32_t xor) |
272 | uint32_t filler) |
- | 273 | { |
|
- | 274 | while (imp) |
|
- | 275 | { |
|
- | 276 | if (imp->fill && |
|
- | 277 | ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler))) |
|
- | 278 | { |
|
- | 279 | return TRUE; |
|
- | 280 | } |
|
- | 281 | ||
- | 282 | imp = imp->fallback; |
|
- | 283 | } |
|
- | 284 | ||
- | 285 | return FALSE; |
|
- | 286 | } |
|
- | 287 | ||
- | 288 | pixman_bool_t |
|
- | 289 | _pixman_implementation_src_iter_init (pixman_implementation_t *imp, |
|
- | 290 | pixman_iter_t *iter, |
|
- | 291 | pixman_image_t *image, |
|
- | 292 | int x, |
|
- | 293 | int y, |
|
- | 294 | int width, |
|
- | 295 | int height, |
|
- | 296 | uint8_t *buffer, |
|
- | 297 | iter_flags_t iter_flags, |
|
- | 298 | uint32_t image_flags) |
|
- | 299 | { |
|
- | 300 | iter->image = image; |
|
- | 301 | iter->buffer = (uint32_t *)buffer; |
|
- | 302 | iter->x = x; |
|
- | 303 | iter->y = y; |
|
- | 304 | iter->width = width; |
|
- | 305 | iter->height = height; |
|
- | 306 | iter->iter_flags = iter_flags; |
|
- | 307 | iter->image_flags = image_flags; |
|
- | 308 | ||
- | 309 | while (imp) |
|
- | 310 | { |
|
- | 311 | if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter)) |
|
- | 312 | return TRUE; |
|
- | 313 | ||
- | 314 | imp = imp->fallback; |
|
- | 315 | } |
|
- | 316 | ||
- | 317 | return FALSE; |
|
- | 318 | } |
|
- | 319 | ||
- | 320 | pixman_bool_t |
|
- | 321 | _pixman_implementation_dest_iter_init (pixman_implementation_t *imp, |
|
- | 322 | pixman_iter_t *iter, |
|
- | 323 | pixman_image_t *image, |
|
- | 324 | int x, |
|
- | 325 | int y, |
|
- | 326 | int width, |
|
- | 327 | int height, |
|
- | 328 | uint8_t *buffer, |
|
- | 329 | iter_flags_t iter_flags, |
|
- | 330 | uint32_t image_flags) |
|
- | 331 | { |
|
- | 332 | iter->image = image; |
|
- | 333 | iter->buffer = (uint32_t *)buffer; |
|
- | 334 | iter->x = x; |
|
- | 335 | iter->y = y; |
|
- | 336 | iter->width = width; |
|
- | 337 | iter->height = height; |
|
- | 338 | iter->iter_flags = iter_flags; |
|
- | 339 | iter->image_flags = image_flags; |
|
- | 340 | ||
- | 341 | while (imp) |
|
- | 342 | { |
|
- | 343 | if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter)) |
|
- | 344 | return TRUE; |
|
- | 345 | ||
- | 346 | imp = imp->fallback; |
|
- | 347 | } |
|
- | 348 | ||
- | 349 | return FALSE; |
|
- | 350 | } |
|
- | 351 | ||
- | 352 | pixman_bool_t |
|
- | 353 | _pixman_disabled (const char *name) |
|
- | 354 | { |
|
- | 355 | const char *env; |
|
- | 356 | ||
- | 357 | if ((env = getenv ("PIXMAN_DISABLE"))) |
|
224 | { |
358 | { |
- | 359 | do |
|
- | 360 | { |
|
- | 361 | const char *end; |
|
- | 362 | int len; |
|
- | 363 | ||
- | 364 | if ((end = strchr (env, ' '))) |
|
- | 365 | len = end - env; |
|
- | 366 | else |
|
- | 367 | len = strlen (env); |
|
- | 368 | ||
225 | return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor); |
369 | if (strlen (name) == len && strncmp (name, env, len) == 0) |
- | 370 | { |
|
- | 371 | printf ("pixman: Disabled %s implementation\n", name); |
|
- | 372 | return TRUE; |
|
- | 373 | } |
|
- | 374 | ||
- | 375 | env += len; |
|
- | 376 | } |
|
- | 377 | while (*env++); |
|
- | 378 | } |
|
- | 379 | ||
- | 380 | return FALSE; |
|
226 | }> |
381 | } |
Line -... | Line 382... | ||
- | 382 | ||
- | 383 | pixman_implementation_t * |
|
- | 384 | _pixman_choose_implementation (void) |
|
- | 385 | { |
|
- | 386 | pixman_implementation_t *imp; |
|
- | 387 | ||
- | 388 | imp = _pixman_implementation_create_general(); |
|
- | 389 | ||
- | 390 | if (!_pixman_disabled ("fast")) |
|
- | 391 | imp = _pixman_implementation_create_fast_path (imp); |
|
- | 392 | ||
- | 393 | imp = _pixman_x86_get_implementations (imp); |
|
- | 394 | ||
- | 395 | imp = _pixman_implementation_create_noop (imp); |
|
- | 396 | ||
- | 397 | return imp; |