diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-09-28 22:13:03 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-01 13:29:27 +0200 |
| commit | f463628639ca1e0c415d5acc952eda409df6d86e (patch) | |
| tree | 2eb25d0bf6f9def5dbe53f7c0d584d9f40177e56 | |
| parent | 30c58551af23a9a5197989955f6ca4376ff29af0 (diff) | |
memcpy in save/restore, getArcStep tests, vbo&pts size *2, dashes fixed array[5], save/restore stack as array
| -rw-r--r-- | CMakeLists.txt | 47 | ||||
| -rw-r--r-- | include/vkvg.h | 2 | ||||
| -rw-r--r-- | src/vkvg_context.c | 179 | ||||
| -rw-r--r-- | src/vkvg_context_internal.c | 30 | ||||
| -rw-r--r-- | src/vkvg_context_internal.h | 182 | ||||
| -rw-r--r-- | src/vkvg_fonts.c | 20 | ||||
| -rw-r--r-- | tests/vkvg-svg/svg-viewer.c | 3 |
7 files changed, 240 insertions, 223 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 10cac4f..a9b0dff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,11 +30,14 @@ ENDIF() OPTION(ENABLE_PROFILING "compile with the -pg options..." OFF) IF (ENABLE_PROFILING) ADD_COMPILE_OPTIONS( - -pg -fno-reorder-functions -fno-inline - -O1 - -fthread-jumps - -falign-functions -falign-jumps - -falign-loops -falign-labels) + -pg + # -fno-reorder-functions -fno-inline + -O2 + # -fthread-jumps + # -falign-functions -falign-jumps + # -falign-loops -falign-labels + ) + ADD_LINK_OPTIONS(-pg) ENDIF() if (CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -236,7 +239,7 @@ SET (VKVG_PUBLIC_HEADERS "include/vkvg.h;include/vkvg-svg.h") IF (VKVG_SVG) ADD_DEFINITIONS (-DVKVG_SVG) - FILE(GLOB SVG_SRC tests/svg-parser-new/*.c) + FILE(GLOB SVG_SRC tests/svg-parser-new/*.c tests/svg-parser-new/*.h) ELSE() FILE(GLOB SVG_SRC src/nsvg/*.c) ENDIF() @@ -267,15 +270,15 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${vkvg_VERSION_MAJOR}.${vkvg_VERSION_MINOR} SOVERSION ${vkvg_VERSION_MAJOR} C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS ON + C_STANDARD_REQUIRED ON + C_EXTENSIONS ON - POSITION_INDEPENDENT_CODE "${BUILD_SHARED_LIBS}" + POSITION_INDEPENDENT_CODE "${BUILD_SHARED_LIBS}" PUBLIC_HEADER "${VKVG_PUBLIC_HEADERS}" - C_VISIBILITY_PRESET hidden - VISIBILITY_INLINES_HIDDEN ON + C_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON ) TARGET_INCLUDE_DIRECTORIES("${PROJECT_NAME}" @@ -286,7 +289,7 @@ TARGET_INCLUDE_DIRECTORIES("${PROJECT_NAME}" $<$<BOOL:${VKVG_USE_HARFBUZZ}>:${HarfBuzz_INCLUDE_DIRS}> $<$<BOOL:${VKVG_USE_FONTCONFIG}>:${Fontconfig_INCLUDE_DIRS}> $<$<NOT:$<BOOL:${VKVG_SVG}>>:${CMAKE_CURRENT_SOURCE_DIR}/src/nsvg> - ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include + ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include PUBLIC ${Vulkan_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -330,6 +333,26 @@ INSTALL(TARGETS "${PROJECT_NAME}" "${PROJECT_NAME}" IF (VKVG_BUILD_TESTS) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(samples) + + #font tests + + ADD_EXECUTABLE(fonts_test "${CMAKE_CURRENT_SOURCE_DIR}/tests/font_tests/font_tests.c") + + TARGET_INCLUDE_DIRECTORIES(fonts_test PRIVATE + ${FREETYPE_INCLUDE_DIRS} + ${HarfBuzz_INCLUDE_DIRS} + ${Vulkan_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + TARGET_LINK_LIBRARIES(fonts_test PUBLIC + #vkvg + ${HarfBuzz_LIBRARIES} + ${FREETYPE_LIBRARY} + ${Vulkan_LIBRARIES} + ) + + ################### + ELSEIF (VKVG_BUILD_OFFSCREEN_TEST) ADD_EXECUTABLE(test_offscreen "${CMAKE_CURRENT_SOURCE_DIR}/tests/offscreen.c") TARGET_INCLUDE_DIRECTORIES(test_offscreen PRIVATE diff --git a/include/vkvg.h b/include/vkvg.h index 51d0754..fa588d6 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -117,6 +117,8 @@ vkvg_public extern vkvg_wired_debug_mode vkvg_wired_debug; #endif #endif +#define VKVG_MAX_DASH_COUNT 5 + /** * @brief vkvg operation status. * diff --git a/src/vkvg_context.c b/src/vkvg_context.c index aae1cef..83240cf 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -16,7 +16,7 @@ const float DBG_LAB_COLOR_SAV[4] = {1, 0, 1, 1}; const float DBG_LAB_COLOR_CLIP[4] = {0, 1, 1, 1}; #endif #endif - +#define CTX_SAVE_SIZE_INI 10 // todo:this could be used to define a default background static VkClearValue clearValues[3] = { {.color.float32 = {0, 0, 0, 0}}, {.depthStencil = {1.0f, 0}}, {.color.float32 = {0, 0, 0, 0}}}; @@ -55,8 +55,8 @@ void _init_ctx(VkvgContext ctx) { ctx->renderPassBeginInfo.clearValueCount = ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT ? 2 : 3; ctx->selectedCharSize = 10 << 6; - ctx->currentFont = NULL; - ctx->selectedFontName = 0; + //ctx->currentFont = NULL; + ctx->selectedFont = 0; ctx->pattern = NULL; ctx->curColor = 0xff000000; // opaque black ctx->cmdStarted = false; @@ -100,13 +100,13 @@ VkvgContext vkvg_create(VkvgSurface surf) { LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf); ctx->pSurf = surf; - ctx->sizePoints = VKVG_PTS_SIZE; - ctx->sizeVertices = ctx->sizeVBO = VKVG_VBO_SIZE; - ctx->sizeIndices = ctx->sizeIBO = VKVG_IBO_SIZE; + 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->dev = surf->dev; + ctx->dev = surf->dev; ctx->points = (vec2*)malloc(VKVG_VBO_SIZE * sizeof(vec2)); ctx->pathes = (uint32_t*)malloc(VKVG_PATHES_SIZE * sizeof(uint32_t)); @@ -206,14 +206,16 @@ void vkvg_flush(VkvgContext ctx) { } void _clear_context(VkvgContext ctx) { + VkvgPattern pat = NULL; + // free saved context stack elmt - vkvg_context_save_t* next = ctx->pSavedCtxs; - ctx->pSavedCtxs = NULL; - while (next != NULL) { - vkvg_context_save_t* cur = next; - next = cur->pNext; - _free_ctx_save(cur); + while (ctx->ctxSaveCount > 0) { + ctx->ctxSaveCount--; + pat = ctx->pSavedCtxs[ctx->ctxSaveCount].pattern; + if (pat) + vkvg_pattern_destroy(pat); } + // free additional stencil use in save/restore process if (ctx->savedStencils) { uint8_t curSaveStencil = ctx->curSavBit / 6; @@ -223,23 +225,6 @@ void _clear_context(VkvgContext ctx) { 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); - ctx->dashCount = 0; - } } void vkvg_destroy(VkvgContext ctx) { @@ -390,6 +375,45 @@ void vkvg_line_to(VkvgContext ctx, float x, float y) { LOG(VKVG_LOG_INFO_CMD, "\tCMD: line_to: %f, %f\n", x, y); _line_to(ctx, x, y); } + + +/*static inline float getArcStep(VkvgContext ctx,float radius, float arcAngle) { + float sx, sy; + vkvg_matrix_get_scale(&ctx->pushConsts.mat, &sx, &sy); + const float delta = 0.5f; + float r = radius * fabsf(fmaxf(sx, sy)); + float res = arcAngle / (acos(1.f - (delta / r)) * M_PI * 2.f); + printf("r:%f alpha:%f step:%f\n", r, arcAngle, res); + return res; +}*/ +/*float getArcStep(VkvgContext ctx, float radius, float angular_length) { + // 1. Establish geometric error tolerance (in screen pixels) + // 0.5 means a segment vertex will never deviate more than half a pixel from the ideal curve. + // Increase slightly (e.g., 0.75 or 1.0) for a massive speed boost with imperceptible visual change. + const float error_tolerance = 0.25f; + float sx, sy; + vkvg_matrix_get_scale(&ctx->pushConsts.mat, &sx, &sy); + float r = radius * fabsf(fmaxf(sx, sy)); + if (r <= 0.1f) + return angular_length * .25f; + float full_circle_segments = M_PI * sqrtf(r / (2.0f * error_tolerance)); + float arc_fraction = fabsf(angular_length) / (2.0f * M_PI); + int optimal_steps = (int)ceilf(full_circle_segments * arc_fraction); + + if (optimal_steps < 4) optimal_steps = 4; + + return angular_length / (float)optimal_steps; +}*/ +float getArcStep(VkvgContext ctx, float radius, float angular_length) { + const float error_tolerance = 0.25f; + float sx, sy; + vkvg_matrix_get_scale(&ctx->pushConsts.mat, &sx, &sy); + float local_tolerance = error_tolerance / fabsf(fmaxf(sx, sy)); + if (radius <= local_tolerance) { + return 1.5707963f; + } + return 2.0f * sqrtf((2.0f * local_tolerance) / radius); +} void vkvg_arc(VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) { if (vkvg_status(ctx)) return; @@ -405,7 +429,8 @@ void vkvg_arc(VkvgContext ctx, float xc, float yc, float radius, float a1, float vec2 v = {cosf(a1) * radius + xc, sinf(a1) * radius + yc}; - float step = _get_arc_step(ctx, radius); + //float step = _get_arc_step(ctx, radius); + float step = getArcStep(ctx, radius, a2 - a1); float a = a1; if (_current_path_is_empty(ctx)) { @@ -458,7 +483,7 @@ void vkvg_arc_negative(VkvgContext ctx, float xc, float yc, float radius, float vec2 v = {cosf(a1) * radius + xc, sinf(a1) * radius + yc}; - float step = _get_arc_step(ctx, radius); + float step = getArcStep(ctx, radius, a1 - a2); float a = a1; if (_current_path_is_empty(ctx)) { @@ -1100,16 +1125,13 @@ float vkvg_get_miter_limit(VkvgContext ctx) { return ctx->miterLimit; } void vkvg_set_dash(VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset) { - if (vkvg_status(ctx)) + if (vkvg_status(ctx) || num_dashes > VKVG_MAX_DASH_COUNT) return; - if (ctx->dashCount > 0) - free(ctx->dashes); RECORD(ctx, VKVG_CMD_SET_DASH, num_dashes, offset, dashes); ctx->dashCount = num_dashes; ctx->dashOffset = offset; if (ctx->dashCount == 0) return; - ctx->dashes = (float*)malloc(sizeof(float) * ctx->dashCount); memcpy(ctx->dashes, dashes, sizeof(float) * ctx->dashCount); } void vkvg_get_dash(VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset) { @@ -1176,15 +1198,15 @@ void vkvg_set_font_size(VkvgContext ctx, uint32_t size) { return; RECORD(ctx, VKVG_CMD_SET_FONT_SIZE, size); #ifdef VKVG_USE_FREETYPE - long newSize = size << 6; + uint32_t newSize = size << 6; #else - long newSize = size; + uint32_t newSize = size; #endif if (ctx->selectedCharSize == newSize) return; ctx->selectedCharSize = newSize; - ctx->currentFont = NULL; - ctx->currentFontSize = NULL; + //ctx->currentFont = NULL; + //ctx->currentFontSize = NULL; } void vkvg_set_text_direction(vkvg_context* ctx, vkvg_direction_t direction) {} @@ -1253,8 +1275,21 @@ void vkvg_save(VkvgContext ctx) { RECORD(ctx, VKVG_CMD_SAVE); LOG(VKVG_LOG_INFO, "SAVE CONTEXT: ctx = %p\n", ctx); + if (ctx->ctxSaveCount >= ctx->sizeCtxSave) { + size_t newSize = ctx->sizeCtxSave + CTX_SAVE_SIZE_INI; + vkvg_context_save_t* tmp = (vkvg_context_save_t*)realloc( + ctx->pSavedCtxs, newSize * sizeof(vkvg_context_save_t)); + if (tmp == NULL) { + ctx->status = VKVG_STATUS_NO_MEMORY; + LOG(VKVG_LOG_ERR, "resize context save stack failed.\n"); + return; + } + ctx->pSavedCtxs = tmp; + ctx->sizeCtxSave = newSize; + } + VkvgDevice dev = ctx->dev; - vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1, sizeof(vkvg_context_save_t)); + vkvg_context_save_t* sav = &ctx->pSavedCtxs[ctx->ctxSaveCount]; _flush_cmd_buff(ctx); @@ -1345,33 +1380,12 @@ void vkvg_save(VkvgContext ctx) { else sav->clippingState = vkvg_clip_state_clear; - sav->dashOffset = ctx->dashOffset; - sav->dashCount = ctx->dashCount; - if (ctx->dashCount > 0) { - sav->dashes = (float*)malloc(sizeof(float) * ctx->dashCount); - memcpy(sav->dashes, ctx->dashes, sizeof(float) * ctx->dashCount); - } - sav->lineWidth = ctx->lineWidth; - sav->miterLimit = ctx->miterLimit; - sav->curOperator = ctx->curOperator; - sav->lineCap = ctx->lineCap; - sav->lineWidth = ctx->lineWidth; - sav->curFillRule = ctx->curFillRule; - - sav->selectedCharSize = ctx->selectedCharSize; - sav->selectedFontName =ctx->selectedFontName; + memcpy((void*)sav, (void*)&(ctx->curColor), (void*)&(ctx->indCount) - (void*)&(ctx->curColor)); - sav->currentFont = ctx->currentFont; - sav->textDirection = ctx->textDirection; - sav->pushConsts = ctx->pushConsts; - if (ctx->pattern) { - sav->pattern = ctx->pattern; // TODO:pattern sav must be imutable (copy?) + if (ctx->pattern) vkvg_pattern_reference(ctx->pattern); - } else - sav->curColor = ctx->curColor; - sav->pNext = ctx->pSavedCtxs; - ctx->pSavedCtxs = sav; + ctx->ctxSaveCount++; } void vkvg_restore(VkvgContext ctx) { if (vkvg_status(ctx)) @@ -1379,15 +1393,14 @@ void vkvg_restore(VkvgContext ctx) { RECORD(ctx, VKVG_CMD_RESTORE); - if (ctx->pSavedCtxs == NULL) { + if (!ctx->ctxSaveCount) { ctx->status = VKVG_STATUS_INVALID_RESTORE; return; } LOG(VKVG_LOG_INFO, "RESTORE CONTEXT: ctx = %p\n", ctx); - vkvg_context_save_t* sav = ctx->pSavedCtxs; - ctx->pSavedCtxs = sav->pNext; + vkvg_context_save_t* sav = &ctx->pSavedCtxs[ctx->ctxSaveCount-1]; _flush_cmd_buff(ctx); @@ -1474,44 +1487,40 @@ void vkvg_restore(VkvgContext ctx) { } } - ctx->pushConsts = sav->pushConsts; - ctx->pushCstDirty = true; - ctx->curClipState = vkvg_clip_state_none; - ctx->dashOffset = sav->dashOffset; - if (ctx->dashCount > 0) - free(ctx->dashes); + memcpy((void*)&(ctx->curColor), (void*)sav, (void*)&(ctx->pattern) - (void*)&(ctx->curColor)); + + /*ctx->curColor = sav->curColor; + ctx->lineWidth = sav->lineWidth; + ctx->miterLimit = sav->miterLimit; ctx->dashCount = sav->dashCount; + ctx->dashOffset = sav->dashOffset; if (ctx->dashCount > 0) { - ctx->dashes = (float*)malloc(sizeof(float) * ctx->dashCount); memcpy(ctx->dashes, sav->dashes, sizeof(float) * ctx->dashCount); } - ctx->lineWidth = sav->lineWidth; - ctx->miterLimit = sav->miterLimit; ctx->curOperator = sav->curOperator; ctx->lineCap = sav->lineCap; ctx->lineJoin = sav->lineJoint; ctx->curFillRule = sav->curFillRule; - + ctx->textDirection = sav->textDirection; ctx->selectedCharSize = sav->selectedCharSize; - ctx->selectedFontName = sav->selectedFontName; + ctx->selectedFont = sav->selectedFont; + ctx->pushConsts = sav->pushConsts;*/ - ctx->currentFont = sav->currentFont; - ctx->textDirection = sav->textDirection; + ctx->pushCstDirty = true; if (sav->pattern) { if (sav->pattern != ctx->pattern) { _update_cur_pattern(ctx, sav->pattern); - vkvg_pattern_reference(ctx->pattern); - } + } else + vkvg_pattern_destroy(ctx->pattern); } else { - ctx->curColor = sav->curColor; _update_cur_pattern(ctx, NULL); } - _free_ctx_save(sav); + ctx->ctxSaveCount--; } void vkvg_translate(VkvgContext ctx, float dx, float dy) { diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 5373035..358b39a 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -80,7 +80,7 @@ void _check_vertex_cache_size(VkvgContext ctx) { assert(ctx->sizeVertices > ctx->vertCount); if (ctx->sizeVertices - VKVG_ARRAY_THRESHOLD > ctx->vertCount) return; - _resize_vertex_cache(ctx, ctx->sizeVertices + VKVG_VBO_SIZE); + _resize_vertex_cache(ctx, ctx->sizeVertices * 2); } void _ensure_index_cache_size(VkvgContext ctx, uint32_t addedIndicesCount) { assert(ctx->sizeIndices > ctx->indCount); @@ -95,7 +95,7 @@ void _ensure_index_cache_size(VkvgContext ctx, uint32_t addedIndicesCount) { void _check_index_cache_size(VkvgContext ctx) { if (ctx->sizeIndices - VKVG_ARRAY_THRESHOLD > ctx->indCount) return; - _resize_index_cache(ctx, ctx->sizeIndices + VKVG_IBO_SIZE); + _resize_index_cache(ctx, ctx->sizeIndices * 2); } // check host path array size, return true if error. pathPtr is already incremented bool _check_pathes_array(VkvgContext ctx) { @@ -911,16 +911,18 @@ void _release_context_ressources(VkvgContext ctx) { vkh_buffer_reset(&ctx->indices); vkh_buffer_reset(&ctx->vertices); - free(ctx->vertexCache); - free(ctx->indexCache); - vkh_image_destroy(ctx->fontCacheImg); // TODO:check this for source counter // vkh_image_destroy (ctx->source); + free(ctx->vertexCache); + free(ctx->indexCache); + free(ctx->pathes); free(ctx->points); + free(ctx->pSavedCtxs); + free(ctx); } // populate vertice buff for stroke @@ -1297,14 +1299,6 @@ bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { return (s >= 0) && (t >= 0) && (s + t <= D); } -void _free_ctx_save(vkvg_context_save_t* sav) { - if (sav->dashCount > 0) - free(sav->dashes); - if (sav->pattern) - vkvg_pattern_destroy(sav->pattern); - free(sav); -} - #define M_APPROXIMATION_SCALE 1.0 #define M_ANGLE_TOLERANCE 0.01 #define M_CUSP_LIMIT 0.01 @@ -1539,7 +1533,7 @@ void _elliptic_arc(VkvgContext ctx, float x1, float y1, float x2, float y2, bool double theta = sa; double ea = sa + delta_theta; - float step = fmaxf(0.001f, fminf(M_PIF, _get_arc_step(ctx, fminf(rx, ry)) * 0.1f)); + float step = fmaxf(0.001f, fminf(M_PIF, _get_arc_step(ctx, fminf(rx, ry)) * 1.0f)); p = (vec2){rx * cosf(theta), ry * sinf(theta)}; vec2 xy = vec2_add(mat2_mult_vec2(m, p), c); @@ -1956,9 +1950,9 @@ void _draw_full_screen_quad(VkvgContext ctx, vec4* scissor) { void _select_font_face(VkvgContext ctx, const char* name) { uint64_t h = fnv1a_64_str(name); - if (ctx->selectedFontName == h) + if (ctx->selectedFont == h) return; - ctx->selectedFontName = h; - ctx->currentFont = NULL; - ctx->currentFontSize = NULL; + ctx->selectedFont = h; + /*ctx->currentFont = NULL; + ctx->currentFontSize = NULL;*/ } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 327bea5..d09535d 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -100,37 +100,82 @@ typedef enum { } vkvg_clip_state_t; typedef struct _vkvg_context_save_t { - struct _vkvg_context_save_t* pNext; + uint32_t curColor; + float lineWidth; + float miterLimit; + uint32_t dashCount; // value count in dash array, 0 if dash not set. + float dashOffset; // an offset for dash + float dashes[VKVG_MAX_DASH_COUNT];// fixed array of alternate lengths of on and off stroke. - float lineWidth; - float miterLimit; - float dashOffset; // an offset for dash - float* dashes; // an array of alternate lengths of on and off stroke. - uint32_t dashCount; // value count in dash array, 0 if dash not set. + vkvg_operator_t curOperator; + vkvg_line_cap_t lineCap; + vkvg_line_join_t lineJoint; + vkvg_fill_rule_t curFillRule; + vkvg_direction_t textDirection; + uint32_t selectedCharSize; /* Font size*/ + uint64_t selectedFont; + //_vkvg_font_identity_t selectedFont; // hold current face and size before cache addition + //_vkvg_font_identity_t* currentFont; // font ready for lookup + push_constants pushConsts; + VkvgPattern pattern; + vkvg_clip_state_t clippingState; +} vkvg_context_save_t; + +typedef struct _vkvg_context_t { + vkvg_status_t status; + uint32_t references; // reference count + + uint32_t curColor; + float lineWidth; + float miterLimit; + uint32_t dashCount; // value count in dash array, 0 if dash not set. + float dashOffset; // an offset for dash + float dashes[VKVG_MAX_DASH_COUNT]; // fixed array of alternate lengths of on and off stroke. vkvg_operator_t curOperator; vkvg_line_cap_t lineCap; - vkvg_line_join_t lineJoint; + vkvg_line_join_t lineJoin; vkvg_fill_rule_t curFillRule; + vkvg_direction_t textDirection; + uint32_t selectedCharSize; /* Font size*/ + uint64_t selectedFont; + // _vkvg_font_identity_t* currentFont; // font pointing to cached fonts identity + /****************************/ + //_vkvg_font_t selectedFont; //hold current face and size before cache addition + //_vkvg_font_t* currentFontSize; // font structure by size ready for lookup + push_constants pushConsts; + VkvgPattern pattern; - long selectedCharSize; /* Font size*/ - uint64_t selectedFontName; - _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; - push_constants pushConsts; - uint32_t curColor; - VkvgPattern pattern; - vkvg_clip_state_t clippingState; + //-------------------------------------------------------------------------------- + uint32_t indCount; // current indice count + uint32_t curIndStart; // last index recorded in cmd buff + VKVG_IBO_INDEX_TYPE curVertOffset; // vertex offset in draw indexed command + uint32_t vertCount; // effective vertices count + // pathes, exists until stroke of fill + uint32_t pointCount; // effective points count + // pathes array is a list of point count per segment + uint32_t pathPtr; // pointer in the path array + uint32_t segmentPtr; // current segment count in current path having curves + uint32_t subpathCount; // store count of subpath, not straight forward to retrieve from segmented path array + uint8_t simpleConvex:1; // true if path is single rect or concave closed curve. + uint8_t cmdStarted:1; // prevent flushing empty renderpass + uint8_t pushCstDirty:1; // prevent pushing to gpu if not requested -} vkvg_context_save_t; + VkRect2D bounds; + VkClearRect clearRect; -typedef struct _vkvg_context_t { - vkvg_status_t status; - uint32_t references; // reference count +#if VKVG_FILL_NZ_GLUTESS + void (*vertex_cb)(VKVG_IBO_INDEX_TYPE, VkvgContext); // tesselator vertex callback + VKVG_IBO_INDEX_TYPE tesselator_fan_start; + uint32_t tesselator_idx_counter; +#endif - VkvgDevice dev; - VkvgSurface pSurf; // surface bound to context, set on creation of ctx +#if VKVG_RECORDING + vkvg_recording_t* recording; +#endif + + VkvgDevice dev; + VkvgSurface pSurf; // surface bound to context, set on creation of ctx #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE uint64_t timelineStep; // context cmd last submission timeline id. #else @@ -145,88 +190,31 @@ typedef struct _vkvg_context_t { VkDescriptorSet dsFont; // fonts glyphs texture atlas descriptor (local for thread safety) VkDescriptorSet dsSrc; // source ds VkDescriptorSet dsGrad; // gradient uniform buffer - - VkhImage fontCacheImg; // current font cache, may not be the last one, updated only if new glyphs are - // uploaded by the current context - - VkRect2D bounds; - - uint32_t curColor; - -#if VKVG_FILL_NZ_GLUTESS - void (*vertex_cb)(VKVG_IBO_INDEX_TYPE, VkvgContext); // tesselator vertex callback - VKVG_IBO_INDEX_TYPE tesselator_fan_start; - uint32_t tesselator_idx_counter; -#endif - -#if VKVG_RECORDING - vkvg_recording_t* recording; -#endif - - vkh_buffer_t uboGrad; // uniform buff obj holdings gradient infos - + VkhImage fontCacheImg; // current font cache, may not be the last one, updated only if new glyphs are uploaded by the current context // vk buffers, holds data until flush - vkh_buffer_t indices; // index buffer with persistent map memory - uint32_t sizeIBO; // size of vk ibo - uint32_t sizeIndices; // reserved size - uint32_t indCount; // current indice count - - uint32_t curIndStart; // last index recorded in cmd buff - VKVG_IBO_INDEX_TYPE curVertOffset; // vertex offset in draw indexed command - - vkh_buffer_t vertices; // vertex buffer with persistent mapped memory - uint32_t sizeVBO; // size of vk vbo size - uint32_t sizeVertices; // reserved size - uint32_t vertCount; // effective vertices count - + vkh_buffer_t uboGrad; // uniform buff obj holdings gradient infos + vkh_buffer_t indices; // index buffer with persistent map memory + vkh_buffer_t vertices; // vertex buffer with persistent mapped memory Vertex* vertexCache; VKVG_IBO_INDEX_TYPE* indexCache; + vec2* points; // points array + uint32_t* pathes; + vkvg_context_save_t* pSavedCtxs; // saved ctx stack - // pathes, exists until stroke of fill - vec2* points; // points array - uint32_t sizePoints; // reserved size - uint32_t pointCount; // effective points count - - // pathes array is a list of point count per segment - uint32_t pathPtr; // pointer in the path array - uint32_t* pathes; - uint32_t sizePathes; - - uint32_t segmentPtr; // current segment count in current path having curves - uint32_t subpathCount; // store count of subpath, not straight forward to retrieve from segmented path array - bool simpleConvex; // true if path is single rect or concave closed curve. - - bool cmdStarted; // prevent flushing empty renderpass - bool pushCstDirty; // prevent pushing to gpu if not requested - - float lineWidth; - float miterLimit; - uint32_t dashCount; // value count in dash array, 0 if dash not set. - float dashOffset; // an offset for dash - float* dashes; // an array of alternate lengths of on and off stroke. - - vkvg_operator_t curOperator; - vkvg_line_cap_t lineCap; - vkvg_line_join_t lineJoin; - vkvg_fill_rule_t curFillRule; - - long selectedCharSize; /* Font size*/ - uint64_t selectedFontName; - //_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 - vkvg_direction_t textDirection; - push_constants pushConsts; - VkvgPattern pattern; + uint32_t sizeIBO; // size of vk ibo + uint32_t sizeIndices; // reserved size + uint32_t sizeVBO; // size of vk vbo size + uint32_t sizeVertices; // reserved size + uint32_t sizePoints; // reserved size + uint32_t sizePathes; + uint8_t sizeCtxSave; // allocated size for saved ctx stack - vkvg_context_save_t* pSavedCtxs; // last ctx saved ptr - uint8_t curSavBit; // current stencil bit used to save context, 6 bits used by stencil for save/restore - VkhImage* savedStencils; // additional image for saving contexes once more than 6 save/restore are reached - vkvg_clip_state_t curClipState; // current clipping status relative to the previous saved one or clear state if - // none. + uint8_t ctxSaveCount;// saved ctx count + uint8_t curSavBit; // current stencil bit used to save context, 6 bits used by stencil for save/restore + vkvg_clip_state_t curClipState; // current clipping status relative to the previous saved one or clear state if - VkClearRect clearRect; + VkhImage* savedStencils; // additional image for saving contexes once more than 6 save/restore are reached VkRenderPassBeginInfo renderPassBeginInfo; } vkvg_context; diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index a676ed8..9a109c0 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -411,7 +411,7 @@ _vkvg_font_identity_t* _font_cache_add_font_identity(VkvgContext ctx, const char } // select current font for context _vkvg_font_t* _find_or_create_font_size(VkvgContext ctx) { - _vkvg_font_identity_t* font = ctx->currentFont; + _vkvg_font_identity_t* font;// = ctx->currentFont; for (uint32_t i = 0; i < font->sizeCount; ++i) { if (font->sizes[i].charSize == ctx->selectedCharSize) @@ -465,7 +465,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 = ctx->dev->fontCache; + /*_font_cache_t* cache = ctx->dev->fontCache; for (int i = 0; i < cache->fontsCount; ++i) { for (uint32_t j = 0; j < cache->fonts[i].namesCount; j++) { if (cache->fonts[i].names[j] == ctx->selectedFontName) { @@ -473,7 +473,7 @@ bool _tryFindFontByName(VkvgContext ctx, _vkvg_font_identity_t** font) { return true; } } - } + }*/ return false; } @@ -562,7 +562,7 @@ hb_buffer_t* _get_hb_buffer(_vkvg_font_t* font, const char* text, int length) { // retrieve global font extends of context's current font as defined by FreeType void _font_cache_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents) { - _update_current_font(ctx); + /*_update_current_font(ctx); if (ctx->status) return; @@ -585,7 +585,7 @@ void _font_cache_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents) { roundf(font->scale * (ctx->currentFont->ascent - ctx->currentFont->descent + ctx->currentFont->lineGap)); extents->max_x_advance = 0; // TODO extents->max_y_advance = 0; -#endif +#endif*/ } // compute text extends for provided string. void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkvg_text_extents_t* extents) { @@ -613,14 +613,14 @@ void _font_cache_create_text_run(VkvgContext ctx, const char* text, int length, if (ctx->status) return; - textRun->fontId = ctx->currentFont; - textRun->font = ctx->currentFontSize; + //textRun->fontId = ctx->currentFont; + //textRun->font = ctx->currentFontSize; textRun->dev = ctx->dev; LOCK_FONTCACHE(ctx->dev) #ifdef VKVG_USE_HARFBUZZ - textRun->hbBuf = _get_hb_buffer(ctx->currentFontSize, text, length); + //textRun->hbBuf = _get_hb_buffer(ctx->currentFontSize, text, length); textRun->glyphs = hb_buffer_get_glyph_positions(textRun->hbBuf, &textRun->glyph_count); #else @@ -658,9 +658,9 @@ void _font_cache_create_text_run(VkvgContext ctx, const char* text, int length, for (uint32_t i = 0; i < textRun->glyph_count; ++i) string_width_in_pixels += textRun->glyphs[i].x_advance >> 6; #ifdef VKVG_USE_FREETYPE - FT_Size_Metrics* metrics = &ctx->currentFontSize->face->size->metrics; + /*FT_Size_Metrics* metrics = &ctx->currentFontSize->face->size->metrics; textRun->extents.height = (float)(FT_MulFix(ctx->currentFontSize->face->height, metrics->y_scale) >> - 6); // (metrics->ascender + metrics->descender) >> 6; + 6); // (metrics->ascender + metrics->descender) >> 6;*/ #else textRun->extents.height = textRun->font->ascent - textRun->font->descent + textRun->font->lineGap; #endif diff --git a/tests/vkvg-svg/svg-viewer.c b/tests/vkvg-svg/svg-viewer.c index 34e5a98..18ec876 100644 --- a/tests/vkvg-svg/svg-viewer.c +++ b/tests/vkvg-svg/svg-viewer.c @@ -303,7 +303,7 @@ int main(int argc, char* argv[]) { if (iconSize > 0 && pCurrentDir) { if (update) { - + queryUpdate(); vkengine_set_title(e, path); double x = 0; double y = (lineToSkip * cellSize) - scrollY; @@ -387,4 +387,5 @@ int main(int argc, char* argv[]) { vkvg_device_destroy(dev); vkengine_destroy(e); + exit(0); } |