1/*
2 * Copyright (c) 2003, 2008, 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_AlphaMacros.h"
29
30/***************************************************************/
31
32void ADD_SUFF(ByteIndexedToIntArgbConvert)(BLIT_PARAMS)
33{
34    jint *pixLut = pSrcInfo->lutBase;
35    mlib_s32 dstScan = pDstInfo->scanStride;
36    mlib_s32 srcScan = pSrcInfo->scanStride;
37    mlib_s32 i, i0, j;
38
39    if (srcScan == width && dstScan == 4*width) {
40        width *= height;
41        height = 1;
42    }
43
44    for (j = 0; j < height; j++) {
45        mlib_u8  *src = srcBase;
46        mlib_s32 *dst = dstBase;
47
48        i = i0 = 0;
49
50        if ((mlib_s32)dst & 7) {
51            dst[i] = pixLut[src[i]];
52            i0 = 1;
53        }
54
55#pragma pipeloop(0)
56        for (i = i0; i <= (mlib_s32)width - 2; i += 2) {
57            *(mlib_d64*)(dst + i) = LOAD_2F32(pixLut, src[i], src[i + 1]);
58        }
59
60        for (; i < width; i++) {
61            dst[i] = pixLut[src[i]];
62        }
63
64        PTR_ADD(dstBase, dstScan);
65        PTR_ADD(srcBase, srcScan);
66    }
67}
68
69/***************************************************************/
70
71void ADD_SUFF(Index12GrayToIntArgbConvert)(BLIT_PARAMS)
72{
73    jint *pixLut = pSrcInfo->lutBase;
74    mlib_s32 dstScan = pDstInfo->scanStride;
75    mlib_s32 srcScan = pSrcInfo->scanStride;
76    mlib_s32 i, i0, j;
77
78    if (srcScan == width && dstScan == 4*width) {
79        width *= height;
80        height = 1;
81    }
82
83    for (j = 0; j < height; j++) {
84        mlib_u16 *src = srcBase;
85        mlib_s32 *dst = dstBase;
86
87        i = i0 = 0;
88
89        if ((mlib_s32)dst & 7) {
90            dst[i] = pixLut[src[i]];
91            i0 = 1;
92        }
93
94#pragma pipeloop(0)
95        for (i = i0; i <= (mlib_s32)width - 2; i += 2) {
96            *(mlib_d64*)(dst + i) = LOAD_2F32(pixLut, src[i], src[i + 1]);
97        }
98
99        for (; i < width; i++) {
100            dst[i] = pixLut[src[i]];
101        }
102
103        PTR_ADD(dstBase, dstScan);
104        PTR_ADD(srcBase, srcScan);
105    }
106}
107
108/***************************************************************/
109
110void ADD_SUFF(ByteIndexedToIntArgbScaleConvert)(SCALE_PARAMS)
111{
112    jint *pixLut = pSrcInfo->lutBase;
113    mlib_s32 dstScan = pDstInfo->scanStride;
114    mlib_s32 srcScan = pSrcInfo->scanStride;
115    mlib_s32 j;
116
117    for (j = 0; j < height; j++) {
118        mlib_u8  *src = srcBase;
119        mlib_s32 *dst = dstBase;
120        mlib_s32 *dst_end = dst + width;
121        mlib_s32 tmpsxloc = sxloc;
122
123        PTR_ADD(src, (syloc >> shift) * srcScan);
124
125        if ((mlib_s32)dst & 7) {
126            *dst++ = pixLut[src[tmpsxloc >> shift]];
127            tmpsxloc += sxinc;
128        }
129
130#pragma pipeloop(0)
131        for (; dst <= dst_end - 2; dst += 2) {
132            *(mlib_d64*)dst = LOAD_2F32(pixLut,
133                                        src[tmpsxloc >> shift],
134                                        src[(tmpsxloc + sxinc) >> shift]);
135            tmpsxloc += 2*sxinc;
136        }
137
138        for (; dst < dst_end; dst++) {
139            *dst = pixLut[src[tmpsxloc >> shift]];
140            tmpsxloc += sxinc;
141        }
142
143        PTR_ADD(dstBase, dstScan);
144        syloc += syinc;
145    }
146}
147
148/***************************************************************/
149
150void ADD_SUFF(ByteIndexedBmToIntArgbXparOver)(BLIT_PARAMS)
151{
152    jint *pixLut = pSrcInfo->lutBase;
153    mlib_s32 dstScan = pDstInfo->scanStride;
154    mlib_s32 srcScan = pSrcInfo->scanStride;
155    mlib_d64 dd, dzero;
156    mlib_s32 i, i0, j, x, mask;
157
158    if (srcScan == width && dstScan == 4*width) {
159        width *= height;
160        height = 1;
161    }
162
163    dzero = vis_fzero();
164
165    for (j = 0; j < height; j++) {
166        mlib_u8  *src = srcBase;
167        mlib_s32 *dst = dstBase;
168
169        i = i0 = 0;
170
171        if ((mlib_s32)dst & 7) {
172            x = pixLut[src[i]];
173            if (x < 0) {
174                dst[i] = x;
175            }
176            i0 = 1;
177        }
178
179#pragma pipeloop(0)
180        for (i = i0; i <= (mlib_s32)width - 2; i += 2) {
181            dd = LOAD_2F32(pixLut, src[i], src[i + 1]);
182            mask = vis_fcmplt32(dd, dzero);
183            vis_pst_32(dd, dst + i, mask);
184        }
185
186        for (; i < width; i++) {
187            x = pixLut[src[i]];
188            if (x < 0) {
189                dst[i] = x;
190            }
191        }
192
193        PTR_ADD(dstBase, dstScan);
194        PTR_ADD(srcBase, srcScan);
195    }
196}
197
198/***************************************************************/
199
200void ADD_SUFF(ByteIndexedBmToIntArgbScaleXparOver)(SCALE_PARAMS)
201{
202    jint *pixLut = pSrcInfo->lutBase;
203    mlib_s32 dstScan = pDstInfo->scanStride;
204    mlib_s32 srcScan = pSrcInfo->scanStride;
205    mlib_d64 dd, dzero;
206    mlib_s32 j, x, mask;
207
208    dzero = vis_fzero();
209
210    for (j = 0; j < height; j++) {
211        mlib_u8  *src = srcBase;
212        mlib_s32 *dst = dstBase;
213        mlib_s32 *dst_end = dst + width;
214        mlib_s32 tmpsxloc = sxloc;
215
216        PTR_ADD(src, (syloc >> shift) * srcScan);
217
218        if ((mlib_s32)dst & 7) {
219            x = pixLut[src[tmpsxloc >> shift]];
220            tmpsxloc += sxinc;
221            if (x < 0) {
222                *dst = x;
223            }
224            dst++;
225        }
226
227#pragma pipeloop(0)
228        for (; dst <= dst_end - 2; dst += 2) {
229            dd = LOAD_2F32(pixLut, src[tmpsxloc >> shift],
230                                   src[(tmpsxloc + sxinc) >> shift]);
231            tmpsxloc += 2*sxinc;
232            mask = vis_fcmplt32(dd, dzero);
233            vis_pst_32(dd, dst, mask);
234        }
235
236        for (; dst < dst_end; dst++) {
237            x = pixLut[src[tmpsxloc >> shift]];
238            tmpsxloc += sxinc;
239            if (x < 0) {
240                *dst = x;
241            }
242        }
243
244        PTR_ADD(dstBase, dstScan);
245        syloc += syinc;
246    }
247}
248
249/***************************************************************/
250
251void ADD_SUFF(IntArgbBmToIntArgbScaleXparOver)(SCALE_PARAMS)
252{
253    mlib_s32 dstScan = pDstInfo->scanStride;
254    mlib_s32 srcScan = pSrcInfo->scanStride;
255    mlib_d64 dd, maskAA;
256    mlib_s32 j, x, mask;
257
258    maskAA = vis_to_double_dup(0xff000000);
259
260    for (j = 0; j < height; j++) {
261        mlib_s32 *src = srcBase;
262        mlib_s32 *dst = dstBase;
263        mlib_s32 *dst_end = dst + width;
264        mlib_s32 tmpsxloc = sxloc;
265
266        PTR_ADD(src, (syloc >> shift) * srcScan);
267
268        if ((mlib_s32)dst & 7) {
269            x = src[tmpsxloc >> shift];
270            tmpsxloc += sxinc;
271            if (x & 0xff000000) {
272                *dst = x | 0xff000000;
273            }
274            dst++;
275        }
276
277#pragma pipeloop(0)
278        for (; dst <= dst_end - 2; dst += 2) {
279            mlib_f32 *pp0 = (mlib_f32*)src + (tmpsxloc >> shift);
280            mlib_f32 *pp1 = (mlib_f32*)src + ((tmpsxloc + sxinc) >> shift);
281            tmpsxloc += 2*sxinc;
282            dd = vis_freg_pair(*pp0, *pp1);
283            mask = (((-*(mlib_u8*)pp0) >> 31) & 2) |
284                   ((mlib_u32)(-*(mlib_u8*)pp1) >> 31);
285            dd = vis_for(dd, maskAA);
286            vis_pst_32(dd, dst, mask);
287        }
288
289        for (; dst < dst_end; dst++) {
290            x = src[tmpsxloc >> shift];
291            tmpsxloc += sxinc;
292            if (x & 0xff000000) {
293                *dst = x | 0xff000000;
294            }
295        }
296
297        PTR_ADD(dstBase, dstScan);
298        syloc += syinc;
299    }
300}
301
302/***************************************************************/
303
304void ADD_SUFF(ByteIndexedBmToIntArgbXparBgCopy)(BCOPY_PARAMS)
305{
306    jint *pixLut = pSrcInfo->lutBase;
307    mlib_s32 dstScan = pDstInfo->scanStride;
308    mlib_s32 srcScan = pSrcInfo->scanStride;
309    mlib_d64 dd, dzero, d_bgpixel;
310    mlib_s32 j, x, mask;
311
312    if (srcScan == width && dstScan == 4*width) {
313        width *= height;
314        height = 1;
315    }
316
317    dzero = vis_fzero();
318    d_bgpixel = vis_to_double_dup(bgpixel);
319
320    for (j = 0; j < height; j++) {
321        mlib_u8  *src = srcBase;
322        mlib_s32 *dst = dstBase;
323        mlib_s32 *dst_end;
324
325        dst_end = dst + width;
326
327        if ((mlib_s32)dst & 7) {
328            x = pixLut[*src++];
329            if (x < 0) {
330                *dst = x;
331            } else {
332                *dst = bgpixel;
333            }
334            dst++;
335        }
336
337#pragma pipeloop(0)
338        for (; dst <= (dst_end - 2); dst += 2) {
339            dd = LOAD_2F32(pixLut, src[0], src[1]);
340            mask = vis_fcmplt32(dd, dzero);
341            *(mlib_d64*)dst = d_bgpixel;
342            vis_pst_32(dd, dst, mask);
343            src += 2;
344        }
345
346        while (dst < dst_end) {
347            x = pixLut[*src++];
348            if (x < 0) {
349                *dst = x;
350            } else {
351                *dst = bgpixel;
352            }
353            dst++;
354        }
355
356        PTR_ADD(dstBase, dstScan);
357        PTR_ADD(srcBase, srcScan);
358    }
359}
360
361/***************************************************************/
362
363void ADD_SUFF(IntArgbDrawGlyphListAA)(GLYPH_LIST_PARAMS)
364{
365    mlib_s32 glyphCounter;
366    mlib_s32 scan = pRasInfo->scanStride;
367    mlib_u8  *dstBase;
368    mlib_s32 j;
369    mlib_d64 dmix0, dmix1, dd, d0, d1, e0, e1, fgpixel_d;
370    mlib_d64 done, done16, d_half;
371    mlib_s32 pix, mask;
372    mlib_f32 srcG_f;
373
374    done = vis_to_double_dup(0x7fff7fff);
375    done16 = vis_to_double_dup(0x7fff);
376    d_half = vis_to_double_dup((1 << (16 + 6)) | (1 << 6));
377
378    fgpixel_d = vis_to_double_dup(fgpixel);
379    srcG_f = vis_to_float(argbcolor);
380
381    vis_write_gsr(0 << 3);
382
383    for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
384        const jubyte *pixels;
385        unsigned int rowBytes;
386        int left, top;
387        int width, height;
388        int right, bottom;
389
390        pixels = (const jubyte *) glyphs[glyphCounter].pixels;
391
392        if (!pixels) continue;
393
394        left = glyphs[glyphCounter].x;
395        top = glyphs[glyphCounter].y;
396        width = glyphs[glyphCounter].width;
397        height = glyphs[glyphCounter].height;
398        rowBytes = width;
399        right = left + width;
400        bottom = top + height;
401        if (left < clipLeft) {
402            pixels += clipLeft - left;
403            left = clipLeft;
404        }
405        if (top < clipTop) {
406            pixels += (clipTop - top) * rowBytes;
407            top = clipTop;
408        }
409        if (right > clipRight) {
410            right = clipRight;
411        }
412        if (bottom > clipBottom) {
413            bottom = clipBottom;
414        }
415        if (right <= left || bottom <= top) {
416            continue;
417        }
418        width = right - left;
419        height = bottom - top;
420
421        dstBase = pRasInfo->rasBase;
422        PTR_ADD(dstBase, top*scan + 4*left);
423
424        for (j = 0; j < height; j++) {
425            mlib_u8  *src = (void*)pixels;
426            mlib_s32 *dst, *dst_end;
427
428            dst = (void*)dstBase;
429            dst_end = dst + width;
430
431            /* Clearing the Graphics Status Register is necessary otherwise
432             * left over scale settings affect the pack instructions.
433             */
434            vis_write_gsr(0 << 3);
435
436            if ((mlib_s32)dst & 7) {
437                pix = *src++;
438                dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half);
439                dd = vis_fpadd16(MUL8_VIS(*(mlib_f32*)dst, 255 - pix), dd);
440                *(mlib_f32*)dst = vis_fpack16(dd);
441                if (pix == 255) *(mlib_f32*)dst = vis_read_hi(fgpixel_d);
442                dst++;
443            }
444
445#pragma pipeloop(0)
446            for (; dst <= (dst_end - 2); dst += 2) {
447                dmix0 = vis_freg_pair(((mlib_f32 *)vis_mul8s_tbl)[src[0]],
448                                      ((mlib_f32 *)vis_mul8s_tbl)[src[1]]);
449                mask = vis_fcmplt32(dmix0, done16);
450                dmix1 = vis_fpsub16(done, dmix0);
451                src += 2;
452
453                dd = *(mlib_d64*)dst;
454                d0 = vis_fmul8x16al(srcG_f, vis_read_hi(dmix0));
455                d1 = vis_fmul8x16al(srcG_f, vis_read_lo(dmix0));
456                e0 = vis_fmul8x16al(vis_read_hi(dd), vis_read_hi(dmix1));
457                e1 = vis_fmul8x16al(vis_read_lo(dd), vis_read_lo(dmix1));
458                d0 = vis_fpadd16(vis_fpadd16(d0, d_half), e0);
459                d1 = vis_fpadd16(vis_fpadd16(d1, d_half), e1);
460                dd = vis_fpack16_pair(d0, d1);
461
462                *(mlib_d64*)dst = fgpixel_d;
463                vis_pst_32(dd, dst, mask);
464            }
465
466            while (dst < dst_end) {
467                pix = *src++;
468                dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half);
469                dd = vis_fpadd16(MUL8_VIS(*(mlib_f32*)dst, 255 - pix), dd);
470                *(mlib_f32*)dst = vis_fpack16(dd);
471                if (pix == 255) *(mlib_f32*)dst = vis_read_hi(fgpixel_d);
472                dst++;
473            }
474
475            ADD_SUFF(IntArgbPreToIntArgbConvert)(dstBase, dstBase, width, 1,
476                                                 pRasInfo, pRasInfo,
477                                                 pPrim, pCompInfo);
478            PTR_ADD(dstBase, scan);
479            pixels += rowBytes;
480        }
481    }
482}
483
484/***************************************************************/
485
486#endif /* JAVA2D_NO_MLIB */
487