From cf63fa9e34bcca6e4d2252f49d8331ef643f2bec Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Mon, 31 Aug 2020 03:13:23 +0200 Subject: [PATCH] debug font cache --- include/vkvg.h | 15 +++++++ src/vkvg_context.c | 8 ++-- src/vkvg_context_internal.c | 24 +++++++---- src/vkvg_context_internal.h | 1 + src/vkvg_device_internal.c | 10 +++-- src/vkvg_fonts.c | 16 ++++--- src/vkvg_fonts.h | 86 ++++++++++++++++++------------------- src/vkvg_internal.h | 8 ---- tests/common/test.c | 4 +- tests/text.c | 26 ++++++----- 10 files changed, 112 insertions(+), 86 deletions(-) diff --git a/include/vkvg.h b/include/vkvg.h index 8f90ee3..169a9b4 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -99,6 +99,21 @@ extern "C" { #define VKVG_VERSION_REVISION 1 /*! @} */ +#ifndef cairo_public +# if defined (_MSC_VER) +# define vkvg_public __declspec(dllimport) +# else +# define vkvg_public +# endif +#endif + +#define VKVG_LOG_ERR 0x10 +#define VKVG_LOG_DEBUG 0x20 +#define VKVG_LOG_INFO 0x40 +#define VKVG_LOG_INFO_PATH 0x41 +#define VKVG_LOG_DBG_ARRAYS 0x80 +#define VKVG_LOG_FULL 0xff + #ifdef DEBUG extern uint8_t vkvg_log_level; #endif diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 0ef3e10..3f3d651 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -59,7 +59,7 @@ VkvgContext vkvg_create(VkvgSurface surf) 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) { {.height=1}, @@ -68,7 +68,7 @@ VkvgContext vkvg_create(VkvgSurface surf) 0, VKVG_IDENTITY_MATRIX, 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; @@ -904,9 +904,9 @@ void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){ } void vkvg_show_text (VkvgContext ctx, const char* text){ - _ensure_renderpass_is_started(ctx); + //_ensure_renderpass_is_started(ctx); _show_text (ctx, text); - _flush_undrawn_vertices (ctx); + //_flush_undrawn_vertices (ctx); } VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text) { diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 1cc3b76..f43e307 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -327,6 +327,7 @@ void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float h } //start render pass if not yet started or update push const if requested void _ensure_renderpass_is_started (VkvgContext ctx) { + LOG(VKVG_LOG_INFO, "_ensure_renderpass_is_started\n"); if (!ctx->cmdStarted) _start_cmd_for_render_pass(ctx); else if (ctx->pushCstDirty) @@ -427,15 +428,11 @@ void _end_render_pass (VkvgContext ctx) { void _check_vao_size (VkvgContext ctx) { if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){ //vbo or ibo buffers too small - if (ctx->cmdStarted) { + if (ctx->cmdStarted) //if cmd is started buffers, are already bound, so no resize is possible //instead we flush, and clear vbo and ibo caches - _end_render_pass (ctx); - if (ctx->curVertOffset > 0) - _flush_vertices_caches_until_vertex_base (ctx); - vkh_cmd_end (ctx->cmd); - _wait_and_submit_cmd (ctx); - } + _flush_cmd_until_vx_base (ctx); + _resize_vbo(ctx, ctx->sizeVertices); _resize_ibo(ctx, ctx->sizeIndices); } @@ -464,16 +461,25 @@ void _flush_undrawn_vertices (VkvgContext ctx){ ctx->curIndStart = ctx->indCount; ctx->curVertOffset = ctx->vertCount; } - +//preflush vertices with drawcommand already emited +void _flush_cmd_until_vx_base (VkvgContext ctx){ + _end_render_pass (ctx); + if (ctx->curVertOffset > 0){ + LOG(VKVG_LOG_INFO, "FLUSH UNTIL VX BASE CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount); + _flush_vertices_caches_until_vertex_base (ctx); + } + vkh_cmd_end (ctx->cmd); + _wait_and_submit_cmd (ctx); +} void _flush_cmd_buff (VkvgContext ctx){ _flush_undrawn_vertices (ctx); if (!ctx->cmdStarted) return; _end_render_pass (ctx); + LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount); _flush_vertices_caches (ctx); vkh_cmd_end (ctx->cmd); - LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount); _wait_and_submit_cmd(ctx); } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 4ce9ad4..9d1a141 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -218,6 +218,7 @@ void _create_cmd_buff (VkvgContext ctx); void _ensure_renderpass_is_started (VkvgContext ctx); void _flush_cmd_buff (VkvgContext ctx); void _flush_undrawn_vertices(VkvgContext ctx); +void _flush_cmd_until_vx_base (VkvgContext ctx); void _wait_flush_fence (VkvgContext ctx); void _reset_flush_fence (VkvgContext ctx); void _wait_and_submit_cmd (VkvgContext ctx); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 81d3315..ae4ba4f 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -48,10 +48,12 @@ PFN_vkCmdPushConstants CmdPushConstants; PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSet; void _flush_all_contexes (VkvgDevice dev){ - VkvgContext next = dev->lastCtx; - while (next != NULL){ - _flush_cmd_buff(next); - next = next->pPrev; + VkvgContext ctx = dev->lastCtx; + while (ctx != NULL){ + if (ctx->cmdStarted) + _flush_cmd_until_vx_base (ctx); + + ctx = ctx->pPrev; } } diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index e198b9b..268a1ce 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -85,6 +85,10 @@ void _init_fonts_cache (VkvgDevice dev){ } ///increase layer count of 2d texture array used as font cache. void _increase_font_tex_array (VkvgDevice dev){ + LOG(VKVG_LOG_INFO, "_increase_font_tex_array\n"); + + _flush_all_contexes (dev); + _font_cache_t* cache = dev->fontCache; vkWaitForFences (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX); @@ -126,20 +130,19 @@ void _increase_font_tex_array (VkvgDevice dev){ _submit_cmd (dev, &cache->cmd, cache->uploadFence); vkWaitForFences (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX); - _flush_all_contexes (dev); - cache->pensY = (int*)realloc(cache->pensY, newSize * sizeof(int)); - memset (cache->pensY + cache->texLength * sizeof(int),0,FONT_CACHE_INIT_LAYERS*sizeof(int)); + void* tmp = memset (&cache->pensY[cache->texLength],0,FONT_CACHE_INIT_LAYERS*sizeof(int)); vkh_image_destroy (cache->texture); cache->texLength = newSize; cache->texture = newImg; - /*VkvgContext next = dev->lastCtx; + VkvgContext next = dev->lastCtx; while (next != NULL){ - _update_descriptor_set (next, next->source, next->dsSrc); + _update_descriptor_set (next, cache->texture, next->dsFont); next = next->pPrev; - }*/ + } + _wait_idle(dev); } ///Start a new line in font cache, increase texture layer count if needed. void _init_next_line_in_tex_cache (VkvgDevice dev, _vkvg_font_t* f){ @@ -220,6 +223,7 @@ void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) { if (cache->stagingX == 0) return; + LOG(VKVG_LOG_INFO, "_flush_chars_to_tex pen(%d, %d)\n",f->curLine.penX, f->curLine.penY); vkWaitForFences (dev->vkDev,1,&cache->uploadFence,VK_TRUE,UINT64_MAX); vkResetCommandBuffer(cache->cmd,0); vkResetFences (dev->vkDev,1,&cache->uploadFence); diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index 87c4b94..e2d17dd 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -37,9 +37,9 @@ #include -#define FONT_PAGE_SIZE 2048 -#define FONT_CACHE_INIT_LAYERS 2 -#define FONT_FILE_NAME_MAX_SIZE 256 +#define FONT_PAGE_SIZE 1024 +#define FONT_CACHE_INIT_LAYERS 1 +#define FONT_FILE_NAME_MAX_SIZE 1024 #include "vkvg_internal.h" #include "vkvg.h" @@ -48,67 +48,67 @@ #define FT_CHECK_RESULT(f) \ { \ - FT_Error res = (f); \ - if (res != 0) \ - { \ - fprintf(stderr,"Fatal : FreeType error is %d in %s at line %d\n", res, __FILE__, __LINE__); \ - assert(res == 0); \ - } \ + FT_Error res = (f); \ + if (res != 0) \ + { \ + fprintf(stderr,"Fatal : FreeType error is %d in %s at line %d\n", res, __FILE__, __LINE__); \ + assert(res == 0); \ + } \ } //texture coordinates of one character in font cache array texture. typedef struct { - vec4 bounds; /* normalized float bounds of character bitmap in font cache texture. */ - vec2i16 bmpDiff; /* Difference in pixel between char bitmap top left corner and char glyph*/ - uint8_t pageIdx; /* Page index in font cache texture array */ + vec4 bounds; /* normalized float bounds of character bitmap in font cache texture. */ + vec2i16 bmpDiff; /* Difference in pixel between char bitmap top left corner and char glyph*/ + uint8_t pageIdx; /* Page index in font cache texture array */ }_char_ref; // Current location in font cache texture array for new character addition. Each font holds such structure to locate // where to upload new chars. typedef struct { - uint8_t pageIdx; /* Current page number in font cache */ - int penX; /* Current X in cache for next char addition */ - int penY; /* Current Y in cache for next char addition */ - int height; /* Height of current line pointed by this structure */ + uint8_t pageIdx; /* Current page number in font cache */ + int penX; /* Current X in cache for next char addition */ + int penY; /* Current Y in cache for next char addition */ + int height; /* Height of current line pointed by this structure */ }_tex_ref_t; // Loaded font structure, holds informations for glyphes upload in cache and the lookup table of characters. typedef struct { - char* fontFile; /* Font file full path*/ - FT_F26Dot6 charSize; /* Font size*/ - hb_font_t* hb_font; /* HarfBuzz font instance*/ - FT_Face face; /* FreeType face*/ - _char_ref** charLookup; /* Lookup table of characteres in cache, if not found, upload is queued*/ + char* fontFile; /* Font file full path*/ + FT_F26Dot6 charSize; /* Font size*/ + hb_font_t* hb_font; /* HarfBuzz font instance*/ + FT_Face face; /* FreeType face*/ + _char_ref** charLookup; /* Lookup table of characteres in cache, if not found, upload is queued*/ - _tex_ref_t curLine; /* tex coord where to add new char bmp's */ + _tex_ref_t curLine; /* tex coord where to add new char bmp's */ }_vkvg_font_t; // Font cache global structure, entry point for all font related operations. typedef struct { - FT_Library library; /* FreeType library*/ - FcConfig* config; /* Font config, used to find font files by font names*/ + FT_Library library; /* FreeType library*/ + FcConfig* config; /* Font config, used to find font files by font names*/ - int stagingX; /* x pen in host buffer */ - uint8_t* hostBuff; /* host memory where bitmaps are first loaded */ + int stagingX; /* x pen in host buffer */ + uint8_t* hostBuff; /* host memory where bitmaps are first loaded */ - VkCommandBuffer cmd; /* vulkan command buffer for font textures upload */ - vkvg_buff buff; /* stagin buffer */ - VkhImage texture; /* 2d array texture used by contexts to draw characteres */ - VkFormat texFormat; /* Format of the fonts texture array */ - uint8_t texPixelSize; /* Size in byte of a single pixel in a font texture */ - uint8_t texLength; /* layer count of 2d array texture, starts with FONT_CACHE_INIT_LAYERS count and increased when needed */ - int* pensY; /* array of current y pen positions for each texture in cache 2d array */ - VkFence uploadFence; /* Signaled when upload is finished */ + VkCommandBuffer cmd; /* vulkan command buffer for font textures upload */ + vkvg_buff buff; /* stagin buffer */ + VkhImage texture; /* 2d array texture used by contexts to draw characteres */ + VkFormat texFormat; /* Format of the fonts texture array */ + uint8_t texPixelSize; /* Size in byte of a single pixel in a font texture */ + uint8_t texLength; /* layer count of 2d array texture, starts with FONT_CACHE_INIT_LAYERS count and increased when needed */ + int* pensY; /* array of current y pen positions for each texture in cache 2d array */ + VkFence uploadFence; /* Signaled when upload is finished */ - _vkvg_font_t* fonts; /* Loaded fonts structure array */ - uint8_t fontsCount; /* Loaded fonts array count*/ + _vkvg_font_t* fonts; /* Loaded fonts structure array */ + uint8_t fontsCount; /* Loaded fonts array count*/ }_font_cache_t; // Precompute everything necessary to draw one line of text, usefull to draw the same text multiple times. typedef struct _vkvg_text_run_t { - hb_buffer_t* hbBuf; /* HarfBuzz buffer of text */ - _vkvg_font_t* font; /* vkvg font structure pointer */ - VkvgDevice dev; /* vkvg device associated with this text run */ - vkvg_text_extents_t extents; /* store computed text extends */ - const char* text; /* utf8 char array of text*/ - unsigned int glyph_count;/* Total glyph count */ - hb_glyph_position_t *glyph_pos; /* HarfBuzz computed glyph positions array */ + hb_buffer_t* hbBuf; /* HarfBuzz buffer of text */ + _vkvg_font_t* font; /* vkvg font structure pointer */ + VkvgDevice dev; /* vkvg device associated with this text run */ + vkvg_text_extents_t extents; /* store computed text extends */ + const char* text; /* utf8 char array of text*/ + unsigned int glyph_count;/* Total glyph count */ + hb_glyph_position_t *glyph_pos; /* HarfBuzz computed glyph positions array */ } vkvg_text_run_t; //Create font cache. void _init_fonts_cache (VkvgDevice dev); diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index 5e85578..f722c9c 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -48,14 +48,6 @@ #define LOG #endif -#define VKVG_LOG_ERR 0x10 -#define VKVG_LOG_DEBUG 0x20 -#define VKVG_LOG_INFO 0x40 -#define VKVG_LOG_INFO_PATH 0x41 -#define VKVG_LOG_DBG_ARRAYS 0x80 -#define VKVG_LOG_FULL 0xff - - #define PATH_CLOSED_BIT 0x80000000 /* most significant bit of path elmts is closed/open path state */ #define PATH_HAS_CURVES_BIT 0x40000000 /* 2d most significant bit of path elmts if curve data are present, stored to avoid emiting joins in curves */ diff --git a/tests/common/test.c b/tests/common/test.c index 733670a..d879fbb 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -33,8 +33,8 @@ bool mouseDown = false; VkvgDevice device = NULL; VkvgSurface surf = NULL; -uint32_t test_size = 100; // items drawn in one run, or complexity -uint32_t iterations = 1000;// repeat test n times +uint32_t test_size = 500; // items drawn in one run, or complexity +uint32_t iterations = 500;// repeat test n times uint32_t test_width = 1024; uint32_t test_height= 768; bool test_vsync = false; diff --git a/tests/text.c b/tests/text.c index 65165bc..da4ee14 100644 --- a/tests/text.c +++ b/tests/text.c @@ -152,23 +152,29 @@ void test(){ vkvg_destroy(ctx); } - -void test_mono () { +void random_text () { VkvgContext ctx = vkvg_create(surf); - vkvg_set_source_rgb(ctx,1,1,1); + vkvg_clear(ctx); vkvg_select_font_face(ctx,"mono"); - vkvg_set_font_size(ctx, 20); - vkvg_move_to(ctx,100,100); - vkvg_show_text(ctx,"This is a test string!"); + for (uint32_t i=0; i