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 
ADD_SUFF(ByteIndexedToIntArgbConvert)32 void 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 
ADD_SUFF(Index12GrayToIntArgbConvert)71 void 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 
ADD_SUFF(ByteIndexedToIntArgbScaleConvert)110 void 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 
ADD_SUFF(ByteIndexedBmToIntArgbXparOver)150 void 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 
ADD_SUFF(ByteIndexedBmToIntArgbScaleXparOver)200 void 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 
ADD_SUFF(IntArgbBmToIntArgbScaleXparOver)251 void 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 
ADD_SUFF(ByteIndexedBmToIntArgbXparBgCopy)304 void 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 
ADD_SUFF(IntArgbDrawGlyphListAA)363 void 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