8298217: Regressions 30-110% in SwingMark on MacOS, more so on aarch64
Reviewed-by: avu, prr, jdv
This commit is contained in:
parent
0ecad28daa
commit
3b7970cab3
@ -51,11 +51,6 @@ enum {
|
||||
MTL_OP_SYNC,
|
||||
MTL_OP_SHAPE_CLIP_SPANS,
|
||||
MTL_OP_MASK_OP,
|
||||
MTL_OP_FILL_PARALLELOGRAM,
|
||||
MTL_OP_FILL_RECT,
|
||||
MTL_OP_DRAW_LINE,
|
||||
MTL_OP_DRAW_RECT,
|
||||
MTL_OP_DRAW_PARALLELOGRAM,
|
||||
MTL_OP_OTHER
|
||||
};
|
||||
/*
|
||||
|
@ -48,18 +48,6 @@ jint mtlPreviousOp = MTL_OP_INIT;
|
||||
|
||||
extern void MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo);
|
||||
|
||||
bool isDrawOp (jint op) {
|
||||
switch(op) {
|
||||
case MTL_OP_DRAW_LINE:
|
||||
case MTL_OP_DRAW_RECT:
|
||||
case MTL_OP_DRAW_PARALLELOGRAM:
|
||||
case MTL_OP_FILL_RECT:
|
||||
case MTL_OP_FILL_PARALLELOGRAM:
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void MTLRenderQueue_CheckPreviousOp(jint op) {
|
||||
|
||||
if (mtlPreviousOp == op) {
|
||||
@ -67,16 +55,6 @@ void MTLRenderQueue_CheckPreviousOp(jint op) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDrawOp(mtlPreviousOp)) {
|
||||
// submit the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
if (isDrawOp(op)) {
|
||||
// Do not cause endEncoder if we continue with Draw operations
|
||||
mtlPreviousOp = op;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == MTL_OP_SET_COLOR) {
|
||||
if (mtlPreviousOp != MTL_OP_MASK_OP) {
|
||||
return; // SET_COLOR should not cause endEncoder
|
||||
@ -150,7 +128,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
// draw ops
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_LINE);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -166,10 +144,9 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_RECT);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
|
||||
commitEncodedCommands();
|
||||
J2dTraceLn(J2D_TRACE_VERBOSE,
|
||||
"DRAW_RECT in XOR mode - Force commit earlier draw calls before DRAW_RECT.");
|
||||
@ -251,7 +228,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_PARALLELOGRAM);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -299,7 +276,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
// fill ops
|
||||
case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_FILL_RECT);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -331,7 +308,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_FILL_PARALLELOGRAM);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -605,7 +582,6 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
jlong pDst = NEXT_LONG(b);
|
||||
|
||||
if (mtlc != NULL) {
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
[mtlc.encoderManager endEncoder];
|
||||
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
||||
@ -633,7 +609,6 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
|
||||
} else {
|
||||
if (mtlc != NULL) {
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
[mtlc.encoderManager endEncoder];
|
||||
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
||||
@ -903,8 +878,6 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
if (mtlPreviousOp == MTL_OP_MASK_OP) {
|
||||
MTLVertexCache_DisableMaskCache(mtlc);
|
||||
}
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
|
||||
[mtlc.encoderManager endEncoder];
|
||||
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
||||
@ -950,9 +923,6 @@ MTLRenderQueue_GetCurrentDestination()
|
||||
* these would be rendered to the back-buffer - which is read in shader while rendering in XOR mode
|
||||
*/
|
||||
void commitEncodedCommands() {
|
||||
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
|
||||
[mtlc.encoderManager endEncoder];
|
||||
|
||||
MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||
|
@ -72,9 +72,5 @@ void MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
||||
jfloat fx11, jfloat fy11,
|
||||
jfloat dx21, jfloat dy21,
|
||||
jfloat dx12, jfloat dy12);
|
||||
void MTLRenderer_AddVertexToBatch(float x, float y);
|
||||
void MTLRenderer_SubmitVertexBatch(MTLContext* mtlc, BMTLSDOps* dstOps);
|
||||
void MTLRenderer_SetPrimitiveType(MTLPrimitiveType type);
|
||||
|
||||
|
||||
#endif /* MTLRenderer_h_Included */
|
||||
|
@ -35,95 +35,6 @@
|
||||
#include "MTLUtils.h"
|
||||
#import "MTLLayer.h"
|
||||
|
||||
/**
|
||||
* The max size of the vertex batch.
|
||||
*
|
||||
* Note:
|
||||
* This is the max number of vertices (of struct Vertex - 8 bytes)
|
||||
* that can be accommodated in 4KB.
|
||||
*
|
||||
* [MTLRenderCommandEncoder setVertexBytes] expects the data size
|
||||
* to be less than or equal to 4KB.
|
||||
*/
|
||||
static const int VERTEX_BATCH_SIZE = 510;
|
||||
|
||||
static const int MAX_NO_OF_BATCHES = 20;
|
||||
|
||||
struct primDetail {
|
||||
MTLPrimitiveType type;
|
||||
int vertexStart;
|
||||
int vertexEnd;
|
||||
};
|
||||
|
||||
static struct Vertex vertexBatch[VERTEX_BATCH_SIZE];
|
||||
static struct primDetail PrimitivesBatch[MAX_NO_OF_BATCHES];
|
||||
static int currentIndexInBatch = 0;
|
||||
static MTLPrimitiveType currentMTLPrimitiveType = MTLPrimitiveTypeTriangleStrip; // invalid type that we do not use in this renderer
|
||||
static int currentBatchNo = -1;
|
||||
|
||||
|
||||
void MTLRenderer_SetPrimitiveType(MTLPrimitiveType type) {
|
||||
if (type != currentMTLPrimitiveType) {
|
||||
|
||||
if (currentBatchNo != -1) {
|
||||
// close the current batch
|
||||
PrimitivesBatch[currentBatchNo].vertexEnd = currentIndexInBatch - 1;
|
||||
}
|
||||
|
||||
// Start a new batch
|
||||
currentBatchNo++;
|
||||
PrimitivesBatch[currentBatchNo].type = type;
|
||||
PrimitivesBatch[currentBatchNo].vertexStart = currentIndexInBatch;
|
||||
PrimitivesBatch[currentBatchNo].vertexEnd = currentIndexInBatch;
|
||||
J2dRlsTraceLn1(J2D_TRACE_ERROR, "MTLRenderer_SetPrimitiveType: starting a new batch : batch %d", currentBatchNo);
|
||||
|
||||
currentMTLPrimitiveType = type;
|
||||
}
|
||||
}
|
||||
|
||||
inline void MTLRenderer_AddVertexToBatch(float x, float y)
|
||||
{
|
||||
vertexBatch[currentIndexInBatch].position[0] = x;
|
||||
vertexBatch[currentIndexInBatch].position[1] = y;
|
||||
|
||||
currentIndexInBatch++;
|
||||
}
|
||||
|
||||
void MTLRenderer_SubmitVertexBatch(MTLContext *mtlc, BMTLSDOps * dstOps)
|
||||
{
|
||||
if (currentIndexInBatch == 0) return;
|
||||
if (currentBatchNo == -1) return;
|
||||
|
||||
// close the current batch
|
||||
PrimitivesBatch[currentBatchNo].vertexEnd = currentIndexInBatch - 1;
|
||||
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
|
||||
if (mtlEncoder == nil) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_SubmitVertexBatch: error creating MTLRenderCommandEncoder.");
|
||||
return;
|
||||
}
|
||||
|
||||
[mtlEncoder setVertexBytes:vertexBatch length:currentIndexInBatch * sizeof(struct Vertex) atIndex:MeshVertexBuffer];
|
||||
|
||||
// Iterate through PrimitivesBatch array
|
||||
for (int i = 0; i <= currentBatchNo; i++) {
|
||||
int numVertices = PrimitivesBatch[i].vertexEnd - PrimitivesBatch[i].vertexStart + 1;
|
||||
J2dRlsTraceLn2(J2D_TRACE_ERROR, "MTLRenderer_SubmitVertexBatch: total vertices in batch %d = %d", i, numVertices);
|
||||
[mtlEncoder drawPrimitives: PrimitivesBatch[i].type
|
||||
vertexStart: PrimitivesBatch[i].vertexStart
|
||||
vertexCount: numVertices];
|
||||
}
|
||||
|
||||
// Reset the index
|
||||
currentIndexInBatch = 0;
|
||||
|
||||
// Reset the batches
|
||||
currentBatchNo = -1;
|
||||
|
||||
// Reset to type that we do not use in this renderer
|
||||
currentMTLPrimitiveType = MTLPrimitiveTypeTriangleStrip;
|
||||
}
|
||||
/**
|
||||
* Note: Some of the methods in this file apply a "magic number"
|
||||
* translation to line segments. It is same as what we have in
|
||||
@ -154,16 +65,12 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
|
||||
J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawLine (x1=%d y1=%d x2=%d y2=%d), dst tex=%p", x1, y1, x2, y2, dstOps->pTexture);
|
||||
|
||||
// Make sure we have space for 2 more vertices in the batch
|
||||
if (((currentIndexInBatch + 2) > VERTEX_BATCH_SIZE) ||
|
||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
||||
// encode the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
}
|
||||
|
||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeLine);
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
if (mtlEncoder == nil)
|
||||
return;
|
||||
|
||||
// DrawLine implementation same as in OGLRenderer.c
|
||||
struct Vertex verts[2];
|
||||
if (y1 == y2) {
|
||||
// horizontal
|
||||
float fx1 = (float)x1;
|
||||
@ -173,8 +80,11 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
if (x1 > x2) {
|
||||
float t = fx1; fx1 = fx2; fx2 = t;
|
||||
}
|
||||
MTLRenderer_AddVertexToBatch(fx1 + 0.2f, fy);
|
||||
MTLRenderer_AddVertexToBatch(fx2 + 1.2f, fy);
|
||||
|
||||
verts[0].position[0] = fx1 + 0.2f;
|
||||
verts[0].position[1] = fy;
|
||||
verts[1].position[0] = fx2 + 1.2f;
|
||||
verts[1].position[1] = fy;
|
||||
} else if (x1 == x2) {
|
||||
// vertical
|
||||
float fx = ((float)x1) + 0.2f;
|
||||
@ -184,8 +94,11 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
if (y1 > y2) {
|
||||
float t = fy1; fy1 = fy2; fy2 = t;
|
||||
}
|
||||
MTLRenderer_AddVertexToBatch(fx, fy1 + 0.2f);
|
||||
MTLRenderer_AddVertexToBatch(fx, fy2 + 1.2f);
|
||||
|
||||
verts[0].position[0] = fx;
|
||||
verts[0].position[1] = fy1 + 0.2f;
|
||||
verts[1].position[0] = fx;
|
||||
verts[1].position[1] = fy2 + 1.2f;
|
||||
} else {
|
||||
// diagonal
|
||||
float fx1 = (float)x1;
|
||||
@ -208,10 +121,14 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
fy1 += 0.8f;
|
||||
fy2 -= 0.2f;
|
||||
}
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx1, fy1);
|
||||
MTLRenderer_AddVertexToBatch(fx2, fy2);
|
||||
verts[0].position[0] = fx1;
|
||||
verts[0].position[1] = fy1;
|
||||
verts[1].position[0] = fx2;
|
||||
verts[1].position[1] = fy2;
|
||||
}
|
||||
|
||||
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
|
||||
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
|
||||
}
|
||||
|
||||
void MTLRenderer_DrawPixel(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y) {
|
||||
@ -245,35 +162,27 @@ void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y,
|
||||
id<MTLTexture> dest = dstOps->pTexture;
|
||||
J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
|
||||
|
||||
// Make sure we have space for 8 more vertices in the batch
|
||||
if ( ((currentIndexInBatch + 8) > VERTEX_BATCH_SIZE) ||
|
||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
||||
|
||||
// encode the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
}
|
||||
|
||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeLine);
|
||||
|
||||
// TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
if (mtlEncoder == nil)
|
||||
return;
|
||||
|
||||
// Translate each vertex by a fraction so
|
||||
// that we hit pixel centers.
|
||||
const int verticesCount = 5;
|
||||
float fx = (float)x + 0.2f;
|
||||
float fy = (float)y + 0.5f;
|
||||
float fw = (float)w;
|
||||
float fh = (float)h;
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx, fy);
|
||||
MTLRenderer_AddVertexToBatch(fx+fw, fy);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx+fw, fy);
|
||||
MTLRenderer_AddVertexToBatch(fx+fw, fy+fh);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx+fw, fy+fh);
|
||||
MTLRenderer_AddVertexToBatch(fx, fy+fh);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx, fy+fh);
|
||||
MTLRenderer_AddVertexToBatch(fx, fy);
|
||||
struct Vertex vertices[5] = {
|
||||
{{fx, fy}},
|
||||
{{fx + fw, fy}},
|
||||
{{fx + fw, fy + fh}},
|
||||
{{fx, fy + fh}},
|
||||
{{fx, fy}},
|
||||
};
|
||||
[mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
|
||||
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount];
|
||||
}
|
||||
|
||||
const int POLYLINE_BUF_SIZE = 64;
|
||||
@ -506,23 +415,24 @@ MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have space for 6 more vertices in the batch
|
||||
if ( ((currentIndexInBatch + 6) > VERTEX_BATCH_SIZE) ||
|
||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
||||
// encode the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
}
|
||||
|
||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeTriangle);
|
||||
struct Vertex verts[QUAD_VERTEX_COUNT] = {
|
||||
{ {x, y}},
|
||||
{ {x, y+h}},
|
||||
{ {x+w, y}},
|
||||
{ {x+w, y+h}
|
||||
}};
|
||||
|
||||
|
||||
MTLRenderer_AddVertexToBatch(x, y);
|
||||
MTLRenderer_AddVertexToBatch(x, y+h);
|
||||
MTLRenderer_AddVertexToBatch(x+w, y);
|
||||
id<MTLTexture> dest = dstOps->pTexture;
|
||||
J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_FillRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(x, y+h);
|
||||
MTLRenderer_AddVertexToBatch(x+w, y);
|
||||
MTLRenderer_AddVertexToBatch(x+w, y+h);
|
||||
// Encode render command.
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
if (mtlEncoder == nil)
|
||||
return;
|
||||
|
||||
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
|
||||
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
|
||||
}
|
||||
|
||||
void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
|
||||
@ -643,22 +553,23 @@ MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
||||
dx21, dy21,
|
||||
dx12, dy12, dest);
|
||||
|
||||
// Make sure we have space for 6 more vertices in the batch
|
||||
if ( ((currentIndexInBatch + 6) > VERTEX_BATCH_SIZE) ||
|
||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
||||
// encode the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
struct Vertex verts[QUAD_VERTEX_COUNT] = {
|
||||
{ {fx11, fy11}},
|
||||
{ {fx11+dx21, fy11+dy21}},
|
||||
{ {fx11+dx12, fy11+dy12}},
|
||||
{ {fx11 + dx21 + dx12, fy11+ dy21 + dy12}
|
||||
}};
|
||||
|
||||
// Encode render command.
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];;
|
||||
|
||||
if (mtlEncoder == nil) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillParallelogram: error creating MTLRenderCommandEncoder.");
|
||||
return;
|
||||
}
|
||||
|
||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeTriangle);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11+dx21, fy11+dy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + dx12, fy11+ dy21 + dy12);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + dx12, fy11+ dy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11+dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
|
||||
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
|
||||
}
|
||||
|
||||
void
|
||||
@ -720,66 +631,69 @@ MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
||||
// Each quad is encoded using two triangles
|
||||
// For 4 segments - there are 8 triangles in total
|
||||
// Each triangle has 3 vertices
|
||||
|
||||
const int TOTAL_VERTICES = 8 * 3;
|
||||
// Make sure we have space for 24 more vertices in the batch
|
||||
if ( ((currentIndexInBatch + TOTAL_VERTICES) > VERTEX_BATCH_SIZE) ||
|
||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
||||
// encode the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
}
|
||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeTriangle);
|
||||
|
||||
struct Vertex vertexList[TOTAL_VERTICES];
|
||||
int i = 0;
|
||||
|
||||
// TOP segment, to left side of RIGHT edge
|
||||
// "width" of original pgram, "height" of hor. line size
|
||||
fx11 = ox11;
|
||||
fy11 = oy11;
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21, fy11 + dy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx12, fy11 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
|
||||
// RIGHT segment, to top of BOTTOM edge
|
||||
// "width" of vert. line size , "height" of original pgram
|
||||
fx11 = ox11 + dx21;
|
||||
fy11 = oy11 + dy21;
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21, fy11 + ldy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
|
||||
// BOTTOM segment, from right side of LEFT edge
|
||||
// "width" of original pgram, "height" of hor. line size
|
||||
fx11 = ox11 + dx12 + ldx21;
|
||||
fy11 = oy11 + dy12 + ldy21;
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21, fy11 + dy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx12, fy11 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
|
||||
// LEFT segment, from bottom of TOP edge
|
||||
// "width" of vert. line size , "height" of inner pgram
|
||||
fx11 = ox11 + ldx12;
|
||||
fy11 = oy11 + ldy12;
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21, fy11 + ldy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
|
||||
// Encode render command.
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
|
||||
if (mtlEncoder == nil) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawParallelogram: error creating MTLRenderCommandEncoder.");
|
||||
return;
|
||||
}
|
||||
|
||||
[mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer];
|
||||
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:TOTAL_VERTICES];
|
||||
} else {
|
||||
// The line width ratios were large enough to consume
|
||||
// the entire hole in the middle of the parallelogram
|
||||
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, JetBrains s.r.o.. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8287600 8291266
|
||||
* @requires os.family == "mac"
|
||||
* @summary [macosx] Some primitives do not render in metal pipeline
|
||||
* @run main DrawPrimitivesTest
|
||||
*/
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Robot;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public abstract class DrawPrimitivesTest extends JFrame {
|
||||
private final static int W = 800;
|
||||
private final static int H = 800;
|
||||
private final static Color[] color = { Color.RED, Color.BLUE, Color.GREEN};
|
||||
private final static int COLOR_TOLERANCE = 10;
|
||||
private final CountDownLatch latchRender = new CountDownLatch(1);
|
||||
private volatile int frameX0 = 0;
|
||||
private volatile int frameY0 = 0;
|
||||
private final String name;
|
||||
|
||||
|
||||
private static boolean isAlmostEqual(Color c1, Color c2) {
|
||||
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE &&
|
||||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE &&
|
||||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException, AWTException, InvocationTargetException {
|
||||
new DrawPrimitivesTest("drawLine") {
|
||||
public void renderPrimitive(Graphics2D g2d, int x0, int y0, int w, int h) {
|
||||
g2d.drawLine(x0, y0, x0+w, y0+h);
|
||||
}
|
||||
}.runTest();
|
||||
|
||||
new DrawPrimitivesTest("fillRect") {
|
||||
public void renderPrimitive(Graphics2D g2d, int x0, int y0, int w, int h) {
|
||||
g2d.fillRect(x0, y0, w, h);
|
||||
}
|
||||
}.runTest();
|
||||
|
||||
new DrawPrimitivesTest("fillOvalAA") {
|
||||
public void renderPrimitive(Graphics2D g2d, int x0, int y0, int w, int h) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.fillOval(x0, y0, w, h);
|
||||
}
|
||||
}.runTest();
|
||||
}
|
||||
|
||||
public abstract void renderPrimitive(Graphics2D g2d, int x0, int y0, int w, int h);
|
||||
|
||||
public DrawPrimitivesTest(String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void runTest() throws InterruptedException, InvocationTargetException, AWTException {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
add(new JPanel() {
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(W, H);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setColor(Color.YELLOW);
|
||||
int c = 0;
|
||||
for (int i = 0; i < W; i += 10) {
|
||||
for (int j = 0; j < H; j += 10) {
|
||||
c = (c + 1) % color.length;
|
||||
g2d.setColor(color[c]);
|
||||
renderPrimitive(g2d, i, j, 10, 10);
|
||||
}
|
||||
}
|
||||
Point p = getLocationOnScreen();
|
||||
frameX0 = p.x;
|
||||
frameY0 = p.y - getInsets().top;
|
||||
|
||||
latchRender.countDown();
|
||||
}
|
||||
});
|
||||
setPreferredSize(new Dimension(W, H));
|
||||
pack();
|
||||
setVisible(true);
|
||||
});
|
||||
|
||||
latchRender.await();
|
||||
Thread.sleep(1000);
|
||||
|
||||
Robot robot = new Robot();
|
||||
|
||||
boolean hasEmptyContent = true;
|
||||
l:for (int i = frameX0 + W/3; i < frameX0 + (2*W)/3; i++) {
|
||||
for (int j = 0; j < 10; j += 2) {
|
||||
if (isAlmostEqual(robot.getPixelColor(i, frameY0 + H / 2 + j), Color.RED)) {
|
||||
hasEmptyContent = false;
|
||||
break l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
});
|
||||
|
||||
if (hasEmptyContent) {
|
||||
throw new RuntimeException(name + ": Empty content");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user