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_SYNC,
|
||||||
MTL_OP_SHAPE_CLIP_SPANS,
|
MTL_OP_SHAPE_CLIP_SPANS,
|
||||||
MTL_OP_MASK_OP,
|
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
|
MTL_OP_OTHER
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
|
@ -48,18 +48,6 @@ jint mtlPreviousOp = MTL_OP_INIT;
|
|||||||
|
|
||||||
extern void MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo);
|
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) {
|
void MTLRenderQueue_CheckPreviousOp(jint op) {
|
||||||
|
|
||||||
if (mtlPreviousOp == op) {
|
if (mtlPreviousOp == op) {
|
||||||
@ -67,16 +55,6 @@ void MTLRenderQueue_CheckPreviousOp(jint op) {
|
|||||||
return;
|
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 (op == MTL_OP_SET_COLOR) {
|
||||||
if (mtlPreviousOp != MTL_OP_MASK_OP) {
|
if (mtlPreviousOp != MTL_OP_MASK_OP) {
|
||||||
return; // SET_COLOR should not cause endEncoder
|
return; // SET_COLOR should not cause endEncoder
|
||||||
@ -150,7 +128,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
// draw ops
|
// draw ops
|
||||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
|
case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
|
||||||
{
|
{
|
||||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_LINE);
|
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||||
|
|
||||||
if ([mtlc useXORComposite]) {
|
if ([mtlc useXORComposite]) {
|
||||||
commitEncodedCommands();
|
commitEncodedCommands();
|
||||||
@ -166,10 +144,9 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
}
|
}
|
||||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
|
case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
|
||||||
{
|
{
|
||||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_RECT);
|
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||||
|
|
||||||
if ([mtlc useXORComposite]) {
|
if ([mtlc useXORComposite]) {
|
||||||
|
|
||||||
commitEncodedCommands();
|
commitEncodedCommands();
|
||||||
J2dTraceLn(J2D_TRACE_VERBOSE,
|
J2dTraceLn(J2D_TRACE_VERBOSE,
|
||||||
"DRAW_RECT in XOR mode - Force commit earlier draw calls before DRAW_RECT.");
|
"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:
|
case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
|
||||||
{
|
{
|
||||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_PARALLELOGRAM);
|
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||||
|
|
||||||
if ([mtlc useXORComposite]) {
|
if ([mtlc useXORComposite]) {
|
||||||
commitEncodedCommands();
|
commitEncodedCommands();
|
||||||
@ -299,7 +276,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
// fill ops
|
// fill ops
|
||||||
case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
|
case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
|
||||||
{
|
{
|
||||||
CHECK_PREVIOUS_OP(MTL_OP_FILL_RECT);
|
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||||
|
|
||||||
if ([mtlc useXORComposite]) {
|
if ([mtlc useXORComposite]) {
|
||||||
commitEncodedCommands();
|
commitEncodedCommands();
|
||||||
@ -331,7 +308,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
}
|
}
|
||||||
case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
|
case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
|
||||||
{
|
{
|
||||||
CHECK_PREVIOUS_OP(MTL_OP_FILL_PARALLELOGRAM);
|
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||||
|
|
||||||
if ([mtlc useXORComposite]) {
|
if ([mtlc useXORComposite]) {
|
||||||
commitEncodedCommands();
|
commitEncodedCommands();
|
||||||
@ -605,7 +582,6 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
jlong pDst = NEXT_LONG(b);
|
jlong pDst = NEXT_LONG(b);
|
||||||
|
|
||||||
if (mtlc != NULL) {
|
if (mtlc != NULL) {
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
[mtlc.encoderManager endEncoder];
|
[mtlc.encoderManager endEncoder];
|
||||||
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||||
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
||||||
@ -633,7 +609,6 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (mtlc != NULL) {
|
if (mtlc != NULL) {
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
[mtlc.encoderManager endEncoder];
|
[mtlc.encoderManager endEncoder];
|
||||||
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||||
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
||||||
@ -903,8 +878,6 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
|||||||
if (mtlPreviousOp == MTL_OP_MASK_OP) {
|
if (mtlPreviousOp == MTL_OP_MASK_OP) {
|
||||||
MTLVertexCache_DisableMaskCache(mtlc);
|
MTLVertexCache_DisableMaskCache(mtlc);
|
||||||
}
|
}
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
|
|
||||||
[mtlc.encoderManager endEncoder];
|
[mtlc.encoderManager endEncoder];
|
||||||
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
MTLCommandBufferWrapper * cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||||
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
|
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
|
* these would be rendered to the back-buffer - which is read in shader while rendering in XOR mode
|
||||||
*/
|
*/
|
||||||
void commitEncodedCommands() {
|
void commitEncodedCommands() {
|
||||||
|
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
|
|
||||||
[mtlc.encoderManager endEncoder];
|
[mtlc.encoderManager endEncoder];
|
||||||
|
|
||||||
MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper];
|
MTLCommandBufferWrapper *cbwrapper = [mtlc pullCommandBufferWrapper];
|
||||||
|
@ -72,9 +72,5 @@ void MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
|||||||
jfloat fx11, jfloat fy11,
|
jfloat fx11, jfloat fy11,
|
||||||
jfloat dx21, jfloat dy21,
|
jfloat dx21, jfloat dy21,
|
||||||
jfloat dx12, jfloat dy12);
|
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 */
|
#endif /* MTLRenderer_h_Included */
|
||||||
|
@ -35,95 +35,6 @@
|
|||||||
#include "MTLUtils.h"
|
#include "MTLUtils.h"
|
||||||
#import "MTLLayer.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"
|
* Note: Some of the methods in this file apply a "magic number"
|
||||||
* translation to line segments. It is same as what we have in
|
* 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);
|
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
|
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||||
if (((currentIndexInBatch + 2) > VERTEX_BATCH_SIZE) ||
|
if (mtlEncoder == nil)
|
||||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
return;
|
||||||
// encode the vertex batch
|
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
}
|
|
||||||
|
|
||||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeLine);
|
|
||||||
|
|
||||||
// DrawLine implementation same as in OGLRenderer.c
|
// DrawLine implementation same as in OGLRenderer.c
|
||||||
|
struct Vertex verts[2];
|
||||||
if (y1 == y2) {
|
if (y1 == y2) {
|
||||||
// horizontal
|
// horizontal
|
||||||
float fx1 = (float)x1;
|
float fx1 = (float)x1;
|
||||||
@ -173,8 +80,11 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
|||||||
if (x1 > x2) {
|
if (x1 > x2) {
|
||||||
float t = fx1; fx1 = fx2; fx2 = t;
|
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) {
|
} else if (x1 == x2) {
|
||||||
// vertical
|
// vertical
|
||||||
float fx = ((float)x1) + 0.2f;
|
float fx = ((float)x1) + 0.2f;
|
||||||
@ -184,8 +94,11 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
|||||||
if (y1 > y2) {
|
if (y1 > y2) {
|
||||||
float t = fy1; fy1 = fy2; fy2 = t;
|
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 {
|
} else {
|
||||||
// diagonal
|
// diagonal
|
||||||
float fx1 = (float)x1;
|
float fx1 = (float)x1;
|
||||||
@ -208,10 +121,14 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
|||||||
fy1 += 0.8f;
|
fy1 += 0.8f;
|
||||||
fy2 -= 0.2f;
|
fy2 -= 0.2f;
|
||||||
}
|
}
|
||||||
|
verts[0].position[0] = fx1;
|
||||||
MTLRenderer_AddVertexToBatch(fx1, fy1);
|
verts[0].position[1] = fy1;
|
||||||
MTLRenderer_AddVertexToBatch(fx2, fy2);
|
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) {
|
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;
|
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);
|
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
|
// TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
|
||||||
if ( ((currentIndexInBatch + 8) > VERTEX_BATCH_SIZE) ||
|
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
if (mtlEncoder == nil)
|
||||||
|
return;
|
||||||
// encode the vertex batch
|
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
}
|
|
||||||
|
|
||||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeLine);
|
|
||||||
|
|
||||||
|
|
||||||
// Translate each vertex by a fraction so
|
// Translate each vertex by a fraction so
|
||||||
// that we hit pixel centers.
|
// that we hit pixel centers.
|
||||||
|
const int verticesCount = 5;
|
||||||
float fx = (float)x + 0.2f;
|
float fx = (float)x + 0.2f;
|
||||||
float fy = (float)y + 0.5f;
|
float fy = (float)y + 0.5f;
|
||||||
float fw = (float)w;
|
float fw = (float)w;
|
||||||
float fh = (float)h;
|
float fh = (float)h;
|
||||||
|
struct Vertex vertices[5] = {
|
||||||
MTLRenderer_AddVertexToBatch(fx, fy);
|
{{fx, fy}},
|
||||||
MTLRenderer_AddVertexToBatch(fx+fw, fy);
|
{{fx + fw, fy}},
|
||||||
|
{{fx + fw, fy + fh}},
|
||||||
MTLRenderer_AddVertexToBatch(fx+fw, fy);
|
{{fx, fy + fh}},
|
||||||
MTLRenderer_AddVertexToBatch(fx+fw, fy+fh);
|
{{fx, fy}},
|
||||||
|
};
|
||||||
MTLRenderer_AddVertexToBatch(fx+fw, fy+fh);
|
[mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
|
||||||
MTLRenderer_AddVertexToBatch(fx, fy+fh);
|
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount];
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(fx, fy+fh);
|
|
||||||
MTLRenderer_AddVertexToBatch(fx, fy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int POLYLINE_BUF_SIZE = 64;
|
const int POLYLINE_BUF_SIZE = 64;
|
||||||
@ -506,23 +415,24 @@ MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we have space for 6 more vertices in the batch
|
struct Vertex verts[QUAD_VERTEX_COUNT] = {
|
||||||
if ( ((currentIndexInBatch + 6) > VERTEX_BATCH_SIZE) ||
|
{ {x, y}},
|
||||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
{ {x, y+h}},
|
||||||
// encode the vertex batch
|
{ {x+w, y}},
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
{ {x+w, y+h}
|
||||||
}
|
}};
|
||||||
|
|
||||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeTriangle);
|
|
||||||
|
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(x, y);
|
id<MTLTexture> dest = dstOps->pTexture;
|
||||||
MTLRenderer_AddVertexToBatch(x, y+h);
|
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+w, y);
|
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(x, y+h);
|
// Encode render command.
|
||||||
MTLRenderer_AddVertexToBatch(x+w, y);
|
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||||
MTLRenderer_AddVertexToBatch(x+w, y+h);
|
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)
|
void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
|
||||||
@ -643,22 +553,23 @@ MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
|||||||
dx21, dy21,
|
dx21, dy21,
|
||||||
dx12, dy12, dest);
|
dx12, dy12, dest);
|
||||||
|
|
||||||
// Make sure we have space for 6 more vertices in the batch
|
struct Vertex verts[QUAD_VERTEX_COUNT] = {
|
||||||
if ( ((currentIndexInBatch + 6) > VERTEX_BATCH_SIZE) ||
|
{ {fx11, fy11}},
|
||||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
{ {fx11+dx21, fy11+dy21}},
|
||||||
// encode the vertex batch
|
{ {fx11+dx12, fy11+dy12}},
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
{ {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);
|
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
|
||||||
|
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -720,66 +631,69 @@ MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
|||||||
// Each quad is encoded using two triangles
|
// Each quad is encoded using two triangles
|
||||||
// For 4 segments - there are 8 triangles in total
|
// For 4 segments - there are 8 triangles in total
|
||||||
// Each triangle has 3 vertices
|
// Each triangle has 3 vertices
|
||||||
|
|
||||||
const int TOTAL_VERTICES = 8 * 3;
|
const int TOTAL_VERTICES = 8 * 3;
|
||||||
// Make sure we have space for 24 more vertices in the batch
|
struct Vertex vertexList[TOTAL_VERTICES];
|
||||||
if ( ((currentIndexInBatch + TOTAL_VERTICES) > VERTEX_BATCH_SIZE) ||
|
int i = 0;
|
||||||
(currentBatchNo == (MAX_NO_OF_BATCHES - 1))) {
|
|
||||||
// encode the vertex batch
|
|
||||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
|
||||||
}
|
|
||||||
MTLRenderer_SetPrimitiveType(MTLPrimitiveTypeTriangle);
|
|
||||||
|
|
||||||
|
|
||||||
// TOP segment, to left side of RIGHT edge
|
// TOP segment, to left side of RIGHT edge
|
||||||
// "width" of original pgram, "height" of hor. line size
|
// "width" of original pgram, "height" of hor. line size
|
||||||
fx11 = ox11;
|
fx11 = ox11;
|
||||||
fy11 = oy11;
|
fy11 = oy11;
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx21, fy11 + dy21);
|
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx12, fy11 + ldy12);
|
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
|
|
||||||
// RIGHT segment, to top of BOTTOM edge
|
// RIGHT segment, to top of BOTTOM edge
|
||||||
// "width" of vert. line size , "height" of original pgram
|
// "width" of vert. line size , "height" of original pgram
|
||||||
fx11 = ox11 + dx21;
|
fx11 = ox11 + dx21;
|
||||||
fy11 = oy11 + dy21;
|
fy11 = oy11 + dy21;
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21, fy11 + ldy21);
|
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11 + dy12);
|
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
|
|
||||||
// BOTTOM segment, from right side of LEFT edge
|
// BOTTOM segment, from right side of LEFT edge
|
||||||
// "width" of original pgram, "height" of hor. line size
|
// "width" of original pgram, "height" of hor. line size
|
||||||
fx11 = ox11 + dx12 + ldx21;
|
fx11 = ox11 + dx12 + ldx21;
|
||||||
fy11 = oy11 + dy12 + ldy21;
|
fy11 = oy11 + dy12 + ldy21;
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx21, fy11 + dy21);
|
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx12, fy11 + ldy12);
|
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
|
|
||||||
// LEFT segment, from bottom of TOP edge
|
// LEFT segment, from bottom of TOP edge
|
||||||
// "width" of vert. line size , "height" of inner pgram
|
// "width" of vert. line size , "height" of inner pgram
|
||||||
fx11 = ox11 + ldx12;
|
fx11 = ox11 + ldx12;
|
||||||
fy11 = oy11 + ldy12;
|
fy11 = oy11 + ldy12;
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
fillVertex(vertexList + (i++), fx11, fy11);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21, fy11 + ldy21);
|
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||||
|
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11 + dy12);
|
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
|
||||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
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 {
|
} else {
|
||||||
// The line width ratios were large enough to consume
|
// The line width ratios were large enough to consume
|
||||||
// the entire hole in the middle of the parallelogram
|
// 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…
x
Reference in New Issue
Block a user