/* * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #if !defined(JAVA2D_NO_MLIB) || defined(MLIB_ADD_SUFF) #include #include "java2d_Mlib.h" /***************************************************************/ #define ARGB_XOR(index, chan) \ { \ jint srcpixel = src_ptr[index]; \ jint neg_mask = srcpixel >> 31; \ dst_ptr[index] ^= (srcpixel ^ xorpixel) & (neg_mask &~ alphamask); \ } /***************************************************************/ #define BGR_XOR(index, chan) \ { \ jint srcpixel = src_ptr[index]; \ jint neg_mask = srcpixel >> 31; \ srcpixel = (srcpixel << 16) | (srcpixel & 0xff00) | \ ((srcpixel >> 16) & 0xff); \ dst_ptr[index] ^= (srcpixel ^ xorpixel) & (neg_mask &~ alphamask); \ } /***************************************************************/ #define ARGB_BM_XOR(index, chan) \ { \ jint srcpixel = src_ptr[index]; \ jint neg_mask = srcpixel >> 31; \ srcpixel |= 0xFF000000; \ dst_ptr[index] ^= (srcpixel ^ xorpixel) & (neg_mask &~ alphamask); \ } /***************************************************************/ #define RGBX_XOR(index, chan) \ { \ jint srcpixel = src_ptr[index]; \ jint neg_mask = srcpixel >> 31; \ dst_ptr[index] ^= ((srcpixel << 8) ^ xorpixel) & \ (neg_mask &~ alphamask); \ } /***************************************************************/ #define ARGB_to_GBGR_FL2(dst, src0, src1) { \ mlib_d64 t0, t1, t2; \ t0 = vis_fpmerge(src0, src1); \ t1 = vis_fpmerge(vis_read_lo(t0), vis_read_hi(t0)); \ t2 = vis_fpmerge(vis_read_lo(t0), vis_read_lo(t0)); \ dst = vis_fpmerge(vis_read_hi(t2), vis_read_lo(t1)); \ } /***************************************************************/ #ifdef MLIB_ADD_SUFF #pragma weak IntArgbToIntRgbXorBlit_F = IntArgbToIntArgbXorBlit_F #else #pragma weak IntArgbToIntRgbXorBlit = IntArgbToIntArgbXorBlit #endif /***************************************************************/ void ADD_SUFF(IntArgbToIntArgbXorBlit)(BLIT_PARAMS) { mlib_s32 dstScan = pDstInfo->scanStride; mlib_s32 srcScan = pSrcInfo->scanStride; mlib_s32 xorpixel = pCompInfo->details.xorPixel; mlib_s32 alphamask = pCompInfo->alphaMask; mlib_s32 i, j; mlib_d64 res, xorpixel64, alphamask64, dzero; if (width < 8) { LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, ARGB_XOR); return; } if (dstScan == 4*width && srcScan == dstScan) { width *= height; height = 1; } xorpixel64 = vis_to_double_dup(xorpixel); alphamask64 = vis_to_double_dup(alphamask); dzero = vis_fzero(); for (j = 0; j < height; j++) { mlib_s32 *dst_ptr = dstBase; mlib_s32 *src_ptr = srcBase; mlib_s32 size = width; if ((mlib_s32)dst_ptr & 7) { ARGB_XOR(0, 0); dst_ptr++; src_ptr++; size--; } #pragma pipeloop(0) for (i = 0; i <= size - 2; i += 2) { mlib_s32 neg_mask; mlib_f32 *pp0 = (mlib_f32*)src_ptr + i; mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1; neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7); res = vis_freg_pair(*pp0, *pp1); res = vis_fxor(res, xorpixel64); res = vis_fandnot(alphamask64, res); res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i)); vis_pst_32(res, dst_ptr + i, neg_mask); } if (i < size) { ARGB_XOR(i, 0); } PTR_ADD(dstBase, dstScan); PTR_ADD(srcBase, srcScan); } } /***************************************************************/ void ADD_SUFF(IntArgbToIntBgrXorBlit)(BLIT_PARAMS) { mlib_s32 dstScan = pDstInfo->scanStride; mlib_s32 srcScan = pSrcInfo->scanStride; mlib_s32 xorpixel = pCompInfo->details.xorPixel; mlib_s32 alphamask = pCompInfo->alphaMask; mlib_s32 i, j; mlib_d64 res, xorpixel64, alphamask64, dzero; if (width < 8) { LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, BGR_XOR); return; } if (dstScan == 4*width && srcScan == dstScan) { width *= height; height = 1; } xorpixel64 = vis_to_double_dup(xorpixel); alphamask64 = vis_to_double_dup(alphamask); dzero = vis_fzero(); for (j = 0; j < height; j++) { mlib_s32 *dst_ptr = dstBase; mlib_s32 *src_ptr = srcBase; mlib_s32 size = width; if ((mlib_s32)dst_ptr & 7) { BGR_XOR(0, 0); dst_ptr++; src_ptr++; size--; } #pragma pipeloop(0) for (i = 0; i <= size - 2; i += 2) { mlib_s32 neg_mask; mlib_f32 *pp0 = (mlib_f32*)src_ptr + i; mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1; neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7); ARGB_to_GBGR_FL2(res, *pp0, *pp1); res = vis_fxor(res, xorpixel64); res = vis_fandnot(alphamask64, res); res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i)); vis_pst_32(res, dst_ptr + i, neg_mask); } if (i < size) { BGR_XOR(i, 0); } PTR_ADD(dstBase, dstScan); PTR_ADD(srcBase, srcScan); } } /***************************************************************/ void ADD_SUFF(IntArgbToIntArgbBmXorBlit)(BLIT_PARAMS) { mlib_s32 dstScan = pDstInfo->scanStride; mlib_s32 srcScan = pSrcInfo->scanStride; mlib_s32 xorpixel = pCompInfo->details.xorPixel; mlib_s32 alphamask = pCompInfo->alphaMask; mlib_s32 i, j, neg_mask; mlib_d64 res, xorpixel64, alphamask64, dzero, dFF; if (width < 8) { LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, ARGB_BM_XOR); return; } if (dstScan == 4*width && srcScan == dstScan) { width *= height; height = 1; } xorpixel64 = vis_to_double_dup(xorpixel); alphamask64 = vis_to_double_dup(alphamask); dzero = vis_fzero(); dFF = vis_to_double_dup(0xFF000000); for (j = 0; j < height; j++) { mlib_s32 *dst_ptr = dstBase; mlib_s32 *src_ptr = srcBase; mlib_s32 size = width; if ((mlib_s32)dst_ptr & 7) { ARGB_BM_XOR(0, 0); dst_ptr++; src_ptr++; size--; } #pragma pipeloop(0) for (i = 0; i <= size - 2; i += 2) { mlib_s32 neg_mask; mlib_f32 *pp0 = (mlib_f32*)src_ptr + i; mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1; neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7); res = vis_freg_pair(*pp0, *pp1); res = vis_for(res, dFF); res = vis_fxor(res, xorpixel64); res = vis_fandnot(alphamask64, res); res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i)); vis_pst_32(res, dst_ptr + i, neg_mask); } if (i < size) { ARGB_BM_XOR(i, 0); } PTR_ADD(dstBase, dstScan); PTR_ADD(srcBase, srcScan); } } /***************************************************************/ void ADD_SUFF(IntArgbToIntRgbxXorBlit)(BLIT_PARAMS) { mlib_s32 dstScan = pDstInfo->scanStride; mlib_s32 srcScan = pSrcInfo->scanStride; mlib_s32 xorpixel = pCompInfo->details.xorPixel; mlib_s32 alphamask = pCompInfo->alphaMask; mlib_s32 i, j, neg_mask; mlib_d64 res, xorpixel64, alphamask64, rgbx_mask, dzero; if (width < 8) { LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, RGBX_XOR); return; } if (dstScan == 4*width && srcScan == dstScan) { width *= height; height = 1; } xorpixel64 = vis_to_double_dup(xorpixel); alphamask64 = vis_to_double_dup(alphamask); rgbx_mask = vis_to_double_dup(0xFFFFFF00); dzero = vis_fzero(); vis_alignaddr(NULL, 1); for (j = 0; j < height; j++) { mlib_s32 *dst_ptr = dstBase; mlib_s32 *src_ptr = srcBase; mlib_s32 size = width; if ((mlib_s32)dst_ptr & 7) { RGBX_XOR(0, 0); dst_ptr++; src_ptr++; size--; } #pragma pipeloop(0) for (i = 0; i <= size - 2; i += 2) { mlib_s32 neg_mask; mlib_f32 *pp0 = (mlib_f32*)src_ptr + i; mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1; neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7); res = vis_freg_pair(*pp0, *pp1); res = vis_fand(vis_faligndata(res, res), rgbx_mask); res = vis_fxor(res, xorpixel64); res = vis_fandnot(alphamask64, res); res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i)); vis_pst_32(res, dst_ptr + i, neg_mask); } if (i < size) { RGBX_XOR(i, 0); } PTR_ADD(dstBase, dstScan); PTR_ADD(srcBase, srcScan); } } /***************************************************************/ void ADD_SUFF(IntArgbToFourByteAbgrPreXorBlit)(BLIT_PARAMS) { jint xorpixel = pCompInfo->details.xorPixel; juint alphamask = pCompInfo->alphaMask; jint xor0, xor1, xor2, xor3; jint mask0, mask1, mask2, mask3; jint *pSrc = srcBase; jubyte *pDst = dstBase; jint srcScan = pSrcInfo->scanStride; jint dstScan = pDstInfo->scanStride; xor0 = xorpixel; xor1 = xorpixel >> 8; xor2 = xorpixel >> 16; xor3 = xorpixel >> 24; mask0 = alphamask; mask1 = alphamask >> 8; mask2 = alphamask >> 16; mask3 = alphamask >> 24; srcScan -= width * 4; dstScan -= width * 4; do { juint w = width;; do { jint srcpixel; jint a, r, g, b; srcpixel = pSrc[0]; b = srcpixel & 0xff; g = (srcpixel >> 8) & 0xff; r = (srcpixel >> 16) & 0xff; a = (mlib_u32)srcpixel >> 24; if (srcpixel < 0) { r = mul8table[a][r]; g = mul8table[a][g]; b = mul8table[a][b]; pDst[0] ^= (a ^ xor0) & ~mask0; pDst[1] ^= (b ^ xor1) & ~mask1; pDst[2] ^= (g ^ xor2) & ~mask2; pDst[3] ^= (r ^ xor3) & ~mask3; } pSrc = ((void *) (((intptr_t) (pSrc)) + (4))); pDst = ((void *) (((intptr_t) (pDst)) + (4)));; } while (--w > 0); pSrc = ((void *) (((intptr_t) (pSrc)) + (srcScan))); pDst = ((void *) (((intptr_t) (pDst)) + (dstScan)));; } while (--height > 0); } /***************************************************************/ #endif