1 /* 2 * Copyright (c) 2019, 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 "MTLBlitLoops.h" 34 #include "MTLBufImgOps.h" 35 #include "MTLMaskBlit.h" 36 #include "MTLMaskFill.h" 37 #include "MTLPaints.h" 38 #include "MTLRenderQueue.h" 39 #include "MTLRenderer.h" 40 #include "MTLTextRenderer.h" 41 42 /** 43 * Used to track whether we are in a series of a simple primitive operations 44 * or texturing operations. This variable should be controlled only via 45 * the INIT/CHECK/RESET_PREVIOUS_OP() macros. See the 46 * MTLRenderQueue_CheckPreviousOp() method below for more information. 47 */ 48 jint previousOp; 49 50 /** 51 * References to the "current" context and destination surface. 52 */ 53 static MTLContext *mtlc = NULL; 54 static BMTLSDOps *dstOps = NULL; 55 56 /** 57 * The following methods are implemented in the windowing system (i.e. GLX 58 * and WGL) source files. 59 */ 60 extern void MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo); 61 extern void MTLSD_SwapBuffers(JNIEnv *env, jlong window); 62 63 /** 64 * Helper methods to manage modified layers 65 */ 66 static MTLLayer ** g_modifiedLayers = NULL; 67 static int g_modifiedLayersCount = 0; 68 static int g_modifiedLayersAllocatedCount = 0; 69 70 static void markLayerModified(MTLLayer * modifiedLayer) { 71 if (modifiedLayer == NULL) 72 return; 73 if (g_modifiedLayers == NULL) { 74 g_modifiedLayersAllocatedCount = 3; 75 g_modifiedLayers = malloc(g_modifiedLayersAllocatedCount * sizeof(MTLLayer *)); 76 } 77 for (int c = 0; c < g_modifiedLayersCount; ++c) { 78 if (g_modifiedLayers[c] == modifiedLayer) 79 return; 80 } 81 ++g_modifiedLayersCount; 82 if (g_modifiedLayersCount > g_modifiedLayersAllocatedCount) { 83 g_modifiedLayersAllocatedCount = g_modifiedLayersCount; 84 g_modifiedLayers = realloc(g_modifiedLayers, g_modifiedLayersAllocatedCount * sizeof(MTLLayer *)); 85 } 86 g_modifiedLayers[g_modifiedLayersCount - 1] = modifiedLayer; 87 } 88 89 static void scheduleBlitAllModifiedLayers() { 90 for (int c = 0; c < g_modifiedLayersCount; ++c) { 91 MTLLayer * layer = g_modifiedLayers[c]; 92 MTLContext * ctx = layer.ctx; 93 if (layer == NULL || ctx == NULL) 94 continue; 95 id<MTLCommandBuffer> bufferToCommit = ctx.commandBuffer; 96 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ 97 [layer blitTexture:bufferToCommit]; 98 }]; 99 100 [ctx releaseCommandBuffer]; 101 } 102 g_modifiedLayersCount = 0; 103 } 104 105 static void onSurfaceModified(BMTLSDOps *bmtldst) { 106 if (bmtldst != NULL && bmtldst->privOps != NULL && ((MTLSDOps *)bmtldst->privOps)->layer != NULL) 107 markLayerModified(((MTLSDOps *) bmtldst->privOps)->layer); 108 } 109 110 static const jint g_drawOpcodes[] = { 111 sun_java2d_pipe_BufferedOpCodes_DRAW_LINE, 112 sun_java2d_pipe_BufferedOpCodes_DRAW_RECT, 113 sun_java2d_pipe_BufferedOpCodes_DRAW_POLY, 114 sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL, 115 sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES, 116 sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM, 117 sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM, 118 119 sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST, 120 121 sun_java2d_pipe_BufferedOpCodes_FILL_RECT, 122 sun_java2d_pipe_BufferedOpCodes_FILL_SPANS, 123 sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM, 124 sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM, 125 126 sun_java2d_pipe_BufferedOpCodes_COPY_AREA, 127 sun_java2d_pipe_BufferedOpCodes_MASK_FILL, 128 sun_java2d_pipe_BufferedOpCodes_MASK_BLIT, 129 sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS 130 }; 131 132 static jboolean isDrawOpcode(jint opcode) { 133 for (int c = 0; c < sizeof(g_drawOpcodes)/sizeof(g_drawOpcodes[0]); ++c) { 134 if (opcode == g_drawOpcodes[c]) 135 return JNI_TRUE; 136 } 137 return JNI_FALSE; 138 } 139 140 JNIEXPORT void JNICALL 141 Java_sun_java2d_metal_MTLRenderQueue_flushBuffer 142 (JNIEnv *env, jobject mtlrq, 143 jlong buf, jint limit) 144 { 145 jboolean sync = JNI_FALSE; 146 unsigned char *b, *end; 147 148 J2dTraceLn1(J2D_TRACE_INFO, 149 "MTLRenderQueue_flushBuffer: limit=%d", limit); 150 151 b = (unsigned char *)jlong_to_ptr(buf); 152 if (b == NULL) { 153 J2dRlsTraceLn(J2D_TRACE_ERROR, 154 "MTLRenderQueue_flushBuffer: cannot get direct buffer address"); 155 return; 156 } 157 158 INIT_PREVIOUS_OP(); 159 end = b + limit; 160 161 while (b < end) { 162 jint opcode = NEXT_INT(b); 163 164 J2dTraceLn2(J2D_TRACE_VERBOSE, 165 "MTLRenderQueue_flushBuffer: opcode=%d, rem=%d", 166 opcode, (end-b)); 167 168 if (opcode != sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST && 169 opcode != sun_java2d_pipe_BufferedOpCodes_NOOP) 170 { 171 //MTLTR_DisableGlyphModeState(); 172 } 173 174 switch (opcode) { 175 176 // draw ops 177 case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE: 178 { 179 J2dTraceLn(J2D_TRACE_VERBOSE, "sun_java2d_pipe_BufferedOpCodes_DRAW_LINE"); 180 jint x1 = NEXT_INT(b); 181 jint y1 = NEXT_INT(b); 182 jint x2 = NEXT_INT(b); 183 jint y2 = NEXT_INT(b); 184 MTLRenderer_DrawLine(mtlc, dstOps, x1, y1, x2, y2); 185 } 186 break; 187 case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT: 188 { 189 jint x = NEXT_INT(b); 190 jint y = NEXT_INT(b); 191 jint w = NEXT_INT(b); 192 jint h = NEXT_INT(b); 193 MTLRenderer_DrawRect(mtlc, dstOps, x, y, w, h); 194 } 195 break; 196 case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY: 197 { 198 jint nPoints = NEXT_INT(b); 199 jboolean isClosed = NEXT_BOOLEAN(b); 200 jint transX = NEXT_INT(b); 201 jint transY = NEXT_INT(b); 202 jint *xPoints = (jint *)b; 203 jint *yPoints = ((jint *)b) + nPoints; 204 MTLRenderer_DrawPoly(mtlc, dstOps, nPoints, isClosed, transX, transY, xPoints, yPoints); 205 SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT); 206 } 207 break; 208 case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL: 209 { 210 jint x = NEXT_INT(b); 211 jint y = NEXT_INT(b); 212 CONTINUE_IF_NULL(mtlc); 213 //TODO 214 J2dTraceNotImplPrimitive("MTLRenderQueue_DRAW_PIXEL"); 215 } 216 break; 217 case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES: 218 { 219 jint count = NEXT_INT(b); 220 MTLRenderer_DrawScanlines(mtlc, dstOps, count, (jint *)b); 221 222 SKIP_BYTES(b, count * BYTES_PER_SCANLINE); 223 } 224 break; 225 case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM: 226 { 227 jfloat x11 = NEXT_FLOAT(b); 228 jfloat y11 = NEXT_FLOAT(b); 229 jfloat dx21 = NEXT_FLOAT(b); 230 jfloat dy21 = NEXT_FLOAT(b); 231 jfloat dx12 = NEXT_FLOAT(b); 232 jfloat dy12 = NEXT_FLOAT(b); 233 jfloat lwr21 = NEXT_FLOAT(b); 234 jfloat lwr12 = NEXT_FLOAT(b); 235 236 MTLRenderer_DrawParallelogram(mtlc, dstOps, 237 x11, y11, 238 dx21, dy21, 239 dx12, dy12, 240 lwr21, lwr12); 241 } 242 break; 243 case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM: 244 { 245 jfloat x11 = NEXT_FLOAT(b); 246 jfloat y11 = NEXT_FLOAT(b); 247 jfloat dx21 = NEXT_FLOAT(b); 248 jfloat dy21 = NEXT_FLOAT(b); 249 jfloat dx12 = NEXT_FLOAT(b); 250 jfloat dy12 = NEXT_FLOAT(b); 251 jfloat lwr21 = NEXT_FLOAT(b); 252 jfloat lwr12 = NEXT_FLOAT(b); 253 254 MTLRenderer_DrawAAParallelogram(mtlc, dstOps, 255 x11, y11, 256 dx21, dy21, 257 dx12, dy12, 258 lwr21, lwr12); 259 } 260 break; 261 262 // fill ops 263 case sun_java2d_pipe_BufferedOpCodes_FILL_RECT: 264 { 265 jint x = NEXT_INT(b); 266 jint y = NEXT_INT(b); 267 jint w = NEXT_INT(b); 268 jint h = NEXT_INT(b); 269 MTLRenderer_FillRect(mtlc, dstOps, x, y, w, h); 270 } 271 break; 272 case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS: 273 { 274 jint count = NEXT_INT(b); 275 MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b); 276 SKIP_BYTES(b, count * BYTES_PER_SPAN); 277 } 278 break; 279 case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM: 280 { 281 jfloat x11 = NEXT_FLOAT(b); 282 jfloat y11 = NEXT_FLOAT(b); 283 jfloat dx21 = NEXT_FLOAT(b); 284 jfloat dy21 = NEXT_FLOAT(b); 285 jfloat dx12 = NEXT_FLOAT(b); 286 jfloat dy12 = NEXT_FLOAT(b); 287 MTLRenderer_FillParallelogram(mtlc, dstOps, 288 x11, y11, 289 dx21, dy21, 290 dx12, dy12); 291 } 292 break; 293 case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM: 294 { 295 jfloat x11 = NEXT_FLOAT(b); 296 jfloat y11 = NEXT_FLOAT(b); 297 jfloat dx21 = NEXT_FLOAT(b); 298 jfloat dy21 = NEXT_FLOAT(b); 299 jfloat dx12 = NEXT_FLOAT(b); 300 jfloat dy12 = NEXT_FLOAT(b); 301 MTLRenderer_FillAAParallelogram(mtlc, dstOps, 302 x11, y11, 303 dx21, dy21, 304 dx12, dy12); 305 } 306 break; 307 308 // text-related ops 309 case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST: 310 { 311 jint numGlyphs = NEXT_INT(b); 312 jint packedParams = NEXT_INT(b); 313 jfloat glyphListOrigX = NEXT_FLOAT(b); 314 jfloat glyphListOrigY = NEXT_FLOAT(b); 315 jboolean usePositions = EXTRACT_BOOLEAN(packedParams, 316 OFFSET_POSITIONS); 317 jboolean subPixPos = EXTRACT_BOOLEAN(packedParams, 318 OFFSET_SUBPIXPOS); 319 jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams, 320 OFFSET_RGBORDER); 321 jint lcdContrast = EXTRACT_BYTE(packedParams, 322 OFFSET_CONTRAST); 323 unsigned char *images = b; 324 unsigned char *positions; 325 jint bytesPerGlyph; 326 if (usePositions) { 327 positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE); 328 bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH; 329 } else { 330 positions = NULL; 331 bytesPerGlyph = BYTES_PER_GLYPH_IMAGE; 332 } 333 MTLTR_DrawGlyphList(env, mtlc, dstOps, 334 numGlyphs, usePositions, 335 subPixPos, rgbOrder, lcdContrast, 336 glyphListOrigX, glyphListOrigY, 337 images, positions); 338 SKIP_BYTES(b, numGlyphs * bytesPerGlyph); 339 } 340 break; 341 342 // copy-related ops 343 case sun_java2d_pipe_BufferedOpCodes_COPY_AREA: 344 { 345 jint x = NEXT_INT(b); 346 jint y = NEXT_INT(b); 347 jint w = NEXT_INT(b); 348 jint h = NEXT_INT(b); 349 jint dx = NEXT_INT(b); 350 jint dy = NEXT_INT(b); 351 MTLBlitLoops_CopyArea(env, mtlc, dstOps, 352 x, y, w, h, dx, dy); 353 } 354 break; 355 case sun_java2d_pipe_BufferedOpCodes_BLIT: 356 { 357 J2dTracePrimitive("MTLRenderQueue_BLIT"); 358 359 jint packedParams = NEXT_INT(b); 360 jint sx1 = NEXT_INT(b); 361 jint sy1 = NEXT_INT(b); 362 jint sx2 = NEXT_INT(b); 363 jint sy2 = NEXT_INT(b); 364 jdouble dx1 = NEXT_DOUBLE(b); 365 jdouble dy1 = NEXT_DOUBLE(b); 366 jdouble dx2 = NEXT_DOUBLE(b); 367 jdouble dy2 = NEXT_DOUBLE(b); 368 jlong pSrc = NEXT_LONG(b); 369 jlong pDst = NEXT_LONG(b); 370 jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT); 371 jboolean texture = EXTRACT_BOOLEAN(packedParams, 372 OFFSET_TEXTURE); 373 jboolean rtt = EXTRACT_BOOLEAN(packedParams, 374 OFFSET_RTT); 375 jboolean xform = EXTRACT_BOOLEAN(packedParams, 376 OFFSET_XFORM); 377 jboolean isoblit = EXTRACT_BOOLEAN(packedParams, 378 OFFSET_ISOBLIT); 379 if (isoblit) { 380 MTLBlitLoops_IsoBlit(env, mtlc, pSrc, pDst, 381 xform, hint, texture, rtt, 382 sx1, sy1, sx2, sy2, 383 dx1, dy1, dx2, dy2); 384 } else { 385 jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE); 386 MTLBlitLoops_Blit(env, mtlc, pSrc, pDst, 387 xform, hint, srctype, texture, 388 sx1, sy1, sx2, sy2, 389 dx1, dy1, dx2, dy2); 390 } 391 onSurfaceModified(jlong_to_ptr(pDst)); 392 } 393 break; 394 case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT: 395 { 396 J2dTracePrimitive("MTLRenderQueue_SURFACE_TO_SW_BLIT"); 397 398 jint sx = NEXT_INT(b); 399 jint sy = NEXT_INT(b); 400 jint dx = NEXT_INT(b); 401 jint dy = NEXT_INT(b); 402 jint w = NEXT_INT(b); 403 jint h = NEXT_INT(b); 404 jint dsttype = NEXT_INT(b); 405 jlong pSrc = NEXT_LONG(b); 406 jlong pDst = NEXT_LONG(b); 407 MTLBlitLoops_SurfaceToSwBlit(env, mtlc, 408 pSrc, pDst, dsttype, 409 sx, sy, dx, dy, w, h); 410 } 411 break; 412 case sun_java2d_pipe_BufferedOpCodes_MASK_FILL: 413 { 414 J2dTracePrimitive("MTLRenderQueue_MASK_FILL"); 415 416 jint x = NEXT_INT(b); 417 jint y = NEXT_INT(b); 418 jint w = NEXT_INT(b); 419 jint h = NEXT_INT(b); 420 jint maskoff = NEXT_INT(b); 421 jint maskscan = NEXT_INT(b); 422 jint masklen = NEXT_INT(b); 423 unsigned char *pMask = (masklen > 0) ? b : NULL; 424 MTLMaskFill_MaskFill(mtlc, dstOps, x, y, w, h, 425 maskoff, maskscan, masklen, pMask); 426 SKIP_BYTES(b, masklen); 427 } 428 break; 429 case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT: 430 { 431 J2dTracePrimitive("MTLRenderQueue_MASK_BLIT"); 432 433 jint dstx = NEXT_INT(b); 434 jint dsty = NEXT_INT(b); 435 jint width = NEXT_INT(b); 436 jint height = NEXT_INT(b); 437 jint masklen = width * height * sizeof(jint); 438 MTLMaskBlit_MaskBlit(env, mtlc, dstOps, 439 dstx, dsty, width, height, b); 440 SKIP_BYTES(b, masklen); 441 } 442 break; 443 444 // state-related ops 445 case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP: 446 { 447 jint x1 = NEXT_INT(b); 448 jint y1 = NEXT_INT(b); 449 jint x2 = NEXT_INT(b); 450 jint y2 = NEXT_INT(b); 451 [mtlc setClipRectX1:x1 Y1:y1 X2:x2 Y2:y2]; 452 } 453 break; 454 case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP: 455 { 456 [mtlc beginShapeClip]; 457 } 458 break; 459 case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS: 460 { 461 jint count = NEXT_INT(b); 462 MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b); 463 SKIP_BYTES(b, count * BYTES_PER_SPAN); 464 } 465 break; 466 case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP: 467 { 468 //TODO 469 [mtlc endShapeClipDstOps:dstOps]; 470 } 471 break; 472 case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP: 473 { 474 [mtlc resetClip]; 475 } 476 break; 477 case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE: 478 { 479 jint rule = NEXT_INT(b); 480 jfloat extraAlpha = NEXT_FLOAT(b); 481 jint flags = NEXT_INT(b); 482 [mtlc setAlphaCompositeRule:rule extraAlpha:extraAlpha flags:flags]; 483 } 484 break; 485 case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE: 486 { 487 jint xorPixel = NEXT_INT(b); 488 [mtlc setXorComposite:xorPixel]; 489 } 490 break; 491 case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE: 492 { 493 [mtlc resetComposite]; 494 } 495 break; 496 case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM: 497 { 498 jdouble m00 = NEXT_DOUBLE(b); 499 jdouble m10 = NEXT_DOUBLE(b); 500 jdouble m01 = NEXT_DOUBLE(b); 501 jdouble m11 = NEXT_DOUBLE(b); 502 jdouble m02 = NEXT_DOUBLE(b); 503 jdouble m12 = NEXT_DOUBLE(b); 504 [mtlc setTransformM00:m00 M10:m10 M01:m01 M11:m11 M02:m02 M12:m12]; 505 } 506 break; 507 case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM: 508 { 509 [mtlc resetTransform]; 510 } 511 break; 512 513 // context-related ops 514 case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES: 515 { 516 J2dTracePrimitive("MTLRenderQueue_SET_SURFACES"); 517 518 jlong pSrc = NEXT_LONG(b); 519 jlong pDst = NEXT_LONG(b); 520 if (mtlc != NULL) { 521 RESET_PREVIOUS_OP(); 522 } 523 524 dstOps = (BMTLSDOps *)jlong_to_ptr(pDst); 525 [MTLContext setSurfacesEnv:env src:pSrc dst:pDst]; 526 } 527 break; 528 case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE: 529 { 530 J2dTracePrimitive("MTLRenderQueue_SET_SCRATCH_SURFACE"); 531 jlong pConfigInfo = NEXT_LONG(b); 532 MTLGraphicsConfigInfo *mtlInfo = 533 (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); 534 535 if (mtlInfo == NULL) { 536 J2dTraceImplPrimitive( 537 "MTLRenderQueue_SET_SCRATCH_SURFACE", 538 "ERROR: mtl config info is null"); 539 } else { 540 MTLContext *newMtlc = mtlInfo->context; 541 if (newMtlc == NULL) { 542 J2dTraceImplPrimitive( 543 "MTLRenderQueue_SET_SCRATCH_SURFACE", 544 "ERROR: mtl context is null"); 545 } else { 546 mtlc = newMtlc; 547 dstOps = NULL; 548 } 549 } 550 } 551 break; 552 case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE: 553 { 554 J2dTracePrimitive("MTLRenderQueue_FLUSH_SURFACE"); 555 jlong pData = NEXT_LONG(b); 556 BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData); 557 if (mtlsdo != NULL) { 558 CONTINUE_IF_NULL(mtlc); 559 RESET_PREVIOUS_OP(); 560 MTLSD_Delete(env, mtlsdo); 561 } 562 } 563 break; 564 case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE: 565 { 566 J2dTracePrimitive("MTLRenderQueue_DISPOSE_SURFACE"); 567 jlong pData = NEXT_LONG(b); 568 BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData); 569 if (mtlsdo != NULL) { 570 CONTINUE_IF_NULL(mtlc); 571 RESET_PREVIOUS_OP(); 572 MTLSD_Delete(env, mtlsdo); 573 if (mtlsdo->privOps != NULL) { 574 free(mtlsdo->privOps); 575 } 576 } 577 } 578 break; 579 case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG: 580 { 581 J2dTracePrimitive("MTLRenderQueue_DISPOSE_CONFIG"); 582 jlong pConfigInfo = NEXT_LONG(b); 583 CONTINUE_IF_NULL(mtlc); 584 RESET_PREVIOUS_OP(); 585 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ 586 MTLGC_DestroyMTLGraphicsConfig(pConfigInfo); 587 }]; 588 589 590 // the previous method will call glX/wglMakeCurrent(None), 591 // so we should nullify the current mtlc and dstOps to avoid 592 // calling glFlush() (or similar) while no context is current 593 mtlc = NULL; 594 // dstOps = NULL; 595 } 596 break; 597 case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT: 598 { 599 //TODO 600 J2dTraceNotImplPrimitive("MTLRenderQueue_INVALIDATE_CONTEXT"); 601 // flush just in case there are any pending operations in 602 // the hardware pipe 603 if (mtlc != NULL) { 604 RESET_PREVIOUS_OP(); 605 } 606 // invalidate the references to the current context and 607 // destination surface that are maintained at the native level 608 mtlc = NULL; 609 // dstOps = NULL; 610 } 611 break; 612 case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE: 613 { 614 //TODO 615 J2dTraceNotImplPrimitive("MTLRenderQueue_INVALIDATE_CONTEXT"); 616 } 617 break; 618 619 case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE: 620 { 621 //TODO 622 J2dTraceNotImplPrimitive("MTLRenderQueue_RESTORE_STATE"); 623 624 } 625 break; 626 case sun_java2d_pipe_BufferedOpCodes_SYNC: 627 { 628 sync = JNI_TRUE; 629 } 630 break; 631 632 // multibuffering ops 633 case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS: 634 { 635 jlong window = NEXT_LONG(b); 636 if (mtlc != NULL) { 637 RESET_PREVIOUS_OP(); 638 } 639 MTLSD_SwapBuffers(env, window); 640 } 641 break; 642 643 // special no-op (mainly used for achieving 8-byte alignment) 644 case sun_java2d_pipe_BufferedOpCodes_NOOP: 645 break; 646 647 // paint-related ops 648 case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT: 649 { 650 MTLPaints_ResetPaint(mtlc); 651 } 652 break; 653 case sun_java2d_pipe_BufferedOpCodes_SET_COLOR: 654 { 655 jint pixel = NEXT_INT(b); 656 657 if (dstOps != NULL) { 658 MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps; 659 dstCGLOps->configInfo->context.color = pixel; 660 } 661 MTLPaints_SetColor(mtlc, pixel); 662 } 663 break; 664 case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT: 665 { 666 J2dTraceNotImplPrimitive("MTLRenderQueue_SET_GRADIENT_PAINT"); 667 jboolean useMask= NEXT_BOOLEAN(b); 668 jboolean cyclic = NEXT_BOOLEAN(b); 669 jdouble p0 = NEXT_DOUBLE(b); 670 jdouble p1 = NEXT_DOUBLE(b); 671 jdouble p3 = NEXT_DOUBLE(b); 672 jint pixel1 = NEXT_INT(b); 673 jint pixel2 = NEXT_INT(b); 674 if (dstOps != NULL) { 675 MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps; 676 [dstCGLOps->configInfo->context setGradientPaintUseMask:useMask cyclic:cyclic 677 p0:p0 p1:p1 p3:p3 678 pixel1:pixel1 pixel2:pixel2]; 679 680 } 681 } 682 break; 683 case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT: 684 { 685 jboolean useMask = NEXT_BOOLEAN(b); 686 jboolean linear = NEXT_BOOLEAN(b); 687 jint cycleMethod = NEXT_INT(b); 688 jint numStops = NEXT_INT(b); 689 jfloat p0 = NEXT_FLOAT(b); 690 jfloat p1 = NEXT_FLOAT(b); 691 jfloat p3 = NEXT_FLOAT(b); 692 void *fractions, *pixels; 693 fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); 694 pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); 695 MTLPaints_SetLinearGradientPaint(mtlc, dstOps, 696 useMask, linear, 697 cycleMethod, numStops, 698 p0, p1, p3, 699 fractions, pixels); 700 } 701 break; 702 case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT: 703 { 704 jboolean useMask = NEXT_BOOLEAN(b); 705 jboolean linear = NEXT_BOOLEAN(b); 706 jint numStops = NEXT_INT(b); 707 jint cycleMethod = NEXT_INT(b); 708 jfloat m00 = NEXT_FLOAT(b); 709 jfloat m01 = NEXT_FLOAT(b); 710 jfloat m02 = NEXT_FLOAT(b); 711 jfloat m10 = NEXT_FLOAT(b); 712 jfloat m11 = NEXT_FLOAT(b); 713 jfloat m12 = NEXT_FLOAT(b); 714 jfloat focusX = NEXT_FLOAT(b); 715 void *fractions, *pixels; 716 fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); 717 pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); 718 MTLPaints_SetRadialGradientPaint(mtlc, dstOps, 719 useMask, linear, 720 cycleMethod, numStops, 721 m00, m01, m02, 722 m10, m11, m12, 723 focusX, 724 fractions, pixels); 725 } 726 break; 727 case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT: 728 { 729 jboolean useMask= NEXT_BOOLEAN(b); 730 jboolean filter = NEXT_BOOLEAN(b); 731 jlong pSrc = NEXT_LONG(b); 732 jdouble xp0 = NEXT_DOUBLE(b); 733 jdouble xp1 = NEXT_DOUBLE(b); 734 jdouble xp3 = NEXT_DOUBLE(b); 735 jdouble yp0 = NEXT_DOUBLE(b); 736 jdouble yp1 = NEXT_DOUBLE(b); 737 jdouble yp3 = NEXT_DOUBLE(b); 738 MTLPaints_SetTexturePaint(mtlc, useMask, pSrc, filter, 739 xp0, xp1, xp3, 740 yp0, yp1, yp3); 741 } 742 break; 743 744 // BufferedImageOp-related ops 745 case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP: 746 { 747 jlong pSrc = NEXT_LONG(b); 748 jboolean edgeZero = NEXT_BOOLEAN(b); 749 jint kernelWidth = NEXT_INT(b); 750 jint kernelHeight = NEXT_INT(b); 751 MTLBufImgOps_EnableConvolveOp(mtlc, pSrc, edgeZero, 752 kernelWidth, kernelHeight, b); 753 SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat)); 754 } 755 break; 756 case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP: 757 { 758 MTLBufImgOps_DisableConvolveOp(mtlc); 759 } 760 break; 761 case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP: 762 { 763 jlong pSrc = NEXT_LONG(b); 764 jboolean nonPremult = NEXT_BOOLEAN(b); 765 jint numFactors = 4; 766 unsigned char *scaleFactors = b; 767 unsigned char *offsets = (b + numFactors * sizeof(jfloat)); 768 MTLBufImgOps_EnableRescaleOp(mtlc, pSrc, nonPremult, 769 scaleFactors, offsets); 770 SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2); 771 } 772 break; 773 case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP: 774 { 775 MTLBufImgOps_DisableRescaleOp(mtlc); 776 } 777 break; 778 case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP: 779 { 780 jlong pSrc = NEXT_LONG(b); 781 jboolean nonPremult = NEXT_BOOLEAN(b); 782 jboolean shortData = NEXT_BOOLEAN(b); 783 jint numBands = NEXT_INT(b); 784 jint bandLength = NEXT_INT(b); 785 jint offset = NEXT_INT(b); 786 jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte); 787 void *tableValues = b; 788 MTLBufImgOps_EnableLookupOp(mtlc, pSrc, nonPremult, shortData, 789 numBands, bandLength, offset, 790 tableValues); 791 SKIP_BYTES(b, numBands * bandLength * bytesPerElem); 792 } 793 break; 794 case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP: 795 { 796 MTLBufImgOps_DisableLookupOp(mtlc); 797 } 798 break; 799 800 default: 801 J2dRlsTraceLn1(J2D_TRACE_ERROR, 802 "MTLRenderQueue_flushBuffer: invalid opcode=%d", opcode); 803 if (mtlc != NULL) { 804 RESET_PREVIOUS_OP(); 805 } 806 return; 807 } 808 809 if (isDrawOpcode(opcode)) // performed rendering operation on dstOps 810 onSurfaceModified(dstOps); 811 } 812 813 MTLTR_DisableGlyphModeState(); 814 scheduleBlitAllModifiedLayers(); 815 } 816 817 /** 818 * Returns a pointer to the "current" context, as set by the last SET_SURFACES 819 * or SET_SCRATCH_SURFACE operation. 820 */ 821 MTLContext * 822 MTLRenderQueue_GetCurrentContext() 823 { 824 return mtlc; 825 } 826 827 /** 828 * Returns a pointer to the "current" destination surface, as set by the last 829 * SET_SURFACES operation. 830 */ 831 BMTLSDOps * 832 MTLRenderQueue_GetCurrentDestination() 833 { 834 return dstOps; 835 } 836 837 /** 838 * Used to track whether we are within a series of simple primitive operations 839 * or texturing operations. The op parameter determines the nature of the 840 * operation that is to follow. Valid values for this op parameter are: 841 */ 842 void 843 MTLRenderQueue_CheckPreviousOp(jint op) 844 { 845 //TODO 846 J2dTraceNotImplPrimitive("MTLRenderQueue_CheckPreviousOp"); 847 previousOp = op; 848 } 849 850 #endif /* !HEADLESS */