]> O.S.I.I.S - jp/vkvg.git/commitdiff
nsvg public iface rename as vkvg-svg, single api for both, recording wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 12 Jan 2022 07:59:33 +0000 (08:59 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 12 Jan 2022 07:59:33 +0000 (08:59 +0100)
CMakeLists.txt
external/vkvg-svg
include/vkvg-svg.h
include/vkvg.h
src/nsvg/vkvg_nsvg.c
src/recording/vkvg_record.c
src/recording/vkvg_record_internal.h
src/vkvg_context.c
src/vkvg_context_internal.h
tests/svg.c

index 4afbcde110b2c36aa5fbe0e10f85e66cfee3d186..15427ea32021a56bf5d4815824af4fd026a37868 100644 (file)
@@ -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 $<TARGET_OBJECTS:vkvg-svg>)
 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)
                        $<$<BOOL:${VKVG_USE_HARFBUZZ}>:${HarfBuzz_INCLUDE_DIRS}>
                        $<$<BOOL:${VKVG_USE_FONTCONFIG}>:${Fontconfig_INCLUDE_DIRS}>
                        $<$<NOT:$<BOOL:${VKVG_SVG}>>:${CMAKE_CURRENT_SOURCE_DIR}/src/nsvg>
-                       $<$<BOOL:${VKVG_RECORDING}>:${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"
                $<$<BOOL:${VKVG_USE_HARFBUZZ}>:${HarfBuzz_INCLUDE_DIRS}>
                $<$<BOOL:${VKVG_USE_FONTCONFIG}>:${Fontconfig_INCLUDE_DIRS}>
                $<$<NOT:$<BOOL:${VKVG_SVG}>>:${CMAKE_CURRENT_SOURCE_DIR}/src/nsvg>
-               $<$<BOOL:${VKVG_RECORDING}>:${CMAKE_CURRENT_SOURCE_DIR}/src/recording>
                $<$<BOOL:${VKVG_USE_GLUTESS}>:${CMAKE_CURRENT_SOURCE_DIR}/external/glutess/include>
        PUBLIC
                ${Vulkan_INCLUDE_DIRS}
index 98dd8e145744f06865ec964e9cae9c9dea461668..efdb580098f7a17085d2bdc91062b331a3abf710 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 98dd8e145744f06865ec964e9cae9c9dea461668
+Subproject commit efdb580098f7a17085d2bdc91062b331a3abf710
index b325c72bce7430a0265f4d6ee482fa834220f271..288dd37d8553d508a7402d8acae65944779ec26a 100644 (file)
 #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
index 18f603e4799f1956b168de31f239edef08e706f0..9a6250135019bf5c47b5997b63a68fa8ea61fa73 100644 (file)
@@ -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
index c638fac452a723d749cffb4633eacfafd216ab11..8cdc16ce1ae5e4c0dc0e6c26b16ee86a6bd3eac0 100644 (file)
@@ -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);
index 18fb85ab4f3b7f59b60eebf185d0acc59e4fc1dc..a70ee183f7b9a70e0ccb6ca02f27e4558a93fa2f 100644 (file)
@@ -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; i<rec->commandsCount; 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;
index 836a3640e482aee455f839da9c444cea89d7039c..a52a3b88d6443146e936fe69103eb22ddce99ad0 100644 (file)
@@ -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;\
        }\
 }
 
index f645ab1e6438676830d18443d27fa9bd5603f89c..a73d0cb764ea1031f7d1344a9bcde9cc26763449 100644 (file)
@@ -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
index 41bba6de9f397a364720f89adebb0909e7b756c1..9243fb25e182325d06a756d4894ff8d2a8644761 100644 (file)
@@ -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
index dd535dafb5b94a30b3ea053f56a452364365cd9f..82adf4f2774f1cbffddc8e98d15509032ad8c162 100644 (file)
@@ -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;
 }