michael@0: /* michael@0: * Copyright © 2008 Mozilla Corporation michael@0: * michael@0: * Permission to use, copy, modify, distribute, and sell this software and its michael@0: * documentation for any purpose is hereby granted without fee, provided that michael@0: * the above copyright notice appear in all copies and that both that michael@0: * copyright notice and this permission notice appear in supporting michael@0: * documentation, and that the name of Mozilla Corporation not be used in michael@0: * advertising or publicity pertaining to distribution of the software without michael@0: * specific, written prior permission. Mozilla Corporation makes no michael@0: * representations about the suitability of this software for any purpose. It michael@0: * is provided "as is" without express or implied warranty. michael@0: * michael@0: * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS michael@0: * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND michael@0: * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY michael@0: * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES michael@0: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN michael@0: * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING michael@0: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS michael@0: * SOFTWARE. michael@0: * michael@0: * Author: Jeff Muizelaar (jeff@infidigm.net) michael@0: * michael@0: */ michael@0: #ifdef HAVE_CONFIG_H michael@0: #include michael@0: #endif michael@0: michael@0: #include "pixman-private.h" michael@0: #include "pixman-arm-common.h" michael@0: #include "pixman-inlines.h" michael@0: michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8888_8888, michael@0: uint32_t, 1, uint32_t, 1) michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_8888, michael@0: uint32_t, 1, uint32_t, 1) michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_0565, michael@0: uint16_t, 1, uint16_t, 1) michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8, michael@0: uint8_t, 1, uint8_t, 1) michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888, michael@0: uint16_t, 1, uint32_t, 1) michael@0: michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8, michael@0: uint8_t, 1, uint8_t, 1) michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888, michael@0: uint32_t, 1, uint32_t, 1) michael@0: michael@0: PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888, michael@0: uint32_t, 1, uint32_t, 1) michael@0: michael@0: PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888, michael@0: uint8_t, 1, uint32_t, 1) michael@0: michael@0: PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC, michael@0: uint16_t, uint16_t) michael@0: PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC, michael@0: uint32_t, uint32_t) michael@0: michael@0: void michael@0: pixman_composite_src_n_8888_asm_armv6 (int32_t w, michael@0: int32_t h, michael@0: uint32_t *dst, michael@0: int32_t dst_stride, michael@0: uint32_t src); michael@0: michael@0: void michael@0: pixman_composite_src_n_0565_asm_armv6 (int32_t w, michael@0: int32_t h, michael@0: uint16_t *dst, michael@0: int32_t dst_stride, michael@0: uint16_t src); michael@0: michael@0: void michael@0: pixman_composite_src_n_8_asm_armv6 (int32_t w, michael@0: int32_t h, michael@0: uint8_t *dst, michael@0: int32_t dst_stride, michael@0: uint8_t src); michael@0: michael@0: static pixman_bool_t michael@0: arm_simd_fill (pixman_implementation_t *imp, michael@0: uint32_t * bits, michael@0: int stride, /* in 32-bit words */ michael@0: int bpp, michael@0: int x, michael@0: int y, michael@0: int width, michael@0: int height, michael@0: uint32_t _xor) michael@0: { michael@0: /* stride is always multiple of 32bit units in pixman */ michael@0: uint32_t byte_stride = stride * sizeof(uint32_t); michael@0: michael@0: switch (bpp) michael@0: { michael@0: case 8: michael@0: pixman_composite_src_n_8_asm_armv6 ( michael@0: width, michael@0: height, michael@0: (uint8_t *)(((char *) bits) + y * byte_stride + x), michael@0: byte_stride, michael@0: _xor & 0xff); michael@0: return TRUE; michael@0: case 16: michael@0: pixman_composite_src_n_0565_asm_armv6 ( michael@0: width, michael@0: height, michael@0: (uint16_t *)(((char *) bits) + y * byte_stride + x * 2), michael@0: byte_stride / 2, michael@0: _xor & 0xffff); michael@0: return TRUE; michael@0: case 32: michael@0: pixman_composite_src_n_8888_asm_armv6 ( michael@0: width, michael@0: height, michael@0: (uint32_t *)(((char *) bits) + y * byte_stride + x * 4), michael@0: byte_stride / 4, michael@0: _xor); michael@0: return TRUE; michael@0: default: michael@0: return FALSE; michael@0: } michael@0: } michael@0: michael@0: static pixman_bool_t michael@0: arm_simd_blt (pixman_implementation_t *imp, michael@0: uint32_t * src_bits, michael@0: uint32_t * dst_bits, michael@0: int src_stride, /* in 32-bit words */ michael@0: int dst_stride, /* in 32-bit words */ michael@0: int src_bpp, michael@0: int dst_bpp, michael@0: int src_x, michael@0: int src_y, michael@0: int dest_x, michael@0: int dest_y, michael@0: int width, michael@0: int height) michael@0: { michael@0: if (src_bpp != dst_bpp) michael@0: return FALSE; michael@0: michael@0: switch (src_bpp) michael@0: { michael@0: case 8: michael@0: pixman_composite_src_8_8_asm_armv6 ( michael@0: width, height, michael@0: (uint8_t *)(((char *) dst_bits) + michael@0: dest_y * dst_stride * 4 + dest_x * 1), dst_stride * 4, michael@0: (uint8_t *)(((char *) src_bits) + michael@0: src_y * src_stride * 4 + src_x * 1), src_stride * 4); michael@0: return TRUE; michael@0: case 16: michael@0: pixman_composite_src_0565_0565_asm_armv6 ( michael@0: width, height, michael@0: (uint16_t *)(((char *) dst_bits) + michael@0: dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2, michael@0: (uint16_t *)(((char *) src_bits) + michael@0: src_y * src_stride * 4 + src_x * 2), src_stride * 2); michael@0: return TRUE; michael@0: case 32: michael@0: pixman_composite_src_8888_8888_asm_armv6 ( michael@0: width, height, michael@0: (uint32_t *)(((char *) dst_bits) + michael@0: dest_y * dst_stride * 4 + dest_x * 4), dst_stride, michael@0: (uint32_t *)(((char *) src_bits) + michael@0: src_y * src_stride * 4 + src_x * 4), src_stride); michael@0: return TRUE; michael@0: default: michael@0: return FALSE; michael@0: } michael@0: } michael@0: michael@0: static const pixman_fast_path_t arm_simd_fast_paths[] = michael@0: { michael@0: PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, armv6_composite_src_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, armv6_composite_src_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888), michael@0: michael@0: PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, armv6_composite_src_x888_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, armv6_composite_src_x888_8888), michael@0: michael@0: PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, a1r5g5b5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, a1b5g5r5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, x1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, a4r4g4b4, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, a4b4g4r4, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, x4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565), michael@0: PIXMAN_STD_FAST_PATH (SRC, x4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565), michael@0: michael@0: PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, r3g3b2, null, r3g3b2, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, b2g3r3, null, b2g3r3, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, a2r2g2b2, null, a2r2g2b2, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, a2b2g2r2, null, a2b2g2r2, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, c8, null, c8, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, g8, null, g8, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, x4a4, null, x4a4, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, x4c4, null, x4c4, armv6_composite_src_8_8), michael@0: PIXMAN_STD_FAST_PATH (SRC, x4g4, null, x4g4, armv6_composite_src_8_8), michael@0: michael@0: PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, armv6_composite_src_0565_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, armv6_composite_src_0565_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888), michael@0: PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888), michael@0: michael@0: PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, armv6_composite_over_8888_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, armv6_composite_over_8888_n_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, armv6_composite_over_8888_n_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888), michael@0: michael@0: PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8), michael@0: michael@0: PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, armv6_composite_over_n_8_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888), michael@0: PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888), michael@0: michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565), michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565), michael@0: michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888), michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888), michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888), michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888), michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888), michael@0: PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888), michael@0: michael@0: { PIXMAN_OP_NONE }, michael@0: }; michael@0: michael@0: pixman_implementation_t * michael@0: _pixman_implementation_create_arm_simd (pixman_implementation_t *fallback) michael@0: { michael@0: pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths); michael@0: michael@0: imp->blt = arm_simd_blt; michael@0: imp->fill = arm_simd_fill; michael@0: michael@0: return imp; michael@0: }