diff -r 05aae7591f43 src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m Wed Sep 11 17:47:02 2019 +0300 +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m Wed Sep 18 16:50:34 2019 +0530 @@ -463,8 +463,14 @@ case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS: { jint count = NEXT_INT(b); - MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b); - SKIP_BYTES(b, count * BYTES_PER_SPAN); + jint *spanbuf = (jint *)b; +fprintf(stdout, "MTLRenderQueue.m#FILL_SPANS count %d, b %p\n", count, spanbuf); +fprintf(stdout, "spanBuf[0] %d\n", spanbuf[0]); +fprintf(stdout, "spanBuf[1] %d\n", spanbuf[1]); +fprintf(stdout, "spanBuf[2] %d\n", spanbuf[2]); +fprintf(stdout, "spanBuf[3] %d\n", spanbuf[3]); + MTLRenderer_FillSpans(mtlc, dstOps, count, spanbuf); + //SKIP_BYTES(b, count * BYTES_PER_SPAN); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM: diff -r 05aae7591f43 src/java.desktop/share/classes/sun/java2d/pipe/BufferedRenderPipe.java --- a/src/java.desktop/share/classes/sun/java2d/pipe/BufferedRenderPipe.java Wed Sep 11 17:47:02 2019 +0300 +++ b/src/java.desktop/share/classes/sun/java2d/pipe/BufferedRenderPipe.java Wed Sep 18 16:50:34 2019 +0530 @@ -390,6 +390,10 @@ SpanIterator si, long iterator, int transx, int transy); + private native int[] fillSpansMetal(RenderQueue rq, long buf, + int pos, int limit, + SpanIterator si, long iterator, + int transx, int transy); protected void fillSpans(SunGraphics2D sg2d, SpanIterator si, int transx, int transy) { @@ -397,11 +401,23 @@ try { validateContext(sg2d); rq.ensureCapacity(24); // so that we have room for at least a span - int newpos = fillSpans(rq, buf.getAddress(), + String metal = System.getProperty("sun,java2d.metal"); + if (metal != null && metal.equals("false")) { + int newpos = fillSpans(rq, buf.getAddress(), buf.position(), buf.capacity(), si, si.getNativeIterator(), transx, transy); - buf.position(newpos); + buf.position(newpos); + } else { + int[] spanbuf= fillSpansMetal(rq, buf.getAddress(), + buf.position(), buf.capacity(), + si, si.getNativeIterator(), + transx, transy); + System.out.println("spanCount length " + spanbuf.length); + buf.putInt(FILL_SPANS); + buf.putInt(spanbuf.length); + buf.put(spanbuf); + } } finally { rq.unlock(); } diff -r 05aae7591f43 src/java.desktop/share/native/libawt/java2d/pipe/BufferedRenderPipe.c --- a/src/java.desktop/share/native/libawt/java2d/pipe/BufferedRenderPipe.c Wed Sep 11 17:47:02 2019 +0300 +++ b/src/java.desktop/share/native/libawt/java2d/pipe/BufferedRenderPipe.c Wed Sep 18 16:50:34 2019 +0530 @@ -144,3 +144,105 @@ // return the current byte position return bpos; } + +JNIEXPORT jintArray JNICALL +Java_sun_java2d_pipe_BufferedRenderPipe_fillSpansMetal + (JNIEnv *env, jobject pipe, + jobject rq, jlong buf, + jint bpos, jint limit, + jobject si, jlong pIterator, + jint transx, jint transy) +{ + SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *)jlong_to_ptr(pIterator); + void *srData; + jint spanbox[4]; + jint spanCount = 0; + jint remainingBytes, remainingSpans; + unsigned char *bbuf; + jint *ibuf; + jint ipos; + jboolean hasException; + + J2dTraceLn2(J2D_TRACE_INFO, + "BufferedRenderPipe_fillSpans: bpos=%d limit=%d", + bpos, limit); + + if (JNU_IsNull(env, rq)) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "BufferedRenderPipe_fillSpans: rq is null"); + return NULL; + } + + if (JNU_IsNull(env, si)) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "BufferedRenderPipe_fillSpans: span iterator is null"); + return NULL; + } + + if (pFuncs == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "BufferedRenderPipe_fillSpans: native iterator not supplied"); + return NULL; + } + + bbuf = (unsigned char *)jlong_to_ptr(buf); + if (bbuf == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "BufferedRenderPipe_fillSpans: cannot get direct buffer address"); + return NULL; + } + + // adjust the int pointer to the current buffer position + ibuf = (jint *)(bbuf + bpos); + + remainingBytes = limit - bpos; + remainingSpans = remainingBytes / BYTES_PER_SPAN; + + jint *spanbuf = (jint *)calloc(limit, sizeof(int)); + jint spanpos = 0; + + srData = (*pFuncs->open)(env, si); + while ((*pFuncs->nextSpan)(srData, spanbox)) { + if (remainingSpans == 0) { + // fill in span count + + bpos = BYTES_PER_HEADER; + + // calculate new limits + remainingBytes = limit - bpos; + remainingSpans = remainingBytes / BYTES_PER_SPAN; + spanCount = 0; + } + + // enqueue span + spanbuf[spanpos++] = spanbox[0] + transx; // x1 + spanbuf[spanpos++] = spanbox[1] + transy; // y1 + spanbuf[spanpos++] = spanbox[2] + transx; // x2 + spanbuf[spanpos++] = spanbox[3] + transy; // y2 + + // update positions + bpos += BYTES_PER_SPAN; + spanCount++; + remainingSpans--; + } + (*pFuncs->close)(env, srData); + +fprintf(stdout, "spanbuf %p\n", spanbuf); +fprintf(stdout, "spanbuf[0] %d\n", spanbuf[0]); +fprintf(stdout, "spanbuf[1] %d\n", spanbuf[1]); +fprintf(stdout, "spanbuf[2] %d\n", spanbuf[2]); +fprintf(stdout, "spanbuf[3] %d\n", spanbuf[3]); + + + fprintf(stdout, "spanCount %d\n", spanCount); + + jintArray ret = NULL; + ret = (*env)->NewIntArray(env, spanCount*4); + jint *elems = (*env)->GetIntArrayElements(env, ret, 0); + CHECK_NULL_RETURN(elems, NULL); + for(int i = 0; i < spanCount*4; ++i) { + elems[i] = spanbuf[i]; + } + (*env)->ReleaseIntArrayElements(env, ret, elems, 0); + return ret; +}