Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libawt/java2d/pipe/BufferedMaskBlit.c
41159 views
1
/*
2
* Copyright (c) 2007, 2010, 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
#include <jni.h>
27
#include <jlong.h>
28
#include <jni_util.h>
29
#include "sun_java2d_pipe_BufferedMaskBlit.h"
30
#include "sun_java2d_pipe_BufferedOpCodes.h"
31
#include "Trace.h"
32
#include "GraphicsPrimitiveMgr.h"
33
#include "IntArgb.h"
34
#include "IntRgb.h"
35
#include "IntBgr.h"
36
37
#define MAX_MASK_LENGTH (32 * 32)
38
extern unsigned char mul8table[256][256];
39
40
/**
41
* This implementation of MaskBlit first combines the source system memory
42
* tile with the corresponding alpha mask and stores the resulting
43
* IntArgbPre pixels directly into the RenderBuffer. Those pixels are
44
* then eventually pulled off the RenderBuffer and copied to the destination
45
* surface in OGL/D3DMaskBlit.
46
*
47
* Note that currently there are only inner loops defined for IntArgb,
48
* IntArgbPre, IntRgb, and IntBgr, as those are the most commonly used
49
* formats for this operation.
50
*/
51
JNIEXPORT jint JNICALL
52
Java_sun_java2d_pipe_BufferedMaskBlit_enqueueTile
53
(JNIEnv *env, jobject mb,
54
jlong buf, jint bpos,
55
jobject srcData, jlong pSrcOps, jint srcType,
56
jbyteArray maskArray, jint masklen, jint maskoff, jint maskscan,
57
jint srcx, jint srcy, jint dstx, jint dsty,
58
jint width, jint height)
59
{
60
SurfaceDataOps *srcOps = (SurfaceDataOps *)jlong_to_ptr(pSrcOps);
61
SurfaceDataRasInfo srcInfo;
62
unsigned char *bbuf;
63
jint *pBuf;
64
65
J2dTraceLn1(J2D_TRACE_INFO,
66
"BufferedMaskBlit_enqueueTile: bpos=%d",
67
bpos);
68
69
if (srcOps == NULL) {
70
J2dRlsTraceLn(J2D_TRACE_ERROR,
71
"BufferedMaskBlit_enqueueTile: srcOps is null");
72
return bpos;
73
}
74
75
bbuf = (unsigned char *)jlong_to_ptr(buf);
76
if (bbuf == NULL) {
77
J2dRlsTraceLn(J2D_TRACE_ERROR,
78
"BufferedMaskBlit_enqueueTile: cannot get direct buffer address");
79
return bpos;
80
}
81
pBuf = (jint *)(bbuf + bpos);
82
83
if (JNU_IsNull(env, maskArray)) {
84
J2dRlsTraceLn(J2D_TRACE_ERROR,
85
"BufferedMaskBlit_enqueueTile: mask array is null");
86
return bpos;
87
}
88
89
if (masklen > MAX_MASK_LENGTH) {
90
// REMIND: this approach is seriously flawed if the mask
91
// length is ever greater than MAX_MASK_LENGTH (won't fit
92
// into the cached mask tile); so far this hasn't
93
// been a problem though...
94
J2dRlsTraceLn(J2D_TRACE_ERROR,
95
"BufferedMaskBlit_enqueueTile: mask array too large");
96
return bpos;
97
}
98
99
srcInfo.bounds.x1 = srcx;
100
srcInfo.bounds.y1 = srcy;
101
srcInfo.bounds.x2 = srcx + width;
102
srcInfo.bounds.y2 = srcy + height;
103
104
if (srcOps->Lock(env, srcOps, &srcInfo, SD_LOCK_READ) != SD_SUCCESS) {
105
J2dRlsTraceLn(J2D_TRACE_WARNING,
106
"BufferedMaskBlit_enqueueTile: could not acquire lock");
107
return bpos;
108
}
109
110
if (srcInfo.bounds.x2 > srcInfo.bounds.x1 &&
111
srcInfo.bounds.y2 > srcInfo.bounds.y1)
112
{
113
srcOps->GetRasInfo(env, srcOps, &srcInfo);
114
if (srcInfo.rasBase) {
115
jint h;
116
jint srcScanStride = srcInfo.scanStride;
117
jint srcPixelStride = srcInfo.pixelStride;
118
jint *pSrc = (jint *)
119
PtrCoord(srcInfo.rasBase,
120
srcInfo.bounds.x1, srcInfo.pixelStride,
121
srcInfo.bounds.y1, srcInfo.scanStride);
122
unsigned char *pMask, *pMaskAlloc;
123
pMask = pMaskAlloc =
124
(*env)->GetPrimitiveArrayCritical(env, maskArray, 0);
125
if (pMask == NULL) {
126
J2dRlsTraceLn(J2D_TRACE_ERROR,
127
"BufferedMaskBlit_enqueueTile: cannot lock mask array");
128
SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
129
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
130
return bpos;
131
}
132
133
width = srcInfo.bounds.x2 - srcInfo.bounds.x1;
134
height = srcInfo.bounds.y2 - srcInfo.bounds.y1;
135
maskoff += ((srcInfo.bounds.y1 - srcy) * maskscan +
136
(srcInfo.bounds.x1 - srcx));
137
maskscan -= width;
138
pMask += maskoff;
139
srcScanStride -= width * srcPixelStride;
140
h = height;
141
142
J2dTraceLn4(J2D_TRACE_VERBOSE,
143
" sx=%d sy=%d w=%d h=%d",
144
srcInfo.bounds.x1, srcInfo.bounds.y1, width, height);
145
J2dTraceLn2(J2D_TRACE_VERBOSE,
146
" maskoff=%d maskscan=%d",
147
maskoff, maskscan);
148
J2dTraceLn2(J2D_TRACE_VERBOSE,
149
" pixstride=%d scanstride=%d",
150
srcPixelStride, srcScanStride);
151
152
// enqueue parameters
153
pBuf[0] = sun_java2d_pipe_BufferedOpCodes_MASK_BLIT;
154
pBuf[1] = dstx;
155
pBuf[2] = dsty;
156
pBuf[3] = width;
157
pBuf[4] = height;
158
pBuf += 5;
159
bpos += 5 * sizeof(jint);
160
161
// apply alpha values from mask to the source tile, and store
162
// resulting IntArgbPre pixels into RenderBuffer (there are
163
// separate inner loops for the most common source formats)
164
switch (srcType) {
165
case sun_java2d_pipe_BufferedMaskBlit_ST_INT_ARGB:
166
do {
167
jint w = width;
168
do {
169
jint pathA = *pMask++;
170
if (!pathA) {
171
pBuf[0] = 0;
172
} else {
173
jint pixel = pSrc[0];
174
if (pathA == 0xff && (pixel >> 24) + 1 == 0) {
175
pBuf[0] = pixel;
176
} else {
177
jint r, g, b, a;
178
ExtractIntDcmComponents1234(pixel, a, r, g, b);
179
a = MUL8(pathA, a);
180
r = MUL8(a, r);
181
g = MUL8(a, g);
182
b = MUL8(a, b);
183
pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
184
}
185
}
186
pSrc = PtrAddBytes(pSrc, srcPixelStride);
187
pBuf++;
188
} while (--w > 0);
189
pSrc = PtrAddBytes(pSrc, srcScanStride);
190
pMask = PtrAddBytes(pMask, maskscan);
191
} while (--h > 0);
192
break;
193
194
case sun_java2d_pipe_BufferedMaskBlit_ST_INT_ARGB_PRE:
195
do {
196
jint w = width;
197
do {
198
jint pathA = *pMask++;
199
if (!pathA) {
200
pBuf[0] = 0;
201
} else if (pathA == 0xff) {
202
pBuf[0] = pSrc[0];
203
} else {
204
jint r, g, b, a;
205
a = MUL8(pathA, (pSrc[0] >> 24) & 0xff);
206
r = MUL8(pathA, (pSrc[0] >> 16) & 0xff);
207
g = MUL8(pathA, (pSrc[0] >> 8) & 0xff);
208
b = MUL8(pathA, (pSrc[0] >> 0) & 0xff);
209
pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
210
}
211
pSrc = PtrAddBytes(pSrc, srcPixelStride);
212
pBuf++;
213
} while (--w > 0);
214
pSrc = PtrAddBytes(pSrc, srcScanStride);
215
pMask = PtrAddBytes(pMask, maskscan);
216
} while (--h > 0);
217
break;
218
219
case sun_java2d_pipe_BufferedMaskBlit_ST_INT_RGB:
220
do {
221
jint w = width;
222
do {
223
jint pathA = *pMask++;
224
if (!pathA) {
225
pBuf[0] = 0;
226
} else if (pathA == 0xff) {
227
pBuf[0] = pSrc[0] | 0xff000000;
228
} else {
229
jint r, g, b, a;
230
LoadIntRgbTo3ByteRgb(pSrc, c, 0, r, g, b);
231
a = pathA;
232
r = MUL8(a, r);
233
g = MUL8(a, g);
234
b = MUL8(a, b);
235
pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
236
}
237
pSrc = PtrAddBytes(pSrc, srcPixelStride);
238
pBuf++;
239
} while (--w > 0);
240
pSrc = PtrAddBytes(pSrc, srcScanStride);
241
pMask = PtrAddBytes(pMask, maskscan);
242
} while (--h > 0);
243
break;
244
245
case sun_java2d_pipe_BufferedMaskBlit_ST_INT_BGR:
246
do {
247
jint w = width;
248
do {
249
jint pathA = *pMask++;
250
if (!pathA) {
251
pBuf[0] = 0;
252
} else {
253
jint r, g, b, a;
254
LoadIntBgrTo3ByteRgb(pSrc, c, 0, r, g, b);
255
a = pathA;
256
r = MUL8(a, r);
257
g = MUL8(a, g);
258
b = MUL8(a, b);
259
pBuf[0] = (a << 24) | (r << 16) | (g << 8) | b;
260
}
261
pSrc = PtrAddBytes(pSrc, srcPixelStride);
262
pBuf++;
263
} while (--w > 0);
264
pSrc = PtrAddBytes(pSrc, srcScanStride);
265
pMask = PtrAddBytes(pMask, maskscan);
266
} while (--h > 0);
267
break;
268
269
default:
270
// should not get here, just no-op...
271
break;
272
}
273
274
// increment current byte position
275
bpos += width * height * sizeof(jint);
276
277
(*env)->ReleasePrimitiveArrayCritical(env, maskArray,
278
pMaskAlloc, JNI_ABORT);
279
}
280
SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
281
}
282
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
283
284
// return the current byte position
285
return bpos;
286
}
287
288