[mtl canvas, wip] cubic bézier implicitization
This commit is contained in:
parent
767841f9c6
commit
9322db8201
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
LogLevel(LOG_LEVEL_WARNING);
|
LogLevel(LOG_LEVEL_MESSAGE);
|
||||||
|
|
||||||
mp_init();
|
mp_init();
|
||||||
mp_clock_init(); //TODO put that in mp_init()?
|
mp_clock_init(); //TODO put that in mp_init()?
|
||||||
|
@ -89,12 +89,18 @@ int main()
|
||||||
mg_close_path();
|
mg_close_path();
|
||||||
mg_set_color_rgba(0, 1, 0, 1);
|
mg_set_color_rgba(0, 1, 0, 1);
|
||||||
mg_fill();
|
mg_fill();
|
||||||
*/
|
|
||||||
mg_move_to(400, 400);
|
mg_move_to(400, 400);
|
||||||
mg_quadratic_to(600, 601, 800, 400);
|
mg_quadratic_to(600, 601, 800, 400);
|
||||||
mg_close_path();
|
mg_close_path();
|
||||||
mg_set_color_rgba(0, 0, 1, 1);
|
mg_set_color_rgba(0, 0, 1, 1);
|
||||||
mg_fill();
|
mg_fill();
|
||||||
|
*/
|
||||||
|
mg_move_to(2*400, 2*400);
|
||||||
|
mg_cubic_to(2*400, 2*200, 2*600, 2*500, 2*600, 2*400);
|
||||||
|
mg_close_path();
|
||||||
|
mg_set_color_rgba(0, 0, 1, 1);
|
||||||
|
mg_fill();
|
||||||
|
|
||||||
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
|
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
|
||||||
frameTime,
|
frameTime,
|
||||||
|
|
|
@ -40,6 +40,8 @@ typedef struct mg_mtl_canvas_backend
|
||||||
|
|
||||||
id<MTLBuffer> pathBuffer[MG_MTL_INPUT_BUFFERS_COUNT];
|
id<MTLBuffer> pathBuffer[MG_MTL_INPUT_BUFFERS_COUNT];
|
||||||
id<MTLBuffer> elementBuffer[MG_MTL_INPUT_BUFFERS_COUNT];
|
id<MTLBuffer> elementBuffer[MG_MTL_INPUT_BUFFERS_COUNT];
|
||||||
|
id<MTLBuffer> logBuffer[MG_MTL_INPUT_BUFFERS_COUNT];
|
||||||
|
id<MTLBuffer> logOffsetBuffer[MG_MTL_INPUT_BUFFERS_COUNT];
|
||||||
|
|
||||||
id<MTLBuffer> segmentCountBuffer;
|
id<MTLBuffer> segmentCountBuffer;
|
||||||
id<MTLBuffer> segmentBuffer;
|
id<MTLBuffer> segmentBuffer;
|
||||||
|
@ -61,6 +63,26 @@ static void mg_update_path_extents(vec4* extents, vec2 p)
|
||||||
extents->w = maximum(extents->w, p.y);
|
extents->w = maximum(extents->w, p.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_mtl_print_log(int bufferIndex, id<MTLBuffer> logBuffer, id<MTLBuffer> logOffsetBuffer)
|
||||||
|
{
|
||||||
|
char* log = [logBuffer contents];
|
||||||
|
int size = *(int*)[logOffsetBuffer contents];
|
||||||
|
|
||||||
|
if(size)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE("Log from buffer %i:\n", bufferIndex);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
while(index < size)
|
||||||
|
{
|
||||||
|
int len = strlen(log+index);
|
||||||
|
printf("%s", log+index);
|
||||||
|
index += (len+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
mg_color clearColor,
|
mg_color clearColor,
|
||||||
u32 primitiveCount,
|
u32 primitiveCount,
|
||||||
|
@ -106,30 +128,11 @@ void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
|
|
||||||
//NOTE: transform and push path elt + update primitive bounding box
|
//NOTE: transform and push path elt + update primitive bounding box
|
||||||
vec2 p0 = mg_mat2x3_mul(primitive->attributes.transform, currentPos);
|
vec2 p0 = mg_mat2x3_mul(primitive->attributes.transform, currentPos);
|
||||||
vec2 p3 = mg_mat2x3_mul(primitive->attributes.transform, elt->p[0]);
|
vec2 p1 = mg_mat2x3_mul(primitive->attributes.transform, elt->p[0]);
|
||||||
currentPos = elt->p[0];
|
currentPos = elt->p[0];
|
||||||
|
|
||||||
mg_update_path_extents(&pathExtents, p0);
|
|
||||||
mg_update_path_extents(&pathExtents, p3);
|
|
||||||
|
|
||||||
mg_mtl_path_elt* mtlElt = &elementBufferData[mtlEltCount];
|
|
||||||
mtlEltCount++;
|
|
||||||
|
|
||||||
mtlElt->pathIndex = primitiveIndex;
|
|
||||||
mtlElt->kind = (mg_mtl_seg_kind)elt->type;
|
|
||||||
mtlElt->p[0] = (vector_float2){p0.x, p0.y};
|
|
||||||
mtlElt->p[3] = (vector_float2){p3.x, p3.y};
|
|
||||||
}
|
|
||||||
else if(elt->type == MG_PATH_QUADRATIC)
|
|
||||||
{
|
|
||||||
vec2 p0 = mg_mat2x3_mul(primitive->attributes.transform, currentPos);
|
|
||||||
vec2 p1 = mg_mat2x3_mul(primitive->attributes.transform, elt->p[0]);
|
|
||||||
vec2 p3 = mg_mat2x3_mul(primitive->attributes.transform, elt->p[1]);
|
|
||||||
currentPos = elt->p[1];
|
|
||||||
|
|
||||||
mg_update_path_extents(&pathExtents, p0);
|
mg_update_path_extents(&pathExtents, p0);
|
||||||
mg_update_path_extents(&pathExtents, p1);
|
mg_update_path_extents(&pathExtents, p1);
|
||||||
mg_update_path_extents(&pathExtents, p3);
|
|
||||||
|
|
||||||
mg_mtl_path_elt* mtlElt = &elementBufferData[mtlEltCount];
|
mg_mtl_path_elt* mtlElt = &elementBufferData[mtlEltCount];
|
||||||
mtlEltCount++;
|
mtlEltCount++;
|
||||||
|
@ -138,7 +141,26 @@ void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
mtlElt->kind = (mg_mtl_seg_kind)elt->type;
|
mtlElt->kind = (mg_mtl_seg_kind)elt->type;
|
||||||
mtlElt->p[0] = (vector_float2){p0.x, p0.y};
|
mtlElt->p[0] = (vector_float2){p0.x, p0.y};
|
||||||
mtlElt->p[1] = (vector_float2){p1.x, p1.y};
|
mtlElt->p[1] = (vector_float2){p1.x, p1.y};
|
||||||
mtlElt->p[3] = (vector_float2){p3.x, p3.y};
|
}
|
||||||
|
else if(elt->type == MG_PATH_QUADRATIC)
|
||||||
|
{
|
||||||
|
vec2 p0 = mg_mat2x3_mul(primitive->attributes.transform, currentPos);
|
||||||
|
vec2 p1 = mg_mat2x3_mul(primitive->attributes.transform, elt->p[0]);
|
||||||
|
vec2 p2 = mg_mat2x3_mul(primitive->attributes.transform, elt->p[1]);
|
||||||
|
currentPos = elt->p[1];
|
||||||
|
|
||||||
|
mg_update_path_extents(&pathExtents, p0);
|
||||||
|
mg_update_path_extents(&pathExtents, p1);
|
||||||
|
mg_update_path_extents(&pathExtents, p2);
|
||||||
|
|
||||||
|
mg_mtl_path_elt* mtlElt = &elementBufferData[mtlEltCount];
|
||||||
|
mtlEltCount++;
|
||||||
|
|
||||||
|
mtlElt->pathIndex = primitiveIndex;
|
||||||
|
mtlElt->kind = (mg_mtl_seg_kind)elt->type;
|
||||||
|
mtlElt->p[0] = (vector_float2){p0.x, p0.y};
|
||||||
|
mtlElt->p[1] = (vector_float2){p1.x, p1.y};
|
||||||
|
mtlElt->p[2] = (vector_float2){p2.x, p2.y};
|
||||||
}
|
}
|
||||||
else if(elt->type == MG_PATH_CUBIC)
|
else if(elt->type == MG_PATH_CUBIC)
|
||||||
{
|
{
|
||||||
|
@ -160,7 +182,7 @@ void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
mtlElt->kind = (mg_mtl_seg_kind)elt->type;
|
mtlElt->kind = (mg_mtl_seg_kind)elt->type;
|
||||||
mtlElt->p[0] = (vector_float2){p0.x, p0.y};
|
mtlElt->p[0] = (vector_float2){p0.x, p0.y};
|
||||||
mtlElt->p[1] = (vector_float2){p1.x, p1.y};
|
mtlElt->p[1] = (vector_float2){p1.x, p1.y};
|
||||||
mtlElt->p[1] = (vector_float2){p2.x, p2.y};
|
mtlElt->p[2] = (vector_float2){p2.x, p2.y};
|
||||||
mtlElt->p[3] = (vector_float2){p3.x, p3.y};
|
mtlElt->p[3] = (vector_float2){p3.x, p3.y};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,6 +231,7 @@ void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
[blitEncoder fillBuffer: backend->segmentCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0];
|
[blitEncoder fillBuffer: backend->segmentCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0];
|
||||||
[blitEncoder fillBuffer: backend->tileQueueCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0];
|
[blitEncoder fillBuffer: backend->tileQueueCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0];
|
||||||
[blitEncoder fillBuffer: backend->tileOpCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0];
|
[blitEncoder fillBuffer: backend->tileOpCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0];
|
||||||
|
[blitEncoder fillBuffer: backend->logOffsetBuffer[backend->bufferIndex] range: NSMakeRange(0, sizeof(int)) value: 0];
|
||||||
[blitEncoder endEncoding];
|
[blitEncoder endEncoding];
|
||||||
|
|
||||||
//NOTE: path setup pass
|
//NOTE: path setup pass
|
||||||
|
@ -243,6 +266,8 @@ void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
[segmentEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:6];
|
[segmentEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:6];
|
||||||
[segmentEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:7];
|
[segmentEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:7];
|
||||||
[segmentEncoder setBytes:&tileSize length:sizeof(int) atIndex:8];
|
[segmentEncoder setBytes:&tileSize length:sizeof(int) atIndex:8];
|
||||||
|
[segmentEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:9];
|
||||||
|
[segmentEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:10];
|
||||||
|
|
||||||
MTLSize segmentGridSize = MTLSizeMake(mtlEltCount, 1, 1);
|
MTLSize segmentGridSize = MTLSizeMake(mtlEltCount, 1, 1);
|
||||||
MTLSize segmentGroupSize = MTLSizeMake([backend->segmentPipeline maxTotalThreadsPerThreadgroup], 1, 1);
|
MTLSize segmentGroupSize = MTLSizeMake([backend->segmentPipeline maxTotalThreadsPerThreadgroup], 1, 1);
|
||||||
|
@ -329,6 +354,7 @@ void mg_mtl_canvas_render(mg_canvas_backend* interface,
|
||||||
//NOTE: finalize
|
//NOTE: finalize
|
||||||
[surface->commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer)
|
[surface->commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer)
|
||||||
{
|
{
|
||||||
|
mg_mtl_print_log(backend->bufferIndex, backend->logBuffer[backend->bufferIndex], backend->logOffsetBuffer[backend->bufferIndex]);
|
||||||
dispatch_semaphore_signal(backend->bufferSemaphore);
|
dispatch_semaphore_signal(backend->bufferSemaphore);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -351,6 +377,8 @@ void mg_mtl_canvas_destroy(mg_canvas_backend* interface)
|
||||||
{
|
{
|
||||||
[backend->pathBuffer[i] release];
|
[backend->pathBuffer[i] release];
|
||||||
[backend->elementBuffer[i] release];
|
[backend->elementBuffer[i] release];
|
||||||
|
[backend->logBuffer[i] release];
|
||||||
|
[backend->logOffsetBuffer[i] release];
|
||||||
}
|
}
|
||||||
[backend->segmentCountBuffer release];
|
[backend->segmentCountBuffer release];
|
||||||
[backend->segmentBuffer release];
|
[backend->segmentBuffer release];
|
||||||
|
@ -502,6 +530,17 @@ mg_canvas_backend* mg_mtl_canvas_create(mg_surface surface)
|
||||||
int nTilesY = (int)(frame.h * scale + tileSize - 1)/tileSize;
|
int nTilesY = (int)(frame.h * scale + tileSize - 1)/tileSize;
|
||||||
backend->screenTilesBuffer = [metalSurface->device newBufferWithLength: nTilesX*nTilesY*sizeof(int)
|
backend->screenTilesBuffer = [metalSurface->device newBufferWithLength: nTilesX*nTilesY*sizeof(int)
|
||||||
options: bufferOptions];
|
options: bufferOptions];
|
||||||
|
|
||||||
|
|
||||||
|
bufferOptions = MTLResourceStorageModeShared;
|
||||||
|
for(int i=0; i<MG_MTL_INPUT_BUFFERS_COUNT; i++)
|
||||||
|
{
|
||||||
|
backend->logBuffer[i] = [metalSurface->device newBufferWithLength: 4<<20
|
||||||
|
options: bufferOptions];
|
||||||
|
|
||||||
|
backend->logOffsetBuffer[i] = [metalSurface->device newBufferWithLength: sizeof(int)
|
||||||
|
options: bufferOptions];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return((mg_canvas_backend*)backend);
|
return((mg_canvas_backend*)backend);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue