[canvas, mtl] clear resets command count and stores clear color. Ccanvas' backend begin proc now takes a clearColor parameter and clears final surface to that color before drawing any batch

This commit is contained in:
Martin Fouilleul 2023-03-15 11:09:42 +01:00
parent 98bac9744f
commit 5ce53001e2
4 changed files with 24 additions and 51 deletions

View File

@ -73,8 +73,7 @@ typedef struct mg_rounded_rect
f32 r; f32 r;
} mg_rounded_rect; } mg_rounded_rect;
typedef enum { MG_CMD_CLEAR = 0, typedef enum { MG_CMD_FILL,
MG_CMD_FILL,
MG_CMD_STROKE, MG_CMD_STROKE,
MG_CMD_RECT_FILL, MG_CMD_RECT_FILL,
MG_CMD_RECT_STROKE, MG_CMD_RECT_STROKE,
@ -202,6 +201,7 @@ typedef struct mg_canvas_data
mg_primitive primitives[MG_MAX_PRIMITIVE_COUNT]; mg_primitive primitives[MG_MAX_PRIMITIVE_COUNT];
//NOTE: these are used at render time //NOTE: these are used at render time
mg_color clearColor;
mp_rect clip; mp_rect clip;
mg_mat2x3 transform; mg_mat2x3 transform;
mg_image image; mg_image image;
@ -2882,17 +2882,14 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
return; return;
} }
mg_color clearColor = {0, 0, 0, 1};
u32 nextIndex = 0; u32 nextIndex = 0;
mg_reset_shape_index(canvas); mg_reset_shape_index(canvas);
canvas->clip = (mp_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX}; canvas->clip = (mp_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX};
canvas->image = mg_image_nil(); canvas->image = mg_image_nil();
canvas->backend->begin(canvas->backend); canvas->backend->begin(canvas->backend, canvas->clearColor);
for(int i=0; i<primitiveCount; i++) for(int i=0; i<primitiveCount; i++)
{ {
@ -2913,15 +2910,6 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
switch(primitive->cmd) switch(primitive->cmd)
{ {
case MG_CMD_CLEAR:
{
//NOTE(martin): clear buffers
canvas->vertexCount = 0;
canvas->indexCount = 0;
canvas->backend->clear(canvas->backend, primitive->attributes.color);
} break;
case MG_CMD_FILL: case MG_CMD_FILL:
{ {
mg_next_shape(canvas, &primitive->attributes); mg_next_shape(canvas, &primitive->attributes);
@ -3482,7 +3470,8 @@ void mg_clear()
mg_canvas_data* canvas = __mgCurrentCanvas; mg_canvas_data* canvas = __mgCurrentCanvas;
if(canvas) if(canvas)
{ {
mg_push_command(canvas, (mg_primitive){.cmd = MG_CMD_CLEAR}); canvas->primitiveCount = 0;
canvas->clearColor = canvas->attributes.color;
} }
} }

View File

@ -104,9 +104,8 @@ typedef struct mg_vertex_layout
typedef struct mg_canvas_backend mg_canvas_backend; typedef struct mg_canvas_backend mg_canvas_backend;
typedef void (*mg_canvas_backend_destroy_proc)(mg_canvas_backend* backend); typedef void (*mg_canvas_backend_destroy_proc)(mg_canvas_backend* backend);
typedef void (*mg_canvas_backend_begin_proc)(mg_canvas_backend* backend); typedef void (*mg_canvas_backend_begin_proc)(mg_canvas_backend* backend, mg_color clearColor);
typedef void (*mg_canvas_backend_end_proc)(mg_canvas_backend* backend); typedef void (*mg_canvas_backend_end_proc)(mg_canvas_backend* backend);
typedef void (*mg_canvas_backend_clear_proc)(mg_canvas_backend* backend, mg_color clearColor);
typedef void (*mg_canvas_backend_draw_batch_proc)(mg_canvas_backend* backend, typedef void (*mg_canvas_backend_draw_batch_proc)(mg_canvas_backend* backend,
mg_image_data* imageData, mg_image_data* imageData,
u32 vertexCount, u32 vertexCount,
@ -128,7 +127,6 @@ typedef struct mg_canvas_backend
mg_canvas_backend_destroy_proc destroy; mg_canvas_backend_destroy_proc destroy;
mg_canvas_backend_begin_proc begin; mg_canvas_backend_begin_proc begin;
mg_canvas_backend_end_proc end; mg_canvas_backend_end_proc end;
mg_canvas_backend_clear_proc clear;
mg_canvas_backend_draw_batch_proc drawBatch; mg_canvas_backend_draw_batch_proc drawBatch;
mg_canvas_backend_image_create_proc imageCreate; mg_canvas_backend_image_create_proc imageCreate;

View File

@ -25,7 +25,6 @@ typedef struct mg_mtl_canvas_backend
mg_canvas_backend interface; mg_canvas_backend interface;
mg_surface surface; mg_surface surface;
mg_color clearColor;
u32 vertexBufferOffset; u32 vertexBufferOffset;
u32 indexBufferOffset; u32 indexBufferOffset;
u32 shapeBufferOffset; u32 shapeBufferOffset;
@ -94,7 +93,7 @@ void mg_mtl_canvas_update_vertex_layout(mg_mtl_canvas_backend* backend)
.indexStride = sizeof(int)}; .indexStride = sizeof(int)};
} }
void mg_mtl_canvas_begin(mg_canvas_backend* interface) void mg_mtl_canvas_begin(mg_canvas_backend* interface, mg_color clearColor)
{ {
mg_mtl_canvas_backend* backend = (mg_mtl_canvas_backend*)interface; mg_mtl_canvas_backend* backend = (mg_mtl_canvas_backend*)interface;
mg_mtl_surface* surface = mg_mtl_canvas_get_surface(backend); mg_mtl_surface* surface = mg_mtl_canvas_get_surface(backend);
@ -114,12 +113,12 @@ void mg_mtl_canvas_begin(mg_canvas_backend* interface)
backend->shapeBufferOffset = 0; backend->shapeBufferOffset = 0;
mg_mtl_canvas_update_vertex_layout(backend); mg_mtl_canvas_update_vertex_layout(backend);
MTLClearColor clearColor = MTLClearColorMake(backend->clearColor.r, backend->clearColor.g, backend->clearColor.b, backend->clearColor.a); MTLClearColor mtlClearColor = MTLClearColorMake(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
renderPassDescriptor.colorAttachments[0].texture = surface->drawable.texture; renderPassDescriptor.colorAttachments[0].texture = surface->drawable.texture;
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDescriptor.colorAttachments[0].clearColor = clearColor; renderPassDescriptor.colorAttachments[0].clearColor = mtlClearColor;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
id<MTLRenderCommandEncoder> renderEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; id<MTLRenderCommandEncoder> renderEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
@ -130,13 +129,6 @@ void mg_mtl_canvas_begin(mg_canvas_backend* interface)
void mg_mtl_canvas_end(mg_canvas_backend* interface) void mg_mtl_canvas_end(mg_canvas_backend* interface)
{} {}
void mg_mtl_canvas_clear(mg_canvas_backend* interface, mg_color clearColor)
{
//TODO
mg_mtl_canvas_backend* backend = (mg_mtl_canvas_backend*)interface;
backend->clearColor = clearColor;
}
void mg_mtl_canvas_draw_batch(mg_canvas_backend* interface, mg_image_data* image, u32 shapeCount, u32 vertexCount, u32 indexCount) void mg_mtl_canvas_draw_batch(mg_canvas_backend* interface, mg_image_data* image, u32 shapeCount, u32 vertexCount, u32 indexCount)
{ {
mg_mtl_canvas_backend* backend = (mg_mtl_canvas_backend*)interface; mg_mtl_canvas_backend* backend = (mg_mtl_canvas_backend*)interface;
@ -207,9 +199,6 @@ void mg_mtl_canvas_draw_batch(mg_canvas_backend* interface, mg_image_data* image
//----------------------------------------------------------- //-----------------------------------------------------------
//NOTE(martin): encode drawing pass //NOTE(martin): encode drawing pass
//----------------------------------------------------------- //-----------------------------------------------------------
//TODO: remove that
vector_float4 clearColorVec4 = {backend->clearColor.r, backend->clearColor.g, backend->clearColor.b, backend->clearColor.a};
id<MTLComputeCommandEncoder> drawEncoder = [surface->commandBuffer computeCommandEncoder]; id<MTLComputeCommandEncoder> drawEncoder = [surface->commandBuffer computeCommandEncoder];
drawEncoder.label = @"drawing pass"; drawEncoder.label = @"drawing pass";
[drawEncoder setComputePipelineState:backend->computePipeline]; [drawEncoder setComputePipelineState:backend->computePipeline];
@ -226,9 +215,8 @@ void mg_mtl_canvas_draw_batch(mg_canvas_backend* interface, mg_image_data* image
useTexture = 1; useTexture = 1;
} }
[drawEncoder setBytes: &clearColorVec4 length: sizeof(vector_float4) atIndex: 3]; [drawEncoder setBytes: &useTexture length:sizeof(int) atIndex: 3];
[drawEncoder setBytes: &useTexture length:sizeof(int) atIndex: 4]; [drawEncoder setBytes: &scale length: sizeof(float) atIndex: 4];
[drawEncoder setBytes: &scale length: sizeof(float) atIndex: 5];
//TODO: check that we don't exceed maxTotalThreadsPerThreadgroup //TODO: check that we don't exceed maxTotalThreadsPerThreadgroup
DEBUG_ASSERT(RENDERER_TILE_SIZE*RENDERER_TILE_SIZE <= backend->computePipeline.maxTotalThreadsPerThreadgroup); DEBUG_ASSERT(RENDERER_TILE_SIZE*RENDERER_TILE_SIZE <= backend->computePipeline.maxTotalThreadsPerThreadgroup);
@ -395,7 +383,6 @@ mg_canvas_backend* mg_mtl_canvas_create(mg_surface surface)
backend->interface.destroy = mg_mtl_canvas_destroy; backend->interface.destroy = mg_mtl_canvas_destroy;
backend->interface.begin = mg_mtl_canvas_begin; backend->interface.begin = mg_mtl_canvas_begin;
backend->interface.end = mg_mtl_canvas_end; backend->interface.end = mg_mtl_canvas_end;
backend->interface.clear = mg_mtl_canvas_clear;
backend->interface.drawBatch = mg_mtl_canvas_draw_batch; backend->interface.drawBatch = mg_mtl_canvas_draw_batch;
backend->interface.imageCreate = mg_mtl_canvas_image_create; backend->interface.imageCreate = mg_mtl_canvas_image_create;

View File

@ -164,9 +164,8 @@ kernel void RenderKernel(const device uint* tileCounters [[buffer(0)]],
const device uint* tileArrayBuffer [[buffer(1)]], const device uint* tileArrayBuffer [[buffer(1)]],
const device mg_triangle_data* triangleArray [[buffer(2)]], const device mg_triangle_data* triangleArray [[buffer(2)]],
constant float4* clearColor [[buffer(3)]], constant int* useTexture [[buffer(3)]],
constant int* useTexture [[buffer(4)]], constant float* scaling [[buffer(4)]],
constant float* scaling [[buffer(5)]],
texture2d<float, access::write> outTexture [[texture(0)]], texture2d<float, access::write> outTexture [[texture(0)]],
texture2d<float> texAtlas [[texture(1)]], texture2d<float> texAtlas [[texture(1)]],