|
1 /* |
|
2 * Copyright (c) 2005, 2012, 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 #ifndef HEADLESS |
|
27 |
|
28 #include <stdlib.h> |
|
29 |
|
30 #include "sun_java2d_pipe_BufferedOpCodes.h" |
|
31 |
|
32 #include "jlong.h" |
|
33 #include "OGLBlitLoops.h" |
|
34 #include "OGLBufImgOps.h" |
|
35 #include "OGLContext.h" |
|
36 #include "OGLMaskBlit.h" |
|
37 #include "OGLMaskFill.h" |
|
38 #include "OGLPaints.h" |
|
39 #include "OGLRenderQueue.h" |
|
40 #include "OGLRenderer.h" |
|
41 #include "OGLSurfaceData.h" |
|
42 #include "OGLTextRenderer.h" |
|
43 #include "OGLVertexCache.h" |
|
44 |
|
45 /** |
|
46 * Used to track whether we are in a series of a simple primitive operations |
|
47 * or texturing operations. This variable should be controlled only via |
|
48 * the INIT/CHECK/RESET_PREVIOUS_OP() macros. See the |
|
49 * OGLRenderQueue_CheckPreviousOp() method below for more information. |
|
50 */ |
|
51 jint previousOp; |
|
52 |
|
53 /** |
|
54 * References to the "current" context and destination surface. |
|
55 */ |
|
56 static OGLContext *oglc = NULL; |
|
57 static OGLSDOps *dstOps = NULL; |
|
58 |
|
59 /** |
|
60 * The following methods are implemented in the windowing system (i.e. GLX |
|
61 * and WGL) source files. |
|
62 */ |
|
63 extern OGLContext *OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo); |
|
64 extern void OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo); |
|
65 extern void OGLSD_SwapBuffers(JNIEnv *env, jlong window); |
|
66 extern void OGLSD_Flush(JNIEnv *env); |
|
67 |
|
68 JNIEXPORT void JNICALL |
|
69 Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer |
|
70 (JNIEnv *env, jobject oglrq, |
|
71 jlong buf, jint limit) |
|
72 { |
|
73 jboolean sync = JNI_FALSE; |
|
74 unsigned char *b, *end; |
|
75 |
|
76 J2dTraceLn1(J2D_TRACE_INFO, |
|
77 "OGLRenderQueue_flushBuffer: limit=%d", limit); |
|
78 |
|
79 b = (unsigned char *)jlong_to_ptr(buf); |
|
80 if (b == NULL) { |
|
81 J2dRlsTraceLn(J2D_TRACE_ERROR, |
|
82 "OGLRenderQueue_flushBuffer: cannot get direct buffer address"); |
|
83 return; |
|
84 } |
|
85 |
|
86 INIT_PREVIOUS_OP(); |
|
87 end = b + limit; |
|
88 |
|
89 while (b < end) { |
|
90 jint opcode = NEXT_INT(b); |
|
91 |
|
92 J2dTraceLn2(J2D_TRACE_VERBOSE, |
|
93 "OGLRenderQueue_flushBuffer: opcode=%d, rem=%d", |
|
94 opcode, (end-b)); |
|
95 |
|
96 switch (opcode) { |
|
97 |
|
98 // draw ops |
|
99 case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE: |
|
100 { |
|
101 jint x1 = NEXT_INT(b); |
|
102 jint y1 = NEXT_INT(b); |
|
103 jint x2 = NEXT_INT(b); |
|
104 jint y2 = NEXT_INT(b); |
|
105 OGLRenderer_DrawLine(oglc, x1, y1, x2, y2); |
|
106 } |
|
107 break; |
|
108 case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT: |
|
109 { |
|
110 jint x = NEXT_INT(b); |
|
111 jint y = NEXT_INT(b); |
|
112 jint w = NEXT_INT(b); |
|
113 jint h = NEXT_INT(b); |
|
114 OGLRenderer_DrawRect(oglc, x, y, w, h); |
|
115 } |
|
116 break; |
|
117 case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY: |
|
118 { |
|
119 jint nPoints = NEXT_INT(b); |
|
120 jboolean isClosed = NEXT_BOOLEAN(b); |
|
121 jint transX = NEXT_INT(b); |
|
122 jint transY = NEXT_INT(b); |
|
123 jint *xPoints = (jint *)b; |
|
124 jint *yPoints = ((jint *)b) + nPoints; |
|
125 OGLRenderer_DrawPoly(oglc, nPoints, isClosed, |
|
126 transX, transY, |
|
127 xPoints, yPoints); |
|
128 SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT); |
|
129 } |
|
130 break; |
|
131 case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL: |
|
132 { |
|
133 jint x = NEXT_INT(b); |
|
134 jint y = NEXT_INT(b); |
|
135 // Note that we could use GL_POINTS here, but the common |
|
136 // use case for DRAW_PIXEL is when rendering a Path2D, |
|
137 // which will consist of a mix of DRAW_PIXEL and DRAW_LINE |
|
138 // calls. So to improve batching we use GL_LINES here, |
|
139 // even though it requires an extra vertex per pixel. |
|
140 CONTINUE_IF_NULL(oglc); |
|
141 CHECK_PREVIOUS_OP(GL_LINES); |
|
142 j2d_glVertex2i(x, y); |
|
143 j2d_glVertex2i(x+1, y+1); |
|
144 } |
|
145 break; |
|
146 case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES: |
|
147 { |
|
148 jint count = NEXT_INT(b); |
|
149 OGLRenderer_DrawScanlines(oglc, count, (jint *)b); |
|
150 SKIP_BYTES(b, count * BYTES_PER_SCANLINE); |
|
151 } |
|
152 break; |
|
153 case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM: |
|
154 { |
|
155 jfloat x11 = NEXT_FLOAT(b); |
|
156 jfloat y11 = NEXT_FLOAT(b); |
|
157 jfloat dx21 = NEXT_FLOAT(b); |
|
158 jfloat dy21 = NEXT_FLOAT(b); |
|
159 jfloat dx12 = NEXT_FLOAT(b); |
|
160 jfloat dy12 = NEXT_FLOAT(b); |
|
161 jfloat lwr21 = NEXT_FLOAT(b); |
|
162 jfloat lwr12 = NEXT_FLOAT(b); |
|
163 OGLRenderer_DrawParallelogram(oglc, |
|
164 x11, y11, |
|
165 dx21, dy21, |
|
166 dx12, dy12, |
|
167 lwr21, lwr12); |
|
168 } |
|
169 break; |
|
170 case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM: |
|
171 { |
|
172 jfloat x11 = NEXT_FLOAT(b); |
|
173 jfloat y11 = NEXT_FLOAT(b); |
|
174 jfloat dx21 = NEXT_FLOAT(b); |
|
175 jfloat dy21 = NEXT_FLOAT(b); |
|
176 jfloat dx12 = NEXT_FLOAT(b); |
|
177 jfloat dy12 = NEXT_FLOAT(b); |
|
178 jfloat lwr21 = NEXT_FLOAT(b); |
|
179 jfloat lwr12 = NEXT_FLOAT(b); |
|
180 OGLRenderer_DrawAAParallelogram(oglc, dstOps, |
|
181 x11, y11, |
|
182 dx21, dy21, |
|
183 dx12, dy12, |
|
184 lwr21, lwr12); |
|
185 } |
|
186 break; |
|
187 |
|
188 // fill ops |
|
189 case sun_java2d_pipe_BufferedOpCodes_FILL_RECT: |
|
190 { |
|
191 jint x = NEXT_INT(b); |
|
192 jint y = NEXT_INT(b); |
|
193 jint w = NEXT_INT(b); |
|
194 jint h = NEXT_INT(b); |
|
195 OGLRenderer_FillRect(oglc, x, y, w, h); |
|
196 } |
|
197 break; |
|
198 case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS: |
|
199 { |
|
200 jint count = NEXT_INT(b); |
|
201 OGLRenderer_FillSpans(oglc, count, (jint *)b); |
|
202 SKIP_BYTES(b, count * BYTES_PER_SPAN); |
|
203 } |
|
204 break; |
|
205 case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM: |
|
206 { |
|
207 jfloat x11 = NEXT_FLOAT(b); |
|
208 jfloat y11 = NEXT_FLOAT(b); |
|
209 jfloat dx21 = NEXT_FLOAT(b); |
|
210 jfloat dy21 = NEXT_FLOAT(b); |
|
211 jfloat dx12 = NEXT_FLOAT(b); |
|
212 jfloat dy12 = NEXT_FLOAT(b); |
|
213 OGLRenderer_FillParallelogram(oglc, |
|
214 x11, y11, |
|
215 dx21, dy21, |
|
216 dx12, dy12); |
|
217 } |
|
218 break; |
|
219 case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM: |
|
220 { |
|
221 jfloat x11 = NEXT_FLOAT(b); |
|
222 jfloat y11 = NEXT_FLOAT(b); |
|
223 jfloat dx21 = NEXT_FLOAT(b); |
|
224 jfloat dy21 = NEXT_FLOAT(b); |
|
225 jfloat dx12 = NEXT_FLOAT(b); |
|
226 jfloat dy12 = NEXT_FLOAT(b); |
|
227 OGLRenderer_FillAAParallelogram(oglc, dstOps, |
|
228 x11, y11, |
|
229 dx21, dy21, |
|
230 dx12, dy12); |
|
231 } |
|
232 break; |
|
233 |
|
234 // text-related ops |
|
235 case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST: |
|
236 { |
|
237 jint numGlyphs = NEXT_INT(b); |
|
238 jint packedParams = NEXT_INT(b); |
|
239 jfloat glyphListOrigX = NEXT_FLOAT(b); |
|
240 jfloat glyphListOrigY = NEXT_FLOAT(b); |
|
241 jboolean usePositions = EXTRACT_BOOLEAN(packedParams, |
|
242 OFFSET_POSITIONS); |
|
243 jboolean subPixPos = EXTRACT_BOOLEAN(packedParams, |
|
244 OFFSET_SUBPIXPOS); |
|
245 jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams, |
|
246 OFFSET_RGBORDER); |
|
247 jint lcdContrast = EXTRACT_BYTE(packedParams, |
|
248 OFFSET_CONTRAST); |
|
249 unsigned char *images = b; |
|
250 unsigned char *positions; |
|
251 jint bytesPerGlyph; |
|
252 if (usePositions) { |
|
253 positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE); |
|
254 bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH; |
|
255 } else { |
|
256 positions = NULL; |
|
257 bytesPerGlyph = BYTES_PER_GLYPH_IMAGE; |
|
258 } |
|
259 OGLTR_DrawGlyphList(env, oglc, dstOps, |
|
260 numGlyphs, usePositions, |
|
261 subPixPos, rgbOrder, lcdContrast, |
|
262 glyphListOrigX, glyphListOrigY, |
|
263 images, positions); |
|
264 SKIP_BYTES(b, numGlyphs * bytesPerGlyph); |
|
265 } |
|
266 break; |
|
267 |
|
268 // copy-related ops |
|
269 case sun_java2d_pipe_BufferedOpCodes_COPY_AREA: |
|
270 { |
|
271 jint x = NEXT_INT(b); |
|
272 jint y = NEXT_INT(b); |
|
273 jint w = NEXT_INT(b); |
|
274 jint h = NEXT_INT(b); |
|
275 jint dx = NEXT_INT(b); |
|
276 jint dy = NEXT_INT(b); |
|
277 OGLBlitLoops_CopyArea(env, oglc, dstOps, |
|
278 x, y, w, h, dx, dy); |
|
279 } |
|
280 break; |
|
281 case sun_java2d_pipe_BufferedOpCodes_BLIT: |
|
282 { |
|
283 jint packedParams = NEXT_INT(b); |
|
284 jint sx1 = NEXT_INT(b); |
|
285 jint sy1 = NEXT_INT(b); |
|
286 jint sx2 = NEXT_INT(b); |
|
287 jint sy2 = NEXT_INT(b); |
|
288 jdouble dx1 = NEXT_DOUBLE(b); |
|
289 jdouble dy1 = NEXT_DOUBLE(b); |
|
290 jdouble dx2 = NEXT_DOUBLE(b); |
|
291 jdouble dy2 = NEXT_DOUBLE(b); |
|
292 jlong pSrc = NEXT_LONG(b); |
|
293 jlong pDst = NEXT_LONG(b); |
|
294 jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT); |
|
295 jboolean texture = EXTRACT_BOOLEAN(packedParams, |
|
296 OFFSET_TEXTURE); |
|
297 jboolean rtt = EXTRACT_BOOLEAN(packedParams, |
|
298 OFFSET_RTT); |
|
299 jboolean xform = EXTRACT_BOOLEAN(packedParams, |
|
300 OFFSET_XFORM); |
|
301 jboolean isoblit = EXTRACT_BOOLEAN(packedParams, |
|
302 OFFSET_ISOBLIT); |
|
303 if (isoblit) { |
|
304 OGLBlitLoops_IsoBlit(env, oglc, pSrc, pDst, |
|
305 xform, hint, texture, rtt, |
|
306 sx1, sy1, sx2, sy2, |
|
307 dx1, dy1, dx2, dy2); |
|
308 } else { |
|
309 jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE); |
|
310 OGLBlitLoops_Blit(env, oglc, pSrc, pDst, |
|
311 xform, hint, srctype, texture, |
|
312 sx1, sy1, sx2, sy2, |
|
313 dx1, dy1, dx2, dy2); |
|
314 } |
|
315 } |
|
316 break; |
|
317 case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT: |
|
318 { |
|
319 jint sx = NEXT_INT(b); |
|
320 jint sy = NEXT_INT(b); |
|
321 jint dx = NEXT_INT(b); |
|
322 jint dy = NEXT_INT(b); |
|
323 jint w = NEXT_INT(b); |
|
324 jint h = NEXT_INT(b); |
|
325 jint dsttype = NEXT_INT(b); |
|
326 jlong pSrc = NEXT_LONG(b); |
|
327 jlong pDst = NEXT_LONG(b); |
|
328 OGLBlitLoops_SurfaceToSwBlit(env, oglc, |
|
329 pSrc, pDst, dsttype, |
|
330 sx, sy, dx, dy, w, h); |
|
331 } |
|
332 break; |
|
333 case sun_java2d_pipe_BufferedOpCodes_MASK_FILL: |
|
334 { |
|
335 jint x = NEXT_INT(b); |
|
336 jint y = NEXT_INT(b); |
|
337 jint w = NEXT_INT(b); |
|
338 jint h = NEXT_INT(b); |
|
339 jint maskoff = NEXT_INT(b); |
|
340 jint maskscan = NEXT_INT(b); |
|
341 jint masklen = NEXT_INT(b); |
|
342 unsigned char *pMask = (masklen > 0) ? b : NULL; |
|
343 OGLMaskFill_MaskFill(oglc, x, y, w, h, |
|
344 maskoff, maskscan, masklen, pMask); |
|
345 SKIP_BYTES(b, masklen); |
|
346 } |
|
347 break; |
|
348 case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT: |
|
349 { |
|
350 jint dstx = NEXT_INT(b); |
|
351 jint dsty = NEXT_INT(b); |
|
352 jint width = NEXT_INT(b); |
|
353 jint height = NEXT_INT(b); |
|
354 jint masklen = width * height * sizeof(jint); |
|
355 OGLMaskBlit_MaskBlit(env, oglc, |
|
356 dstx, dsty, width, height, b); |
|
357 SKIP_BYTES(b, masklen); |
|
358 } |
|
359 break; |
|
360 |
|
361 // state-related ops |
|
362 case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP: |
|
363 { |
|
364 jint x1 = NEXT_INT(b); |
|
365 jint y1 = NEXT_INT(b); |
|
366 jint x2 = NEXT_INT(b); |
|
367 jint y2 = NEXT_INT(b); |
|
368 OGLContext_SetRectClip(oglc, dstOps, x1, y1, x2, y2); |
|
369 } |
|
370 break; |
|
371 case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP: |
|
372 { |
|
373 OGLContext_BeginShapeClip(oglc); |
|
374 } |
|
375 break; |
|
376 case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS: |
|
377 { |
|
378 jint count = NEXT_INT(b); |
|
379 OGLRenderer_FillSpans(oglc, count, (jint *)b); |
|
380 SKIP_BYTES(b, count * BYTES_PER_SPAN); |
|
381 } |
|
382 break; |
|
383 case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP: |
|
384 { |
|
385 OGLContext_EndShapeClip(oglc, dstOps); |
|
386 } |
|
387 break; |
|
388 case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP: |
|
389 { |
|
390 OGLContext_ResetClip(oglc); |
|
391 } |
|
392 break; |
|
393 case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE: |
|
394 { |
|
395 jint rule = NEXT_INT(b); |
|
396 jfloat extraAlpha = NEXT_FLOAT(b); |
|
397 jint flags = NEXT_INT(b); |
|
398 OGLContext_SetAlphaComposite(oglc, rule, extraAlpha, flags); |
|
399 } |
|
400 break; |
|
401 case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE: |
|
402 { |
|
403 jint xorPixel = NEXT_INT(b); |
|
404 OGLContext_SetXorComposite(oglc, xorPixel); |
|
405 } |
|
406 break; |
|
407 case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE: |
|
408 { |
|
409 OGLContext_ResetComposite(oglc); |
|
410 } |
|
411 break; |
|
412 case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM: |
|
413 { |
|
414 jdouble m00 = NEXT_DOUBLE(b); |
|
415 jdouble m10 = NEXT_DOUBLE(b); |
|
416 jdouble m01 = NEXT_DOUBLE(b); |
|
417 jdouble m11 = NEXT_DOUBLE(b); |
|
418 jdouble m02 = NEXT_DOUBLE(b); |
|
419 jdouble m12 = NEXT_DOUBLE(b); |
|
420 OGLContext_SetTransform(oglc, m00, m10, m01, m11, m02, m12); |
|
421 } |
|
422 break; |
|
423 case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM: |
|
424 { |
|
425 OGLContext_ResetTransform(oglc); |
|
426 } |
|
427 break; |
|
428 |
|
429 // context-related ops |
|
430 case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES: |
|
431 { |
|
432 jlong pSrc = NEXT_LONG(b); |
|
433 jlong pDst = NEXT_LONG(b); |
|
434 if (oglc != NULL) { |
|
435 RESET_PREVIOUS_OP(); |
|
436 } |
|
437 oglc = OGLContext_SetSurfaces(env, pSrc, pDst); |
|
438 dstOps = (OGLSDOps *)jlong_to_ptr(pDst); |
|
439 } |
|
440 break; |
|
441 case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE: |
|
442 { |
|
443 jlong pConfigInfo = NEXT_LONG(b); |
|
444 if (oglc != NULL) { |
|
445 RESET_PREVIOUS_OP(); |
|
446 } |
|
447 oglc = OGLSD_SetScratchSurface(env, pConfigInfo); |
|
448 dstOps = NULL; |
|
449 } |
|
450 break; |
|
451 case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE: |
|
452 { |
|
453 jlong pData = NEXT_LONG(b); |
|
454 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); |
|
455 if (oglsdo != NULL) { |
|
456 CONTINUE_IF_NULL(oglc); |
|
457 RESET_PREVIOUS_OP(); |
|
458 OGLSD_Delete(env, oglsdo); |
|
459 } |
|
460 } |
|
461 break; |
|
462 case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE: |
|
463 { |
|
464 jlong pData = NEXT_LONG(b); |
|
465 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); |
|
466 if (oglsdo != NULL) { |
|
467 CONTINUE_IF_NULL(oglc); |
|
468 RESET_PREVIOUS_OP(); |
|
469 OGLSD_Delete(env, oglsdo); |
|
470 if (oglsdo->privOps != NULL) { |
|
471 free(oglsdo->privOps); |
|
472 } |
|
473 } |
|
474 } |
|
475 break; |
|
476 case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG: |
|
477 { |
|
478 jlong pConfigInfo = NEXT_LONG(b); |
|
479 CONTINUE_IF_NULL(oglc); |
|
480 RESET_PREVIOUS_OP(); |
|
481 OGLGC_DestroyOGLGraphicsConfig(pConfigInfo); |
|
482 |
|
483 // the previous method will call glX/wglMakeCurrent(None), |
|
484 // so we should nullify the current oglc and dstOps to avoid |
|
485 // calling glFlush() (or similar) while no context is current |
|
486 oglc = NULL; |
|
487 dstOps = NULL; |
|
488 } |
|
489 break; |
|
490 case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT: |
|
491 { |
|
492 // flush just in case there are any pending operations in |
|
493 // the hardware pipe |
|
494 if (oglc != NULL) { |
|
495 RESET_PREVIOUS_OP(); |
|
496 j2d_glFlush(); |
|
497 } |
|
498 |
|
499 // invalidate the references to the current context and |
|
500 // destination surface that are maintained at the native level |
|
501 oglc = NULL; |
|
502 dstOps = NULL; |
|
503 } |
|
504 break; |
|
505 case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE: |
|
506 { |
|
507 j2d_glPushAttrib(GL_ALL_ATTRIB_BITS); |
|
508 j2d_glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); |
|
509 j2d_glMatrixMode(GL_MODELVIEW); |
|
510 j2d_glPushMatrix(); |
|
511 j2d_glMatrixMode(GL_PROJECTION); |
|
512 j2d_glPushMatrix(); |
|
513 j2d_glMatrixMode(GL_TEXTURE); |
|
514 j2d_glPushMatrix(); |
|
515 } |
|
516 break; |
|
517 |
|
518 case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE: |
|
519 { |
|
520 j2d_glPopAttrib(); |
|
521 j2d_glPopClientAttrib(); |
|
522 j2d_glMatrixMode(GL_MODELVIEW); |
|
523 j2d_glPopMatrix(); |
|
524 j2d_glMatrixMode(GL_PROJECTION); |
|
525 j2d_glPopMatrix(); |
|
526 j2d_glMatrixMode(GL_TEXTURE); |
|
527 j2d_glPopMatrix(); |
|
528 } |
|
529 break; |
|
530 case sun_java2d_pipe_BufferedOpCodes_SYNC: |
|
531 { |
|
532 sync = JNI_TRUE; |
|
533 } |
|
534 break; |
|
535 |
|
536 // multibuffering ops |
|
537 case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS: |
|
538 { |
|
539 jlong window = NEXT_LONG(b); |
|
540 if (oglc != NULL) { |
|
541 RESET_PREVIOUS_OP(); |
|
542 } |
|
543 OGLSD_SwapBuffers(env, window); |
|
544 } |
|
545 break; |
|
546 |
|
547 // special no-op (mainly used for achieving 8-byte alignment) |
|
548 case sun_java2d_pipe_BufferedOpCodes_NOOP: |
|
549 break; |
|
550 |
|
551 // paint-related ops |
|
552 case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT: |
|
553 { |
|
554 OGLPaints_ResetPaint(oglc); |
|
555 } |
|
556 break; |
|
557 case sun_java2d_pipe_BufferedOpCodes_SET_COLOR: |
|
558 { |
|
559 jint pixel = NEXT_INT(b); |
|
560 OGLPaints_SetColor(oglc, pixel); |
|
561 } |
|
562 break; |
|
563 case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT: |
|
564 { |
|
565 jboolean useMask= NEXT_BOOLEAN(b); |
|
566 jboolean cyclic = NEXT_BOOLEAN(b); |
|
567 jdouble p0 = NEXT_DOUBLE(b); |
|
568 jdouble p1 = NEXT_DOUBLE(b); |
|
569 jdouble p3 = NEXT_DOUBLE(b); |
|
570 jint pixel1 = NEXT_INT(b); |
|
571 jint pixel2 = NEXT_INT(b); |
|
572 OGLPaints_SetGradientPaint(oglc, useMask, cyclic, |
|
573 p0, p1, p3, |
|
574 pixel1, pixel2); |
|
575 } |
|
576 break; |
|
577 case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT: |
|
578 { |
|
579 jboolean useMask = NEXT_BOOLEAN(b); |
|
580 jboolean linear = NEXT_BOOLEAN(b); |
|
581 jint cycleMethod = NEXT_INT(b); |
|
582 jint numStops = NEXT_INT(b); |
|
583 jfloat p0 = NEXT_FLOAT(b); |
|
584 jfloat p1 = NEXT_FLOAT(b); |
|
585 jfloat p3 = NEXT_FLOAT(b); |
|
586 void *fractions, *pixels; |
|
587 fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); |
|
588 pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); |
|
589 OGLPaints_SetLinearGradientPaint(oglc, dstOps, |
|
590 useMask, linear, |
|
591 cycleMethod, numStops, |
|
592 p0, p1, p3, |
|
593 fractions, pixels); |
|
594 } |
|
595 break; |
|
596 case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT: |
|
597 { |
|
598 jboolean useMask = NEXT_BOOLEAN(b); |
|
599 jboolean linear = NEXT_BOOLEAN(b); |
|
600 jint numStops = NEXT_INT(b); |
|
601 jint cycleMethod = NEXT_INT(b); |
|
602 jfloat m00 = NEXT_FLOAT(b); |
|
603 jfloat m01 = NEXT_FLOAT(b); |
|
604 jfloat m02 = NEXT_FLOAT(b); |
|
605 jfloat m10 = NEXT_FLOAT(b); |
|
606 jfloat m11 = NEXT_FLOAT(b); |
|
607 jfloat m12 = NEXT_FLOAT(b); |
|
608 jfloat focusX = NEXT_FLOAT(b); |
|
609 void *fractions, *pixels; |
|
610 fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); |
|
611 pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); |
|
612 OGLPaints_SetRadialGradientPaint(oglc, dstOps, |
|
613 useMask, linear, |
|
614 cycleMethod, numStops, |
|
615 m00, m01, m02, |
|
616 m10, m11, m12, |
|
617 focusX, |
|
618 fractions, pixels); |
|
619 } |
|
620 break; |
|
621 case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT: |
|
622 { |
|
623 jboolean useMask= NEXT_BOOLEAN(b); |
|
624 jboolean filter = NEXT_BOOLEAN(b); |
|
625 jlong pSrc = NEXT_LONG(b); |
|
626 jdouble xp0 = NEXT_DOUBLE(b); |
|
627 jdouble xp1 = NEXT_DOUBLE(b); |
|
628 jdouble xp3 = NEXT_DOUBLE(b); |
|
629 jdouble yp0 = NEXT_DOUBLE(b); |
|
630 jdouble yp1 = NEXT_DOUBLE(b); |
|
631 jdouble yp3 = NEXT_DOUBLE(b); |
|
632 OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter, |
|
633 xp0, xp1, xp3, |
|
634 yp0, yp1, yp3); |
|
635 } |
|
636 break; |
|
637 |
|
638 // BufferedImageOp-related ops |
|
639 case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP: |
|
640 { |
|
641 jlong pSrc = NEXT_LONG(b); |
|
642 jboolean edgeZero = NEXT_BOOLEAN(b); |
|
643 jint kernelWidth = NEXT_INT(b); |
|
644 jint kernelHeight = NEXT_INT(b); |
|
645 OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero, |
|
646 kernelWidth, kernelHeight, b); |
|
647 SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat)); |
|
648 } |
|
649 break; |
|
650 case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP: |
|
651 { |
|
652 OGLBufImgOps_DisableConvolveOp(oglc); |
|
653 } |
|
654 break; |
|
655 case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP: |
|
656 { |
|
657 jlong pSrc = NEXT_LONG(b); |
|
658 jboolean nonPremult = NEXT_BOOLEAN(b); |
|
659 jint numFactors = 4; |
|
660 unsigned char *scaleFactors = b; |
|
661 unsigned char *offsets = (b + numFactors * sizeof(jfloat)); |
|
662 OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult, |
|
663 scaleFactors, offsets); |
|
664 SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2); |
|
665 } |
|
666 break; |
|
667 case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP: |
|
668 { |
|
669 OGLBufImgOps_DisableRescaleOp(oglc); |
|
670 } |
|
671 break; |
|
672 case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP: |
|
673 { |
|
674 jlong pSrc = NEXT_LONG(b); |
|
675 jboolean nonPremult = NEXT_BOOLEAN(b); |
|
676 jboolean shortData = NEXT_BOOLEAN(b); |
|
677 jint numBands = NEXT_INT(b); |
|
678 jint bandLength = NEXT_INT(b); |
|
679 jint offset = NEXT_INT(b); |
|
680 jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte); |
|
681 void *tableValues = b; |
|
682 OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData, |
|
683 numBands, bandLength, offset, |
|
684 tableValues); |
|
685 SKIP_BYTES(b, numBands * bandLength * bytesPerElem); |
|
686 } |
|
687 break; |
|
688 case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP: |
|
689 { |
|
690 OGLBufImgOps_DisableLookupOp(oglc); |
|
691 } |
|
692 break; |
|
693 |
|
694 default: |
|
695 J2dRlsTraceLn1(J2D_TRACE_ERROR, |
|
696 "OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode); |
|
697 if (oglc != NULL) { |
|
698 RESET_PREVIOUS_OP(); |
|
699 } |
|
700 return; |
|
701 } |
|
702 } |
|
703 |
|
704 if (oglc != NULL) { |
|
705 RESET_PREVIOUS_OP(); |
|
706 if (sync) { |
|
707 j2d_glFinish(); |
|
708 } else { |
|
709 j2d_glFlush(); |
|
710 } |
|
711 OGLSD_Flush(env); |
|
712 } |
|
713 } |
|
714 |
|
715 /** |
|
716 * Returns a pointer to the "current" context, as set by the last SET_SURFACES |
|
717 * or SET_SCRATCH_SURFACE operation. |
|
718 */ |
|
719 OGLContext * |
|
720 OGLRenderQueue_GetCurrentContext() |
|
721 { |
|
722 return oglc; |
|
723 } |
|
724 |
|
725 /** |
|
726 * Returns a pointer to the "current" destination surface, as set by the last |
|
727 * SET_SURFACES operation. |
|
728 */ |
|
729 OGLSDOps * |
|
730 OGLRenderQueue_GetCurrentDestination() |
|
731 { |
|
732 return dstOps; |
|
733 } |
|
734 |
|
735 /** |
|
736 * Used to track whether we are within a series of simple primitive operations |
|
737 * or texturing operations. The op parameter determines the nature of the |
|
738 * operation that is to follow. Valid values for this op parameter are: |
|
739 * |
|
740 * GL_QUADS |
|
741 * GL_LINES |
|
742 * GL_LINE_LOOP |
|
743 * GL_LINE_STRIP |
|
744 * (basically any of the valid parameters for glBegin()) |
|
745 * |
|
746 * GL_TEXTURE_2D |
|
747 * GL_TEXTURE_RECTANGLE_ARB |
|
748 * |
|
749 * OGL_STATE_RESET |
|
750 * OGL_STATE_CHANGE |
|
751 * OGL_STATE_MASK_OP |
|
752 * OGL_STATE_GLYPH_OP |
|
753 * |
|
754 * Note that the above constants are guaranteed to be unique values. The |
|
755 * last few are defined to be negative values to differentiate them from |
|
756 * the core GL* constants, which are defined to be non-negative. |
|
757 * |
|
758 * For simple primitives, this method allows us to batch similar primitives |
|
759 * within the same glBegin()/glEnd() pair. For example, if we have 100 |
|
760 * consecutive FILL_RECT operations, we only have to call glBegin(GL_QUADS) |
|
761 * for the first op, and then subsequent operations will consist only of |
|
762 * glVertex*() calls, which helps improve performance. The glEnd() call |
|
763 * only needs to be issued before an operation that cannot happen within a |
|
764 * glBegin()/glEnd() pair (e.g. updating the clip), or one that requires a |
|
765 * different primitive mode (e.g. GL_LINES). |
|
766 * |
|
767 * For operations that involve texturing, this method helps us to avoid |
|
768 * calling glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D) around each |
|
769 * operation. For example, if we have an alternating series of ISO_BLIT |
|
770 * and MASK_BLIT operations (both of which involve texturing), we need |
|
771 * only to call glEnable(GL_TEXTURE_2D) before the first ISO_BLIT operation. |
|
772 * The glDisable(GL_TEXTURE_2D) call only needs to be issued before an |
|
773 * operation that cannot (or should not) happen while texturing is enabled |
|
774 * (e.g. a context change, or a simple primitive operation like GL_QUADS). |
|
775 */ |
|
776 void |
|
777 OGLRenderQueue_CheckPreviousOp(jint op) |
|
778 { |
|
779 if (previousOp == op) { |
|
780 // The op is the same as last time, so we can return immediately. |
|
781 return; |
|
782 } |
|
783 |
|
784 J2dTraceLn1(J2D_TRACE_VERBOSE, |
|
785 "OGLRenderQueue_CheckPreviousOp: new op=%d", op); |
|
786 |
|
787 switch (previousOp) { |
|
788 case GL_TEXTURE_2D: |
|
789 case GL_TEXTURE_RECTANGLE_ARB: |
|
790 if (op == OGL_STATE_CHANGE) { |
|
791 // Optimization: Certain state changes (those marked as |
|
792 // OGL_STATE_CHANGE) are allowed while texturing is enabled. |
|
793 // In this case, we can allow previousOp to remain as it is and |
|
794 // then return early. |
|
795 return; |
|
796 } else { |
|
797 // Otherwise, op must be a primitive operation, or a reset, so |
|
798 // we will disable texturing. |
|
799 j2d_glDisable(previousOp); |
|
800 // This next step of binding to zero should not be strictly |
|
801 // necessary, but on some older Nvidia boards (e.g. GeForce 2) |
|
802 // problems will arise if GL_TEXTURE_2D and |
|
803 // GL_TEXTURE_RECTANGLE_ARB are bound at the same time, so we |
|
804 // will do this just to be safe. |
|
805 j2d_glBindTexture(previousOp, 0); |
|
806 } |
|
807 break; |
|
808 case OGL_STATE_MASK_OP: |
|
809 OGLVertexCache_DisableMaskCache(oglc); |
|
810 break; |
|
811 case OGL_STATE_GLYPH_OP: |
|
812 OGLTR_DisableGlyphVertexCache(oglc); |
|
813 break; |
|
814 case OGL_STATE_PGRAM_OP: |
|
815 OGLRenderer_DisableAAParallelogramProgram(); |
|
816 break; |
|
817 case OGL_STATE_RESET: |
|
818 case OGL_STATE_CHANGE: |
|
819 // No-op |
|
820 break; |
|
821 default: |
|
822 // In this case, op must be one of: |
|
823 // - the start of a different primitive type (glBegin()) |
|
824 // - a texturing operation |
|
825 // - a state change (not allowed within glBegin()/glEnd() pairs) |
|
826 // - a reset |
|
827 // so we must first complete the previous primitive operation. |
|
828 j2d_glEnd(); |
|
829 break; |
|
830 } |
|
831 |
|
832 switch (op) { |
|
833 case GL_TEXTURE_2D: |
|
834 case GL_TEXTURE_RECTANGLE_ARB: |
|
835 // We are starting a texturing operation, so enable texturing. |
|
836 j2d_glEnable(op); |
|
837 break; |
|
838 case OGL_STATE_MASK_OP: |
|
839 OGLVertexCache_EnableMaskCache(oglc); |
|
840 break; |
|
841 case OGL_STATE_GLYPH_OP: |
|
842 OGLTR_EnableGlyphVertexCache(oglc); |
|
843 break; |
|
844 case OGL_STATE_PGRAM_OP: |
|
845 OGLRenderer_EnableAAParallelogramProgram(); |
|
846 break; |
|
847 case OGL_STATE_RESET: |
|
848 case OGL_STATE_CHANGE: |
|
849 // No-op |
|
850 break; |
|
851 default: |
|
852 // We are starting a primitive operation, so call glBegin() with |
|
853 // the given primitive type. |
|
854 j2d_glBegin(op); |
|
855 break; |
|
856 } |
|
857 |
|
858 previousOp = op; |
|
859 } |
|
860 |
|
861 #endif /* !HEADLESS */ |