From: Jean-Philippe Bruyère Date: Sun, 29 Apr 2018 16:47:17 +0000 (+0200) Subject: mimic reference counting from cairo X-Git-Tag: v0.1-alpha~124 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=eadc23473b9935d2c88a0687b7eefbf09b1e6746;p=jp%2Fvkvg.git mimic reference counting from cairo --- diff --git a/include/vkvg.h b/include/vkvg.h index b1333bf..d11f649 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -119,9 +119,13 @@ typedef struct _vkvg_pattern_t* VkvgPattern; VkvgDevice vkvg_device_create (VkPhysicalDevice phy, VkDevice vkdev, VkQueue queue, uint32_t qFam); void vkvg_device_destroy (VkvgDevice dev); +VkvgDevice vkvg_device_reference (VkvgDevice dev); +uint32_t vkvg_device_get_reference_count (VkvgDevice dev); VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height); VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath); +VkvgSurface vkvg_surface_reference (VkvgSurface surf); +uint32_t vkvg_surface_get_reference_count(VkvgSurface surf); void vkvg_surface_destroy (VkvgSurface surf); VkImage vkvg_surface_get_vk_image (VkvgSurface surf); @@ -166,8 +170,10 @@ typedef enum _vkvg_operator { } vkvg_operator_t; /*Context*/ -VkvgContext vkvg_create (VkvgSurface surf); -void vkvg_destroy (VkvgContext ctx); +VkvgContext vkvg_create (VkvgSurface surf); +void vkvg_destroy (VkvgContext ctx); +VkvgContext vkvg_reference (VkvgContext ctx); +uint32_t vkvg_get_reference_count(VkvgContext ctx); void vkvg_flush (VkvgContext ctx); @@ -224,6 +230,8 @@ void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents); //pattern VkvgPattern vkvg_pattern_create (); +VkvgPattern vkvg_pattern_reference (VkvgPattern pat); +uint32_t vkvg_pattern_get_reference_count(VkvgPattern pat); VkvgPattern vkvg_pattern_create_rgba (float r, float g, float b, float a); VkvgPattern vkvg_pattern_create_rgb (float r, float g, float b); VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf); diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 659f740..13e84b7 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -82,6 +82,8 @@ VkvgContext vkvg_create(VkvgSurface surf) _init_cmd_buff (ctx); _clear_path (ctx); + ctx->references = 1; + return ctx; } void vkvg_flush (VkvgContext ctx){ @@ -113,6 +115,10 @@ void vkvg_flush (VkvgContext ctx){ void vkvg_destroy (VkvgContext ctx) { + ctx->references--; + if (ctx->references > 0) + return; + _flush_cmd_buff(ctx); VkDevice dev = ctx->pSurf->dev->vkDev; @@ -142,6 +148,8 @@ void vkvg_destroy (VkvgContext ctx) vkvg_context_save_t* cur = next; next = cur->pNext; _free_ctx_save (cur); + if (cur->pattern) + vkvg_pattern_destroy (cur->pattern); } if (ctx->pSurf->dev->lastCtx == ctx){ @@ -158,6 +166,14 @@ void vkvg_destroy (VkvgContext ctx) free(ctx); } +VkvgContext vkvg_reference (VkvgContext ctx) { + ctx->references++; + return ctx; +} +uint32_t vkvg_get_reference_count (VkvgContext ctx) { + return ctx->references; +} + void vkvg_new_sub_path (VkvgContext ctx){ _finish_path(ctx); } @@ -532,6 +548,7 @@ void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y } void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ _update_cur_pattern (ctx, pat); + vkvg_pattern_reference (pat); } void vkvg_set_line_width (VkvgContext ctx, float width){ ctx->lineWidth = width; @@ -642,6 +659,9 @@ void vkvg_save (VkvgContext ctx){ sav->pNext = ctx->pSavedCtxs; ctx->pSavedCtxs = sav; + if (ctx->pattern) + vkvg_pattern_reference (ctx->pattern); + _wait_and_reset_ctx_cmd (ctx); _init_cmd_buff (ctx); } diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index fe993c2..36cfae3 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -364,6 +364,9 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { _init_cmd_buff (ctx); break; } + + if (lastPat) + vkvg_pattern_destroy (lastPat); } void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){ VkDescriptorImageInfo descSrcTex = vkh_image_get_descriptor (img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 6901cc5..7ac2c05 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -80,6 +80,7 @@ typedef struct _vkvg_context_save_t{ typedef struct _vkvg_context_t { VkvgContext pPrev; //double linked list of contexts VkvgContext pNext; + uint32_t references; VkvgSurface pSurf; VkFence flushFence; diff --git a/src/vkvg_device.c b/src/vkvg_device.c index ee5deb5..cea8b43 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -49,11 +49,17 @@ VkvgDevice vkvg_device_create(VkPhysicalDevice phy, VkDevice vkdev, VkQueue queu _createDescriptorSetLayout (dev); _setupPipelines (dev); + dev->references = 1; + return dev; } void vkvg_device_destroy (VkvgDevice dev) { + dev->references--; + if (dev->references > 0) + return; + vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslGrad,NULL); vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslFont,NULL); vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslSrc, NULL); @@ -81,3 +87,11 @@ void vkvg_device_destroy (VkvgDevice dev) _destroy_font_cache(dev); free(dev); } + +VkvgDevice vkvg_device_reference (VkvgDevice dev) { + dev->references++; + return dev; +} +uint32_t vkvg_device_get_reference_count (VkvgDevice dev) { + return dev->references; +} diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index b11ac24..9d19c3c 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -33,11 +33,12 @@ typedef struct _vkvg_device_t{ VkDevice vkDev; VkPhysicalDeviceMemoryProperties phyMemProps; - VkRenderPass renderPass; VkPhysicalDevice phy; VkhQueue gQueue; + VkRenderPass renderPass; + uint32_t references; VkCommandPool cmdPool; VkCommandBuffer cmd; VkFence fence; diff --git a/src/vkvg_pattern.c b/src/vkvg_pattern.c index c242085..767f701 100644 --- a/src/vkvg_pattern.c +++ b/src/vkvg_pattern.c @@ -30,6 +30,9 @@ VkvgPattern vkvg_pattern_create(){ pat->type = VKVG_PATTERN_TYPE_SOLID; pat->extend = VKVG_EXTEND_NONE; pat->data = (vkvg_color_t*)calloc(1,sizeof(vkvg_color_t)); + + pat->references = 1; + return pat; } VkvgPattern vkvg_pattern_create_rgba (float r, float g, float b, float a){ @@ -42,6 +45,9 @@ VkvgPattern vkvg_pattern_create_rgba (float r, float g, float b, float a){ c->b = b; c->a = a; pat->data = c; + + pat->references = 1; + return pat; } VkvgPattern vkvg_pattern_create_rgb (float r, float g, float b){ @@ -52,6 +58,10 @@ VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf){ pat->type = VKVG_PATTERN_TYPE_SURFACE; pat->extend = VKVG_EXTEND_NONE; pat->data = surf; + + pat->references = 1; + vkvg_surface_reference (surf); + return pat; } VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1){ @@ -65,6 +75,9 @@ VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1){ grad->cp[1] = cp1; pat->data = grad; + + pat->references = 1; + return pat; } VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, @@ -79,8 +92,18 @@ VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, grad->cp[2] = rads; pat->data = grad; + + pat->references = 1; + + return pat; +} +VkvgPattern vkvg_pattern_reference (VkvgPattern pat) { + pat->references++; return pat; } +uint32_t vkvg_pattern_get_reference_count (VkvgPattern pat) { + return pat->references; +} void vkvg_patter_add_color_stop (VkvgPattern pat, float offset, float r, float g, float b, float a) { if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID){ @@ -109,7 +132,14 @@ vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat){ void vkvg_pattern_destroy(VkvgPattern pat) { - if (pat->type != VKVG_PATTERN_TYPE_SURFACE) + pat->references--; + if (pat->references > 0) + return; + + if (pat->type == VKVG_PATTERN_TYPE_SURFACE) { + VkvgSurface surf = (VkvgSurface)pat->data; + vkvg_surface_destroy (surf); + }else free (pat->data); free(pat); diff --git a/src/vkvg_pattern.h b/src/vkvg_pattern.h index 4211915..7aff2e0 100644 --- a/src/vkvg_pattern.h +++ b/src/vkvg_pattern.h @@ -30,6 +30,7 @@ typedef struct _vkvg_pattern_t { vkvg_pattern_type_t type; vkvg_extend_t extend; vkvg_filter_t filter; + uint32_t references; void* data; }vkvg_pattern_t; diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 08ed2a2..ce9d19c 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -91,6 +91,9 @@ VkvgSurface vkvg_surface_create(VkvgDevice dev, uint32_t width, uint32_t height) _init_surface (surf); + surf->references = 1; + vkvg_device_reference (surf->dev); + return surf; } @@ -187,18 +190,34 @@ VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath vkh_image_destroy (tmpImg); + surf->references = 1; + vkvg_device_reference (surf->dev); + return surf; } void vkvg_surface_destroy(VkvgSurface surf) { + surf->references--; + if (surf->references > 0) + return; vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL); vkh_image_destroy(surf->img); vkh_image_destroy(surf->imgMS); vkh_image_destroy(surf->stencilMS); + + vkvg_device_destroy (surf->dev); free(surf); } +VkvgSurface vkvg_surface_reference (VkvgSurface surf) { + surf->references++; + return surf; +} +uint32_t vkvg_surface_get_reference_count (VkvgSurface surf) { + return surf->references; +} + VkImage vkvg_surface_get_vk_image(VkvgSurface surf) { return vkh_image_get_vkimage (surf->img); diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index 18de4ca..8f15866 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -35,6 +35,7 @@ typedef struct _vkvg_surface_t { VkhImage img; VkhImage imgMS; VkhImage stencilMS; + uint32_t references; }vkvg_surface; void _clear_stencil (VkvgSurface surf); diff --git a/vkh b/vkh index 9eca1ff..d54f6f1 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit 9eca1ffd9de3da3814d634a28b10f61b1e43816e +Subproject commit d54f6f1c5b8847fe75431e9fd2e70e4aeb7462b9