michael@0: #ifdef HAVE_CONFIG_H michael@0: #include michael@0: #endif michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "pixman-private.h" michael@0: michael@0: #include "pixman-combine32.h" michael@0: michael@0: static force_inline uint32_t michael@0: combine_mask (const uint32_t src, const uint32_t mask) michael@0: { michael@0: uint32_t s, m; michael@0: michael@0: m = mask >> A_SHIFT; michael@0: michael@0: if (!m) michael@0: return 0; michael@0: s = src; michael@0: michael@0: UN8x4_MUL_UN8 (s, m); michael@0: michael@0: return s; michael@0: } michael@0: michael@0: static void michael@0: combine_src_u (pixman_implementation_t *imp, michael@0: pixman_op_t op, michael@0: uint32_t * dest, michael@0: const uint32_t * src, michael@0: const uint32_t * mask, michael@0: int width) michael@0: { michael@0: int i; michael@0: michael@0: if (!mask) michael@0: memcpy (dest, src, width * sizeof (uint16_t)); michael@0: else michael@0: { michael@0: uint16_t *d = (uint16_t*)dest; michael@0: uint16_t *src16 = (uint16_t*)src; michael@0: for (i = 0; i < width; ++i) michael@0: { michael@0: if ((*mask & 0xff000000) == 0xff000000) { michael@0: // it's likely worth special casing michael@0: // fully opaque because it avoids michael@0: // the cost of conversion as well the multiplication michael@0: *(d + i) = *src16; michael@0: } else { michael@0: // the mask is still 32bits michael@0: uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); michael@0: *(d + i) = convert_8888_to_0565(s); michael@0: } michael@0: mask++; michael@0: src16++; michael@0: } michael@0: } michael@0: michael@0: } michael@0: michael@0: static void michael@0: combine_over_u (pixman_implementation_t *imp, michael@0: pixman_op_t op, michael@0: uint32_t * dest, michael@0: const uint32_t * src, michael@0: const uint32_t * mask, michael@0: int width) michael@0: { michael@0: int i; michael@0: michael@0: if (!mask) michael@0: memcpy (dest, src, width * sizeof (uint16_t)); michael@0: else michael@0: { michael@0: uint16_t *d = (uint16_t*)dest; michael@0: uint16_t *src16 = (uint16_t*)src; michael@0: for (i = 0; i < width; ++i) michael@0: { michael@0: if ((*mask & 0xff000000) == 0xff000000) { michael@0: // it's likely worth special casing michael@0: // fully opaque because it avoids michael@0: // the cost of conversion as well the multiplication michael@0: *(d + i) = *src16; michael@0: } else if ((*mask & 0xff000000) == 0x00000000) { michael@0: // keep the dest the same michael@0: } else { michael@0: // the mask is still 32bits michael@0: uint32_t s = combine_mask (convert_0565_to_8888(*src16), *mask); michael@0: uint32_t ia = ALPHA_8 (~s); michael@0: uint32_t d32 = convert_0565_to_8888(*(d + i)); michael@0: UN8x4_MUL_UN8_ADD_UN8x4 (d32, ia, s); michael@0: *(d + i) = convert_8888_to_0565(d32); michael@0: } michael@0: mask++; michael@0: src16++; michael@0: } michael@0: } michael@0: michael@0: } michael@0: michael@0: michael@0: void michael@0: _pixman_setup_combiner_functions_16 (pixman_implementation_t *imp) michael@0: { michael@0: int i; michael@0: for (i = 0; i < PIXMAN_N_OPERATORS; i++) { michael@0: imp->combine_16[i] = NULL; michael@0: } michael@0: imp->combine_16[PIXMAN_OP_SRC] = combine_src_u; michael@0: imp->combine_16[PIXMAN_OP_OVER] = combine_over_u; michael@0: } michael@0: