]> O.S.I.I.S - jp/vkvg.git/commitdiff
merge multithreading device guards with cached context
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 27 Jan 2022 04:08:24 +0000 (05:08 +0100)
committerj-p <jp_bruyere@hotmail.com>
Fri, 18 Feb 2022 20:09:23 +0000 (21:09 +0100)
include/vkvg.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
src/vkvg_device.c
src/vkvg_device_internal.c
src/vkvg_device_internal.h
tests/multithreading/multithreaded.c
tests/multithreading/multithreaded2.c

index 8280658ef00352a32fca72c2ff4b1609063daaae..950882351c2ca2ba6d9c3fa2da6ead52d3886e74 100644 (file)
@@ -535,9 +535,9 @@ void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy);
  * Device holds the font cache so that each time a context draws text, the same cache is used.
  *
  * @{ */
-typedef void (*vkvg_queue_guard)(void* user_data);
+typedef void (*vkvg_device_guard)(void* user_data);
 vkvg_public
-void vkvg_device_set_queue_guards (VkvgDevice dev, vkvg_queue_guard before_submit, vkvg_queue_guard after_submit, void* user_data);
+void vkvg_device_set_guards (VkvgDevice dev, vkvg_device_guard lock_callback, vkvg_device_guard unlock_callback, void* user_data);
 
 /**
  * @brief Create a new vkvg device.
index 42fc2d3ef67fe974332a5f80ee81326db1448f7e..c7f5faf99ff927cc1747f4ac277afaac1272f8a7 100644 (file)
@@ -89,9 +89,9 @@ void _init_ctx (VkvgContext ctx) {
 VkvgContext vkvg_create(VkvgSurface surf)
 {
        VkvgDevice dev = surf->dev;
+       VkvgContext ctx = NULL;
 
-       if (dev->cachedContextCount) {
-               VkvgContext ctx = dev->cachedContext[--dev->cachedContextCount];
+       if (_vkvg_device_try_get_cached_context (dev, &ctx) ) {
                ctx->pSurf = surf;
 
                if (!surf || surf->status) {
@@ -106,7 +106,7 @@ VkvgContext vkvg_create(VkvgSurface surf)
                ctx->status = VKVG_STATUS_SUCCESS;
                return ctx;
        }
-       VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context));
+       ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context));
 
        LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf);
 
@@ -151,9 +151,9 @@ VkvgContext vkvg_create(VkvgSurface surf)
        }
 
        //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->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);
 
-       ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)ctx->dev);
        _create_vertices_buff   (ctx);
        _create_gradient_buff   (ctx);
        _create_cmd_buff                (ctx);
@@ -274,7 +274,7 @@ void vkvg_destroy (VkvgContext ctx)
        if (ctx->pattern)
                vkvg_pattern_destroy (ctx->pattern);
 
-       VkDevice dev = ctx->dev->vkDev;
+       _clear_context (ctx);
 
 #if VKVG_DBG_STATS
        vkvg_debug_stats_t* dbgstats = &ctx->pSurf->dev->debug_stats;
@@ -294,37 +294,11 @@ void vkvg_destroy (VkvgContext ctx)
 #endif
 
        if (!ctx->status && ctx->dev->cachedContextCount < VKVG_MAX_CACHED_CONTEXT_COUNT) {
-               ctx->dev->cachedContext[ctx->dev->cachedContextCount++] = ctx;
-               _clear_context (ctx);
-               ctx->references++;
+               _vkvg_device_store_context (ctx);
                return;
        }
 
-       _clear_context (ctx);
-       _vkvg_device_destroy_fence (ctx->pSurf->dev, ctx->flushFence);
-
-       vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers);
-       vkDestroyCommandPool(dev, ctx->cmdPool, NULL);
-
-       VkDescriptorSet dss[] = {ctx->dsFont,ctx->dsSrc, ctx->dsGrad};
-       vkFreeDescriptorSets    (dev, ctx->descriptorPool, 3, dss);
-
-       vkDestroyDescriptorPool (dev, ctx->descriptorPool,NULL);
-
-       vkvg_buffer_destroy (&ctx->uboGrad);
-       vkvg_buffer_destroy (&ctx->indices);
-       vkvg_buffer_destroy (&ctx->vertices);
-
-       free(ctx->vertexCache);
-       free(ctx->indexCache);
-
-       //TODO:check this for source counter
-       //vkh_image_destroy       (ctx->source);
-
-       free(ctx->pathes);
-       free(ctx->points);
-
-       free(ctx);
+       _release_context_ressources (ctx);
 }
 void vkvg_set_opacity (VkvgContext ctx, float opacity) {
        if (ctx->status)
index c5880daaee51a2b16b133df308b2f4d07cd1ee36..4e1cf778ee51c8858e1b9b9b878b7be33ea00909 100644 (file)
@@ -852,6 +852,32 @@ void _init_descriptor_sets (VkvgContext ctx){
        descriptorSetAllocateInfo.pSetLayouts = &dev->dslGrad;
        VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad));
 }
+void _release_context_ressources (VkvgContext ctx) {
+       VkDevice dev = ctx->dev->vkDev;
+       _vkvg_device_destroy_fence (ctx->dev, ctx->flushFence);
+       vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers);
+       vkDestroyCommandPool(dev, ctx->cmdPool, NULL);
+
+       VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc, ctx->dsGrad};
+       vkFreeDescriptorSets    (dev, ctx->descriptorPool, 3, dss);
+
+       vkDestroyDescriptorPool (dev, ctx->descriptorPool,NULL);
+
+       vkvg_buffer_destroy (&ctx->uboGrad);
+       vkvg_buffer_destroy (&ctx->indices);
+       vkvg_buffer_destroy (&ctx->vertices);
+
+       free(ctx->vertexCache);
+       free(ctx->indexCache);
+
+       //TODO:check this for source counter
+       //vkh_image_destroy       (ctx->source);
+
+       free(ctx->pathes);
+       free(ctx->points);
+
+       free(ctx);
+}
 //populate vertice buff for stroke
 bool _build_vb_step (vkvg_context* ctx, float hw, stroke_context_t* str, bool isCurve){
        Vertex v = {{0},ctx->curColor, {0,0,-1}};
index fd219a846726407f9d8c3df26aa3e182cb069a06..5f5017c1208f7e26be7ebaab4346dc69ab659e49 100644 (file)
@@ -311,6 +311,7 @@ void _init_descriptor_sets  (VkvgContext ctx);
 void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds);
 void _update_gradient_desc_set(VkvgContext ctx);
 void _free_ctx_save                    (vkvg_context_save_t* sav);
+void _release_context_ressources (VkvgContext ctx);
 
 static inline float vec2_zcross (vec2 v1, vec2 v2){
        return v1.x*v2.y-v1.y*v2.x;
index a90ea8bc866a01c45558ab1c81da825caeedc941..2691d26ff8e1cef0ab1c4ed38749c053f3ed770e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "vkvg_device_internal.h"
 #include "vkvg_surface_internal.h"
+#include "vkvg_context_internal.h"
 #include "vkh_queue.h"
 #include "vkh_phyinfo.h"
 #include "vk_mem_alloc.h"
@@ -260,11 +261,8 @@ 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]);
-       }
+       while (dev->cachedContextCount > 0)
+               _release_context_ressources (dev->cachedContext[--dev->cachedContextCount]);
 
        LOG(VKVG_LOG_INFO, "DESTROY Device\n");
 
@@ -334,10 +332,10 @@ void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy) {
        *hdpy = dev->hdpi;
        *vdpy = dev->vdpi;
 }
-void vkvg_device_set_queue_guards (VkvgDevice dev, vkvg_queue_guard before_submit, vkvg_queue_guard after_submit, void* user_data) {
-       dev->gQLockGuard = before_submit;
-       dev->gQUnlockGuard = after_submit;
-       dev->gQGuardUserData = user_data;
+void vkvg_device_set_guards (VkvgDevice dev, vkvg_device_guard lock_callback, vkvg_device_guard unlock_callback, void* user_data) {
+       dev->deviceLockGuard            = lock_callback;
+       dev->deviceUnlockGuard          = unlock_callback;
+       dev->deviceGuardUserData        = user_data;
 }
 #if VKVG_DBG_STATS
 vkvg_debug_stats_t vkvg_device_get_stats (VkvgDevice dev) {
index 38f6e55f83b3883f52d667814912aa7fb5cc9de5..5d08bf1cea822e0be2876fc5663991e1723381f4 100644 (file)
@@ -428,45 +428,72 @@ void _wait_and_reset_device_fence (VkvgDevice dev) {
 }
 
 void _vkvg_device_destroy_fence (VkvgDevice dev, VkFence fence) {
-       if (dev->gQLockGuard)
-               dev->gQLockGuard (dev->gQGuardUserData);
+       if (dev->deviceLockGuard)
+               dev->deviceLockGuard (dev->deviceGuardUserData);
 
        if (dev->gQLastFence == fence)
                dev->gQLastFence = VK_NULL_HANDLE;
 
        vkDestroyFence (dev->vkDev, fence, NULL);
 
-       if (dev->gQUnlockGuard)
-               dev->gQUnlockGuard (dev->gQGuardUserData);
+       if (dev->deviceUnlockGuard)
+               dev->deviceUnlockGuard (dev->deviceGuardUserData);
 }
 void _vkvg_device_reset_fence (VkvgDevice dev, VkFence fence){
-       if (dev->gQLockGuard)
-               dev->gQLockGuard (dev->gQGuardUserData);
+       if (dev->deviceLockGuard)
+               dev->deviceLockGuard (dev->deviceGuardUserData);
 
        if (dev->gQLastFence == fence)
                dev->gQLastFence = VK_NULL_HANDLE;
 
        ResetFences (dev->vkDev, 1, &fence);
 
-       if (dev->gQUnlockGuard)
-               dev->gQUnlockGuard (dev->gQGuardUserData);
+       if (dev->deviceUnlockGuard)
+               dev->deviceUnlockGuard (dev->deviceGuardUserData);
 }
-void _vkvg_device_wait_fence                   (VkvgDevice dev, VkFence fence){
+void _vkvg_device_wait_fence (VkvgDevice dev, VkFence fence){
 
 }
 void _vkvg_device_wait_and_reset_fence (VkvgDevice dev, VkFence fence){
 
 }
+bool _vkvg_device_try_get_cached_context (VkvgDevice dev, VkvgContext* pCtx) {
+       if (dev->deviceLockGuard)
+               dev->deviceLockGuard (dev->deviceGuardUserData);
 
+       if (dev->cachedContextCount)
+               *pCtx = dev->cachedContext[--dev->cachedContextCount];
+       else
+               *pCtx = NULL;
+
+       if (dev->deviceUnlockGuard)
+               dev->deviceUnlockGuard (dev->deviceGuardUserData);
+
+       return *pCtx != NULL;
+}
+void _vkvg_device_store_context (VkvgContext ctx) {
+       VkvgDevice dev = ctx->dev;
+
+       if (dev->deviceLockGuard)
+               dev->deviceLockGuard (dev->deviceGuardUserData);
+
+       if (dev->gQLastFence == ctx->flushFence)
+               dev->gQLastFence = VK_NULL_HANDLE;
+       dev->cachedContext[dev->cachedContextCount++] = ctx;
+       ctx->references++;
+
+       if (dev->deviceUnlockGuard)
+               dev->deviceUnlockGuard (dev->deviceGuardUserData);
+}
 void _submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) {
-       if (dev->gQLockGuard)
-               dev->gQLockGuard (dev->gQGuardUserData);
+       if (dev->deviceLockGuard)
+               dev->deviceLockGuard (dev->deviceGuardUserData);
        if (dev->gQLastFence != VK_NULL_HANDLE)
                WaitForFences (dev->vkDev, 1, &dev->gQLastFence, VK_TRUE, VKVG_FENCE_TIMEOUT);
        vkh_cmd_submit (dev->gQueue, cmd, fence);
        dev->gQLastFence = fence;
-       if (dev->gQUnlockGuard)
-               dev->gQUnlockGuard (dev->gQGuardUserData);
+       if (dev->deviceUnlockGuard)
+               dev->deviceUnlockGuard (dev->deviceGuardUserData);
 }
 
 bool _init_function_pointers (VkvgDevice dev) {
index c702e1cfc1b69c23232b32e8cfec39f3453caff4..db2c3d3f7e360400922e8e121660c18421af4b56 100644 (file)
@@ -65,9 +65,9 @@ typedef struct _vkvg_device_t{
        VkFormat                                pngStagFormat;                  /**< Supported vulkan image format png write staging img */
        VkImageTiling                   pngStagTiling;                  /**< tiling for the blit operation */
 
-       vkvg_queue_guard                gQLockGuard;
-       vkvg_queue_guard                gQUnlockGuard;
-       void*                                   gQGuardUserData;
+       vkvg_device_guard               deviceLockGuard;
+       vkvg_device_guard               deviceUnlockGuard;
+       void*                                   deviceGuardUserData;
        VkhQueue                                gQueue;                                 /**< Vulkan Queue with Graphic flag */
        VkFence                                 gQLastFence;
 
@@ -137,4 +137,6 @@ void _vkvg_device_destroy_fence                     (VkvgDevice dev, VkFence fence);
 void _vkvg_device_reset_fence                  (VkvgDevice dev, VkFence fence);
 void _vkvg_device_wait_fence                   (VkvgDevice dev, VkFence fence);
 void _vkvg_device_wait_and_reset_fence (VkvgDevice dev, VkFence fence);
+bool _vkvg_device_try_get_cached_context(VkvgDevice dev, VkvgContext* pCtx);
+void _vkvg_device_store_context                        (VkvgContext ctx);
 #endif
index 5e6620aaf9a52c0a8460d7c764dc287e0cb7c5c0..00e14445b7d9d90dfa1967369ea1c58c0f4f954f 100644 (file)
@@ -53,7 +53,7 @@ void fixedSizeRects(){
        pmutex = &mutex;
 
        mtx_init (pgQMutex, mtx_plain);
-       vkvg_device_set_queue_guards (device, _before_submit, _after_submit, pgQMutex);
+       vkvg_device_set_guards (device, _before_submit, _after_submit, pgQMutex);
 
        thrd_t threads[THREAD_COUNT];
 
@@ -72,7 +72,7 @@ void fixedSizeRects(){
        mtx_destroy (pmutex);
        pmutex = NULL;
 
-       vkvg_device_set_queue_guards (device, NULL, NULL, NULL);
+       vkvg_device_set_guards (device, NULL, NULL, NULL);
        mtx_destroy (pgQMutex);
        pgQMutex = NULL;
 }
index ab557613d74948448bae2777be858c0c850d05cb..1b79ecb15ac680aa4516049db6678b1fca4ea478 100644 (file)
@@ -42,7 +42,7 @@ void fixedSizeRects(){
        pmutex = &mutex;
 
        mtx_init (pgQMutex, mtx_plain);
-       vkvg_device_set_queue_guards (device, _before_submit, _after_submit, pgQMutex);
+       vkvg_device_set_guards (device, _before_submit, _after_submit, pgQMutex);
 
        thrd_t threads[THREAD_COUNT];
 
@@ -61,7 +61,7 @@ void fixedSizeRects(){
        mtx_destroy (pmutex);
        pmutex = NULL;
 
-       vkvg_device_set_queue_guards (device, NULL, NULL, NULL);
+       vkvg_device_set_guards (device, NULL, NULL, NULL);
        mtx_destroy (pgQMutex);
        pgQMutex = NULL;
 }