From: Jean-Philippe Bruyère Date: Wed, 12 Jan 2022 07:59:33 +0000 (+0100) Subject: nsvg public iface rename as vkvg-svg, single api for both, recording wip X-Git-Tag: v0.3.0-beta~19 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=6c9ef4c420e79acfe7e9c1ea83589355faf9ee19;p=jp%2Fvkvg.git nsvg public iface rename as vkvg-svg, single api for both, recording wip --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 4afbcde..15427ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,17 +57,15 @@ ENDIF() OPTION(ENABLE_PROFILING "compile with the -pg options..." OFF) IF (ENABLE_PROFILING) - ADD_DEFINITIONS(${CMAKE_CXX_FLAGS} "-pg -fno-reorder-functions -fno-inline") - ADD_DEFINITIONS(${CMAKE_CXX_FLAGS} "-O1") - ADD_DEFINITIONS(${CMAKE_CXX_FLAGS} "-fthread-jumps") - ADD_DEFINITIONS(${CMAKE_CXX_FLAGS} "-falign-functions -falign-jumps") - ADD_DEFINITIONS(${CMAKE_CXX_FLAGS} "-falign-loops -falign-labels") + ADD_COMPILE_OPTIONS( + -pg -fno-reorder-functions -fno-inline + -O1 + -fthread-jumps + -falign-functions -falign-jumps + -falign-loops -falign-labels) ENDIF() OPTION(VKVG_RECORDING "enable experimental recording functions" ON) -IF (VKVG_RECORDING) - ADD_DEFINITIONS (-DVKVG_RECORDING) -ENDIF () OPTION(VKVG_PREMULT_ALPHA "use premultiplied alpha for internal rendering" ON) IF (VKVG_PREMULT_ALPHA) @@ -80,19 +78,13 @@ IF (VKVG_DBG_STATS) ENDIF () OPTION(VKVG_USE_GLUTESS "Fill non-zero with glu tesselator" OFF) -IF (VKVG_USE_GLUTESS) - ADD_DEFINITIONS (-DVKVG_FILL_NZ_GLUTESS) -ENDIF () CMAKE_DEPENDENT_OPTION(VKVG_SVG "render svg with vkvg-svg library" ON "UNIX" OFF) -IF (VKVG_SVG) - ADD_DEFINITIONS (-DVKVG_SVG) -ENDIF () INCLUDE ("${CMAKE_CURRENT_SOURCE_DIR}/cmake/GitSubmoduleUpdate.cmake") IF(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") - OPTION(GIT_SUBMODULE "Check submodules during build" ON) + OPTION(GIT_SUBMODULE "Check submodules during build" OFF) IF(GIT_SUBMODULE) updateGitSubmodule(vkh) IF (VKVG_USE_GLUTESS) @@ -204,6 +196,7 @@ IF(GLSLC AND XXD) ENDIF() IF (VKVG_USE_GLUTESS) + ADD_DEFINITIONS (-DVKVG_FILL_NZ_GLUTESS) ADD_SUBDIRECTORY (external/glutess) ENDIF () @@ -211,6 +204,7 @@ FILE(GLOB VKVG_OBJ_SRC src/*.c) SET (VKVG_PUBLIC_HEADERS "include/vkvg.h") IF (VKVG_SVG) + ADD_DEFINITIONS (-DVKVG_SVG) ADD_SUBDIRECTORY (external/vkvg-svg) LIST (APPEND VKVG_SRC $) ELSE() @@ -220,8 +214,9 @@ ELSE() ENDIF() IF (VKVG_RECORDING) + ADD_DEFINITIONS (-DVKVG_RECORDING) FILE(GLOB RECORDING_SRC src/recording/*.c) - LIST (APPEND VKVG_SRC ${RECORDING_SRC}) + LIST (APPEND VKVG_OBJ_SRC ${RECORDING_SRC}) ENDIF() CONFIGURE_FILE(vkvg.pc.in vkvg.pc @ONLY) @@ -247,7 +242,6 @@ FUNCTION (setup_lib LibName) $<$:${HarfBuzz_INCLUDE_DIRS}> $<$:${Fontconfig_INCLUDE_DIRS}> $<$>:${CMAKE_CURRENT_SOURCE_DIR}/src/nsvg> - $<$:${CMAKE_CURRENT_SOURCE_DIR}/src/recording> PUBLIC ${Vulkan_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -295,7 +289,6 @@ TARGET_INCLUDE_DIRECTORIES("${PROJECT_NAME}_obj" $<$:${HarfBuzz_INCLUDE_DIRS}> $<$:${Fontconfig_INCLUDE_DIRS}> $<$>:${CMAKE_CURRENT_SOURCE_DIR}/src/nsvg> - $<$:${CMAKE_CURRENT_SOURCE_DIR}/src/recording> $<$:${CMAKE_CURRENT_SOURCE_DIR}/external/glutess/include> PUBLIC ${Vulkan_INCLUDE_DIRS} diff --git a/external/vkvg-svg b/external/vkvg-svg index 98dd8e1..efdb580 160000 --- a/external/vkvg-svg +++ b/external/vkvg-svg @@ -1 +1 @@ -Subproject commit 98dd8e145744f06865ec964e9cae9c9dea461668 +Subproject commit efdb580098f7a17085d2bdc91062b331a3abf710 diff --git a/include/vkvg-svg.h b/include/vkvg-svg.h index b325c72..288dd37 100644 --- a/include/vkvg-svg.h +++ b/include/vkvg-svg.h @@ -25,6 +25,12 @@ #ifdef __cplusplus extern "C" { #endif + +#ifdef VKVG_SVG +typedef struct _vkvg_svg_t* VkvgSvg; +#else +typedef struct NSVGimage* VkvgSvg; +#endif /** * @brief load svg file into @ref surface * @@ -36,7 +42,7 @@ extern "C" { * @return The new vkvg surface with the loaded SVG drawing as content, or null if an error occured. */ vkvg_public -VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_t height, const char* filePath); +VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_t height, const char* svgFilePath); /** * @brief create surface from svg fragment * @@ -50,83 +56,22 @@ VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_ vkvg_public VkvgSurface vkvg_surface_create_from_svg_fragment(VkvgDevice dev, uint32_t width, uint32_t height, const char* svgFragment); -#ifndef VKVG_SVG -/*! @defgroup nsvg Nano SVG - * @brief Render SVG drawings - * - * [NanoSVG](https://github.com/memononen/nanosvg) is a simple svg parser. - * nanosvg does not suit production needs, but is implemented - * in vkvg for quickly presenting some outputs with the library. - * - * First load svg file with #nsvg_load_file() then render it with vkvg by calling #vkvg_render_svg(). - * The #NSVGimage pointer has to be destroyed by calling #nsvg_destroy(). @ref context use is guarded by - * a save/restore couple that will restore context at its state before the svg draw. - * @{ */ - -/** - * @brief nanosvg image structure - * - */ -typedef struct NSVGimage NSVGimage; -/** - * @brief load svg file - * - * Load basic svg file and store datas in a #NSVGimage structure. This structure - * has to be destroyed by a call to #nsvg_destroy() when no longuer in use. - * @param dev VkvgDevice to use for loading the svg file, needed for dpy. - * @param filePath the path of the svg file to load - * @return NSVGimage* a new pointer on a NSVGimage structure - */ vkvg_public -NSVGimage* nsvg_load_file (VkvgDevice dev, const char* filePath); -/** - * @brief load svg fragment - * - * create a new #NSVGimage by parsing an svg fragment passed as string. The - * vkvg @ref device is required to get the device dot per inch configuration. - * @param dev the vkvg @ref device - * @param fragment a valid svg expression - * @return NSVGimage* a new pointer on the resulting nanovg structure - */ +void vkvg_svg_get_dimensions (VkvgSvg svg, uint32_t* width, uint32_t* height); + vkvg_public -NSVGimage* nsvg_load (VkvgDevice dev, char* fragment); -/** - * @brief release #NSVGimage pointer - * - * destroy the #NSVGimage passed as argument. - * @param svg the nanovg structure to release - */ +VkvgSvg vkvg_svg_load (const char* svgFilePath); + vkvg_public -void nsvg_destroy (NSVGimage* svg); -/** - * @brief get svg dimensions - * - * query an #NSVGimage for its width and height. - * @param svg a valid #NSVGimage pointer - * @param width[out] a valid integer pointer to hold the svg width - * @param height[out] a valid integer pointer to hold the svg height - */ +VkvgSvg vkvg_svg_load_fragment (const char* svgFragment); + vkvg_public -void nsvg_get_size (NSVGimage* svg, int* width, int* height); -/** - * @brief render #NSVGimage with vkvg context - * - * Render a svg drawing loaded with #nsvg_load_file() or #nsvg_load() using - * a valid #VkvgContext. Svg rendering is guarded with a save/restore so that the supplied context - * is not affected by the rendering and will be restored to it's previous state. - * - * @param ctx the #VkvgContext to use for rendering. - * @param svg the #NSVGimage to render - * @param subId Render only a subpart of the svg identified by a named svg group or NULL for - * rendering the whole svg. - */ +void vkvg_svg_render (VkvgSvg svg, VkvgContext ctx, const char* id); + vkvg_public -void vkvg_render_svg (VkvgContext ctx, NSVGimage* svg, char* subId); -/** @}*/ +void vkvg_svg_destroy (VkvgSvg svg); #ifdef __cplusplus } -#endif - #endif #endif diff --git a/include/vkvg.h b/include/vkvg.h index 18f603e..9a62501 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -1746,17 +1746,26 @@ void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix); vkvg_public void vkvg_set_source_color_name (VkvgContext ctx, const char* color); -/*************************************/ - #ifdef VKVG_RECORDING typedef struct _vkvg_recording_t* VkvgRecording; vkvg_public void vkvg_start_recording (VkvgContext ctx); +vkvg_public VkvgRecording vkvg_stop_recording (VkvgContext ctx); +vkvg_public void vkvg_replay (VkvgContext ctx, VkvgRecording rec); +vkvg_public +void vkvg_replay_command (VkvgContext ctx, VkvgRecording rec, uint32_t cmdIndex); +vkvg_public +void vkvg_recording_get_command (VkvgRecording rec, uint32_t cmdIndex, uint32_t* cmd, void** dataOffset); +vkvg_public uint32_t vkvg_recording_get_count(VkvgRecording rec); +vkvg_public +void* vkvg_recording_get_data (VkvgRecording rec); +vkvg_public void vkvg_recording_destroy (VkvgRecording rec); +/*************************************/ #endif diff --git a/src/nsvg/vkvg_nsvg.c b/src/nsvg/vkvg_nsvg.c index c638fac..8cdc16c 100644 --- a/src/nsvg/vkvg_nsvg.c +++ b/src/nsvg/vkvg_nsvg.c @@ -51,7 +51,7 @@ VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) { _create_surface_images (surf); VkvgContext ctx = vkvg_create(surf); - vkvg_render_svg(ctx, svg, NULL); + vkvg_svg_render(svg, ctx, NULL); vkvg_destroy(ctx); nsvgDelete(svg); @@ -65,24 +65,24 @@ VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) { VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, uint32_t width, uint32_t height, const char* filePath) { return _svg_load(dev, nsvgParseFromFile(filePath, "px", (float)dev->hdpi)); } -VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, uint32_t width, uint32_t height, char* fragment) { +VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, uint32_t width, uint32_t height,const char* fragment) { return _svg_load(dev, nsvgParse(fragment, "px", (float)dev->hdpi)); } -NSVGimage* nsvg_load_file (VkvgDevice dev, const char* filePath) { - return nsvgParseFromFile(filePath, "px", (float)dev->hdpi); +VkvgSvg vkvg_svg_load (const char* svgFilePath) { + return nsvgParseFromFile(svgFilePath, "px", 96.0f); } -NSVGimage* nsvg_load (VkvgDevice dev, char* fragment) { - return nsvgParse (fragment, "px", (float)dev->hdpi); +VkvgSvg vkvg_svg_load_fragment (const char* svgFragment) { + return nsvgParse (svgFragment, "px", 96.0f); } -void nsvg_destroy (NSVGimage* svg) { +void vkvg_svg_destroy (VkvgSvg svg) { nsvgDelete(svg); } -void nsvg_get_size (NSVGimage* svg, int* width, int* height) { - *width = (int)svg->width; - *height = (int)svg->height; +void vkvg_svg_get_dimensions (VkvgSvg svg, uint32_t* width, uint32_t* height) { + *width = (uint32_t)svg->width; + *height = (uint32_t)svg->height; } -void vkvg_render_svg (VkvgContext ctx, NSVGimage* svg, char *subId){ +void vkvg_svg_render (VkvgSvg svg, VkvgContext ctx, const char* subId){ NSVGshape* shape; NSVGpath* path; vkvg_save (ctx); diff --git a/src/recording/vkvg_record.c b/src/recording/vkvg_record.c index 18fb85a..a70ee18 100644 --- a/src/recording/vkvg_record.c +++ b/src/recording/vkvg_record.c @@ -40,12 +40,35 @@ uint32_t vkvg_recording_get_count (VkvgRecording rec) { return 0; return rec->commandsCount; } +void* vkvg_recording_get_data (VkvgRecording rec) { + if (!rec) + return 0; + return rec->buffer; +} +void vkvg_recording_get_command (VkvgRecording rec, uint32_t cmdIndex, uint32_t* cmd, void** dataOffset) { + if (!rec) + return; + if (cmdIndex < rec->commandsCount) { + *cmd = rec->commands[cmdIndex].cmd; + *dataOffset = (void*)rec->commands[cmdIndex].dataOffset; + } else { + *cmd = 0; + *dataOffset = NULL; + } + +} void vkvg_replay (VkvgContext ctx, VkvgRecording rec) { if (!rec) return; for (uint32_t i=0; icommandsCount; i++) _replay_command(ctx, rec, i); } +void vkvg_replay_command (VkvgContext ctx, VkvgRecording rec, uint32_t cmdIndex) { + if (!rec) + return; + if (cmdIndex < rec->commandsCount) + _replay_command(ctx, rec, cmdIndex); +} void vkvg_recording_destroy (VkvgRecording rec) { if (!rec) return; diff --git a/src/recording/vkvg_record_internal.h b/src/recording/vkvg_record_internal.h index 836a364..a52a3b8 100644 --- a/src/recording/vkvg_record_internal.h +++ b/src/recording/vkvg_record_internal.h @@ -80,7 +80,8 @@ #define VKVG_CMD_FILL (0x0002|VKVG_CMD_DRAW_COMMANDS) #define VKVG_CMD_STROKE (0x0003|VKVG_CMD_DRAW_COMMANDS) #define VKVG_CMD_CLIP (0x0004|VKVG_CMD_DRAW_COMMANDS) -#define VKVG_CMD_CLEAR (0x0005|VKVG_CMD_DRAW_COMMANDS) +#define VKVG_CMD_RESET_CLIP (0x0005|VKVG_CMD_DRAW_COMMANDS) +#define VKVG_CMD_CLEAR (0x0006|VKVG_CMD_DRAW_COMMANDS) #define VKVG_CMD_FILL_PRESERVE (VKVG_CMD_FILL |VKVG_CMD_PRESERVE_COMMANDS) #define VKVG_CMD_STROKE_PRESERVE (VKVG_CMD_STROKE |VKVG_CMD_PRESERVE_COMMANDS) @@ -118,6 +119,7 @@ void _record (vkvg_recording_t* rec,...); #define RECORD(ctx,...) {\ if (ctx->recording) {\ _record (ctx->recording,__VA_ARGS__);\ + return;\ }\ } diff --git a/src/vkvg_context.c b/src/vkvg_context.c index f645ab1..a73d0cb 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -207,6 +207,11 @@ void vkvg_destroy (VkvgContext ctx) LOG(VKVG_LOG_DBG_ARRAYS, "END\tctx = %p; pathes:%d pts:%d vch:%d vbo:%d ich:%d ibo:%d\n", ctx, ctx->sizePathes, ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO); +#if VKVG_RECORDING + if (ctx->recording) + _destroy_recording(ctx->recording); +#endif + if (ctx->pattern) vkvg_pattern_destroy (ctx->pattern); @@ -322,10 +327,10 @@ void vkvg_new_path (VkvgContext ctx){ if (ctx->status) return; - RECORD(ctx, VKVG_CMD_NEW_PATH); LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_path:\n"); _clear_path(ctx); + RECORD(ctx, VKVG_CMD_NEW_PATH); } void vkvg_close_path (VkvgContext ctx){ if (ctx->status) @@ -665,6 +670,7 @@ static const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, void vkvg_reset_clip (VkvgContext ctx){ if (ctx->status) return; + RECORD(ctx, VKVG_CMD_RESET_CLIP); _emit_draw_cmd_undrawn_vertices(ctx); if (!ctx->cmdStarted) { //if command buffer is not already started and in a renderpass, we use the renderpass diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 41bba6d..9243fb2 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -29,9 +29,9 @@ #include "vkvg_fonts.h" #if VKVG_RECORDING -#include "vkvg_record_internal.h" + #include "recording/vkvg_record_internal.h" #else -#define RECORD(ctx,cmd,...) + #define RECORD(ctx,cmd,...) #endif #define VKVG_PTS_SIZE 1024 diff --git a/tests/svg.c b/tests/svg.c index dd535da..82adf4f 100644 --- a/tests/svg.c +++ b/tests/svg.c @@ -6,9 +6,9 @@ static float rotation = 0.f; static const char* path = "data/tiger.svg"; void svg_surface() { - VkvgSurface svgSurf = vkvg_surface_create_from_svg(device, test_width, test_height, path); + VkvgSurface svgSurf = vkvg_surface_create_from_svg (device, test_width, test_height, path); - VkvgContext ctx = vkvg_create(surf); + VkvgContext ctx = _initCtx(surf); vkvg_set_source_rgb(ctx,1,1,1); vkvg_paint(ctx); @@ -19,35 +19,23 @@ void svg_surface() { vkvg_destroy(ctx); vkvg_surface_destroy(svgSurf); } -#ifndef VKVG_SVG -void nsvg() { - NSVGimage* svg = nsvg_load_file(device, path); - if (svg == NULL) { - fprintf (stderr, "svg file not found: %s", path); - return; - } - - VkvgContext ctx = vkvg_create(surf); - vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - vkvg_set_source_rgba(ctx,0.9f,1.0,1.0f,1); - vkvg_paint(ctx); - - vkvg_scale(ctx,1.0f,1.0f); - //vkvg_render_svg(ctx, svg, "wq"); +void vkvg_svg () { + VkvgSvg svg = vkvg_svg_load (path); + uint32_t w, h; + vkvg_svg_get_dimensions(svg, &w, &h); + VkvgContext ctx = _initCtx(surf); + vkvg_clear(ctx); - vkvg_render_svg(ctx, svg, NULL); + vkvg_svg_render (svg, ctx, NULL); vkvg_destroy(ctx); - - nsvg_destroy(svg); + vkvg_svg_destroy (svg); } -#endif int main(int argc, char *argv[]) { no_test_size = true; + PERFORM_TEST (svg_surface, argc, argv); -#ifndef VKVG_SVG - PERFORM_TEST (nsvg, argc, argv); -#endif + PERFORM_TEST (vkvg_svg, argc, argv); return 0; }