static void general_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *info) { pixman_image_t *image = iter->image; switch (image->type) { case BITS: if ((iter->iter_flags & ITER_SRC) == ITER_SRC) _pixman_bits_image_src_iter_init (image, iter); else _pixman_bits_image_dest_iter_init (image, iter); break; case LINEAR: _pixman_linear_gradient_iter_init (image, iter); break; case RADIAL: _pixman_radial_gradient_iter_init (image, iter); break; case CONICAL: _pixman_conical_gradient_iter_init (image, iter); break; case SOLID: _pixman_log_error (FUNC, "Solid image not handled by noop"); break; default: _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); break; } }
static pixman_bool_t general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; if (image->type == LINEAR) _pixman_linear_gradient_iter_init (image, iter); else if (image->type == RADIAL) _pixman_radial_gradient_iter_init (image, iter); else if (image->type == CONICAL) _pixman_conical_gradient_iter_init (image, iter); else if (image->type == BITS) _pixman_bits_image_src_iter_init (image, iter); else if (image->type == SOLID) _pixman_log_error (FUNC, "Solid image not handled by noop"); else _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); return TRUE; }
static void general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { if (iter->image->type == BITS) { _pixman_bits_image_dest_iter_init (iter->image, iter); } else { _pixman_log_error (FUNC, "Trying to write to a non-writable image"); } }
static void ssse3_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info) { int width = iter->width; bilinear_info_t *info; pixman_vector_t v; /* Reference point is the center of the pixel */ v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2; v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2; v.vector[2] = pixman_fixed_1; if (!pixman_transform_point_3d (iter->image->common.transform, &v)) goto fail; info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t) + 64); if (!info) goto fail; info->x = v.vector[0] - pixman_fixed_1 / 2; info->y = v.vector[1] - pixman_fixed_1 / 2; #define ALIGN(addr) \ ((void *)((((uintptr_t)(addr)) + 15) & (~15))) /* It is safe to set the y coordinates to -1 initially * because COVER_CLIP_BILINEAR ensures that we will only * be asked to fetch lines in the [0, height) interval */ info->lines[0].y = -1; info->lines[0].buffer = ALIGN (&(info->data[0])); info->lines[1].y = -1; info->lines[1].buffer = ALIGN (info->lines[0].buffer + width); iter->get_scanline = ssse3_fetch_bilinear_cover; iter->fini = ssse3_bilinear_cover_iter_fini; iter->data = info; return; fail: /* Something went wrong, either a bad matrix or OOM; in such cases, * we don't guarantee any particular rendering. */ _pixman_log_error ( FUNC, "Allocation failure or bad matrix, skipping rendering\n"); iter->get_scanline = _pixman_iter_get_scanline_noop; iter->fini = NULL; }
static void general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) { pixman_image_t *image = iter->image; if (image->type == SOLID) _pixman_solid_fill_iter_init (image, iter); else if (image->type == LINEAR) _pixman_linear_gradient_iter_init (image, iter); else if (image->type == RADIAL) _pixman_radial_gradient_iter_init (image, iter); else if (image->type == CONICAL) _pixman_conical_gradient_iter_init (image, iter); else if (image->type == BITS) _pixman_bits_image_src_iter_init (image, iter); else _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); }
pixman_combine_32_func_t _pixman_implementation_lookup_combiner (pixman_implementation_t *imp, pixman_op_t op, pixman_bool_t component_alpha, pixman_bool_t narrow) { while (imp) { pixman_combine_32_func_t f = NULL; switch ((narrow << 1) | component_alpha) { case 0: /* not narrow, not component alpha */ f = (pixman_combine_32_func_t)imp->combine_float[op]; break; case 1: /* not narrow, component_alpha */ f = (pixman_combine_32_func_t)imp->combine_float_ca[op]; break; case 2: /* narrow, not component alpha */ f = imp->combine_32[op]; break; case 3: /* narrow, component_alpha */ f = imp->combine_32_ca[op]; break; } if (f) return f; imp = imp->fallback; } /* We should never reach this point */ _pixman_log_error (FUNC, "No known combine function\n"); return dummy_combine; }
void _pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, pixman_op_t op, pixman_format_code_t src_format, uint32_t src_flags, pixman_format_code_t mask_format, uint32_t mask_flags, pixman_format_code_t dest_format, uint32_t dest_flags, pixman_implementation_t **out_imp, pixman_composite_func_t *out_func) { pixman_implementation_t *imp; cache_t *cache; int i; /* Check cache for fast paths */ cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); for (i = 0; i < N_CACHED_FAST_PATHS; ++i) { const pixman_fast_path_t *info = &(cache->cache[i].fast_path); /* Note that we check for equality here, not whether * the cached fast path matches. This is to prevent * us from selecting an overly general fast path * when a more specific one would work. */ if (info->op == op && info->src_format == src_format && info->mask_format == mask_format && info->dest_format == dest_format && info->src_flags == src_flags && info->mask_flags == mask_flags && info->dest_flags == dest_flags && info->func) { *out_imp = cache->cache[i].imp; *out_func = cache->cache[i].fast_path.func; goto update_cache; } } for (imp = toplevel; imp != NULL; imp = imp->fallback) { const pixman_fast_path_t *info = imp->fast_paths; while (info->op != PIXMAN_OP_NONE) { if ((info->op == op || info->op == PIXMAN_OP_any) && /* Formats */ ((info->src_format == src_format) || (info->src_format == PIXMAN_any)) && ((info->mask_format == mask_format) || (info->mask_format == PIXMAN_any)) && ((info->dest_format == dest_format) || (info->dest_format == PIXMAN_any)) && /* Flags */ (info->src_flags & src_flags) == info->src_flags && (info->mask_flags & mask_flags) == info->mask_flags && (info->dest_flags & dest_flags) == info->dest_flags) { *out_imp = imp; *out_func = info->func; /* Set i to the last spot in the cache so that the * move-to-front code below will work */ i = N_CACHED_FAST_PATHS - 1; goto update_cache; } ++info; } } /* We should never reach this point */ _pixman_log_error (FUNC, "No known composite function\n"); *out_imp = NULL; *out_func = dummy_composite_rect; update_cache: if (i) { while (i--) cache->cache[i + 1] = cache->cache[i]; cache->cache[0].imp = *out_imp; cache->cache[0].fast_path.op = op; cache->cache[0].fast_path.src_format = src_format; cache->cache[0].fast_path.src_flags = src_flags; cache->cache[0].fast_path.mask_format = mask_format; cache->cache[0].fast_path.mask_flags = mask_flags; cache->cache[0].fast_path.dest_format = dest_format; cache->cache[0].fast_path.dest_flags = dest_flags; cache->cache[0].fast_path.func = *out_func; } }