1/*
2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#if !defined(JAVA2D_NO_MLIB) || defined(MLIB_ADD_SUFF)
27
28#include <vis_proto.h>
29#include "java2d_Mlib.h"
30
31/***************************************************************/
32
33#define ARGB_XOR(index, chan)                                                \
34{                                                                            \
35    jint srcpixel = src_ptr[index];                                          \
36    jint neg_mask = srcpixel >> 31;                                          \
37    dst_ptr[index] ^= (srcpixel ^ xorpixel) & (neg_mask &~ alphamask);       \
38}
39
40/***************************************************************/
41
42#define BGR_XOR(index, chan)                                                 \
43{                                                                            \
44    jint srcpixel = src_ptr[index];                                          \
45    jint neg_mask = srcpixel >> 31;                                          \
46    srcpixel = (srcpixel << 16) | (srcpixel & 0xff00) |                      \
47               ((srcpixel >> 16) & 0xff);                                    \
48    dst_ptr[index] ^= (srcpixel ^ xorpixel) & (neg_mask &~ alphamask);       \
49}
50
51/***************************************************************/
52
53#define ARGB_BM_XOR(index, chan)                                             \
54{                                                                            \
55    jint srcpixel = src_ptr[index];                                          \
56    jint neg_mask = srcpixel >> 31;                                          \
57    srcpixel |= 0xFF000000;                                                  \
58    dst_ptr[index] ^= (srcpixel ^ xorpixel) & (neg_mask &~ alphamask);       \
59}
60
61/***************************************************************/
62
63#define RGBX_XOR(index, chan)                          \
64{                                                      \
65    jint srcpixel = src_ptr[index];                    \
66    jint neg_mask = srcpixel >> 31;                    \
67    dst_ptr[index] ^= ((srcpixel << 8) ^ xorpixel) &   \
68                      (neg_mask &~ alphamask);         \
69}
70
71/***************************************************************/
72
73#define ARGB_to_GBGR_FL2(dst, src0, src1) {                    \
74    mlib_d64 t0, t1, t2;                                       \
75    t0 = vis_fpmerge(src0, src1);                              \
76    t1 = vis_fpmerge(vis_read_lo(t0), vis_read_hi(t0));        \
77    t2 = vis_fpmerge(vis_read_lo(t0), vis_read_lo(t0));        \
78    dst = vis_fpmerge(vis_read_hi(t2), vis_read_lo(t1));       \
79}
80
81/***************************************************************/
82
83#ifdef MLIB_ADD_SUFF
84#pragma weak IntArgbToIntRgbXorBlit_F = IntArgbToIntArgbXorBlit_F
85#else
86#pragma weak IntArgbToIntRgbXorBlit   = IntArgbToIntArgbXorBlit
87#endif
88
89/***************************************************************/
90
91void ADD_SUFF(IntArgbToIntArgbXorBlit)(BLIT_PARAMS)
92{
93    mlib_s32 dstScan = pDstInfo->scanStride;
94    mlib_s32 srcScan = pSrcInfo->scanStride;
95    mlib_s32 xorpixel = pCompInfo->details.xorPixel;
96    mlib_s32 alphamask = pCompInfo->alphaMask;
97    mlib_s32 i, j;
98    mlib_d64 res, xorpixel64, alphamask64, dzero;
99
100    if (width < 8) {
101        LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, ARGB_XOR);
102        return;
103    }
104
105    if (dstScan == 4*width && srcScan == dstScan) {
106        width *= height;
107        height = 1;
108    }
109
110    xorpixel64 = vis_to_double_dup(xorpixel);
111    alphamask64 = vis_to_double_dup(alphamask);
112    dzero = vis_fzero();
113
114    for (j = 0; j < height; j++) {
115        mlib_s32 *dst_ptr = dstBase;
116        mlib_s32 *src_ptr = srcBase;
117        mlib_s32 size = width;
118
119        if ((mlib_s32)dst_ptr & 7) {
120            ARGB_XOR(0, 0);
121            dst_ptr++;
122            src_ptr++;
123            size--;
124        }
125
126#pragma pipeloop(0)
127        for (i = 0; i <= size - 2; i += 2) {
128            mlib_s32 neg_mask;
129            mlib_f32 *pp0 = (mlib_f32*)src_ptr + i;
130            mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1;
131            neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7);
132            res = vis_freg_pair(*pp0, *pp1);
133            res = vis_fxor(res, xorpixel64);
134            res = vis_fandnot(alphamask64, res);
135            res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i));
136            vis_pst_32(res, dst_ptr + i, neg_mask);
137        }
138
139        if (i < size) {
140            ARGB_XOR(i, 0);
141        }
142
143        PTR_ADD(dstBase, dstScan);
144        PTR_ADD(srcBase, srcScan);
145    }
146}
147
148/***************************************************************/
149
150void ADD_SUFF(IntArgbToIntBgrXorBlit)(BLIT_PARAMS)
151{
152    mlib_s32 dstScan = pDstInfo->scanStride;
153    mlib_s32 srcScan = pSrcInfo->scanStride;
154    mlib_s32 xorpixel = pCompInfo->details.xorPixel;
155    mlib_s32 alphamask = pCompInfo->alphaMask;
156    mlib_s32 i, j;
157    mlib_d64 res, xorpixel64, alphamask64, dzero;
158
159    if (width < 8) {
160        LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, BGR_XOR);
161        return;
162    }
163
164    if (dstScan == 4*width && srcScan == dstScan) {
165        width *= height;
166        height = 1;
167    }
168
169    xorpixel64 = vis_to_double_dup(xorpixel);
170    alphamask64 = vis_to_double_dup(alphamask);
171    dzero = vis_fzero();
172
173    for (j = 0; j < height; j++) {
174        mlib_s32 *dst_ptr = dstBase;
175        mlib_s32 *src_ptr = srcBase;
176        mlib_s32 size = width;
177
178        if ((mlib_s32)dst_ptr & 7) {
179            BGR_XOR(0, 0);
180            dst_ptr++;
181            src_ptr++;
182            size--;
183        }
184
185#pragma pipeloop(0)
186        for (i = 0; i <= size - 2; i += 2) {
187            mlib_s32 neg_mask;
188            mlib_f32 *pp0 = (mlib_f32*)src_ptr + i;
189            mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1;
190            neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7);
191            ARGB_to_GBGR_FL2(res, *pp0, *pp1);
192            res = vis_fxor(res, xorpixel64);
193            res = vis_fandnot(alphamask64, res);
194            res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i));
195            vis_pst_32(res, dst_ptr + i, neg_mask);
196        }
197
198        if (i < size) {
199            BGR_XOR(i, 0);
200        }
201
202        PTR_ADD(dstBase, dstScan);
203        PTR_ADD(srcBase, srcScan);
204    }
205}
206
207/***************************************************************/
208
209void ADD_SUFF(IntArgbToIntArgbBmXorBlit)(BLIT_PARAMS)
210{
211    mlib_s32 dstScan = pDstInfo->scanStride;
212    mlib_s32 srcScan = pSrcInfo->scanStride;
213    mlib_s32 xorpixel = pCompInfo->details.xorPixel;
214    mlib_s32 alphamask = pCompInfo->alphaMask;
215    mlib_s32 i, j, neg_mask;
216    mlib_d64 res, xorpixel64, alphamask64, dzero, dFF;
217
218    if (width < 8) {
219        LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan,
220                     ARGB_BM_XOR);
221        return;
222    }
223
224    if (dstScan == 4*width && srcScan == dstScan) {
225        width *= height;
226        height = 1;
227    }
228
229    xorpixel64 = vis_to_double_dup(xorpixel);
230    alphamask64 = vis_to_double_dup(alphamask);
231    dzero = vis_fzero();
232    dFF = vis_to_double_dup(0xFF000000);
233
234    for (j = 0; j < height; j++) {
235        mlib_s32 *dst_ptr = dstBase;
236        mlib_s32 *src_ptr = srcBase;
237        mlib_s32 size = width;
238
239        if ((mlib_s32)dst_ptr & 7) {
240            ARGB_BM_XOR(0, 0);
241            dst_ptr++;
242            src_ptr++;
243            size--;
244        }
245
246#pragma pipeloop(0)
247        for (i = 0; i <= size - 2; i += 2) {
248            mlib_s32 neg_mask;
249            mlib_f32 *pp0 = (mlib_f32*)src_ptr + i;
250            mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1;
251            neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7);
252            res = vis_freg_pair(*pp0, *pp1);
253            res = vis_for(res, dFF);
254            res = vis_fxor(res, xorpixel64);
255            res = vis_fandnot(alphamask64, res);
256            res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i));
257            vis_pst_32(res, dst_ptr + i, neg_mask);
258        }
259
260        if (i < size) {
261            ARGB_BM_XOR(i, 0);
262        }
263
264        PTR_ADD(dstBase, dstScan);
265        PTR_ADD(srcBase, srcScan);
266    }
267}
268
269/***************************************************************/
270
271void ADD_SUFF(IntArgbToIntRgbxXorBlit)(BLIT_PARAMS)
272{
273    mlib_s32 dstScan = pDstInfo->scanStride;
274    mlib_s32 srcScan = pSrcInfo->scanStride;
275    mlib_s32 xorpixel = pCompInfo->details.xorPixel;
276    mlib_s32 alphamask = pCompInfo->alphaMask;
277    mlib_s32 i, j, neg_mask;
278    mlib_d64 res, xorpixel64, alphamask64, rgbx_mask, dzero;
279
280    if (width < 8) {
281        LOOP_DST_SRC(AnyInt, 1, dstBase, dstScan, srcBase, srcScan, RGBX_XOR);
282        return;
283    }
284
285    if (dstScan == 4*width && srcScan == dstScan) {
286        width *= height;
287        height = 1;
288    }
289
290    xorpixel64 = vis_to_double_dup(xorpixel);
291    alphamask64 = vis_to_double_dup(alphamask);
292    rgbx_mask = vis_to_double_dup(0xFFFFFF00);
293    dzero = vis_fzero();
294
295    vis_alignaddr(NULL, 1);
296
297    for (j = 0; j < height; j++) {
298        mlib_s32 *dst_ptr = dstBase;
299        mlib_s32 *src_ptr = srcBase;
300        mlib_s32 size = width;
301
302        if ((mlib_s32)dst_ptr & 7) {
303            RGBX_XOR(0, 0);
304            dst_ptr++;
305            src_ptr++;
306            size--;
307        }
308
309#pragma pipeloop(0)
310        for (i = 0; i <= size - 2; i += 2) {
311            mlib_s32 neg_mask;
312            mlib_f32 *pp0 = (mlib_f32*)src_ptr + i;
313            mlib_f32 *pp1 = (mlib_f32*)src_ptr + i + 1;
314            neg_mask = (((*(mlib_u8*)pp0) >> 6) & 2) | ((*(mlib_u8*)pp1) >> 7);
315            res = vis_freg_pair(*pp0, *pp1);
316            res = vis_fand(vis_faligndata(res, res), rgbx_mask);
317            res = vis_fxor(res, xorpixel64);
318            res = vis_fandnot(alphamask64, res);
319            res = vis_fxor(res, *(mlib_d64*)(dst_ptr + i));
320            vis_pst_32(res, dst_ptr + i, neg_mask);
321        }
322
323        if (i < size) {
324            RGBX_XOR(i, 0);
325        }
326
327        PTR_ADD(dstBase, dstScan);
328        PTR_ADD(srcBase, srcScan);
329    }
330}
331
332/***************************************************************/
333
334void ADD_SUFF(IntArgbToFourByteAbgrPreXorBlit)(BLIT_PARAMS)
335{
336    jint   xorpixel = pCompInfo->details.xorPixel;
337    juint  alphamask = pCompInfo->alphaMask;
338    jint   xor0, xor1, xor2, xor3;
339    jint   mask0, mask1, mask2, mask3;
340    jint   *pSrc = srcBase;
341    jubyte *pDst = dstBase;
342    jint   srcScan = pSrcInfo->scanStride;
343    jint   dstScan = pDstInfo->scanStride;
344
345    xor0 = xorpixel;
346    xor1 = xorpixel >> 8;
347    xor2 = xorpixel >> 16;
348    xor3 = xorpixel >> 24;
349    mask0 = alphamask;
350    mask1 = alphamask >> 8;
351    mask2 = alphamask >> 16;
352    mask3 = alphamask >> 24;
353
354    srcScan -= width * 4;
355    dstScan -= width * 4;
356
357    do {
358        juint w = width;;
359        do {
360            jint srcpixel;
361            jint a, r, g, b;
362
363            srcpixel = pSrc[0];
364            b = srcpixel & 0xff;
365            g = (srcpixel >> 8) & 0xff;
366            r = (srcpixel >> 16) & 0xff;
367            a = (mlib_u32)srcpixel >> 24;
368
369            if (srcpixel < 0) {
370                r = mul8table[a][r];
371                g = mul8table[a][g];
372                b = mul8table[a][b];
373
374                pDst[0] ^= (a ^ xor0) & ~mask0;
375                pDst[1] ^= (b ^ xor1) & ~mask1;
376                pDst[2] ^= (g ^ xor2) & ~mask2;
377                pDst[3] ^= (r ^ xor3) & ~mask3;
378            }
379            pSrc = ((void *) (((intptr_t) (pSrc)) + (4)));
380            pDst = ((void *) (((intptr_t) (pDst)) + (4)));;
381        }
382        while (--w > 0);
383        pSrc = ((void *) (((intptr_t) (pSrc)) + (srcScan)));
384        pDst = ((void *) (((intptr_t) (pDst)) + (dstScan)));;
385    }
386    while (--height > 0);
387}
388
389/***************************************************************/
390
391#endif
392