michael@0: /* michael@0: * Copyright (c) 2012 michael@0: * MIPS Technologies, Inc., California. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its michael@0: * contributors may be used to endorse or promote products derived from michael@0: * this software without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND michael@0: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE michael@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE michael@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE michael@0: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL michael@0: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS michael@0: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) michael@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT michael@0: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY michael@0: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF michael@0: * SUCH DAMAGE. michael@0: * michael@0: * Author: Nemanja Lukic (nlukic@mips.com) michael@0: */ michael@0: michael@0: #ifndef PIXMAN_MIPS_DSPR2_H michael@0: #define PIXMAN_MIPS_DSPR2_H michael@0: michael@0: #include "pixman-private.h" michael@0: #include "pixman-inlines.h" michael@0: michael@0: #define SKIP_ZERO_SRC 1 michael@0: #define SKIP_ZERO_MASK 2 michael@0: #define DO_FAST_MEMCPY 3 michael@0: michael@0: void michael@0: pixman_mips_fast_memcpy (void *dst, void *src, uint32_t n_bytes); michael@0: void michael@0: pixman_fill_buff16_mips (void *dst, uint32_t n_bytes, uint16_t value); michael@0: void michael@0: pixman_fill_buff32_mips (void *dst, uint32_t n_bytes, uint32_t value); michael@0: michael@0: /****************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST(flags, name, \ michael@0: src_type, src_cnt, \ michael@0: dst_type, dst_cnt) \ michael@0: void \ michael@0: pixman_composite_##name##_asm_mips (dst_type *dst, \ michael@0: src_type *src, \ michael@0: int32_t w); \ michael@0: \ michael@0: static void \ michael@0: mips_composite_##name (pixman_implementation_t *imp, \ michael@0: pixman_composite_info_t *info) \ michael@0: { \ michael@0: PIXMAN_COMPOSITE_ARGS (info); \ michael@0: dst_type *dst_line, *dst; \ michael@0: src_type *src_line, *src; \ michael@0: int32_t dst_stride, src_stride; \ michael@0: int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8; \ michael@0: \ michael@0: PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ michael@0: src_stride, src_line, src_cnt); \ michael@0: PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ michael@0: dst_stride, dst_line, dst_cnt); \ michael@0: \ michael@0: while (height--) \ michael@0: { \ michael@0: dst = dst_line; \ michael@0: dst_line += dst_stride; \ michael@0: src = src_line; \ michael@0: src_line += src_stride; \ michael@0: \ michael@0: if (flags == DO_FAST_MEMCPY) \ michael@0: pixman_mips_fast_memcpy (dst, src, width * bpp); \ michael@0: else \ michael@0: pixman_composite_##name##_asm_mips (dst, src, width); \ michael@0: } \ michael@0: } michael@0: michael@0: /****************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_FAST_PATH_N_DST(flags, name, \ michael@0: dst_type, dst_cnt) \ michael@0: void \ michael@0: pixman_composite_##name##_asm_mips (dst_type *dst, \ michael@0: uint32_t src, \ michael@0: int32_t w); \ michael@0: \ michael@0: static void \ michael@0: mips_composite_##name (pixman_implementation_t *imp, \ michael@0: pixman_composite_info_t *info) \ michael@0: { \ michael@0: PIXMAN_COMPOSITE_ARGS (info); \ michael@0: dst_type *dst_line, *dst; \ michael@0: int32_t dst_stride; \ michael@0: uint32_t src; \ michael@0: \ michael@0: src = _pixman_image_get_solid ( \ michael@0: imp, src_image, dest_image->bits.format); \ michael@0: \ michael@0: if ((flags & SKIP_ZERO_SRC) && src == 0) \ michael@0: return; \ michael@0: \ michael@0: PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ michael@0: dst_stride, dst_line, dst_cnt); \ michael@0: \ michael@0: while (height--) \ michael@0: { \ michael@0: dst = dst_line; \ michael@0: dst_line += dst_stride; \ michael@0: \ michael@0: pixman_composite_##name##_asm_mips (dst, src, width); \ michael@0: } \ michael@0: } michael@0: michael@0: /*******************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST(flags, name, \ michael@0: mask_type, mask_cnt, \ michael@0: dst_type, dst_cnt) \ michael@0: void \ michael@0: pixman_composite_##name##_asm_mips (dst_type *dst, \ michael@0: uint32_t src, \ michael@0: mask_type *mask, \ michael@0: int32_t w); \ michael@0: \ michael@0: static void \ michael@0: mips_composite_##name (pixman_implementation_t *imp, \ michael@0: pixman_composite_info_t *info) \ michael@0: { \ michael@0: PIXMAN_COMPOSITE_ARGS (info); \ michael@0: dst_type *dst_line, *dst; \ michael@0: mask_type *mask_line, *mask; \ michael@0: int32_t dst_stride, mask_stride; \ michael@0: uint32_t src; \ michael@0: \ michael@0: src = _pixman_image_get_solid ( \ michael@0: imp, src_image, dest_image->bits.format); \ michael@0: \ michael@0: if ((flags & SKIP_ZERO_SRC) && src == 0) \ michael@0: return; \ michael@0: \ michael@0: PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ michael@0: dst_stride, dst_line, dst_cnt); \ michael@0: PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ michael@0: mask_stride, mask_line, mask_cnt); \ michael@0: \ michael@0: while (height--) \ michael@0: { \ michael@0: dst = dst_line; \ michael@0: dst_line += dst_stride; \ michael@0: mask = mask_line; \ michael@0: mask_line += mask_stride; \ michael@0: pixman_composite_##name##_asm_mips (dst, src, mask, width); \ michael@0: } \ michael@0: } michael@0: michael@0: /*******************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST(flags, name, \ michael@0: src_type, src_cnt, \ michael@0: dst_type, dst_cnt) \ michael@0: void \ michael@0: pixman_composite_##name##_asm_mips (dst_type *dst, \ michael@0: src_type *src, \ michael@0: uint32_t mask, \ michael@0: int32_t w); \ michael@0: \ michael@0: static void \ michael@0: mips_composite_##name (pixman_implementation_t *imp, \ michael@0: pixman_composite_info_t *info) \ michael@0: { \ michael@0: PIXMAN_COMPOSITE_ARGS (info); \ michael@0: dst_type *dst_line, *dst; \ michael@0: src_type *src_line, *src; \ michael@0: int32_t dst_stride, src_stride; \ michael@0: uint32_t mask; \ michael@0: \ michael@0: mask = _pixman_image_get_solid ( \ michael@0: imp, mask_image, dest_image->bits.format); \ michael@0: \ michael@0: if ((flags & SKIP_ZERO_MASK) && mask == 0) \ michael@0: return; \ michael@0: \ michael@0: PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ michael@0: dst_stride, dst_line, dst_cnt); \ michael@0: PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ michael@0: src_stride, src_line, src_cnt); \ michael@0: \ michael@0: while (height--) \ michael@0: { \ michael@0: dst = dst_line; \ michael@0: dst_line += dst_stride; \ michael@0: src = src_line; \ michael@0: src_line += src_stride; \ michael@0: \ michael@0: pixman_composite_##name##_asm_mips (dst, src, mask, width); \ michael@0: } \ michael@0: } michael@0: michael@0: /************************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST(name, src_type, src_cnt, \ michael@0: mask_type, mask_cnt, \ michael@0: dst_type, dst_cnt) \ michael@0: void \ michael@0: pixman_composite_##name##_asm_mips (dst_type *dst, \ michael@0: src_type *src, \ michael@0: mask_type *mask, \ michael@0: int32_t w); \ michael@0: \ michael@0: static void \ michael@0: mips_composite_##name (pixman_implementation_t *imp, \ michael@0: pixman_composite_info_t *info) \ michael@0: { \ michael@0: PIXMAN_COMPOSITE_ARGS (info); \ michael@0: dst_type *dst_line, *dst; \ michael@0: src_type *src_line, *src; \ michael@0: mask_type *mask_line, *mask; \ michael@0: int32_t dst_stride, src_stride, mask_stride; \ michael@0: \ michael@0: PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ michael@0: dst_stride, dst_line, dst_cnt); \ michael@0: PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ michael@0: src_stride, src_line, src_cnt); \ michael@0: PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ michael@0: mask_stride, mask_line, mask_cnt); \ michael@0: \ michael@0: while (height--) \ michael@0: { \ michael@0: dst = dst_line; \ michael@0: dst_line += dst_stride; \ michael@0: mask = mask_line; \ michael@0: mask_line += mask_stride; \ michael@0: src = src_line; \ michael@0: src_line += src_stride; \ michael@0: pixman_composite_##name##_asm_mips (dst, src, mask, width); \ michael@0: } \ michael@0: } michael@0: michael@0: /*****************************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST(flags, name, op, \ michael@0: src_type, dst_type) \ michael@0: void \ michael@0: pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \ michael@0: dst_type * dst, \ michael@0: const src_type * src, \ michael@0: const uint8_t * mask, \ michael@0: int32_t w, \ michael@0: pixman_fixed_t vx, \ michael@0: pixman_fixed_t unit_x); \ michael@0: \ michael@0: static force_inline void \ michael@0: scaled_nearest_scanline_mips_##name##_##op (const uint8_t * mask, \ michael@0: dst_type * pd, \ michael@0: const src_type * ps, \ michael@0: int32_t w, \ michael@0: pixman_fixed_t vx, \ michael@0: pixman_fixed_t unit_x, \ michael@0: pixman_fixed_t max_vx, \ michael@0: pixman_bool_t zero_src) \ michael@0: { \ michael@0: if ((flags & SKIP_ZERO_SRC) && zero_src) \ michael@0: return; \ michael@0: pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, \ michael@0: mask, w, \ michael@0: vx, unit_x); \ michael@0: } \ michael@0: \ michael@0: FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_cover_##op, \ michael@0: scaled_nearest_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\ michael@0: FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_none_##op, \ michael@0: scaled_nearest_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \ michael@0: FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_pad_##op, \ michael@0: scaled_nearest_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, PAD, TRUE, FALSE) michael@0: michael@0: /* Provide entries for the fast path table */ michael@0: #define PIXMAN_MIPS_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \ michael@0: SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER (op,s,d,func), \ michael@0: SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE (op,s,d,func), \ michael@0: SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func) michael@0: michael@0: /****************************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST(flags, name, op, \ michael@0: src_type, dst_type) \ michael@0: void \ michael@0: pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips( \ michael@0: dst_type * dst, \ michael@0: const src_type * src_top, \ michael@0: const src_type * src_bottom, \ michael@0: int32_t w, \ michael@0: int wt, \ michael@0: int wb, \ michael@0: pixman_fixed_t vx, \ michael@0: pixman_fixed_t unit_x); \ michael@0: static force_inline void \ michael@0: scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \ michael@0: const uint32_t * mask, \ michael@0: const src_type * src_top, \ michael@0: const src_type * src_bottom, \ michael@0: int32_t w, \ michael@0: int wt, \ michael@0: int wb, \ michael@0: pixman_fixed_t vx, \ michael@0: pixman_fixed_t unit_x, \ michael@0: pixman_fixed_t max_vx, \ michael@0: pixman_bool_t zero_src) \ michael@0: { \ michael@0: if ((flags & SKIP_ZERO_SRC) && zero_src) \ michael@0: return; \ michael@0: pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips (dst, src_top, \ michael@0: src_bottom, w, \ michael@0: wt, wb, \ michael@0: vx, unit_x); \ michael@0: } \ michael@0: \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint32_t, dst_type, COVER, FLAG_NONE) \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint32_t, dst_type, NONE, FLAG_NONE) \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint32_t, dst_type, PAD, FLAG_NONE) \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint32_t, dst_type, NORMAL, \ michael@0: FLAG_NONE) michael@0: michael@0: /*****************************************************************************/ michael@0: michael@0: #define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, name, op, \ michael@0: src_type, dst_type) \ michael@0: void \ michael@0: pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \ michael@0: dst_type * dst, \ michael@0: const uint8_t * mask, \ michael@0: const src_type * top, \ michael@0: const src_type * bottom, \ michael@0: int wt, \ michael@0: int wb, \ michael@0: pixman_fixed_t x, \ michael@0: pixman_fixed_t ux, \ michael@0: int width); \ michael@0: \ michael@0: static force_inline void \ michael@0: scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \ michael@0: const uint8_t * mask, \ michael@0: const src_type * src_top, \ michael@0: const src_type * src_bottom, \ michael@0: int32_t w, \ michael@0: int wt, \ michael@0: int wb, \ michael@0: pixman_fixed_t vx, \ michael@0: pixman_fixed_t unit_x, \ michael@0: pixman_fixed_t max_vx, \ michael@0: pixman_bool_t zero_src) \ michael@0: { \ michael@0: if ((flags & SKIP_ZERO_SRC) && zero_src) \ michael@0: return; \ michael@0: pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \ michael@0: dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \ michael@0: } \ michael@0: \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, COVER, \ michael@0: FLAG_HAVE_NON_SOLID_MASK) \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, NONE, \ michael@0: FLAG_HAVE_NON_SOLID_MASK) \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, PAD, \ michael@0: FLAG_HAVE_NON_SOLID_MASK) \ michael@0: FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \ michael@0: scaled_bilinear_scanline_mips_##name##_##op, \ michael@0: src_type, uint8_t, dst_type, NORMAL, \ michael@0: FLAG_HAVE_NON_SOLID_MASK) michael@0: michael@0: #endif //PIXMAN_MIPS_DSPR2_H