]> O.S.I.I.S - jp/vkvg.git/commitdiff
store context in vkvgdevice to be reused on creation
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 19 Jan 2022 08:51:17 +0000 (09:51 +0100)
committerj-p <jp_bruyere@hotmail.com>
Fri, 18 Feb 2022 20:09:23 +0000 (21:09 +0100)
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
src/vkvg_device.c
src/vkvg_device_internal.h
src/vkvg_fonts.c

index 0d5cec6f19ac590b95b5714873701547b8cbd1ca..74a00bfc9732dec76dc18629837bd298be274751 100644 (file)
@@ -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);
index c191c4e98d55106af6720728cef8325a0ac73fa7..1676f756938675d9bda8e084621070356ad6e725 100644 (file)
@@ -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);
index ebc7e48a9a4357e08a6639dc73f4d6de59d43710..c663baf8361b3d3744b10dd24514b18804e74715 100644 (file)
@@ -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
index 5f0d19be463fa26b66b8fff842107246976a56f3..8bd01ea446d30bb590659264e05794d6331d9c05 100644 (file)
@@ -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);
index ef91e64d91ea6be0f5fb46deb45ad34213b973d2..b51deae0d845791877bc241aecf639b8da7d70e2 100644 (file)
@@ -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);
index c551a15dac7bf74f06fd1f9c1932ea2413dea82f..78970be2b1525cbf1f9eb46d951a5a7f950f0052 100644 (file)
@@ -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);