diff options
Diffstat (limited to 'gfx/cairo/libpixman/src/pixman-combine16.c')
-rw-r--r-- | gfx/cairo/libpixman/src/pixman-combine16.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/gfx/cairo/libpixman/src/pixman-combine16.c b/gfx/cairo/libpixman/src/pixman-combine16.c new file mode 100644 index 000000000..9ba439fe5 --- /dev/null +++ b/gfx/cairo/libpixman/src/pixman-combine16.c @@ -0,0 +1,114 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <math.h> +#include <string.h> + +#include "pixman-private.h" + +#include "pixman-combine32.h" + +static force_inline uint32_t +combine_mask (const uint32_t src, const uint32_t mask) +{ + uint32_t s, m; + + m = mask >> A_SHIFT; + + if (!m) + return 0; + s = src; + + UN8x4_MUL_UN8 (s, m); + + return s; +} + +static void +combine_src_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + int i; + + if (!mask) + memcpy (dest, src, width * sizeof (uint16_t)); + else + { + uint16_t *d = (uint16_t*)dest; + uint16_t *src16 = (uint16_t*)src; + for (i = 0; i < width; ++i) + { + if ((*mask & 0xff000000) == 0xff000000) { + // it's likely worth special casing + // fully opaque because it avoids + // the cost of conversion as well the multiplication + *(d + i) = *src16; + } else { + // the mask is still 32bits + uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); + *(d + i) = convert_8888_to_0565(s); + } + mask++; + src16++; + } + } + +} + +static void +combine_over_u (pixman_implementation_t *imp, + pixman_op_t op, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, + int width) +{ + int i; + + if (!mask) + memcpy (dest, src, width * sizeof (uint16_t)); + else + { + uint16_t *d = (uint16_t*)dest; + uint16_t *src16 = (uint16_t*)src; + for (i = 0; i < width; ++i) + { + if ((*mask & 0xff000000) == 0xff000000) { + // it's likely worth special casing + // fully opaque because it avoids + // the cost of conversion as well the multiplication + *(d + i) = *src16; + } else if ((*mask & 0xff000000) == 0x00000000) { + // keep the dest the same + } else { + // the mask is still 32bits + uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); + uint32_t ia = ALPHA_8 (~s); + uint32_t d32 = convert_0565_to_8888(*(d + i)); + UN8x4_MUL_UN8_ADD_UN8x4 (d32, ia, s); + *(d + i) = convert_8888_to_0565(d32); + } + mask++; + src16++; + } + } + +} + + +void +_pixman_setup_combiner_functions_16 (pixman_implementation_t *imp) +{ + int i; + for (i = 0; i < PIXMAN_N_OPERATORS; i++) { + imp->combine_16[i] = NULL; + } + imp->combine_16[PIXMAN_OP_SRC] = combine_src_u; + imp->combine_16[PIXMAN_OP_OVER] = combine_over_u; +} + |