Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m
41159 views
/*1* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <stdlib.h>2627#include "sun_java2d_pipe_BufferedOpCodes.h"2829#include "jlong.h"30#include "MTLBlitLoops.h"31#include "MTLBufImgOps.h"32#include "MTLMaskBlit.h"33#include "MTLMaskFill.h"34#include "MTLPaints.h"35#include "MTLRenderQueue.h"36#include "MTLRenderer.h"37#include "MTLTextRenderer.h"38#import "ThreadUtilities.h"3940/**41* References to the "current" context and destination surface.42*/43static MTLContext *mtlc = NULL;44static BMTLSDOps *dstOps = NULL;45jint mtlPreviousOp = MTL_OP_INIT;464748extern void MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo);4950void MTLRenderQueue_CheckPreviousOp(jint op) {5152if (mtlPreviousOp == op) {53// The op is the same as last time, so we can return immediately.54return;55}5657if (op == MTL_OP_SET_COLOR) {58if (mtlPreviousOp != MTL_OP_MASK_OP) {59return; // SET_COLOR should not cause endEncoder60}61} else if (op == MTL_OP_MASK_OP) {62MTLVertexCache_EnableMaskCache(mtlc, dstOps);63mtlPreviousOp = op;64return;65}6667J2dTraceLn1(J2D_TRACE_VERBOSE,68"MTLRenderQueue_CheckPreviousOp: new op=%d", op);6970switch (mtlPreviousOp) {71case MTL_OP_INIT :72mtlPreviousOp = op;73return;74case MTL_OP_MASK_OP :75MTLVertexCache_DisableMaskCache(mtlc);76break;77}7879if (mtlc != NULL) {80[mtlc.encoderManager endEncoder];8182if (op == MTL_OP_RESET_PAINT || op == MTL_OP_SYNC || op == MTL_OP_SHAPE_CLIP_SPANS) {83MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper];84id <MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];85[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {86[cbwrapper release];87}];88[commandbuf commit];89if (op == MTL_OP_SYNC || op == MTL_OP_SHAPE_CLIP_SPANS) {90[commandbuf waitUntilCompleted];91}92}93}94mtlPreviousOp = op;95}9697JNIEXPORT void JNICALL98Java_sun_java2d_metal_MTLRenderQueue_flushBuffer99(JNIEnv *env, jobject mtlrq,100jlong buf, jint limit)101{102unsigned char *b, *end;103104J2dTraceLn1(J2D_TRACE_INFO,105"MTLRenderQueue_flushBuffer: limit=%d", limit);106107b = (unsigned char *)jlong_to_ptr(buf);108if (b == NULL) {109J2dRlsTraceLn(J2D_TRACE_ERROR,110"MTLRenderQueue_flushBuffer: cannot get direct buffer address");111return;112}113114end = b + limit;115@autoreleasepool {116while (b < end) {117jint opcode = NEXT_INT(b);118119J2dTraceLn2(J2D_TRACE_VERBOSE,120"MTLRenderQueue_flushBuffer: opcode=%d, rem=%d",121opcode, (end-b));122123switch (opcode) {124125// draw ops126case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:127{128CHECK_PREVIOUS_OP(MTL_OP_OTHER);129130if ([mtlc useXORComposite]) {131commitEncodedCommands();132J2dTraceLn(J2D_TRACE_VERBOSE,133"DRAW_LINE in XOR mode - Force commit earlier draw calls before DRAW_LINE.");134}135jint x1 = NEXT_INT(b);136jint y1 = NEXT_INT(b);137jint x2 = NEXT_INT(b);138jint y2 = NEXT_INT(b);139MTLRenderer_DrawLine(mtlc, dstOps, x1, y1, x2, y2);140break;141}142case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:143{144CHECK_PREVIOUS_OP(MTL_OP_OTHER);145146if ([mtlc useXORComposite]) {147commitEncodedCommands();148J2dTraceLn(J2D_TRACE_VERBOSE,149"DRAW_RECT in XOR mode - Force commit earlier draw calls before DRAW_RECT.");150}151jint x = NEXT_INT(b);152jint y = NEXT_INT(b);153jint w = NEXT_INT(b);154jint h = NEXT_INT(b);155MTLRenderer_DrawRect(mtlc, dstOps, x, y, w, h);156break;157}158case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:159{160CHECK_PREVIOUS_OP(MTL_OP_OTHER);161jint nPoints = NEXT_INT(b);162jboolean isClosed = NEXT_BOOLEAN(b);163jint transX = NEXT_INT(b);164jint transY = NEXT_INT(b);165jint *xPoints = (jint *)b;166jint *yPoints = ((jint *)b) + nPoints;167168if ([mtlc useXORComposite]) {169commitEncodedCommands();170J2dTraceLn(J2D_TRACE_VERBOSE,171"DRAW_POLY in XOR mode - Force commit earlier draw calls before DRAW_POLY.");172173// draw separate (N-1) lines using N points174for(int point = 0; point < nPoints-1; point++) {175jint x1 = xPoints[point] + transX;176jint y1 = yPoints[point] + transY;177jint x2 = xPoints[point + 1] + transX;178jint y2 = yPoints[point + 1] + transY;179MTLRenderer_DrawLine(mtlc, dstOps, x1, y1, x2, y2);180}181182if (isClosed) {183MTLRenderer_DrawLine(mtlc, dstOps, xPoints[0] + transX, yPoints[0] + transY,184xPoints[nPoints-1] + transX, yPoints[nPoints-1] + transY);185}186} else {187MTLRenderer_DrawPoly(mtlc, dstOps, nPoints, isClosed, transX, transY, xPoints, yPoints);188}189190SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT);191break;192}193case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:194{195CHECK_PREVIOUS_OP(MTL_OP_OTHER);196197if ([mtlc useXORComposite]) {198commitEncodedCommands();199J2dTraceLn(J2D_TRACE_VERBOSE,200"DRAW_PIXEL in XOR mode - Force commit earlier draw calls before DRAW_PIXEL.");201}202203jint x = NEXT_INT(b);204jint y = NEXT_INT(b);205CONTINUE_IF_NULL(mtlc);206MTLRenderer_DrawPixel(mtlc, dstOps, x, y);207break;208}209case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:210{211CHECK_PREVIOUS_OP(MTL_OP_OTHER);212213if ([mtlc useXORComposite]) {214commitEncodedCommands();215J2dTraceLn(J2D_TRACE_VERBOSE,216"DRAW_SCANLINES in XOR mode - Force commit earlier draw calls before "217"DRAW_SCANLINES.");218}219220jint count = NEXT_INT(b);221MTLRenderer_DrawScanlines(mtlc, dstOps, count, (jint *)b);222223SKIP_BYTES(b, count * BYTES_PER_SCANLINE);224break;225}226case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:227{228CHECK_PREVIOUS_OP(MTL_OP_OTHER);229230if ([mtlc useXORComposite]) {231commitEncodedCommands();232J2dTraceLn(J2D_TRACE_VERBOSE,233"DRAW_PARALLELOGRAM in XOR mode - Force commit earlier draw calls before "234"DRAW_PARALLELOGRAM.");235}236237jfloat x11 = NEXT_FLOAT(b);238jfloat y11 = NEXT_FLOAT(b);239jfloat dx21 = NEXT_FLOAT(b);240jfloat dy21 = NEXT_FLOAT(b);241jfloat dx12 = NEXT_FLOAT(b);242jfloat dy12 = NEXT_FLOAT(b);243jfloat lwr21 = NEXT_FLOAT(b);244jfloat lwr12 = NEXT_FLOAT(b);245246MTLRenderer_DrawParallelogram(mtlc, dstOps,247x11, y11,248dx21, dy21,249dx12, dy12,250lwr21, lwr12);251break;252}253case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:254{255CHECK_PREVIOUS_OP(MTL_OP_OTHER);256jfloat x11 = NEXT_FLOAT(b);257jfloat y11 = NEXT_FLOAT(b);258jfloat dx21 = NEXT_FLOAT(b);259jfloat dy21 = NEXT_FLOAT(b);260jfloat dx12 = NEXT_FLOAT(b);261jfloat dy12 = NEXT_FLOAT(b);262jfloat lwr21 = NEXT_FLOAT(b);263jfloat lwr12 = NEXT_FLOAT(b);264265MTLRenderer_DrawAAParallelogram(mtlc, dstOps,266x11, y11,267dx21, dy21,268dx12, dy12,269lwr21, lwr12);270break;271}272273// fill ops274case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:275{276CHECK_PREVIOUS_OP(MTL_OP_OTHER);277278if ([mtlc useXORComposite]) {279commitEncodedCommands();280J2dTraceLn(J2D_TRACE_VERBOSE,281"FILL_RECT in XOR mode - Force commit earlier draw calls before FILL_RECT.");282}283284jint x = NEXT_INT(b);285jint y = NEXT_INT(b);286jint w = NEXT_INT(b);287jint h = NEXT_INT(b);288MTLRenderer_FillRect(mtlc, dstOps, x, y, w, h);289break;290}291case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:292{293CHECK_PREVIOUS_OP(MTL_OP_OTHER);294295if ([mtlc useXORComposite]) {296commitEncodedCommands();297J2dTraceLn(J2D_TRACE_VERBOSE,298"FILL_SPANS in XOR mode - Force commit earlier draw calls before FILL_SPANS.");299}300301jint count = NEXT_INT(b);302MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b);303SKIP_BYTES(b, count * BYTES_PER_SPAN);304break;305}306case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:307{308CHECK_PREVIOUS_OP(MTL_OP_OTHER);309310if ([mtlc useXORComposite]) {311commitEncodedCommands();312J2dTraceLn(J2D_TRACE_VERBOSE,313"FILL_PARALLELOGRAM in XOR mode - Force commit earlier draw calls before "314"FILL_PARALLELOGRAM.");315}316317jfloat x11 = NEXT_FLOAT(b);318jfloat y11 = NEXT_FLOAT(b);319jfloat dx21 = NEXT_FLOAT(b);320jfloat dy21 = NEXT_FLOAT(b);321jfloat dx12 = NEXT_FLOAT(b);322jfloat dy12 = NEXT_FLOAT(b);323MTLRenderer_FillParallelogram(mtlc, dstOps,324x11, y11,325dx21, dy21,326dx12, dy12);327break;328}329case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:330{331CHECK_PREVIOUS_OP(MTL_OP_OTHER);332jfloat x11 = NEXT_FLOAT(b);333jfloat y11 = NEXT_FLOAT(b);334jfloat dx21 = NEXT_FLOAT(b);335jfloat dy21 = NEXT_FLOAT(b);336jfloat dx12 = NEXT_FLOAT(b);337jfloat dy12 = NEXT_FLOAT(b);338MTLRenderer_FillAAParallelogram(mtlc, dstOps,339x11, y11,340dx21, dy21,341dx12, dy12);342break;343}344345// text-related ops346case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST:347{348CHECK_PREVIOUS_OP(MTL_OP_OTHER);349350if ([mtlc useXORComposite]) {351commitEncodedCommands();352J2dTraceLn(J2D_TRACE_VERBOSE,353"DRAW_GLYPH_LIST in XOR mode - Force commit earlier draw calls before "354"DRAW_GLYPH_LIST.");355}356357jint numGlyphs = NEXT_INT(b);358jint packedParams = NEXT_INT(b);359jfloat glyphListOrigX = NEXT_FLOAT(b);360jfloat glyphListOrigY = NEXT_FLOAT(b);361jboolean usePositions = EXTRACT_BOOLEAN(packedParams,362OFFSET_POSITIONS);363jboolean subPixPos = EXTRACT_BOOLEAN(packedParams,364OFFSET_SUBPIXPOS);365jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams,366OFFSET_RGBORDER);367jint lcdContrast = EXTRACT_BYTE(packedParams,368OFFSET_CONTRAST);369unsigned char *images = b;370unsigned char *positions;371jint bytesPerGlyph;372if (usePositions) {373positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE);374bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH;375} else {376positions = NULL;377bytesPerGlyph = BYTES_PER_GLYPH_IMAGE;378}379MTLTR_DrawGlyphList(env, mtlc, dstOps,380numGlyphs, usePositions,381subPixPos, rgbOrder, lcdContrast,382glyphListOrigX, glyphListOrigY,383images, positions);384SKIP_BYTES(b, numGlyphs * bytesPerGlyph);385break;386}387388// copy-related ops389case sun_java2d_pipe_BufferedOpCodes_COPY_AREA:390{391CHECK_PREVIOUS_OP(MTL_OP_OTHER);392jint x = NEXT_INT(b);393jint y = NEXT_INT(b);394jint w = NEXT_INT(b);395jint h = NEXT_INT(b);396jint dx = NEXT_INT(b);397jint dy = NEXT_INT(b);398MTLBlitLoops_CopyArea(env, mtlc, dstOps,399x, y, w, h, dx, dy);400break;401}402case sun_java2d_pipe_BufferedOpCodes_BLIT:403{404CHECK_PREVIOUS_OP(MTL_OP_OTHER);405jint packedParams = NEXT_INT(b);406jint sx1 = NEXT_INT(b);407jint sy1 = NEXT_INT(b);408jint sx2 = NEXT_INT(b);409jint sy2 = NEXT_INT(b);410jdouble dx1 = NEXT_DOUBLE(b);411jdouble dy1 = NEXT_DOUBLE(b);412jdouble dx2 = NEXT_DOUBLE(b);413jdouble dy2 = NEXT_DOUBLE(b);414jlong pSrc = NEXT_LONG(b);415jlong pDst = NEXT_LONG(b);416jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT);417jboolean texture = EXTRACT_BOOLEAN(packedParams,418OFFSET_TEXTURE);419jboolean xform = EXTRACT_BOOLEAN(packedParams,420OFFSET_XFORM);421jboolean isoblit = EXTRACT_BOOLEAN(packedParams,422OFFSET_ISOBLIT);423if (isoblit) {424MTLBlitLoops_IsoBlit(env, mtlc, pSrc, pDst,425xform, hint, texture,426sx1, sy1, sx2, sy2,427dx1, dy1, dx2, dy2);428} else {429jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE);430MTLBlitLoops_Blit(env, mtlc, pSrc, pDst,431xform, hint, srctype, texture,432sx1, sy1, sx2, sy2,433dx1, dy1, dx2, dy2);434}435break;436}437case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:438{439CHECK_PREVIOUS_OP(MTL_OP_OTHER);440jint sx = NEXT_INT(b);441jint sy = NEXT_INT(b);442jint dx = NEXT_INT(b);443jint dy = NEXT_INT(b);444jint w = NEXT_INT(b);445jint h = NEXT_INT(b);446jint dsttype = NEXT_INT(b);447jlong pSrc = NEXT_LONG(b);448jlong pDst = NEXT_LONG(b);449MTLBlitLoops_SurfaceToSwBlit(env, mtlc,450pSrc, pDst, dsttype,451sx, sy, dx, dy, w, h);452break;453}454case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:455{456jint x = NEXT_INT(b);457jint y = NEXT_INT(b);458jint w = NEXT_INT(b);459jint h = NEXT_INT(b);460jint maskoff = NEXT_INT(b);461jint maskscan = NEXT_INT(b);462jint masklen = NEXT_INT(b);463unsigned char *pMask = (masklen > 0) ? b : NULL;464if (mtlc == nil)465return;466CHECK_PREVIOUS_OP(MTL_OP_MASK_OP);467MTLMaskFill_MaskFill(mtlc, dstOps, x, y, w, h,468maskoff, maskscan, masklen, pMask);469SKIP_BYTES(b, masklen);470break;471}472case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:473{474CHECK_PREVIOUS_OP(MTL_OP_OTHER);475jint dstx = NEXT_INT(b);476jint dsty = NEXT_INT(b);477jint width = NEXT_INT(b);478jint height = NEXT_INT(b);479jint masklen = width * height * sizeof(jint);480MTLMaskBlit_MaskBlit(env, mtlc, dstOps,481dstx, dsty, width, height, b);482SKIP_BYTES(b, masklen);483break;484}485486// state-related ops487case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP:488{489CHECK_PREVIOUS_OP(MTL_OP_OTHER);490jint x1 = NEXT_INT(b);491jint y1 = NEXT_INT(b);492jint x2 = NEXT_INT(b);493jint y2 = NEXT_INT(b);494[mtlc setClipRectX1:x1 Y1:y1 X2:x2 Y2:y2];495break;496}497case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:498{499CHECK_PREVIOUS_OP(MTL_OP_OTHER);500[mtlc beginShapeClip:dstOps];501break;502}503case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:504{505CHECK_PREVIOUS_OP(MTL_OP_SHAPE_CLIP_SPANS);506// This results in creation of new render encoder with507// stencil buffer set as render target508jint count = NEXT_INT(b);509MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b);510SKIP_BYTES(b, count * BYTES_PER_SPAN);511break;512}513case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:514{515CHECK_PREVIOUS_OP(MTL_OP_OTHER);516[mtlc endShapeClip:dstOps];517break;518}519case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:520{521CHECK_PREVIOUS_OP(MTL_OP_OTHER);522[mtlc resetClip];523break;524}525case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:526{527CHECK_PREVIOUS_OP(MTL_OP_OTHER);528jint rule = NEXT_INT(b);529jfloat extraAlpha = NEXT_FLOAT(b);530jint flags = NEXT_INT(b);531[mtlc setAlphaCompositeRule:rule extraAlpha:extraAlpha flags:flags];532break;533}534case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:535{536CHECK_PREVIOUS_OP(MTL_OP_OTHER);537jint xorPixel = NEXT_INT(b);538[mtlc setXorComposite:xorPixel];539break;540}541case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:542{543/* TODO: check whether something needs to be done here if we are moving out of XOR composite544commitEncodedCommands();545MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];546[cbwrapper onComplete];547548J2dTraceLn(J2D_TRACE_VERBOSE,549"RESET_COMPOSITE - Force commit earlier draw calls before RESET_COMPOSITE.");*/550551CHECK_PREVIOUS_OP(MTL_OP_OTHER);552[mtlc resetComposite];553break;554}555case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:556{557CHECK_PREVIOUS_OP(MTL_OP_OTHER);558jdouble m00 = NEXT_DOUBLE(b);559jdouble m10 = NEXT_DOUBLE(b);560jdouble m01 = NEXT_DOUBLE(b);561jdouble m11 = NEXT_DOUBLE(b);562jdouble m02 = NEXT_DOUBLE(b);563jdouble m12 = NEXT_DOUBLE(b);564[mtlc setTransformM00:m00 M10:m10 M01:m01 M11:m11 M02:m02 M12:m12];565break;566}567case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:568{569CHECK_PREVIOUS_OP(MTL_OP_OTHER);570[mtlc resetTransform];571break;572}573574// context-related ops575case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:576{577CHECK_PREVIOUS_OP(MTL_OP_OTHER);578jlong pSrc = NEXT_LONG(b);579jlong pDst = NEXT_LONG(b);580581if (mtlc != NULL) {582[mtlc.encoderManager endEncoder];583MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];584id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];585[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {586[cbwrapper release];587}];588[commandbuf commit];589}590mtlc = [MTLContext setSurfacesEnv:env src:pSrc dst:pDst];591dstOps = (BMTLSDOps *)jlong_to_ptr(pDst);592break;593}594case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:595{596CHECK_PREVIOUS_OP(MTL_OP_OTHER);597jlong pConfigInfo = NEXT_LONG(b);598MTLGraphicsConfigInfo *mtlInfo =599(MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);600601if (mtlInfo == NULL) {602603} else {604MTLContext *newMtlc = mtlInfo->context;605if (newMtlc == NULL) {606607} else {608if (mtlc != NULL) {609[mtlc.encoderManager endEncoder];610MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];611id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];612[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {613[cbwrapper release];614}];615[commandbuf commit];616}617mtlc = newMtlc;618dstOps = NULL;619}620}621break;622}623case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:624{625CHECK_PREVIOUS_OP(MTL_OP_OTHER);626jlong pData = NEXT_LONG(b);627BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);628if (mtlsdo != NULL) {629CONTINUE_IF_NULL(mtlc);630MTLTR_FreeGlyphCaches();631MTLSD_Delete(env, mtlsdo);632}633break;634}635case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:636{637CHECK_PREVIOUS_OP(MTL_OP_OTHER);638jlong pData = NEXT_LONG(b);639BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);640if (mtlsdo != NULL) {641CONTINUE_IF_NULL(mtlc);642MTLSD_Delete(env, mtlsdo);643if (mtlsdo->privOps != NULL) {644free(mtlsdo->privOps);645}646}647break;648}649case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:650{651CHECK_PREVIOUS_OP(MTL_OP_OTHER);652jlong pConfigInfo = NEXT_LONG(b);653CONTINUE_IF_NULL(mtlc);654655if (mtlc != NULL) {656[mtlc.encoderManager endEncoder];657}658659MTLGC_DestroyMTLGraphicsConfig(pConfigInfo);660661mtlc = NULL;662// dstOps = NULL;663break;664}665666case sun_java2d_pipe_BufferedOpCodes_SYNC:667{668CHECK_PREVIOUS_OP(MTL_OP_SYNC);669break;670}671672// special no-op (mainly used for achieving 8-byte alignment)673case sun_java2d_pipe_BufferedOpCodes_NOOP:674break;675676// paint-related ops677case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT:678{679CHECK_PREVIOUS_OP(MTL_OP_RESET_PAINT);680[mtlc resetPaint];681break;682}683case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:684{685CHECK_PREVIOUS_OP(MTL_OP_SET_COLOR);686jint pixel = NEXT_INT(b);687[mtlc setColorPaint:pixel];688break;689}690case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:691{692CHECK_PREVIOUS_OP(MTL_OP_OTHER);693jboolean useMask= NEXT_BOOLEAN(b);694jboolean cyclic = NEXT_BOOLEAN(b);695jdouble p0 = NEXT_DOUBLE(b);696jdouble p1 = NEXT_DOUBLE(b);697jdouble p3 = NEXT_DOUBLE(b);698jint pixel1 = NEXT_INT(b);699jint pixel2 = NEXT_INT(b);700[mtlc setGradientPaintUseMask:useMask701cyclic:cyclic702p0:p0703p1:p1704p3:p3705pixel1:pixel1706pixel2:pixel2];707break;708}709case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:710{711CHECK_PREVIOUS_OP(MTL_OP_OTHER);712jboolean useMask = NEXT_BOOLEAN(b);713jboolean linear = NEXT_BOOLEAN(b);714jint cycleMethod = NEXT_INT(b);715jint numStops = NEXT_INT(b);716jfloat p0 = NEXT_FLOAT(b);717jfloat p1 = NEXT_FLOAT(b);718jfloat p3 = NEXT_FLOAT(b);719void *fractions, *pixels;720fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));721pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));722[mtlc setLinearGradientPaint:useMask723linear:linear724cycleMethod:cycleMethod725numStops:numStops726p0:p0727p1:p1728p3:p3729fractions:fractions730pixels:pixels];731break;732}733case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:734{735CHECK_PREVIOUS_OP(MTL_OP_OTHER);736jboolean useMask = NEXT_BOOLEAN(b);737jboolean linear = NEXT_BOOLEAN(b);738jint numStops = NEXT_INT(b);739jint cycleMethod = NEXT_INT(b);740jfloat m00 = NEXT_FLOAT(b);741jfloat m01 = NEXT_FLOAT(b);742jfloat m02 = NEXT_FLOAT(b);743jfloat m10 = NEXT_FLOAT(b);744jfloat m11 = NEXT_FLOAT(b);745jfloat m12 = NEXT_FLOAT(b);746jfloat focusX = NEXT_FLOAT(b);747void *fractions, *pixels;748fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));749pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));750[mtlc setRadialGradientPaint:useMask751linear:linear752cycleMethod:cycleMethod753numStops:numStops754m00:m00755m01:m01756m02:m02757m10:m10758m11:m11759m12:m12760focusX:focusX761fractions:fractions762pixels:pixels];763break;764}765case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:766{767CHECK_PREVIOUS_OP(MTL_OP_OTHER);768jboolean useMask= NEXT_BOOLEAN(b);769jboolean filter = NEXT_BOOLEAN(b);770jlong pSrc = NEXT_LONG(b);771jdouble xp0 = NEXT_DOUBLE(b);772jdouble xp1 = NEXT_DOUBLE(b);773jdouble xp3 = NEXT_DOUBLE(b);774jdouble yp0 = NEXT_DOUBLE(b);775jdouble yp1 = NEXT_DOUBLE(b);776jdouble yp3 = NEXT_DOUBLE(b);777[mtlc setTexturePaint:useMask778pSrcOps:pSrc779filter:filter780xp0:xp0781xp1:xp1782xp3:xp3783yp0:yp0784yp1:yp1785yp3:yp3];786break;787}788789// BufferedImageOp-related ops790case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP:791{792CHECK_PREVIOUS_OP(MTL_OP_OTHER);793jlong pSrc = NEXT_LONG(b);794jboolean edgeZero = NEXT_BOOLEAN(b);795jint kernelWidth = NEXT_INT(b);796jint kernelHeight = NEXT_INT(b);797798BMTLSDOps * bmtlsdOps = (BMTLSDOps *)pSrc;799MTLConvolveOp * convolveOp = [[MTLConvolveOp alloc] init:edgeZero800kernelWidth:kernelWidth801kernelHeight:kernelHeight802srcWidth:bmtlsdOps->width803srcHeight:bmtlsdOps->height804kernel:b805device:mtlc.device806];807[mtlc setBufImgOp:convolveOp];808SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));809break;810}811case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:812{813CHECK_PREVIOUS_OP(MTL_OP_OTHER);814[mtlc setBufImgOp:NULL];815break;816}817case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:818{819CHECK_PREVIOUS_OP(MTL_OP_OTHER);820jlong pSrc = NEXT_LONG(b);821jboolean nonPremult = NEXT_BOOLEAN(b);822jint numFactors = 4;823unsigned char *scaleFactors = b;824unsigned char *offsets = (b + numFactors * sizeof(jfloat));825MTLRescaleOp * rescaleOp =826[[MTLRescaleOp alloc] init:nonPremult factors:scaleFactors offsets:offsets];827[mtlc setBufImgOp:rescaleOp];828SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);829break;830}831case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:832{833CHECK_PREVIOUS_OP(MTL_OP_OTHER);834[mtlc setBufImgOp:NULL];835break;836}837case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:838{839CHECK_PREVIOUS_OP(MTL_OP_OTHER);840jlong pSrc = NEXT_LONG(b);841jboolean nonPremult = NEXT_BOOLEAN(b);842jboolean shortData = NEXT_BOOLEAN(b);843jint numBands = NEXT_INT(b);844jint bandLength = NEXT_INT(b);845jint offset = NEXT_INT(b);846jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte);847void *tableValues = b;848849MTLLookupOp * lookupOp = [[MTLLookupOp alloc] init:nonPremult850shortData:shortData851numBands:numBands852bandLength:bandLength853offset:offset854tableValues:tableValues855device:mtlc.device];856[mtlc setBufImgOp:lookupOp];857SKIP_BYTES(b, numBands * bandLength * bytesPerElem);858break;859}860case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:861{862CHECK_PREVIOUS_OP(MTL_OP_OTHER);863[mtlc setBufImgOp:NULL];864break;865}866867default:868J2dRlsTraceLn1(J2D_TRACE_ERROR,869"MTLRenderQueue_flushBuffer: invalid opcode=%d", opcode);870return;871}872}873874if (mtlc != NULL) {875if (mtlPreviousOp == MTL_OP_MASK_OP) {876MTLVertexCache_DisableMaskCache(mtlc);877}878[mtlc.encoderManager endEncoder];879MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];880id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];881[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {882[cbwrapper release];883}];884[commandbuf commit];885BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination();886if (dstOps != NULL) {887MTLSDOps *dstMTLOps = (MTLSDOps *)dstOps->privOps;888MTLLayer *layer = (MTLLayer*)dstMTLOps->layer;889if (layer != NULL) {890[layer startDisplayLink];891}892}893}894RESET_PREVIOUS_OP();895}896}897898/**899* Returns a pointer to the "current" context, as set by the last SET_SURFACES900* or SET_SCRATCH_SURFACE operation.901*/902MTLContext *903MTLRenderQueue_GetCurrentContext()904{905return mtlc;906}907908/**909* Returns a pointer to the "current" destination surface, as set by the last910* SET_SURFACES operation.911*/912BMTLSDOps *913MTLRenderQueue_GetCurrentDestination()914{915return dstOps;916}917918/**919* commit earlier encoded commmands920* these would be rendered to the back-buffer - which is read in shader while rendering in XOR mode921*/922void commitEncodedCommands() {923[mtlc.encoderManager endEncoder];924925MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper];926id <MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];927[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {928[cbwrapper release];929}];930[commandbuf commit];931[commandbuf waitUntilCompleted];932}933934935