mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-15 21:05:11 +00:00
8288948: Few J2DBench tests indicate lower primitive drawing performance with metal rendering pipeline
Reviewed-by: avu, prr
This commit is contained in:
parent
84f23149e2
commit
bc7a1ea249
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. 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
|
||||
@ -51,6 +51,11 @@ 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
|
||||
};
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. 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
|
||||
@ -48,6 +48,18 @@ 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) {
|
||||
@ -55,6 +67,12 @@ void MTLRenderQueue_CheckPreviousOp(jint op) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDrawOp(mtlPreviousOp) && !isDrawOp(op)) {
|
||||
// submit the vertex batch
|
||||
MTLRenderer_SubmitVertexBatch(mtlc, dstOps);
|
||||
mtlPreviousOp = op;
|
||||
}
|
||||
|
||||
if (op == MTL_OP_SET_COLOR) {
|
||||
if (mtlPreviousOp != MTL_OP_MASK_OP) {
|
||||
return; // SET_COLOR should not cause endEncoder
|
||||
@ -128,7 +146,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
// draw ops
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_LINE);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -144,9 +162,10 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_RECT);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
|
||||
commitEncodedCommands();
|
||||
J2dTraceLn(J2D_TRACE_VERBOSE,
|
||||
"DRAW_RECT in XOR mode - Force commit earlier draw calls before DRAW_RECT.");
|
||||
@ -228,7 +247,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_DRAW_PARALLELOGRAM);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -276,7 +295,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
// fill ops
|
||||
case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_FILL_RECT);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -308,7 +327,7 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
|
||||
{
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
CHECK_PREVIOUS_OP(MTL_OP_FILL_PARALLELOGRAM);
|
||||
|
||||
if ([mtlc useXORComposite]) {
|
||||
commitEncodedCommands();
|
||||
@ -582,6 +601,7 @@ 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];
|
||||
@ -609,6 +629,7 @@ 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];
|
||||
@ -878,6 +899,8 @@ 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];
|
||||
@ -923,6 +946,9 @@ 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];
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. 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
|
||||
@ -72,5 +72,9 @@ 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 */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. 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
|
||||
@ -35,6 +35,95 @@
|
||||
#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
|
||||
@ -65,12 +154,16 @@ 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);
|
||||
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
if (mtlEncoder == nil)
|
||||
return;
|
||||
// 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);
|
||||
|
||||
// DrawLine implementation same as in OGLRenderer.c
|
||||
struct Vertex verts[2];
|
||||
if (y1 == y2) {
|
||||
// horizontal
|
||||
float fx1 = (float)x1;
|
||||
@ -80,11 +173,8 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
if (x1 > x2) {
|
||||
float t = fx1; fx1 = fx2; fx2 = t;
|
||||
}
|
||||
|
||||
verts[0].position[0] = fx1 + 0.2f;
|
||||
verts[0].position[1] = fy;
|
||||
verts[1].position[0] = fx2 + 1.2f;
|
||||
verts[1].position[1] = fy;
|
||||
MTLRenderer_AddVertexToBatch(fx1 + 0.2f, fy);
|
||||
MTLRenderer_AddVertexToBatch(fx2 + 1.2f, fy);
|
||||
} else if (x1 == x2) {
|
||||
// vertical
|
||||
float fx = ((float)x1) + 0.2f;
|
||||
@ -94,11 +184,8 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
if (y1 > y2) {
|
||||
float t = fy1; fy1 = fy2; fy2 = t;
|
||||
}
|
||||
|
||||
verts[0].position[0] = fx;
|
||||
verts[0].position[1] = fy1 + 0.2f;
|
||||
verts[1].position[0] = fx;
|
||||
verts[1].position[1] = fy2 + 1.2f;
|
||||
MTLRenderer_AddVertexToBatch(fx, fy1 + 0.2f);
|
||||
MTLRenderer_AddVertexToBatch(fx, fy2 + 1.2f);
|
||||
} else {
|
||||
// diagonal
|
||||
float fx1 = (float)x1;
|
||||
@ -121,14 +208,10 @@ void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1
|
||||
fy1 += 0.8f;
|
||||
fy2 -= 0.2f;
|
||||
}
|
||||
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];
|
||||
MTLRenderer_AddVertexToBatch(fx1, fy1);
|
||||
MTLRenderer_AddVertexToBatch(fx2, fy2);
|
||||
}
|
||||
}
|
||||
|
||||
void MTLRenderer_DrawPixel(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y) {
|
||||
@ -162,27 +245,35 @@ 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);
|
||||
|
||||
// TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
|
||||
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
|
||||
if (mtlEncoder == nil)
|
||||
return;
|
||||
// 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);
|
||||
|
||||
|
||||
// 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;
|
||||
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];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const int POLYLINE_BUF_SIZE = 64;
|
||||
@ -415,24 +506,23 @@ MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint
|
||||
return;
|
||||
}
|
||||
|
||||
struct Vertex verts[QUAD_VERTEX_COUNT] = {
|
||||
{ {x, y}},
|
||||
{ {x, y+h}},
|
||||
{ {x+w, y}},
|
||||
{ {x+w, y+h}
|
||||
}};
|
||||
// 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);
|
||||
|
||||
|
||||
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);
|
||||
MTLRenderer_AddVertexToBatch(x, y+h);
|
||||
MTLRenderer_AddVertexToBatch(x+w, y);
|
||||
|
||||
// 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];
|
||||
MTLRenderer_AddVertexToBatch(x, y+h);
|
||||
MTLRenderer_AddVertexToBatch(x+w, y);
|
||||
MTLRenderer_AddVertexToBatch(x+w, y+h);
|
||||
}
|
||||
|
||||
void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
|
||||
@ -553,23 +643,22 @@ MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
|
||||
dx21, dy21,
|
||||
dx12, dy12, dest);
|
||||
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
|
||||
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
@ -631,69 +720,66 @@ 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;
|
||||
struct Vertex vertexList[TOTAL_VERTICES];
|
||||
int i = 0;
|
||||
// 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);
|
||||
|
||||
|
||||
// TOP segment, to left side of RIGHT edge
|
||||
// "width" of original pgram, "height" of hor. line size
|
||||
fx11 = ox11;
|
||||
fy11 = oy11;
|
||||
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21, fy11 + dy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx12, fy11 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
|
||||
// RIGHT segment, to top of BOTTOM edge
|
||||
// "width" of vert. line size , "height" of original pgram
|
||||
fx11 = ox11 + dx21;
|
||||
fy11 = oy11 + dy21;
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21, fy11 + ldy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(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;
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21, fy11 + dy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
|
||||
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx12, fy11 + ldy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
|
||||
// LEFT segment, from bottom of TOP edge
|
||||
// "width" of vert. line size , "height" of inner pgram
|
||||
fx11 = ox11 + ldx12;
|
||||
fy11 = oy11 + ldy12;
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21, fy11 + ldy21);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
|
||||
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
|
||||
fillVertex(vertexList + (i++), fx11, fy11);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(fx11 + dx12, fy11 + dy12);
|
||||
MTLRenderer_AddVertexToBatch(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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user