* 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.
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) {
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);
}
//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);
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;
#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)
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}};
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;
#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"
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");
*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) {
}
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) {
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;
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
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];
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;
}
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];
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;
}