From b03afe104972225bd24684a7816186bfcab00e88 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Wed, 19 Jan 2022 09:51:17 +0100 Subject: [PATCH] store context in vkvgdevice to be reused on creation --- src/vkvg_context.c | 200 +++++++++++++++++++++--------------- src/vkvg_context_internal.c | 51 +++++---- src/vkvg_context_internal.h | 5 +- src/vkvg_device.c | 7 ++ src/vkvg_device_internal.h | 5 + src/vkvg_fonts.c | 12 +-- 6 files changed, 161 insertions(+), 119 deletions(-) diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 0d5cec6..74a00bf 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -42,31 +42,10 @@ static VkClearValue clearValues[3] = { { .color.float32 = {0,0,0,0} } }; -VkvgContext vkvg_create(VkvgSurface surf) -{ - VkvgDevice dev = surf->dev; - VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context)); - - LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf); - - if (ctx==NULL) { - dev->status = VKVG_STATUS_NO_MEMORY; - return NULL; - } - if (!surf || surf->status) { - ctx->status = VKVG_STATUS_INVALID_SURFACE; - return ctx; - } - - ctx->sizePoints = VKVG_PTS_SIZE; - ctx->sizeVertices = ctx->sizeVBO = VKVG_VBO_SIZE; - ctx->sizeIndices = ctx->sizeIBO = VKVG_IBO_SIZE; - ctx->sizePathes = VKVG_PATHES_SIZE; +void _init_ctx (VkvgContext ctx) { ctx->lineWidth = 1; ctx->curOperator = VKVG_OPERATOR_OVER; ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO; - ctx->pSurf = surf; - ctx->bounds = (VkRect2D) {{0,0},{ctx->pSurf->width,ctx->pSurf->height}}; ctx->pushConsts = (push_constants) { {.a = 1}, @@ -77,41 +56,80 @@ VkvgContext vkvg_create(VkvgSurface surf) VKVG_IDENTITY_MATRIX }; ctx->clearRect = (VkClearRect) {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1}; - - ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; ctx->renderPassBeginInfo.framebuffer = ctx->pSurf->fb; ctx->renderPassBeginInfo.renderArea.extent.width = ctx->pSurf->width; ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height; ctx->renderPassBeginInfo.pClearValues = clearValues; if (ctx->pSurf->new) - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearAll; + ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll; else - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil; + ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil; ctx->pSurf->new = false; - if (dev->samples == VK_SAMPLE_COUNT_1_BIT) + if (ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT) ctx->renderPassBeginInfo.clearValueCount = 2; else ctx->renderPassBeginInfo.clearValueCount = 3; - - ctx->pPrev = surf->dev->lastCtx; + ctx->selectedCharSize = 10 << 6; + ctx->currentFont = NULL; + ctx->selectedFontName[0] = 0; + ctx->pattern = NULL; + /*ctx->pPrev = ctx->dev->lastCtx; if (ctx->pPrev != NULL) ctx->pPrev->pNext = ctx; - surf->dev->lastCtx = ctx; + ctx->dev->lastCtx = ctx;*/ +} + +VkvgContext vkvg_create(VkvgSurface surf) +{ + VkvgDevice dev = surf->dev; + + if (dev->cachedContextCount) { + VkvgContext ctx = dev->cachedContext[--dev->cachedContextCount]; + ctx->pSurf = surf; + _init_ctx (ctx); + _update_descriptor_set (ctx, surf->dev->emptyImg, ctx->dsSrc); + _clear_path (ctx); + ctx->cmd = ctx->cmdBuffers[0];//current recording buffer + ctx->cmdStarted = false; + ctx->curClipState = vkvg_clip_state_none; + ctx->status = VKVG_STATUS_SUCCESS; + ctx->vertCount = ctx->indCount = ctx->curColor = 0; + + return ctx; + } + VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context)); + + LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf); + + if (ctx==NULL) { + dev->status = VKVG_STATUS_NO_MEMORY; + return NULL; + } + if (!surf || surf->status) { + ctx->status = VKVG_STATUS_INVALID_SURFACE; + return ctx; + } + + ctx->sizePoints = VKVG_PTS_SIZE; + ctx->sizeVertices = ctx->sizeVBO = VKVG_VBO_SIZE; + ctx->sizeIndices = ctx->sizeIBO = VKVG_IBO_SIZE; + ctx->sizePathes = VKVG_PATHES_SIZE; + ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + + ctx->pSurf = surf; + ctx->dev = surf->dev; + + _init_ctx (ctx); ctx->points = (vec2*)malloc (VKVG_VBO_SIZE*sizeof(vec2)); ctx->pathes = (uint32_t*)malloc (VKVG_PATHES_SIZE*sizeof(uint32_t)); ctx->vertexCache = (Vertex*)malloc(ctx->sizeVertices * sizeof(Vertex)); ctx->indexCache = (VKVG_IBO_INDEX_TYPE*)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); - ctx->savedStencils = malloc(0); - - ctx->selectedFontName = (char*)calloc(FONT_NAME_MAX_SIZE, sizeof(char)); - ctx->selectedCharSize = 10 << 6; - ctx->currentFont = NULL; - if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache || !ctx->savedStencils || !ctx->selectedFontName) { + if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache) { dev->status = VKVG_STATUS_NO_MEMORY; if (ctx->points) free(ctx->points); @@ -121,23 +139,19 @@ VkvgContext vkvg_create(VkvgSurface surf) free(ctx->vertexCache); if (ctx->indexCache) free(ctx->indexCache); - if (ctx->savedStencils) - free(ctx->savedStencils); - if (ctx->selectedFontName) - free(ctx->selectedFontName); return NULL; } - ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)dev); //for context to be thread safe, command pool and descriptor pool have to be created in the thread of the context. ctx->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); + ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)ctx->dev); _create_vertices_buff (ctx); _create_gradient_buff (ctx); _create_cmd_buff (ctx); _createDescriptorPool (ctx); _init_descriptor_sets (ctx); - _update_descriptor_set (ctx, ctx->pSurf->dev->fontCache->texture, ctx->dsFont); + _update_descriptor_set (ctx, ctx->dev->fontCache->texture, ctx->dsFont); _update_descriptor_set (ctx, surf->dev->emptyImg, ctx->dsSrc); _update_gradient_desc_set(ctx); @@ -196,6 +210,42 @@ void vkvg_flush (VkvgContext ctx){ */ } +void _clear_context (VkvgContext ctx) { + //free saved context stack elmt + vkvg_context_save_t* next = ctx->pSavedCtxs; + while (next != NULL) { + vkvg_context_save_t* cur = next; + next = cur->pNext; + _free_ctx_save (cur); + if (cur->pattern) + vkvg_pattern_destroy (cur->pattern); + } + //free additional stencil use in save/restore process + if (ctx->savedStencils) { + uint8_t curSaveStencil = ctx->curSavBit / 6; + for (int i=curSaveStencil;i>0;i--) + vkh_image_destroy(ctx->savedStencils[i-1]); + free(ctx->savedStencils); + ctx->savedStencils = NULL; + ctx->curSavBit = 0; + } + + //remove context from double linked list of context in device + /*if (ctx->dev->lastCtx == ctx){ + ctx->dev->lastCtx = ctx->pPrev; + if (ctx->pPrev != NULL) + ctx->pPrev->pNext = NULL; + }else if (ctx->pPrev == NULL){ + //first elmt, and it's not last one so pnext is not null + ctx->pNext->pPrev = NULL; + }else{ + ctx->pPrev->pNext = ctx->pNext; + ctx->pNext->pPrev = ctx->pPrev; + }*/ + if (ctx->dashCount > 0) + free(ctx->dashes); +} + void vkvg_destroy (VkvgContext ctx) { ctx->references--; @@ -216,7 +266,7 @@ void vkvg_destroy (VkvgContext ctx) if (ctx->pattern) vkvg_pattern_destroy (ctx->pattern); - VkDevice dev = ctx->pSurf->dev->vkDev; + VkDevice dev = ctx->dev->vkDev; #if VKVG_DBG_STATS vkvg_debug_stats_t* dbgstats = &ctx->pSurf->dev->debug_stats; @@ -235,7 +285,16 @@ void vkvg_destroy (VkvgContext ctx) #endif - vkDestroyFence (dev, ctx->flushFence,NULL); + if (ctx->dev->cachedContextCount < VKVG_MAX_CACHED_CONTEXT_COUNT) { + ctx->dev->cachedContext[ctx->dev->cachedContextCount++] = ctx; + _clear_context (ctx); + ctx->references++; + return; + } + + _clear_context (ctx); + + vkDestroyFence (ctx->dev->vkDev, ctx->flushFence,NULL); vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers); vkDestroyCommandPool(dev, ctx->cmdPool, NULL); @@ -254,40 +313,8 @@ void vkvg_destroy (VkvgContext ctx) //TODO:check this for source counter //vkh_image_destroy (ctx->source); - free(ctx->selectedFontName); free(ctx->pathes); free(ctx->points); - if (ctx->dashCount > 0) - free(ctx->dashes); - - //free saved context stack elmt - vkvg_context_save_t* next = ctx->pSavedCtxs; - while (next != NULL) { - vkvg_context_save_t* cur = next; - next = cur->pNext; - _free_ctx_save (cur); - if (cur->pattern) - vkvg_pattern_destroy (cur->pattern); - } - //free additional stencil use in save/restore process - uint8_t curSaveStencil = ctx->curSavBit / 6; - for (int i=curSaveStencil;i>0;i--) - vkh_image_destroy(ctx->savedStencils[i-1]); - - free(ctx->savedStencils); - - //remove context from double linked list of context in device - if (ctx->pSurf->dev->lastCtx == ctx){ - ctx->pSurf->dev->lastCtx = ctx->pPrev; - if (ctx->pPrev != NULL) - ctx->pPrev->pNext = NULL; - }else if (ctx->pPrev == NULL){ - //first elmt, and it's not last one so pnext is not null - ctx->pNext->pPrev = NULL; - }else{ - ctx->pPrev->pNext = ctx->pNext; - ctx->pNext->pPrev = ctx->pPrev; - } free(ctx); } @@ -688,7 +715,7 @@ void _reset_clip (VkvgContext ctx) { if (!ctx->cmdStarted) { //if command buffer is not already started and in a renderpass, we use the renderpass //with the loadop clear for stencil - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil; + ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil; //force run of one renderpass (even empty) to perform clear load op _start_cmd_for_render_pass(ctx); return; @@ -724,7 +751,7 @@ void vkvg_clear (VkvgContext ctx){ _emit_draw_cmd_undrawn_vertices(ctx); if (!ctx->cmdStarted) { - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearAll; + ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll; _start_cmd_for_render_pass(ctx); return; } @@ -749,9 +776,9 @@ void _clip_preserve (VkvgContext ctx){ if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ _poly_fill (ctx); - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); }else{ - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); @@ -1169,7 +1196,7 @@ void vkvg_save (VkvgContext ctx){ RECORD(ctx, VKVG_CMD_SAVE); LOG(VKVG_LOG_INFO, "SAVE CONTEXT: ctx = %p\n", ctx); - VkvgDevice dev = ctx->pSurf->dev; + VkvgDevice dev = ctx->dev; vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t)); _flush_cmd_buff (ctx); @@ -1184,7 +1211,11 @@ void vkvg_save (VkvgContext ctx){ uint8_t curSaveStencil = ctx->curSavBit / 6; if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//new save/restore stencil image have to be created - VkhImage* savedStencilsPtr = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof(VkhImage)); + VkhImage* savedStencilsPtr = NULL; + if (savedStencilsPtr) + savedStencilsPtr = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof(VkhImage)); + else + savedStencilsPtr = (VkhImage*)malloc(curSaveStencil * sizeof(VkhImage)); if (savedStencilsPtr == NULL) { free(sav); ctx->status = VKVG_STATUS_NO_MEMORY; @@ -1237,7 +1268,7 @@ void vkvg_save (VkvgContext ctx){ vkh_cmd_label_start(ctx->cmd, "save rp", DBG_LAB_COLOR_SAV); #endif - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); @@ -1270,7 +1301,6 @@ void vkvg_save (VkvgContext ctx){ sav->curFillRule= ctx->curFillRule; sav->selectedCharSize = ctx->selectedCharSize; - sav->selectedFontName = (char*)calloc(FONT_NAME_MAX_SIZE,sizeof(char)); strcpy (sav->selectedFontName, ctx->selectedFontName); sav->currentFont = ctx->currentFont; @@ -1322,7 +1352,7 @@ void vkvg_restore (VkvgContext ctx){ vkh_cmd_label_start(ctx->cmd, "restore rp", DBG_LAB_COLOR_SAV); #endif - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index c191c4e..1676f75 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -252,17 +252,17 @@ float _get_arc_step (VkvgContext ctx, float radius) { return fminf(M_PI / 3.f,M_PI / (r * 0.4f)); } void _create_gradient_buff (VkvgContext ctx){ - vkvg_buffer_create (ctx->pSurf->dev, + vkvg_buffer_create (ctx->dev, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, sizeof(vkvg_gradient_t), &ctx->uboGrad); } void _create_vertices_buff (VkvgContext ctx){ - vkvg_buffer_create (ctx->pSurf->dev, + vkvg_buffer_create (ctx->dev, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); - vkvg_buffer_create (ctx->pSurf->dev, + vkvg_buffer_create (ctx->dev, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); @@ -276,7 +276,7 @@ void _resize_vbo (VkvgContext ctx, uint32_t new_size) { ctx->sizeVBO += VKVG_VBO_SIZE - mod; LOG(VKVG_LOG_DBG_ARRAYS, "resize VBO: new size: %d\n", ctx->sizeVBO); vkvg_buffer_destroy (&ctx->vertices); - vkvg_buffer_create (ctx->pSurf->dev, + vkvg_buffer_create (ctx->dev, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); @@ -290,7 +290,7 @@ void _resize_ibo (VkvgContext ctx, size_t new_size) { ctx->sizeIBO += VKVG_IBO_SIZE - mod; LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %d\n", ctx->sizeIBO); vkvg_buffer_destroy (&ctx->indices); - vkvg_buffer_create (ctx->pSurf->dev, + vkvg_buffer_create (ctx->dev, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); @@ -400,7 +400,7 @@ void _ensure_renderpass_is_started (VkvgContext ctx) { _update_push_constants(ctx); } void _create_cmd_buff (VkvgContext ctx){ - vkh_cmd_buffs_create((VkhDevice)ctx->pSurf->dev, ctx->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 2, ctx->cmdBuffers); + vkh_cmd_buffs_create((VkhDevice)ctx->dev, ctx->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 2, ctx->cmdBuffers); #if defined(DEBUG) && defined(ENABLE_VALIDATION) vkh_device_set_object_name((VkhDevice)ctx->pSurf->dev, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)ctx->cmd, "vkvgCtxCmd"); #endif @@ -410,7 +410,7 @@ void _clear_attachment (VkvgContext ctx) { } bool _wait_flush_fence (VkvgContext ctx) { LOG(VKVG_LOG_INFO, "CTX: _wait_flush_fence\n"); - if (WaitForFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) + if (WaitForFences (ctx->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) return true; LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n"); ctx->status = VKVG_STATUS_TIMEOUT; @@ -418,7 +418,7 @@ bool _wait_flush_fence (VkvgContext ctx) { } void _reset_flush_fence (VkvgContext ctx) { LOG(VKVG_LOG_INFO, "CTX: _reset_flush_fence\n"); - ResetFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence); + ResetFences (ctx->dev->vkDev, 1, &ctx->flushFence); } bool _wait_and_submit_cmd (VkvgContext ctx){ if (!ctx->cmdStarted)//current cmd buff is empty, be aware that wait is also canceled!! @@ -430,7 +430,7 @@ bool _wait_and_submit_cmd (VkvgContext ctx){ return false; _reset_flush_fence(ctx); - _submit_cmd (ctx->pSurf->dev, &ctx->cmd, ctx->flushFence); + _submit_cmd (ctx->dev, &ctx->cmd, ctx->flushFence); if (ctx->cmd == ctx->cmdBuffers[0]) ctx->cmd = ctx->cmdBuffers[1]; @@ -499,7 +499,7 @@ void _end_render_pass (VkvgContext ctx) { #if defined(DEBUG) && defined (VKVG_DBG_UTILS) vkh_cmd_label_end (ctx->cmd); #endif - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass; + ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass; } void _check_vao_size (VkvgContext ctx) { @@ -574,16 +574,16 @@ void _flush_cmd_buff (VkvgContext ctx){ void _bind_draw_pipeline (VkvgContext ctx) { switch (ctx->curOperator) { case VKVG_OPERATOR_OVER: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER); break; case VKVG_OPERATOR_CLEAR: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_CLEAR); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_CLEAR); break; case VKVG_OPERATOR_DIFFERENCE: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_SUB); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_SUB); break; default: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER); break; } } @@ -622,7 +622,7 @@ void _start_cmd_for_render_pass (VkvgContext ctx) { CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc,ctx->dsGrad}; - CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLayout, + CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout, 0, 3, dss, 0, NULL); VkDeviceSize offsets[1] = { 0 }; @@ -643,7 +643,7 @@ void _set_mat_inv_and_vkCmdPush (VkvgContext ctx) { ctx->pushCstDirty = true; } void _update_push_constants (VkvgContext ctx) { - CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, + CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),&ctx->pushConsts); ctx->pushCstDirty = false; } @@ -667,7 +667,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { if (!_wait_flush_fence (ctx)) return; if (lastPat->type == VKVG_PATTERN_TYPE_SURFACE)//unbind current source surface by replacing it with empty texture - _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); + _update_descriptor_set (ctx, ctx->dev->emptyImg, ctx->dsSrc); break; case VKVG_PATTERN_TYPE_SURFACE: { @@ -741,7 +741,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { return; if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE) - _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); + _update_descriptor_set (ctx, ctx->dev->emptyImg, ctx->dsSrc); vec4 bounds = {{(float)ctx->pSurf->width}, {(float)ctx->pSurf->height}, {0}, {0}};//store img bounds in unused source field ctx->pushConsts.source = bounds; @@ -802,7 +802,7 @@ void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){ .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .pImageInfo = &descSrcTex }; - vkUpdateDescriptorSets(ctx->pSurf->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); + vkUpdateDescriptorSets(ctx->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); } void _update_gradient_desc_set (VkvgContext ctx){ VkDescriptorBufferInfo dbi = {ctx->uboGrad.buffer, 0, VK_WHOLE_SIZE}; @@ -814,7 +814,7 @@ void _update_gradient_desc_set (VkvgContext ctx){ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .pBufferInfo = &dbi }; - vkUpdateDescriptorSets(ctx->pSurf->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); + vkUpdateDescriptorSets(ctx->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); } /* * Reset currently bound descriptor which image could be destroyed @@ -832,7 +832,7 @@ void _update_gradient_desc_set (VkvgContext ctx){ }*/ void _createDescriptorPool (VkvgContext ctx) { - VkvgDevice dev = ctx->pSurf->dev; + VkvgDevice dev = ctx->dev; const VkDescriptorPoolSize descriptorPoolSize[] = { {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 }, {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1 } @@ -845,7 +845,7 @@ void _createDescriptorPool (VkvgContext ctx) { VK_CHECK_RESULT(vkCreateDescriptorPool (dev->vkDev, &descriptorPoolCreateInfo, NULL, &ctx->descriptorPool)); } void _init_descriptor_sets (VkvgContext ctx){ - VkvgDevice dev = ctx->pSurf->dev; + VkvgDevice dev = ctx->dev; VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .descriptorPool = ctx->descriptorPool, .descriptorSetCount = 1, @@ -1223,7 +1223,6 @@ bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { void _free_ctx_save (vkvg_context_save_t* sav){ if (sav->dashCount > 0) free (sav->dashes); - free(sav->selectedFontName); free (sav); } @@ -1568,7 +1567,7 @@ void _poly_fill (VkvgContext ctx){ }else _ensure_renderpass_is_started(ctx); - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelinePolyFill); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelinePolyFill); Vertex v = {{0},ctx->curColor, {0,0,-1}}; uint32_t ptrPath = 0; @@ -1894,11 +1893,11 @@ void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) { ctx->curVertOffset = ctx->vertCount; ctx->pushConsts.fsq_patternType |= FULLSCREEN_BIT; - CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, + CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType); CmdDraw (ctx->cmd,3,1,firstVertIdx,0); ctx->pushConsts.fsq_patternType &= ~FULLSCREEN_BIT; - CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, + CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType); if (us) CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index ebc7e48..c663baf 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -113,7 +113,7 @@ typedef struct _vkvg_context_save_t{ vkvg_fill_rule_t curFillRule; long selectedCharSize; /* Font size*/ - char* selectedFontName; + char selectedFontName[FONT_NAME_MAX_SIZE]; _vkvg_font_identity_t selectedFont; //hold current face and size before cache addition _vkvg_font_identity_t* currentFont; //font ready for lookup vkvg_direction_t textDirection; @@ -129,6 +129,7 @@ typedef struct _vkvg_context_t { VkvgContext pNext; uint32_t references; //reference count + VkvgDevice dev; VkvgSurface pSurf; //surface bound to context, set on creation of ctx VkFence flushFence; //context fence VkhImage source; //source of painting operation @@ -205,7 +206,7 @@ typedef struct _vkvg_context_t { vkvg_fill_rule_t curFillRule; long selectedCharSize; /* Font size*/ - char* selectedFontName; + char selectedFontName[FONT_NAME_MAX_SIZE]; //_vkvg_font_t selectedFont; //hold current face and size before cache addition _vkvg_font_identity_t* currentFont; //font pointing to cached fonts identity _vkvg_font_t* currentFontSize; //font structure by size ready for lookup diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 5f0d19b..8bd01ea 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -21,6 +21,7 @@ */ #include "vkvg_device_internal.h" +#include "vkvg_surface_internal.h" #include "vkh_queue.h" #include "vkh_phyinfo.h" #include "vk_mem_alloc.h" @@ -261,6 +262,12 @@ void vkvg_device_destroy (VkvgDevice dev) if (dev->references > 0) return; + int32_t cachedCtxCount = dev->cachedContextCount; + dev->cachedContextCount = VKVG_MAX_CACHED_CONTEXT_COUNT; + while (cachedCtxCount > 0) { + vkvg_destroy(dev->cachedContext[--cachedCtxCount]); + } + LOG(VKVG_LOG_INFO, "DESTROY Device\n"); vkh_image_destroy (dev->emptyImg); diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index ef91e64..b51deae 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -30,6 +30,8 @@ #define STENCIL_CLIP_BIT 0x2 #define STENCIL_ALL_BIT 0x3 +#define VKVG_MAX_CACHED_CONTEXT_COUNT 16 + extern PFN_vkCmdBindPipeline CmdBindPipeline; extern PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets; extern PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer; @@ -106,6 +108,9 @@ typedef struct _vkvg_device_t{ _font_cache_t* fontCache; /**< Store everything relative to common font caching system */ VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/ + + int32_t cachedContextCount; + VkvgContext cachedContext[VKVG_MAX_CACHED_CONTEXT_COUNT]; }vkvg_device; bool _try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy); diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index c551a15..78970be 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -364,7 +364,7 @@ void _font_add_name (_vkvg_font_identity_t* font, const char* name, int nameLeng strcpy (font->names[font->namesCount-1], name); } void _add_new_font_identity (VkvgContext ctx, const char* fontFile, const char* name){ - _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; + _font_cache_t* cache = (_font_cache_t*)ctx->dev->fontCache; if (++cache->fontsCount == 1) cache->fonts = (_vkvg_font_identity_t*) malloc (cache->fontsCount * sizeof(_vkvg_font_identity_t)); else @@ -413,9 +413,9 @@ _vkvg_font_t* _find_or_create_font_size (VkvgContext ctx) { font->sizes = (_vkvg_font_t*) realloc (font->sizes, font->sizeCount * sizeof(_vkvg_font_t)); _vkvg_font_t newSize = {.charSize = ctx->selectedCharSize}; - VkvgDevice dev = ctx->pSurf->dev; + VkvgDevice dev = ctx->dev; #ifdef VKVG_USE_FREETYPE - _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; + _font_cache_t* cache = (_font_cache_t*)ctx->dev->fontCache; FT_CHECK_RESULT(FT_New_Face (cache->library, font->fontFile, 0, &newSize.face)); FT_CHECK_RESULT(FT_Set_Char_Size(newSize.face, 0, newSize.charSize, dev->hdpi, dev->vdpi )); @@ -447,7 +447,7 @@ _vkvg_font_t* _find_or_create_font_size (VkvgContext ctx) { //try find font already resolved with fontconfig by font name bool _tryFindFontByName (VkvgContext ctx, _vkvg_font_identity_t** font){ - _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; + _font_cache_t* cache = (_font_cache_t*)ctx->dev->fontCache; for (int i = 0; i < cache->fontsCount; ++i) { for (uint32_t j = 0; j < cache->fonts[i].namesCount; j++) { if (strcmp (cache->fonts[i].names[j], ctx->selectedFontName) == 0) { @@ -459,7 +459,7 @@ bool _tryFindFontByName (VkvgContext ctx, _vkvg_font_identity_t** font){ return false; } bool _tryResolveFontNameWithFontConfig (VkvgContext ctx, _vkvg_font_identity_t** resolvedFont) { - _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; + _font_cache_t* cache = (_font_cache_t*)ctx->dev->fontCache; char* fontFile = NULL; #ifdef VKVG_USE_FONTCONFIG @@ -584,7 +584,7 @@ void _create_text_run (VkvgContext ctx, const char* text, VkvgText textRun) { textRun->fontId = ctx->currentFont; textRun->font = ctx->currentFontSize; - textRun->dev = ctx->pSurf->dev; + textRun->dev = ctx->dev; #ifdef VKVG_USE_HARFBUZZ textRun->hbBuf = _get_hb_buffer (ctx->currentFontSize, text); -- 2.47.3