From: j-p Date: Mon, 1 Jun 2020 00:20:05 +0000 (+0200) Subject: Win warn clean (#38) X-Git-Tag: v0.1-alpha~14 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=b1970a05b2958e4ea59814420811a2d0b35b3fec;p=jp%2Fvkvg.git Win warn clean (#38) * windows warnings cleaning * use always fixed FONT_FILE_NAME_MAX_SIZE for allocating file name * batch tests * debug draw even odd fill + stroke with curves * clean linux warnings --- diff --git a/.gitignore b/.gitignore index 912b8bb..197514b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build/ *.user ignore +.vs/ +*.json diff --git a/CMakeLists.txt b/CMakeLists.txt index b21d0b8..cadab67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12) +SET(LANG "CXX") + +#PROJECT(vkvg VERSION 0.1.1 DESCRIPTION "Vulkan Vector Graphic" LANGUAGES ${LANG}) PROJECT(vkvg VERSION 0.1.1 DESCRIPTION "Vulkan Vector Graphic") INCLUDE(CheckSymbolExists) @@ -9,25 +12,33 @@ INCLUDE(CMakeDependentOption) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -IF (UNIX) - SET(CMAKE_CXX_FLAGS "-Wall -Wno-extra") - SET(CMAKE_EXE_LINKER_FLAGS "-lm") -ELSEIF(MSVC) - SET(CMAKE_CXX_FLAGS "-W4") -ENDIF() - - IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE Debug) ENDIF() +IF (UNIX) + SET(LINKER_FLAGS "-lm") + SET(CMAKE_EXE_LINKER_FLAGS ${LINKER_FLAGS}) + SET(CMAKE_SHARED_LINKER_FLAGS ${LINKER_FLAGS}) +ENDIF() + if (CMAKE_BUILD_TYPE STREQUAL "Debug") ADD_DEFINITIONS (-DDEBUG) OPTION(ENABLE_VALIDATION "enable vulkan validation layer" ON) OPTION(ENABLE_WIRED_FILL "enable wired polygon draw to check vertices and primitives" OFF) + IF (UNIX) + SET(CMAKE_${LANG}_FLAGS "-Wall -Wno-extra -Wno-unknown-pragmas -Wno-missing-braces -Wno-unused-variable") + ELSEIF(MSVC) + SET(CMAKE_${LANG}_FLAGS "/TC /W4 /wd4201 /wd4204 /wd4221 /wd4100")#c11 complient + ENDIF() ELSE() UNSET(ENABLE_VALIDATION CACHE) UNSET(ENABLE_WIRED_FILL CACHE) + IF (UNIX) + SET(CMAKE_${LANG}_FLAGS "-w") + ELSEIF(MSVC) + SET(CMAKE_${LANG}_FLAGS "/TC /W0") + ENDIF() ENDIF() OPTION(VKVG_TEST_DIRECT_DRAW "(Experimental)Draw directly on backend surface, if off surface is blitted." OFF) IF (VKVG_TEST_DIRECT_DRAW) @@ -82,7 +93,11 @@ CMAKE_DEPENDENT_OPTION(VKVG_BUILD_TESTS "build tests with glfw" ON "GLFW3_FOUND" #Freetype lcd font filtering #CHECK_SYMBOL_EXISTS (FT_CONFIG_OPTION_SUBPIXEL_RENDERING "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/config/ftoption.h" FT_HAS_SUBPIXEL_RENDERING) #IF (FT_HAS_SUBPIXEL_RENDERING) - OPTION(VKVG_LCD_FONT_FILTER "enable freetype lcd font filtering" ON) + IF (UNIX) + OPTION(VKVG_LCD_FONT_FILTER "enable freetype lcd font filtering" ON) + ELSEIF(MSVC) + OPTION(VKVG_LCD_FONT_FILTER "enable freetype lcd font filtering" OFF) + ENDIF() IF (VKVG_LCD_FONT_FILTER) ADD_DEFINITIONS (-DVKVG_LCD_FONT_FILTER) ENDIF () @@ -131,7 +146,7 @@ if(GLSLC AND XXD) ADD_CUSTOM_COMMAND (TARGET BuildShaderHeader POST_BUILD WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SHADER_DIR} - COMMAND xxd -i ${SPV} >> ${SHADERS_H} + COMMAND ${XXD} -i ${SPV} >> ${SHADERS_H} DEPENDS ${SHADERS_H} ) ENDFOREACH() @@ -203,7 +218,7 @@ FUNCTION (buildtest TEST_NAME) ENDFUNCTION (buildtest) if (VKVG_BUILD_TESTS) - ADD_LIBRARY("tests_common" STATIC tests/common/vkengine.c tests/common/test.c) + ADD_LIBRARY("tests_common" STATIC tests/common/vkengine.c tests/common/test.c) TARGET_INCLUDE_DIRECTORIES(tests_common PRIVATE ${Vulkan_INCLUDE_DIRS} ${GLFW3_INCLUDE_DIR} @@ -213,12 +228,13 @@ if (VKVG_BUILD_TESTS) ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src ) - TARGET_LINK_LIBRARIES(tests_common - ${Vulkan_LIBRARIES} - ${GLFW3_LIBRARY} - vkh_static - vkvg_static - ) + TARGET_LINK_LIBRARIES(tests_common + ${Vulkan_LIBRARIES} + ${GLFW3_LIBRARY} + vkh_static + vkvg_static + ) + file(GLOB_RECURSE DATAS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/tests" "tests/data/*") FOREACH(DATA_FILE ${DATAS}) GET_FILENAME_COMPONENT(copy-dest-dir ${CMAKE_CURRENT_BINARY_DIR}/${DATA_FILE} DIRECTORY) diff --git a/include/vkvg.h b/include/vkvg.h index 4345945..28af6cf 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -30,16 +30,16 @@ extern "C" { #include #include -#define LOG_ERR 0x00 -#define LOG_DEBUG 0x10 -#define LOG_INFO 0x20 -#define LOG_INFO_PATH 0x40 -#define LOG_DBG_ARRAYS 0x80 -#define LOG_FULL 0xff +#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 -static uint8_t log_level = LOG_ERR;// | LOG_INFO | LOG_DEBUG | LOG_INFO_PATH; -#define LOG(level,...) (log_level & level) ? fprintf (stdout, __VA_ARGS__):true; +extern uint8_t vkvg_log_level; +#define LOG(level,...) (vkvg_log_level & level) ? fprintf (stdout, __VA_ARGS__):true; #else #define LOG #endif diff --git a/scripts/batchTests.sh b/scripts/batchTests.sh new file mode 100755 index 0000000..b880572 --- /dev/null +++ b/scripts/batchTests.sh @@ -0,0 +1,65 @@ +#!/bin/bash +#!/bin/bash +today=`date '+%Y%m%d-%HH%MM%S'`; +logdir=`pwd` + +POSITIONAL=() +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -i|--iterations) + ITERATIONS="$2" + shift # past argument + shift # past value + ;; + -s|--size) + SIZE="$2" + shift # past argument + shift # past value + ;; + -d|--directory) + TESTDIR="$2" + shift # past argument + shift # past value + ;; + *) # unknown option + POSITIONAL+=("$1") # save it in an array for later + shift # past argument + ;; +esac +done +set -- "${POSITIONAL[@]}" # restore positional parameters + +if test -z "$TESTDIR" +then + TESTDIR="." +fi +if test -z "$ITERATIONS" +then + ITERATIONS="100" +fi +if test -z "$SIZE" +then + SIZE="100" +fi + + +cd $TESTDIR + +logfile="$logdir/log-$today.txt" + +git log -n 1 --pretty=format:'%h %d %s%n%n' > $logfile + +echo "_____________________________________________________________________________________________________" >> $logfile +echo "| Test File Name | Sub Test | Iter | SIZE | FPS | Average | Median | Sigma |" >> $logfile +echo "|-----------------|---------------------------|------|------|---------|---------|---------|---------|" >> $logfile +for file in test_* +do + if [[ -x "$file" ]] + then + ./"$file" $ITERATIONS $SIZE >> $logfile + fi +done +echo "_____________________________________________________________________________________________________" >> $logfile diff --git a/src/cross_mutex.c b/src/cross_mutex.c index c8c1cde..7a33c87 100644 --- a/src/cross_mutex.c +++ b/src/cross_mutex.c @@ -29,8 +29,9 @@ int MUTEX_INIT(MUTEX *mutex) #elif __APPLE__ #elif __unix__ return pthread_mutex_init (mutex, NULL); -#endif +#else return -1; +#endif } int MUTEX_LOCK(MUTEX *mutex) @@ -40,8 +41,9 @@ int MUTEX_LOCK(MUTEX *mutex) #elif __APPLE__ #elif __unix__ return pthread_mutex_lock( mutex ); -#endif +#else return -1; +#endif } int MUTEX_UNLOCK(MUTEX *mutex) @@ -51,8 +53,9 @@ int MUTEX_UNLOCK(MUTEX *mutex) #elif __APPLE__ #elif __unix__ return pthread_mutex_unlock( mutex ); -#endif +#else return -1; +#endif } int MUTEX_DESTROY(MUTEX *mutex) @@ -62,6 +65,7 @@ int MUTEX_DESTROY(MUTEX *mutex) #elif __APPLE__ #elif __unix__ return pthread_mutex_destroy(mutex); -#endif +#else return -1; +#endif } diff --git a/src/cross_os.c b/src/cross_os.c index 80456b2..1db376c 100644 --- a/src/cross_os.c +++ b/src/cross_os.c @@ -24,16 +24,18 @@ #include //#include +#define _CRT_SECURE_NO_WARNINGS int directoryExists (const char* path) { #if defined(_WIN32) || defined(_WIN64) - return getenv("HOME"); + return getenv("HOME") != NULL; #elif __APPLE__ #elif __unix__ struct stat st = {0}; return stat(path, &st)+1; -#endif +#else return -1; +#endif } const char* getUserDir () { #if defined(_WIN32) || defined(_WIN64) @@ -43,5 +45,4 @@ const char* getUserDir () { struct passwd *pw = getpwuid(getuid()); return pw->pw_dir; #endif - return -1; } diff --git a/src/cross_os.h b/src/cross_os.h index e11e2fb..b27537c 100644 --- a/src/cross_os.h +++ b/src/cross_os.h @@ -24,6 +24,8 @@ //cross platform os helpers #if defined(_WIN32) || defined(_WIN64) +//disable warning on iostream functions on windows +#define _CRT_SECURE_NO_WARNINGS #include "windows.h" #define isnanf _isnanf #elif __APPLE__ diff --git a/src/nanosvg.h b/src/nanosvg.h index 65ba2a7..933f02d 100644 --- a/src/nanosvg.h +++ b/src/nanosvg.h @@ -279,7 +279,7 @@ static void nsvg__parseElement(char* s, // Get attribs while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) { - char* name = NULL; + char* name2 = NULL; char* value = NULL; // Skip white space before the attrib name @@ -289,7 +289,7 @@ static void nsvg__parseElement(char* s, end = 1; break; } - name = s; + name2 = s; // Find end of the attrib name. while (*s && !nsvg__isspace(*s) && *s != '=') s++; if (*s) { *s++ = '\0'; } @@ -304,8 +304,8 @@ static void nsvg__parseElement(char* s, if (*s) { *s++ = '\0'; } // Store only well formed attributes - if (name && value) { - attr[nattr++] = name; + if (name2 && value) { + attr[nattr++] = name2; attr[nattr++] = value; } } @@ -792,8 +792,7 @@ static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, case NSVG_UNITS_IN: return c.value * p->dpi; case NSVG_UNITS_EM: return c.value * attr->fontSize; case NSVG_UNITS_EX: return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. - case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; - default: return c.value; + case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; } return c.value; } diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 4a985a3..fbbbf89 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -34,9 +34,9 @@ static uint32_t dlpCount = 0; #endif static VkClearValue clearValues[3] = { - { 0 }, - { 1.0f, 0 }, - { 0 } + { {{0}} }, + { {{1.0f, 0}} }, + { {{0}} } }; /** @@ -46,149 +46,162 @@ static VkClearValue clearValues[3] = { */ VkvgContext vkvg_create(VkvgSurface surf) { - VkvgDevice dev = surf->dev; - VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context)); - - LOG(LOG_INFO, "CREATE Context: ctx = %lu; surf = %lu\n", (uint64_t)ctx, (uint64_t)surf); - - if (ctx==NULL) { - dev->status = VKVG_STATUS_NO_MEMORY; - return NULL; - } - - 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->lineWidth = 1; - ctx->dashCount = 0; - ctx->dashOffset = 0; - ctx->dashes = NULL; - ctx->pSurf = surf; - ctx->curOperator = VKVG_OPERATOR_OVER; - ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO; - ctx->curSavBit = 0; - ctx->vertCount = 0; - ctx->indCount = 0; - ctx->curIndStart = 0; - ctx->curVertOffset = 0; - - VkRect2D scissor = {{0,0},{ctx->pSurf->width,ctx->pSurf->height}}; - ctx->bounds = scissor; - - ctx->savedStencils = malloc(0); - - push_constants pc = { - {.height=1}, - {(float)ctx->pSurf->width,(float)ctx->pSurf->height}, - VKVG_PATTERN_TYPE_SOLID, - 0, - VKVG_IDENTITY_MATRIX, - VKVG_IDENTITY_MATRIX - }; - ctx->pushConsts = pc; - - const VkClearRect cr = {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1}; - ctx->clearRect = cr; - ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - ctx->renderPassBeginInfo.framebuffer = ctx->pSurf->fb; - ctx->renderPassBeginInfo.renderArea.extent.width = ctx->pSurf->width; - ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height; - ctx->renderPassBeginInfo.pClearValues = clearValues; - - if (ctx->pSurf->new) - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearAll; - else - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil; - - ctx->pSurf->new = false; - - if (dev->samples == VK_SAMPLE_COUNT_1_BIT) - ctx->renderPassBeginInfo.clearValueCount = 2; - else - ctx->renderPassBeginInfo.clearValueCount = 3; - - ctx->pPrev = surf->dev->lastCtx; - if (ctx->pPrev != NULL) - ctx->pPrev->pNext = ctx; - surf->dev->lastCtx = ctx; - - ctx->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); - ctx->currentFont = NULL; - - ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)dev); - - ctx->points = (vec2*) malloc (VKVG_VBO_SIZE*sizeof(vec2)); - ctx->pathes = (uint32_t*) malloc (VKVG_PATHES_SIZE*sizeof(uint32_t)); - - //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->vertexCache = (Vertex*)malloc(ctx->sizeVertices * sizeof(Vertex)); - ctx->indexCache = (VKVG_IBO_INDEX_TYPE*)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); - - _create_vertices_buff (ctx); - _create_gradient_buff (ctx); - _create_cmd_buff (ctx); - _createDescriptorPool (ctx); - _init_descriptor_sets (ctx); - _update_descriptor_set (ctx, ctx->pSurf->dev->fontCache->texture, ctx->dsFont); - _update_descriptor_set (ctx, surf->dev->emptyImg, ctx->dsSrc); - _update_gradient_desc_set(ctx); - - _clear_path (ctx); - - ctx->cmd = ctx->cmdBuffers[0];//current recording buffer - - ctx->references = 1; - ctx->status = VKVG_STATUS_SUCCESS; - - LOG(LOG_DBG_ARRAYS, "START\tctx = %lu; 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); + VkvgDevice dev = surf->dev; + VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context)); + + LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf); + + if (ctx==NULL) { + dev->status = VKVG_STATUS_NO_MEMORY; + return NULL; + } + + 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->lineWidth = 1; + ctx->dashCount = 0; + ctx->dashOffset = 0; + ctx->dashes = NULL; + ctx->pSurf = surf; + ctx->curOperator = VKVG_OPERATOR_OVER; + ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO; + ctx->curSavBit = 0; + ctx->vertCount = 0; + ctx->indCount = 0; + ctx->curIndStart = 0; + ctx->curVertOffset = 0; + + VkRect2D scissor = {{0,0},{ctx->pSurf->width,ctx->pSurf->height}}; + ctx->bounds = scissor; + + push_constants pc = { + {.height=1}, + {(float)ctx->pSurf->width,(float)ctx->pSurf->height}, + VKVG_PATTERN_TYPE_SOLID, + 0, + VKVG_IDENTITY_MATRIX, + VKVG_IDENTITY_MATRIX + }; + ctx->pushConsts = pc; + + const VkClearRect cr = {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1}; + ctx->clearRect = cr; + ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + ctx->renderPassBeginInfo.framebuffer = ctx->pSurf->fb; + ctx->renderPassBeginInfo.renderArea.extent.width = ctx->pSurf->width; + ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height; + ctx->renderPassBeginInfo.pClearValues = clearValues; + + if (ctx->pSurf->new) + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearAll; + else + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil; + + ctx->pSurf->new = false; + + if (dev->samples == VK_SAMPLE_COUNT_1_BIT) + ctx->renderPassBeginInfo.clearValueCount = 2; + else + ctx->renderPassBeginInfo.clearValueCount = 3; + + ctx->pPrev = surf->dev->lastCtx; + if (ctx->pPrev != NULL) + ctx->pPrev->pNext = ctx; + surf->dev->lastCtx = ctx; + + ctx->points = (vec2*)malloc (VKVG_VBO_SIZE*sizeof(vec2)); + ctx->pathes = (uint32_t*)malloc (VKVG_PATHES_SIZE*sizeof(uint32_t)); + ctx->vertexCache = (Vertex*)malloc(ctx->sizeVertices * sizeof(Vertex)); + ctx->indexCache = (VKVG_IBO_INDEX_TYPE*)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); + ctx->savedStencils = malloc(0); + ctx->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); + ctx->currentFont = NULL; + + if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache || !ctx->savedStencils || !ctx->selectedFont.fontFile) { + dev->status = VKVG_STATUS_NO_MEMORY; + if (ctx->points) + free(ctx->points); + if (ctx->pathes) + free(ctx->pathes); + if (ctx->vertexCache) + free(ctx->vertexCache); + if (ctx->indexCache) + free(ctx->indexCache); + if (ctx->savedStencils) + free(ctx->savedStencils); + if (ctx->selectedFont.fontFile) + free(ctx->selectedFont.fontFile); + return NULL; + } + + ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)dev); + //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); + + _create_vertices_buff (ctx); + _create_gradient_buff (ctx); + _create_cmd_buff (ctx); + _createDescriptorPool (ctx); + _init_descriptor_sets (ctx); + _update_descriptor_set (ctx, ctx->pSurf->dev->fontCache->texture, ctx->dsFont); + _update_descriptor_set (ctx, surf->dev->emptyImg, ctx->dsSrc); + _update_gradient_desc_set(ctx); + + _clear_path (ctx); + + ctx->cmd = ctx->cmdBuffers[0];//current recording buffer + + ctx->references = 1; + ctx->status = VKVG_STATUS_SUCCESS; + + LOG(VKVG_LOG_DBG_ARRAYS, "INIT\tctx = %p; pathes:%ju pts:%ju vch:%d vbo:%d ich:%d ibo:%d\n", ctx, (uint64_t)ctx->sizePathes, (uint64_t)ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO); #ifdef DEBUG - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)ctx->cmdPool, "CTX Cmd Pool"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[0], "CTX Cmd Buff A"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[1], "CTX Cmd Buff B"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)ctx->flushFence, "CTX Flush Fence"); - - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (uint64_t)ctx->descriptorPool, "CTX Descriptor Pool"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsSrc, "CTX DescSet SOURCE"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsFont, "CTX DescSet FONT"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsGrad, "CTX DescSet GRADIENT"); - - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->indices.buffer, "CTX Index Buff"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->vertices.buffer, "CTX Vertex Buff"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)ctx->cmdPool, "CTX Cmd Pool"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[0], "CTX Cmd Buff A"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[1], "CTX Cmd Buff B"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)ctx->flushFence, "CTX Flush Fence"); + + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (uint64_t)ctx->descriptorPool, "CTX Descriptor Pool"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsSrc, "CTX DescSet SOURCE"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsFont, "CTX DescSet FONT"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsGrad, "CTX DescSet GRADIENT"); + + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->indices.buffer, "CTX Index Buff"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->vertices.buffer, "CTX Vertex Buff"); #endif - return ctx; + return ctx; } /** * @brief explicitly flush pending drawing operations on context * @param context pointer to flush */ void vkvg_flush (VkvgContext ctx){ - _flush_cmd_buff(ctx); - //_wait_flush_fence(ctx); + _flush_cmd_buff(ctx); + //_wait_flush_fence(ctx); /* #ifdef DEBUG - vec4 red = {0,0,1,1}; - vec4 green = {0,1,0,1}; - vec4 white = {1,1,1,1}; - - int j = 0; - while (j < dlpCount) { - add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],green); - j+=2; - add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],red); - j+=2; - add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],white); - j+=2; - } - dlpCount = 0; - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLineList); - CmdDrawIndexed(ctx->cmd, ctx->indCount-ctx->curIndStart, 1, ctx->curIndStart, 0, 1); - _flush_cmd_buff(ctx); + vec4 red = {0,0,1,1}; + vec4 green = {0,1,0,1}; + vec4 white = {1,1,1,1}; + + int j = 0; + while (j < dlpCount) { + add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],green); + j+=2; + add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],red); + j+=2; + add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],white); + j+=2; + } + dlpCount = 0; + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLineList); + CmdDrawIndexed(ctx->cmd, ctx->indCount-ctx->curIndStart, 1, ctx->curIndStart, 0, 1); + _flush_cmd_buff(ctx); #endif */ } @@ -199,77 +212,77 @@ void vkvg_flush (VkvgContext ctx){ */ void vkvg_destroy (VkvgContext ctx) { - ctx->references--; - if (ctx->references > 0) - return; - - _flush_cmd_buff(ctx); - _wait_flush_fence(ctx); - - LOG(LOG_INFO, "DESTROY Context: ctx = %lu; surf = %lu\n", (uint64_t)ctx, (uint64_t)ctx->pSurf); - - if (ctx->pattern) - vkvg_pattern_destroy (ctx->pattern); - - VkDevice dev = ctx->pSurf->dev->vkDev; - - vkDestroyFence (dev, ctx->flushFence,NULL); - 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->selectedFont.fontFile); - free(ctx->pathes); - free(ctx->points); - if (ctx->dashCount > 0) - free(ctx->dashes); - - //free saved context stack elmt - vkvg_context_save_t* next = ctx->pSavedCtxs; - while (next != NULL) { - vkvg_context_save_t* cur = next; - next = cur->pNext; - _free_ctx_save (cur); - if (cur->pattern) - vkvg_pattern_destroy (cur->pattern); - } - //free additional stencil use in save/restore process - uint8_t curSaveStencil = ctx->curSavBit / 6; - for (int i=curSaveStencil;i>0;i--) - vkh_image_destroy(ctx->savedStencils[i-1]); - - free(ctx->savedStencils); - - //remove context from double linked list of context in device - if (ctx->pSurf->dev->lastCtx == ctx){ - ctx->pSurf->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; - } - - LOG(LOG_DBG_ARRAYS, "END\tctx = %lu; 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); - - free(ctx); + ctx->references--; + if (ctx->references > 0) + return; + + _flush_cmd_buff(ctx); + _wait_flush_fence(ctx); + + LOG(VKVG_LOG_INFO, "DESTROY Context: ctx = %p; surf = %p\n", ctx, ctx->pSurf); + 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 (ctx->pattern) + vkvg_pattern_destroy (ctx->pattern); + + VkDevice dev = ctx->pSurf->dev->vkDev; + + vkDestroyFence (dev, ctx->flushFence,NULL); + 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->selectedFont.fontFile); + free(ctx->pathes); + free(ctx->points); + if (ctx->dashCount > 0) + free(ctx->dashes); + + //free saved context stack elmt + vkvg_context_save_t* next = ctx->pSavedCtxs; + while (next != NULL) { + vkvg_context_save_t* cur = next; + next = cur->pNext; + _free_ctx_save (cur); + if (cur->pattern) + vkvg_pattern_destroy (cur->pattern); + } + //free additional stencil use in save/restore process + uint8_t curSaveStencil = ctx->curSavBit / 6; + for (int i=curSaveStencil;i>0;i--) + vkh_image_destroy(ctx->savedStencils[i-1]); + + free(ctx->savedStencils); + + //remove context from double linked list of context in device + if (ctx->pSurf->dev->lastCtx == ctx){ + ctx->pSurf->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; + } + + + free(ctx); } /** * @brief increment reference count on context @@ -277,8 +290,8 @@ void vkvg_destroy (VkvgContext ctx) * @return */ VkvgContext vkvg_reference (VkvgContext ctx) { - ctx->references++; - return ctx; + ctx->references++; + return ctx; } /** * @brief get current reference count for context @@ -286,40 +299,40 @@ VkvgContext vkvg_reference (VkvgContext ctx) { * @return */ uint32_t vkvg_get_reference_count (VkvgContext ctx) { - return ctx->references; + return ctx->references; } /** * @brief Start new sub path, no current point is defined * @param context pointer */ void vkvg_new_sub_path (VkvgContext ctx){ - _finish_path(ctx); + _finish_path(ctx); } /** * @brief clear current context path without drawing anything * @param context pointer */ void vkvg_new_path (VkvgContext ctx){ - _clear_path(ctx); + _clear_path(ctx); } /** * @brief Close current path if at least 3 points are present * @param context pointer */ void vkvg_close_path (VkvgContext ctx){ - if (_current_path_is_empty(ctx)){ - ctx->status = VKVG_STATUS_NO_CURRENT_POINT; - return; - } - //check if at least 3 points are present - if (ctx->pointCount - (ctx->pathes [ctx->pathPtr-1]&PATH_ELT_MASK) > 2){ - ctx->pathes[ctx->pathPtr] = ctx->pointCount - 1; - ctx->pathes[ctx->pathPtr-1] |= PATH_CLOSED_BIT; - _check_pathes_array(ctx); - ctx->pathPtr += ctx->curvePtr + 1; - ctx->curvePtr = 0; - }else - _finish_path(ctx); + if (_current_path_is_empty(ctx)){ + ctx->status = VKVG_STATUS_NO_CURRENT_POINT; + return; + } + //check if at least 3 points are present + if (ctx->pointCount - (ctx->pathes [ctx->pathPtr-1]&PATH_ELT_MASK) > 2){ + ctx->pathes[ctx->pathPtr] = ctx->pointCount - 1; + ctx->pathes[ctx->pathPtr-1] |= PATH_CLOSED_BIT; + _check_pathes_array(ctx); + ctx->pathPtr += ctx->curvePtr + 1; + ctx->curvePtr = 0; + }else + _finish_path(ctx); } /** * @brief draw line with second point coordinates relative to current point @@ -328,12 +341,12 @@ void vkvg_close_path (VkvgContext ctx){ * @param delta y */ void vkvg_rel_line_to (VkvgContext ctx, float x, float y){ - if (_current_path_is_empty(ctx)){ - ctx->status = VKVG_STATUS_NO_CURRENT_POINT; - return; - } - vec2 cp = _get_current_position(ctx); - vkvg_line_to(ctx, cp.x + x, cp.y + y); + if (_current_path_is_empty(ctx)){ + ctx->status = VKVG_STATUS_NO_CURRENT_POINT; + return; + } + vec2 cp = _get_current_position(ctx); + vkvg_line_to(ctx, cp.x + x, cp.y + y); } /** * @brief Draw line from current point, if no current point is defined, only a move to will be executed. @@ -343,14 +356,14 @@ void vkvg_rel_line_to (VkvgContext ctx, float x, float y){ */ void vkvg_line_to (VkvgContext ctx, float x, float y) { - vec2 p = {x,y}; - if (_current_path_is_empty(ctx)){ - vkvg_move_to(ctx, x,y); - return; - }else if (vec2_equ(_get_current_position(ctx),p)) - return; + vec2 p = {x,y}; + if (_current_path_is_empty(ctx)){ + vkvg_move_to(ctx, x,y); + return; + }else if (vec2_equ(_get_current_position(ctx),p)) + return; - _add_point(ctx,x,y); + _add_point(ctx,x,y); } /** * @brief Draw arc in clockwise order following angles of the trigonometric circle. @@ -362,48 +375,48 @@ void vkvg_line_to (VkvgContext ctx, float x, float y) * @param end angle of arc */ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2){ - while (a2 < a1)//positive arc must have a1 2.f * M_PIF) //limit arc to 2PI - a2 = a1 + 2.f * M_PIF; + if (a2 - a1 > 2.f * M_PIF) //limit arc to 2PI + a2 = a1 + 2.f * M_PIF; - vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc}; + vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc}; - float step = _get_arc_step(ctx, radius); - float a = a1; + float step = _get_arc_step(ctx, radius); + float a = a1; - if (_current_path_is_empty(ctx)) - vkvg_move_to(ctx, v.x, v.y); - else - vkvg_line_to(ctx, v.x, v.y); + if (_current_path_is_empty(ctx)) + vkvg_move_to(ctx, v.x, v.y); + else + vkvg_line_to(ctx, v.x, v.y); - a+=step; + a+=step; - if (EQUF(a2, a1)) - return; + if (EQUF(a2, a1)) + return; - _set_curve_start (ctx); + _set_curve_start (ctx); - while(a < a2){ - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; - _add_point (ctx, v.x, v.y); - a+=step; - } + while(a < a2){ + v.x = cosf(a)*radius + xc; + v.y = sinf(a)*radius + yc; + _add_point (ctx, v.x, v.y); + a+=step; + } - if (EQUF(a2-a1,M_PIF*2.f)){//if arc is complete circle, last point is the same as the first one - _set_curve_end(ctx); - vkvg_close_path(ctx); - return; - } - a = a2; - vec2 lastP = v; - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; - //if (!vec2_equ (v,lastP))//this test should not be required - _add_point (ctx, v.x, v.y); - _set_curve_end(ctx); + if (EQUF(a2-a1,M_PIF*2.f)){//if arc is complete circle, last point is the same as the first one + _set_curve_end(ctx); + vkvg_close_path(ctx); + return; + } + a = a2; + //vec2 lastP = v; + v.x = cosf(a)*radius + xc; + v.y = sinf(a)*radius + yc; + //if (!vec2_equ (v,lastP))//this test should not be required + _add_point (ctx, v.x, v.y); + _set_curve_end(ctx); } /** * @brief Draw arc in counter clockwise order following angles of the trigonometric circle. @@ -415,46 +428,46 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa * @param end angle of arc */ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) { - while (a2 > a1) - a2 -= 2.f*M_PIF; - if (a1 - a2 > a1 + 2.f * M_PIF) //limit arc to 2PI - a2 = a1 - 2.f * M_PIF; + while (a2 > a1) + a2 -= 2.f*M_PIF; + if (a1 - a2 > a1 + 2.f * M_PIF) //limit arc to 2PI + a2 = a1 - 2.f * M_PIF; - vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc}; + vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc}; - float step = _get_arc_step(ctx, radius); - float a = a1; + float step = _get_arc_step(ctx, radius); + float a = a1; - if (_current_path_is_empty(ctx)) - vkvg_move_to(ctx, v.x, v.y); - else { - vkvg_line_to(ctx, v.x, v.y); - } + if (_current_path_is_empty(ctx)) + vkvg_move_to(ctx, v.x, v.y); + else { + vkvg_line_to(ctx, v.x, v.y); + } - a-=step; + a-=step; - if (EQUF(a2, a1)) - return; + if (EQUF(a2, a1)) + return; - _set_curve_start (ctx); + _set_curve_start (ctx); - while(a > a2){ - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; - _add_point (ctx,v.x,v.y); - a-=step; - } + while(a > a2){ + v.x = cosf(a)*radius + xc; + v.y = sinf(a)*radius + yc; + _add_point (ctx,v.x,v.y); + a-=step; + } - if (EQUF(a1-a2,M_PIF*2.f))//if arc is complete circle, last point is the same as the first one - return; + if (EQUF(a1-a2,M_PIF*2.f))//if arc is complete circle, last point is the same as the first one + return; - a = a2; - vec2 lastP = v; - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; - //if (!vec2_equ (v,lastP)) - _add_point (ctx, v.x, v.y); - _set_curve_end(ctx); + a = a2; + //vec2 lastP = v; + v.x = cosf(a)*radius + xc; + v.y = sinf(a)*radius + yc; + //if (!vec2_equ (v,lastP)) + _add_point (ctx, v.x, v.y); + _set_curve_end(ctx); } /** * @brief move pen relative to the current point. @@ -464,12 +477,12 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float */ void vkvg_rel_move_to (VkvgContext ctx, float x, float y) { - if (_current_path_is_empty(ctx)){ - ctx->status = VKVG_STATUS_NO_CURRENT_POINT; - return; - } - vec2 cp = _get_current_position(ctx); - vkvg_move_to(ctx, cp.x + x, cp.y + y); + if (_current_path_is_empty(ctx)){ + ctx->status = VKVG_STATUS_NO_CURRENT_POINT; + return; + } + vec2 cp = _get_current_position(ctx); + vkvg_move_to(ctx, cp.x + x, cp.y + y); } /** * @brief move pen to the position given in argument @@ -479,193 +492,193 @@ void vkvg_rel_move_to (VkvgContext ctx, float x, float y) */ void vkvg_move_to (VkvgContext ctx, float x, float y) { - _finish_path(ctx); - _start_sub_path(ctx, x, y); + _finish_path(ctx); + _start_sub_path(ctx, x, y); } void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { - if (_current_path_is_empty(ctx)) - vkvg_move_to(ctx, x1, y1); + if (_current_path_is_empty(ctx)) + vkvg_move_to(ctx, x1, y1); - vec2 cp = _get_current_position(ctx); + vec2 cp = _get_current_position(ctx); - _set_curve_start (ctx); - _recursive_bezier (ctx, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); - /*cp.x = x3; - cp.y = y3; - if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/ - _add_point(ctx,x3,y3); - _set_curve_end (ctx); + _set_curve_start (ctx); + _recursive_bezier (ctx, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); + /*cp.x = x3; + cp.y = y3; + if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/ + _add_point(ctx,x3,y3); + _set_curve_end (ctx); } void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { - if (_current_path_is_empty(ctx)){ - ctx->status = VKVG_STATUS_NO_CURRENT_POINT; - return; - } - vec2 cp = _get_current_position(ctx); - vkvg_curve_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2, cp.x + x3, cp.y + y3); + if (_current_path_is_empty(ctx)){ + ctx->status = VKVG_STATUS_NO_CURRENT_POINT; + return; + } + vec2 cp = _get_current_position(ctx); + vkvg_curve_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2, cp.x + x3, cp.y + y3); } void vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float w, float h){ - _vao_add_rectangle (ctx,x,y,w,h); - _record_draw_cmd(ctx); + _vao_add_rectangle (ctx,x,y,w,h); + _record_draw_cmd(ctx); } void vkvg_rectangle (VkvgContext ctx, float x, float y, float w, float h){ - _finish_path (ctx); + _finish_path (ctx); - _start_sub_path(ctx, x, y); - _add_point (ctx, x + w, y); - _add_point (ctx, x + w, y + h); - _add_point (ctx, x, y + h); + _start_sub_path(ctx, x, y); + _add_point (ctx, x + w, y); + _add_point (ctx, x + w, y + h); + _add_point (ctx, x, y + h); - vkvg_close_path (ctx); + vkvg_close_path (ctx); } -static const VkClearAttachment clearStencil = {VK_IMAGE_ASPECT_STENCIL_BIT, 1, {0}}; -static const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {0}}; +static const VkClearAttachment clearStencil = {VK_IMAGE_ASPECT_STENCIL_BIT, 1, {{{0}}}}; +static const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {{{0}}}}; void vkvg_reset_clip (VkvgContext ctx){ - _check_cmd_buff_state (ctx); - vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect); + _check_cmd_buff_state (ctx); + vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect); } void vkvg_clear (VkvgContext ctx){ - _check_cmd_buff_state (ctx); - VkClearAttachment ca[2] = {clearColorAttach, clearStencil}; - vkCmdClearAttachments(ctx->cmd, 2, ca, 1, &ctx->clearRect); + _check_cmd_buff_state (ctx); + VkClearAttachment ca[2] = {clearColorAttach, clearStencil}; + vkCmdClearAttachments(ctx->cmd, 2, ca, 1, &ctx->clearRect); } void vkvg_clip (VkvgContext ctx){ - vkvg_clip_preserve(ctx); - _clear_path(ctx); + vkvg_clip_preserve(ctx); + _clear_path(ctx); } void vkvg_stroke (VkvgContext ctx) { - vkvg_stroke_preserve(ctx); - _clear_path(ctx); + vkvg_stroke_preserve(ctx); + _clear_path(ctx); } void vkvg_fill (VkvgContext ctx){ - vkvg_fill_preserve(ctx); - _clear_path(ctx); + vkvg_fill_preserve(ctx); + _clear_path(ctx); } void vkvg_clip_preserve (VkvgContext ctx){ - if (ctx->pathPtr == 0) //nothing to fill - return; - _finish_path(ctx); - - LOG(LOG_INFO, "CLIP: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2); - - if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ - _check_cmd_buff_state(ctx); - _poly_fill (ctx); - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); - CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); - CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT); - }else{ - _check_cmd_buff_state(ctx); - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); - CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); - _fill_ec(ctx); - CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); - CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT); - } - _draw_full_screen_quad (ctx, false); - //should test current operator to bind correct pipeline - _bind_draw_pipeline (ctx); - CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + if (ctx->pathPtr == 0) //nothing to fill + return; + _finish_path(ctx); + + LOG(VKVG_LOG_INFO, "CLIP: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2); + + if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ + _check_cmd_buff_state(ctx); + _poly_fill (ctx); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); + CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT); + }else{ + _check_cmd_buff_state(ctx); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); + _fill_ec(ctx); + CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); + CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT); + } + _draw_full_screen_quad (ctx, false); + //should test current operator to bind correct pipeline + _bind_draw_pipeline (ctx); + CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); } void vkvg_fill_preserve (VkvgContext ctx){ - if (ctx->pathPtr == 0) //nothing to fill - return; - _finish_path(ctx); + if (ctx->pathPtr == 0) //nothing to fill + return; + _finish_path(ctx); - LOG(LOG_INFO, "FILL: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2); + LOG(VKVG_LOG_INFO, "FILL: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2); - if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ - _poly_fill (ctx); - _bind_draw_pipeline (ctx); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); - _draw_full_screen_quad(ctx,true); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - }else{ - _check_cmd_buff_state (ctx); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - _fill_ec(ctx); - } + if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ + _poly_fill (ctx); + _bind_draw_pipeline (ctx); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); + _draw_full_screen_quad(ctx,true); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + }else{ + _check_cmd_buff_state (ctx); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + _fill_ec(ctx); + } } void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart) { - Vertex v = {{0},{0,0,-1}}; + Vertex v = {{0},{0,0,-1}}; - VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); - if (isStart){ - vec2 vhw = vec2_mult(n,hw); + if (isStart){ + vec2 vhw = vec2_mult(n,hw); - if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) - p0 = vec2_sub(p0, vhw); + if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) + p0 = vec2_sub(p0, vhw); - vhw = vec2_perp(vhw); + vhw = vec2_perp(vhw); - if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ - float step = M_PIF / fmaxf(hw, 4.f); - float a = acosf(n.x) + M_PIF_2; - if (n.y < 0) - a = M_PIF-a; - float a1 = a + M_PIF; + if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ + float step = M_PIF / fmaxf(hw, 4.f); + float a = acosf(n.x) + M_PIF_2; + if (n.y < 0) + a = M_PIF-a; + float a1 = a + M_PIF; - a+=step; - while (a < a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); - a+=step; - } - VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); - for (VKVG_IBO_INDEX_TYPE p = firstIdx; p < p0Idx; p++) - _add_triangle_indices(ctx, p0Idx+1, p, p+1); - firstIdx = p0Idx; - } + a+=step; + while (a < a1){ + _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + a+=step; + } + VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + for (VKVG_IBO_INDEX_TYPE p = firstIdx; p < p0Idx; p++) + _add_triangle_indices(ctx, p0Idx+1, p, p+1); + firstIdx = p0Idx; + } - v.pos = vec2_add(p0, vhw); - _add_vertex(ctx, v); - v.pos = vec2_sub(p0, vhw); - _add_vertex(ctx, v); + v.pos = vec2_add(p0, vhw); + _add_vertex(ctx, v); + v.pos = vec2_sub(p0, vhw); + _add_vertex(ctx, v); - _add_tri_indices_for_rect(ctx, firstIdx); - }else{ - vec2 vhw = vec2_mult(n, hw); + _add_tri_indices_for_rect(ctx, firstIdx); + }else{ + vec2 vhw = vec2_mult(n, hw); - if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) - p0 = vec2_add(p0, vhw); + if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) + p0 = vec2_add(p0, vhw); - vhw = vec2_perp(vhw); + vhw = vec2_perp(vhw); - v.pos = vec2_add(p0, vhw); - _add_vertex(ctx, v); - v.pos = vec2_sub(p0, vhw); - _add_vertex(ctx, v); + v.pos = vec2_add(p0, vhw); + _add_vertex(ctx, v); + v.pos = vec2_sub(p0, vhw); + _add_vertex(ctx, v); - firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); - if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ - float step = M_PIF / fmaxf(hw, 4.f); - float a = acosf(n.x)+ M_PIF_2; - if (n.y < 0) - a = M_PIF-a; - float a1 = a - M_PIF; + if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ + float step = M_PIF / fmaxf(hw, 4.f); + float a = acosf(n.x)+ M_PIF_2; + if (n.y < 0) + a = M_PIF-a; + float a1 = a - M_PIF; - a-=step; - while ( a > a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); - a-=step; - } + a-=step; + while ( a > a1){ + _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + a-=step; + } - VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset - 1); - for (VKVG_IBO_INDEX_TYPE p = firstIdx-1 ; p < p0Idx; p++) - _add_triangle_indices(ctx, p+1, p, firstIdx-2); - } - } + VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset - 1); + for (VKVG_IBO_INDEX_TYPE p = firstIdx-1 ; p < p0Idx; p++) + _add_triangle_indices(ctx, p+1, p, firstIdx-2); + } + } } static bool dashOn = true; @@ -674,180 +687,180 @@ static float curDashOffset = 0.f; //cur dash offset between defined path p static vec2 normal = {0}; float _draw_dashed_segment (VkvgContext ctx, float hw, vec2 pL, vec2 p, vec2 pR, bool isCurve) { - if (!dashOn)//we test in fact the next dash start, if dashOn = true => next segment is a void. - _build_vb_step (ctx, hw, pL, p, pR, isCurve); + if (!dashOn)//we test in fact the next dash start, if dashOn = true => next segment is a void. + _build_vb_step (ctx, hw, pL, p, pR, isCurve); - vec2 d = vec2_sub (pR, p); - normal = vec2_norm (d); - float segmentLength = vec2_length(d); + vec2 d = vec2_sub (pR, p); + normal = vec2_norm (d); + float segmentLength = vec2_length(d); - while (curDashOffset < segmentLength){ - vec2 p0 = vec2_add (p, vec2_mult(normal, curDashOffset)); + while (curDashOffset < segmentLength){ + vec2 p0 = vec2_add (p, vec2_mult(normal, curDashOffset)); - _draw_stoke_cap (ctx, hw, p0, normal, dashOn); - dashOn ^= true; + _draw_stoke_cap (ctx, hw, p0, normal, dashOn); + dashOn ^= true; - curDashOffset += ctx->dashes[curDash++]; - if (curDash == ctx->dashCount) - curDash = 0; - } - curDashOffset -= segmentLength; - return segmentLength; + curDashOffset += ctx->dashes[curDash++]; + if (curDash == ctx->dashCount) + curDash = 0; + } + curDashOffset -= segmentLength; + return segmentLength; } static uint32_t curPathPointIdx, lastPathPointIdx, ptrPath, iL, iR; void _draw_segment (VkvgContext ctx, float hw, bool isCurve) { - iR = curPathPointIdx+1; - if (ctx->dashCount > 0) - _draw_dashed_segment(ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve); - else - _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve); - iL = curPathPointIdx++; + iR = curPathPointIdx+1; + if (ctx->dashCount > 0) + _draw_dashed_segment(ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve); + else + _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve); + iL = curPathPointIdx++; } void vkvg_stroke_preserve (VkvgContext ctx) { - if (ctx->pathPtr == 0)//nothing to stroke - return; - _finish_path(ctx); - - LOG(LOG_INFO, "STROKE: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2); - - float hw = ctx->lineWidth / 2.0f; - curPathPointIdx = lastPathPointIdx = ptrPath = iL = iR = 0; - - while (ptrPath < ctx->pathPtr){ - uint32_t ptrCurve = 0; - - - VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); - curPathPointIdx = ctx->pathes[ptrPath]&PATH_ELT_MASK; - - LOG(LOG_INFO_PATH, "\tPATH: start = %d; ", ctx->pathes[ptrPath]&PATH_ELT_MASK, ctx->pathes[ptrPath+1]&PATH_ELT_MASK); - - lastPathPointIdx = ctx->pathes[ptrPath+1]&PATH_ELT_MASK; - LOG(LOG_INFO_PATH, "end = %d\n", lastPathPointIdx); - - if (ctx->dashCount > 0) { - //init dash stroke - dashOn = true; - curDash = 0; //current dash index - - //limit offset to total length of dashes - float totDashLength = 0; - for (uint32_t i=0;idashCount;i++) - totDashLength+=ctx->dashes[i]; - if (totDashLength == 0){ - ctx->status = VKVG_STATUS_INVALID_DASH; - return; - } - /*if (ctx->dashOffset == 0) - curDashOffset = 0; - else*/ - curDashOffset = fmodf(ctx->dashOffset, totDashLength); //cur dash offset between defined path point and last dash segment(on/off) start - //----- - - iL = lastPathPointIdx; - } else if (_path_is_closed(ctx,ptrPath)){ - //prevent closing on the same position, this could be generalize - //to prevent processing of two consecutive point at the same position - if (vec2_equ(ctx->points[curPathPointIdx], ctx->points[lastPathPointIdx])) - lastPathPointIdx--; - iL = lastPathPointIdx; - }else{ - _draw_stoke_cap(ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx], ctx->points[curPathPointIdx+1]), true); - iL = curPathPointIdx++; - } - - if (_path_has_curves (ctx,ptrPath)) { - while (curPathPointIdx < lastPathPointIdx){ - if (ptrPath + ptrCurve + 2 < ctx->pathPtr && (ctx->pathes [ptrPath + 2 + ptrCurve]&PATH_ELT_MASK) == curPathPointIdx){ - uint32_t lastCurvePointIdx = ctx->pathes[ptrPath + 3 + ptrCurve]&PATH_ELT_MASK; - while (curPathPointIdx < lastCurvePointIdx) - _draw_segment(ctx, hw, true); - ptrCurve += 2; - }else - _draw_segment(ctx, hw, false); - } - }else while (curPathPointIdx < lastPathPointIdx) - _draw_segment(ctx, hw, false); - - if (ctx->dashCount > 0) { - if (_path_is_closed(ctx,ptrPath)){ - iR = ctx->pathes[ptrPath] & PATH_ELT_MASK; - _draw_dashed_segment(ctx, hw, ctx->points[iL++], ctx->points[curPathPointIdx++], ctx->points[iR], false); - } - if (!dashOn){ - //finishing last dash that is already started, draw end caps but not too close to start - //the default gap is the next void - uint32_t prevDash = curDash-1; - if (prevDash < 0) - curDash = ctx->dashCount-1; - float m = fminf (ctx->dashes[prevDash] - curDashOffset, ctx->dashes[curDash]); - vec2 p = vec2_sub(ctx->points[iR], vec2_mult(normal, m)); - _draw_stoke_cap (ctx, hw, p, normal, false); - } - } else if (_path_is_closed(ctx,ptrPath)){ - iR = ctx->pathes[ptrPath] & PATH_ELT_MASK; - float cross = _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], false); - - VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache [ctx->indCount-6]; - VKVG_IBO_INDEX_TYPE ii = firstIdx; - if (cross < 0 && ctx->lineJoin != VKVG_LINE_JOIN_MITER){ - inds[1] = ii+1; - inds[4] = ii+1; - inds[5] = ii; - }else{ - inds[1] = ii; - inds[4] = ii; - inds[5] = ii+1; - } - curPathPointIdx++; - }else - _draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false); - - ptrPath+=2+ptrCurve; - } - _record_draw_cmd(ctx); + if (ctx->pathPtr == 0)//nothing to stroke + return; + _finish_path(ctx); + + LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2); + + float hw = ctx->lineWidth / 2.0f; + curPathPointIdx = lastPathPointIdx = ptrPath = iL = iR = 0; + + while (ptrPath < ctx->pathPtr){ + uint32_t ptrCurve = 0; + + + VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + curPathPointIdx = ctx->pathes[ptrPath]&PATH_ELT_MASK; + + LOG(VKVG_LOG_INFO_PATH, "\tPATH: start=%d end=%d", ctx->pathes[ptrPath]&PATH_ELT_MASK, ctx->pathes[ptrPath+1]&PATH_ELT_MASK); + + lastPathPointIdx = ctx->pathes[ptrPath+1]&PATH_ELT_MASK; + LOG(VKVG_LOG_INFO_PATH, "end = %d\n", lastPathPointIdx); + + if (ctx->dashCount > 0) { + //init dash stroke + dashOn = true; + curDash = 0; //current dash index + + //limit offset to total length of dashes + float totDashLength = 0; + for (uint32_t i=0;idashCount;i++) + totDashLength+=ctx->dashes[i]; + if (totDashLength == 0){ + ctx->status = VKVG_STATUS_INVALID_DASH; + return; + } + /*if (ctx->dashOffset == 0) + curDashOffset = 0; + else*/ + curDashOffset = fmodf(ctx->dashOffset, totDashLength); //cur dash offset between defined path point and last dash segment(on/off) start + //----- + + iL = lastPathPointIdx; + } else if (_path_is_closed(ctx,ptrPath)){ + //prevent closing on the same position, this could be generalize + //to prevent processing of two consecutive point at the same position + if (vec2_equ(ctx->points[curPathPointIdx], ctx->points[lastPathPointIdx])) + lastPathPointIdx--; + iL = lastPathPointIdx; + }else{ + _draw_stoke_cap(ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx], ctx->points[curPathPointIdx+1]), true); + iL = curPathPointIdx++; + } + + if (_path_has_curves (ctx,ptrPath)) { + while (curPathPointIdx < lastPathPointIdx){ + if (ptrPath + ptrCurve + 2 < ctx->pathPtr && (ctx->pathes [ptrPath + 2 + ptrCurve] & PATH_ELT_MASK) == curPathPointIdx){ + uint32_t lastCurvePointIdx = ctx->pathes[ptrPath + 3 + ptrCurve]&PATH_ELT_MASK; + while (curPathPointIdx < lastCurvePointIdx) + _draw_segment(ctx, hw, true); + ptrCurve += 2; + }else + _draw_segment(ctx, hw, false); + } + }else while (curPathPointIdx < lastPathPointIdx) + _draw_segment(ctx, hw, false); + + if (ctx->dashCount > 0) { + if (_path_is_closed(ctx,ptrPath)){ + iR = ctx->pathes[ptrPath] & PATH_ELT_MASK; + _draw_dashed_segment(ctx, hw, ctx->points[iL++], ctx->points[curPathPointIdx++], ctx->points[iR], false); + } + if (!dashOn){ + //finishing last dash that is already started, draw end caps but not too close to start + //the default gap is the next void + uint32_t prevDash = curDash-1; + if (prevDash < 0) + curDash = ctx->dashCount-1; + float m = fminf (ctx->dashes[prevDash] - curDashOffset, ctx->dashes[curDash]); + vec2 p = vec2_sub(ctx->points[iR], vec2_mult(normal, m)); + _draw_stoke_cap (ctx, hw, p, normal, false); + } + } else if (_path_is_closed(ctx,ptrPath)){ + iR = ctx->pathes[ptrPath] & PATH_ELT_MASK; + float cross = _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], false); + + VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache [ctx->indCount-6]; + VKVG_IBO_INDEX_TYPE ii = firstIdx; + if (cross < 0 && ctx->lineJoin != VKVG_LINE_JOIN_MITER){ + inds[1] = ii+1; + inds[4] = ii+1; + inds[5] = ii; + }else{ + inds[1] = ii; + inds[4] = ii; + inds[5] = ii+1; + } + curPathPointIdx++; + }else + _draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false); + + ptrPath+=2+ptrCurve; + } + _record_draw_cmd(ctx); } void vkvg_paint (VkvgContext ctx){ - _check_cmd_buff_state (ctx); - _draw_full_screen_quad (ctx, true); + _check_cmd_buff_state (ctx); + _draw_full_screen_quad (ctx, true); } void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) { - vkvg_set_source_rgba (ctx, r, g, b, 1); + vkvg_set_source_rgba (ctx, r, g, b, 1); } void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a) { - _update_cur_pattern (ctx, vkvg_pattern_create_rgba (r,g,b,a)); + _update_cur_pattern (ctx, vkvg_pattern_create_rgba (r,g,b,a)); } void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y){ - _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); - ctx->pushConsts.source.x = x; - ctx->pushConsts.source.y = y; - ctx->pushCstDirty = true; + _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); + ctx->pushConsts.source.x = x; + ctx->pushConsts.source.y = y; + ctx->pushCstDirty = true; } void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ - _update_cur_pattern (ctx, pat); - vkvg_pattern_reference (pat); + _update_cur_pattern (ctx, pat); + vkvg_pattern_reference (pat); } void vkvg_set_line_width (VkvgContext ctx, float width){ - ctx->lineWidth = width; + ctx->lineWidth = width; } void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap){ - ctx->lineCap = cap; + ctx->lineCap = cap; } void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join){ - ctx->lineJoin = join; + ctx->lineJoin = join; } void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op){ - ctx->curOperator = op; - if (ctx->cmdStarted) - _bind_draw_pipeline (ctx); + ctx->curOperator = op; + if (ctx->cmdStarted) + _bind_draw_pipeline (ctx); } void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr){ - ctx->curFillRule = fr; + ctx->curFillRule = fr; } vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx){ - return ctx->curFillRule; + return ctx->curFillRule; } /** * @brief This function return the current line width use by vkvg_stroke() as set by vkvg_set_line_width(). @@ -855,7 +868,7 @@ vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx){ * @return current line width. */ float vkvg_get_line_width (VkvgContext ctx){ - return ctx->lineWidth; + return ctx->lineWidth; } /** * @brief Sets the dash pattern to be used by vkvg_stroke(). A dash pattern is specified by dashes , an array of positive values. Each value provides the length of alternate "on" and "off" portions of the stroke. The offset specifies an offset into the pattern at which the stroke begins. @@ -865,14 +878,14 @@ float vkvg_get_line_width (VkvgContext ctx){ * @param an offset into the dash pattern at which the stroke should start. */ void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset){ - if (ctx->dashCount > 0) - free (ctx->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); + if (ctx->dashCount > 0) + free (ctx->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); } /** * @brief get dash settings. If dashes pointer is NULL, only count and offset are returned. @@ -882,33 +895,33 @@ void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, f * @param return value for the current dash offset */ void vkvg_get_dash (VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset){ - *num_dashes = ctx->dashCount; - *offset = ctx->dashOffset; - if (ctx->dashCount == 0 || dashes == NULL) - return; - memcpy ((float*)dashes, ctx->dashes, sizeof(float) * ctx->dashCount); + *num_dashes = ctx->dashCount; + *offset = ctx->dashOffset; + if (ctx->dashCount == 0 || dashes == NULL) + return; + memcpy ((float*)dashes, ctx->dashes, sizeof(float) * ctx->dashCount); } vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx){ - return ctx->lineCap; + return ctx->lineCap; } vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx){ - return ctx->lineJoin; + return ctx->lineJoin; } vkvg_operator_t vkvg_get_operator (VkvgContext ctx){ - return ctx->curOperator; + return ctx->curOperator; } VkvgPattern vkvg_get_source (VkvgContext ctx){ - vkvg_pattern_reference (ctx->pattern); - return ctx->pattern; + vkvg_pattern_reference (ctx->pattern); + return ctx->pattern; } void vkvg_select_font_face (VkvgContext ctx, const char* name){ - _select_font_face (ctx, name); + _select_font_face (ctx, name); } void vkvg_set_font_size (VkvgContext ctx, uint32_t size){ - _set_font_size (ctx,size); + _set_font_size (ctx,size); } void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){ @@ -916,299 +929,305 @@ void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){ } void vkvg_show_text (VkvgContext ctx, const char* text){ - _check_cmd_buff_state(ctx); - _show_text (ctx, text); - _record_draw_cmd (ctx); + _check_cmd_buff_state(ctx); + _show_text (ctx, text); + _record_draw_cmd (ctx); } VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text) { - VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t)); - _create_text_run(ctx, text, tr); - return tr; + VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t)); + _create_text_run(ctx, text, tr); + return tr; } void vkvg_text_run_destroy (VkvgText textRun) { - _destroy_text_run (textRun); - free (textRun); + _destroy_text_run (textRun); + free (textRun); } void vkvg_show_text_run (VkvgContext ctx, VkvgText textRun) { - _show_text_run(ctx, textRun); + _show_text_run(ctx, textRun); } void vkvg_text_run_get_extents (VkvgText textRun, vkvg_text_extents_t* extents) { - extents = &textRun->extents; + extents = &textRun->extents; } void vkvg_text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t* extents) { - _text_extents(ctx, text, extents); + _text_extents(ctx, text, extents); } void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents) { - _font_extents(ctx, extents); + _font_extents(ctx, extents); } void vkvg_save (VkvgContext ctx){ - LOG(LOG_INFO, "SAVE CONTEXT: ctx = %lu\n", (uint64_t)ctx); - - _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); - - VkvgDevice dev = ctx->pSurf->dev; - vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t)); - - uint8_t curSaveStencil = ctx->curSavBit / 6; - - if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//new save/restore stencil image have to be created - ctx->savedStencils = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof (VkhImage)); - VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev,FB_STENCIL_FORMAT, dev->samples, ctx->pSurf->width, ctx->pSurf->height, - VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); - ctx->savedStencils[curSaveStencil-1] = savStencil; - - vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - ctx->cmdStarted = true; - - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (ctx->cmd, savStencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, - .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, - .extent = {ctx->pSurf->width,ctx->pSurf->height,1}}; - vkCmdCopyImage(ctx->cmd, - vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (savStencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, &cregion); - - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); - - VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); - _wait_and_submit_cmd(ctx); - } - - uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2); - - _start_cmd_for_render_pass (ctx); - - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); - - CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); - - _draw_full_screen_quad (ctx, false); - - _bind_draw_pipeline (ctx); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - - 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->curOperator= ctx->curOperator; - sav->lineCap = ctx->lineCap; - sav->lineWidth = ctx->lineWidth; - sav->curFillRule= ctx->curFillRule; - - sav->selectedFont = ctx->selectedFont; - sav->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); - strcpy (sav->selectedFont.fontFile, ctx->selectedFont.fontFile); - - sav->currentFont = ctx->currentFont; - sav->textDirection= ctx->textDirection; - sav->pushConsts = ctx->pushConsts; - sav->pattern = ctx->pattern; - - sav->pNext = ctx->pSavedCtxs; - ctx->pSavedCtxs = sav; - ctx->curSavBit++; - - if (ctx->pattern) - vkvg_pattern_reference (ctx->pattern); + LOG(VKVG_LOG_INFO, "SAVE CONTEXT: ctx = %p\n", ctx); + + _flush_cmd_buff (ctx); + _wait_flush_fence (ctx); + + VkvgDevice dev = ctx->pSurf->dev; + vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t)); + + uint8_t curSaveStencil = ctx->curSavBit / 6; + + if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//new save/restore stencil image have to be created + VkhImage* savedStencilsPtr = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof(VkhImage)); + if (savedStencilsPtr == NULL) { + free(sav); + ctx->status = VKVG_STATUS_NO_MEMORY; + return; + } + ctx->savedStencils = savedStencilsPtr; + VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev,FB_STENCIL_FORMAT, dev->samples, ctx->pSurf->width, ctx->pSurf->height, + VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); + ctx->savedStencils[curSaveStencil-1] = savStencil; + + vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; + + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (ctx->cmd, savStencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, + .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, + .extent = {ctx->pSurf->width,ctx->pSurf->height,1}}; + vkCmdCopyImage(ctx->cmd, + vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (savStencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &cregion); + + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); + + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); + _wait_and_submit_cmd(ctx); + } + + uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2); + + _start_cmd_for_render_pass (ctx); + + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + + CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); + + _draw_full_screen_quad (ctx, false); + + _bind_draw_pipeline (ctx); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + + 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->curOperator= ctx->curOperator; + sav->lineCap = ctx->lineCap; + sav->lineWidth = ctx->lineWidth; + sav->curFillRule= ctx->curFillRule; + + sav->selectedFont = ctx->selectedFont; + sav->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); + strcpy (sav->selectedFont.fontFile, ctx->selectedFont.fontFile); + + sav->currentFont = ctx->currentFont; + sav->textDirection= ctx->textDirection; + sav->pushConsts = ctx->pushConsts; + sav->pattern = ctx->pattern; + + sav->pNext = ctx->pSavedCtxs; + ctx->pSavedCtxs = sav; + ctx->curSavBit++; + + if (ctx->pattern) + vkvg_pattern_reference (ctx->pattern); } void vkvg_restore (VkvgContext ctx){ - if (ctx->pSavedCtxs == NULL){ - ctx->status = VKVG_STATUS_INVALID_RESTORE; - return; - } + if (ctx->pSavedCtxs == NULL){ + ctx->status = VKVG_STATUS_INVALID_RESTORE; + return; + } - LOG(LOG_INFO, "RESTORE CONTEXT: ctx = %lu\n", ctx); + 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->pSavedCtxs = sav->pNext; - ctx->pushConsts = sav->pushConsts; + ctx->pushConsts = sav->pushConsts; - if (sav->pattern) - _update_cur_pattern (ctx, sav->pattern); + if (sav->pattern) + _update_cur_pattern (ctx, sav->pattern); - _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + _flush_cmd_buff (ctx); + _wait_flush_fence (ctx); - ctx->curSavBit--; + ctx->curSavBit--; - uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2); + uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2); - _start_cmd_for_render_pass (ctx); + _start_cmd_for_render_pass (ctx); - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); - CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); - CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); + CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - _draw_full_screen_quad (ctx, false); + _draw_full_screen_quad (ctx, false); - _bind_draw_pipeline (ctx); - CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + _bind_draw_pipeline (ctx); + CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + _flush_cmd_buff (ctx); + _wait_flush_fence (ctx); - uint8_t curSaveStencil = ctx->curSavBit / 6; - if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//addtional save/restore stencil image have to be copied back to surf stencil first - VkhImage savStencil = ctx->savedStencils[curSaveStencil-1]; + uint8_t curSaveStencil = ctx->curSavBit / 6; + if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//addtional save/restore stencil image have to be copied back to surf stencil first + VkhImage savStencil = ctx->savedStencils[curSaveStencil-1]; - vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - ctx->cmdStarted = true; + vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (ctx->cmd, savStencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (ctx->cmd, savStencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, - .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, - .extent = {ctx->pSurf->width,ctx->pSurf->height,1}}; - vkCmdCopyImage(ctx->cmd, - vkh_image_get_vkimage (savStencil), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, &cregion); - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); + VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, + .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, + .extent = {ctx->pSurf->width,ctx->pSurf->height,1}}; + vkCmdCopyImage(ctx->cmd, + vkh_image_get_vkimage (savStencil), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &cregion); + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); - VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); - _wait_and_submit_cmd (ctx); - _wait_flush_fence (ctx); - vkh_image_destroy (savStencil); - } + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); + _wait_and_submit_cmd (ctx); + _wait_flush_fence (ctx); + vkh_image_destroy (savStencil); + } - ctx->dashOffset = sav->dashOffset; - if (ctx->dashCount > 0) - free (ctx->dashes); - ctx->dashCount = sav->dashCount; - if (ctx->dashCount > 0) { - ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); - memcpy (ctx->dashes, sav->dashes, sizeof(float) * ctx->dashCount); - } + ctx->dashOffset = sav->dashOffset; + if (ctx->dashCount > 0) + free (ctx->dashes); + ctx->dashCount = sav->dashCount; + 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->curOperator= sav->curOperator; - ctx->lineCap = sav->lineCap; - ctx->lineJoin = sav->lineJoint; - ctx->curFillRule= sav->curFillRule; + ctx->lineWidth = sav->lineWidth; + ctx->curOperator= sav->curOperator; + ctx->lineCap = sav->lineCap; + ctx->lineJoin = sav->lineJoint; + ctx->curFillRule= sav->curFillRule; - ctx->selectedFont.charSize = sav->selectedFont.charSize; - strcpy (ctx->selectedFont.fontFile, sav->selectedFont.fontFile); + ctx->selectedFont.charSize = sav->selectedFont.charSize; + strcpy (ctx->selectedFont.fontFile, sav->selectedFont.fontFile); - ctx->currentFont = sav->currentFont; - ctx->textDirection= sav->textDirection; + ctx->currentFont = sav->currentFont; + ctx->textDirection= sav->textDirection; - _free_ctx_save(sav); + _free_ctx_save(sav); } void vkvg_translate (VkvgContext ctx, float dx, float dy){ - vkvg_matrix_translate (&ctx->pushConsts.mat, dx, dy); - _set_mat_inv_and_vkCmdPush (ctx); + vkvg_matrix_translate (&ctx->pushConsts.mat, dx, dy); + _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_scale (VkvgContext ctx, float sx, float sy){ - vkvg_matrix_scale (&ctx->pushConsts.mat, sx, sy); - _set_mat_inv_and_vkCmdPush (ctx); + vkvg_matrix_scale (&ctx->pushConsts.mat, sx, sy); + _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_rotate (VkvgContext ctx, float radians){ - vkvg_matrix_rotate (&ctx->pushConsts.mat, radians); - _set_mat_inv_and_vkCmdPush (ctx); + vkvg_matrix_rotate (&ctx->pushConsts.mat, radians); + _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix) { - vkvg_matrix_t res; - vkvg_matrix_multiply (&res, &ctx->pushConsts.mat, matrix); - ctx->pushConsts.mat = res; - _set_mat_inv_and_vkCmdPush (ctx); + vkvg_matrix_t res; + vkvg_matrix_multiply (&res, &ctx->pushConsts.mat, matrix); + ctx->pushConsts.mat = res; + _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_identity_matrix (VkvgContext ctx) { - vkvg_matrix_t im = VKVG_IDENTITY_MATRIX; - ctx->pushConsts.mat = im; - _set_mat_inv_and_vkCmdPush (ctx); + vkvg_matrix_t im = VKVG_IDENTITY_MATRIX; + ctx->pushConsts.mat = im; + _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){ - ctx->pushConsts.mat = (*matrix); - _set_mat_inv_and_vkCmdPush (ctx); + ctx->pushConsts.mat = (*matrix); + _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_get_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){ - memcpy ((void*)matrix, &ctx->pushConsts.mat, sizeof(vkvg_matrix_t)); + memcpy ((void*)matrix, &ctx->pushConsts.mat, sizeof(vkvg_matrix_t)); } void vkvg_render_svg (VkvgContext ctx, NSVGimage* svg, char *subId){ - NSVGshape* shape; - NSVGpath* path; - - vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - - vkvg_set_source_rgba(ctx,0.0,0.0,0.0,1); - - for (shape = svg->shapes; shape != NULL; shape = shape->next) { - if (subId != NULL) { - if (strcmp(shape->id, subId)!=0) - continue; - } - - vkvg_new_path(ctx); - - float o = shape->opacity; - - vkvg_set_line_width(ctx, shape->strokeWidth); - - for (path = shape->paths; path != NULL; path = path->next) { - float* p = path->pts; - vkvg_move_to(ctx, p[0],p[1]); - for (int i = 1; i < path->npts-2; i += 3) { - p = &path->pts[i*2]; - vkvg_curve_to(ctx, p[0],p[1], p[2],p[3], p[4],p[5]); - } - if (path->closed) - vkvg_close_path(ctx); - } - - if (shape->fill.type == NSVG_PAINT_COLOR) - _svg_set_color(ctx, shape->fill.color, o); - else if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT){ - NSVGgradient* g = shape->fill.gradient; - _svg_set_color(ctx, g->stops[0].color, o); - } - - if (shape->fill.type != NSVG_PAINT_NONE){ - if (shape->stroke.type == NSVG_PAINT_NONE){ - vkvg_fill(ctx); - continue; - } - vkvg_fill_preserve (ctx); - } - - if (shape->stroke.type == NSVG_PAINT_COLOR) - _svg_set_color(ctx, shape->stroke.color, o); - else if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT){ - NSVGgradient* g = shape->stroke.gradient; - _svg_set_color(ctx, g->stops[0].color, o); - } - - vkvg_stroke(ctx); - } + NSVGshape* shape; + NSVGpath* path; + + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); + + vkvg_set_source_rgba(ctx,0.0,0.0,0.0,1); + + for (shape = svg->shapes; shape != NULL; shape = shape->next) { + if (subId != NULL) { + if (strcmp(shape->id, subId)!=0) + continue; + } + + vkvg_new_path(ctx); + + float o = shape->opacity; + + vkvg_set_line_width(ctx, shape->strokeWidth); + + for (path = shape->paths; path != NULL; path = path->next) { + float* p = path->pts; + vkvg_move_to(ctx, p[0],p[1]); + for (int i = 1; i < path->npts-2; i += 3) { + p = &path->pts[i*2]; + vkvg_curve_to(ctx, p[0],p[1], p[2],p[3], p[4],p[5]); + } + if (path->closed) + vkvg_close_path(ctx); + } + + if (shape->fill.type == NSVG_PAINT_COLOR) + _svg_set_color(ctx, shape->fill.color, o); + else if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT){ + NSVGgradient* g = shape->fill.gradient; + _svg_set_color(ctx, g->stops[0].color, o); + } + + if (shape->fill.type != NSVG_PAINT_NONE){ + if (shape->stroke.type == NSVG_PAINT_NONE){ + vkvg_fill(ctx); + continue; + } + vkvg_fill_preserve (ctx); + } + + if (shape->stroke.type == NSVG_PAINT_COLOR) + _svg_set_color(ctx, shape->stroke.color, o); + else if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT){ + NSVGgradient* g = shape->stroke.gradient; + _svg_set_color(ctx, g->stops[0].color, o); + } + + vkvg_stroke(ctx); + } } diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index e8ff1dd..9c01720 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -37,1098 +37,1124 @@ #include "vkh_image.h" void _check_flush_needed (VkvgContext ctx) { - if (!ctx->cmdStarted) - return; - if (ctx->pointCount * 4 < ctx->sizeIndices - ctx->indCount) - return; - _flush_cmd_buff(ctx); + if (!ctx->cmdStarted) + return; + if (ctx->pointCount * 4 < ctx->sizeIndices - ctx->indCount) + return; + _flush_cmd_buff(ctx); } -void _check_vbo_size (VkvgContext ctx) { - if (ctx->sizeVertices - ctx->vertCount > VKVG_ARRAY_THRESHOLD) - return; - ctx->sizeVertices += VKVG_VBO_SIZE; - Vertex* tmp = (Vertex*) realloc (ctx->vertexCache, ctx->sizeVertices * sizeof(Vertex)); - if (tmp == NULL) - ctx->status = VKVG_STATUS_NO_MEMORY; - else - ctx->vertexCache = tmp; +void _resize_vertex_cache (VkvgContext ctx, uint32_t newSize) { + Vertex* tmp = (Vertex*) realloc (ctx->vertexCache, (size_t)newSize * sizeof(Vertex)); + LOG(VKVG_LOG_DBG_ARRAYS, "resize VBO: new size: %u size(byte): %zu Ptr: %p -> %p\n", newSize, (size_t)newSize * sizeof(Vertex), ctx->vertexCache, tmp); + if (tmp == NULL){ + ctx->status = VKVG_STATUS_NO_MEMORY; + LOG(VKVG_LOG_ERR, "resize VBO failed: vert count: %u byte size: %zu\n", ctx->sizeVertices, ctx->sizeVertices * sizeof(Vertex)); + return; + } + ctx->vertexCache = tmp; + ctx->sizeVertices = newSize; } -void _check_ibo_size (VkvgContext ctx) { - if (ctx->sizeIndices - ctx->indCount > VKVG_ARRAY_THRESHOLD) - return; - ctx->sizeIndices += VKVG_IBO_SIZE; - VKVG_IBO_INDEX_TYPE* tmp = (VKVG_IBO_INDEX_TYPE*) realloc (ctx->indexCache, ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); - if (tmp == NULL) - ctx->status = VKVG_STATUS_NO_MEMORY; - else - ctx->indexCache = tmp; +void _check_vertex_cache_size (VkvgContext ctx) { + if (ctx->sizeVertices - ctx->vertCount > VKVG_ARRAY_THRESHOLD) + return; + _resize_vertex_cache (ctx, ctx->sizeVertices + VKVG_VBO_SIZE); +} +void _check_index_cache_size (VkvgContext ctx) { + if (ctx->sizeIndices - ctx->indCount > VKVG_ARRAY_THRESHOLD) + return; + ctx->sizeIndices += VKVG_IBO_SIZE; + VKVG_IBO_INDEX_TYPE* tmp = (VKVG_IBO_INDEX_TYPE*) realloc (ctx->indexCache, (size_t)ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); + LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %u Ptr: %p -> %p\n", ctx->sizeIndices, ctx->indexCache, tmp); + if (tmp == NULL){ + ctx->status = VKVG_STATUS_NO_MEMORY; + LOG(VKVG_LOG_ERR, "resize IBO failed: idx count: %u size(byte): %zu\n", ctx->sizeIndices, (size_t)ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); + return; + } + ctx->indexCache = tmp; } void _check_pathes_array (VkvgContext ctx){ - if (ctx->sizePathes - ctx->pathPtr - ctx->curvePtr > VKVG_ARRAY_THRESHOLD) - return; - ctx->sizePathes += VKVG_PATHES_SIZE; - uint32_t* tmp = (uint32_t*) realloc (ctx->pathes, ctx->sizePathes * sizeof(uint32_t)); - if (tmp == NULL){ - ctx->status = VKVG_STATUS_NO_MEMORY; - ctx->pathPtr = 0 + (ctx->pathPtr % 2); - }else - ctx->pathes = tmp; + if (ctx->sizePathes - ctx->pathPtr - ctx->curvePtr > VKVG_ARRAY_THRESHOLD) + return; + ctx->sizePathes += VKVG_PATHES_SIZE; + uint32_t* tmp = (uint32_t*) realloc (ctx->pathes, (size_t)ctx->sizePathes * sizeof(uint32_t)); + LOG(VKVG_LOG_DBG_ARRAYS, "resize PATH: new size: %u Ptr: %p -> %p\n", ctx->sizePathes, ctx->pathes, tmp); + if (tmp == NULL){ + ctx->status = VKVG_STATUS_NO_MEMORY; + LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePathes * sizeof(uint32_t)); + ctx->pathPtr = 0 + (ctx->pathPtr % 2); + }else + ctx->pathes = tmp; } void _check_point_array (VkvgContext ctx){ - if (ctx->sizePoints - ctx->pointCount > VKVG_ARRAY_THRESHOLD) - return; - ctx->sizePoints += VKVG_PATHES_SIZE; - vec2* tmp = (vec2*) realloc (ctx->points, ctx->sizePoints * sizeof(vec2)); - if (tmp == NULL){ - ctx->status = VKVG_STATUS_NO_MEMORY; - ctx->pointCount = 0; - }else - ctx->points = tmp; + if (ctx->sizePoints - ctx->pointCount > VKVG_ARRAY_THRESHOLD) + return; + ctx->sizePoints += VKVG_PATHES_SIZE; + vec2* tmp = (vec2*) realloc (ctx->points, (size_t)ctx->sizePoints * sizeof(vec2)); + LOG(VKVG_LOG_DBG_ARRAYS, "resize Points: new size(point): %u Ptr: %p -> %p\n", ctx->sizePoints, ctx->points, tmp); + if (tmp == NULL){ + ctx->status = VKVG_STATUS_NO_MEMORY; + LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePoints * sizeof(vec2)); + ctx->pointCount = 0; + }else + ctx->points = tmp; } //when empty, ptr is even, else it's odd //when empty, no current point is defined. bool _current_path_is_empty (VkvgContext ctx) { - return ctx->pathPtr % 2 == 0; + return ctx->pathPtr % 2 == 0; } //this function expect that current point exists vec2 _get_current_position (VkvgContext ctx) { - return ctx->points[ctx->pointCount-1]; + return ctx->points[ctx->pointCount-1]; } //set curve start point and set path has curve bit void _set_curve_start (VkvgContext ctx) { - ctx->pathes[ctx->pathPtr+ctx->curvePtr+1] = (ctx->pointCount - 1); - ctx->pathes[ctx->pathPtr-1] |= PATH_HAS_CURVES_BIT; + ctx->pathes[ctx->pathPtr + ctx->curvePtr + 1] = (ctx->pointCount - 1); + ctx->pathes[ctx->pathPtr - 1] |= PATH_HAS_CURVES_BIT; } //set curve end point and set path is curve bit void _set_curve_end (VkvgContext ctx) { - ctx->pathes[ctx->pathPtr+ctx->curvePtr+2] = (ctx->pointCount - 1)|PATH_IS_CURVE_BIT; - ctx->curvePtr+=2; - _check_pathes_array(ctx); + ctx->pathes [ctx->pathPtr + ctx->curvePtr + 2] = (ctx->pointCount - 1) | PATH_IS_CURVE_BIT; + ctx->curvePtr+=2; + _check_pathes_array(ctx); } //path start pointed at ptrPath has curve bit bool _path_has_curves (VkvgContext ctx, uint32_t ptrPath) { - return ctx->pathes[ptrPath] & PATH_HAS_CURVES_BIT; + return ctx->pathes[ptrPath] & PATH_HAS_CURVES_BIT; } //this function expect that current path is empty void _start_sub_path (VkvgContext ctx, float x, float y) { - //set start to current idx in point array - ctx->pathes[ctx->pathPtr] = ctx->pointCount; - _add_point(ctx, x, y); - _check_pathes_array(ctx); - ctx->pathPtr++; + //set start to current idx in point array + ctx->pathes[ctx->pathPtr] = ctx->pointCount; + _add_point(ctx, x, y); + _check_pathes_array(ctx); + ctx->pathPtr++; } void _finish_path (VkvgContext ctx){ - if (_current_path_is_empty(ctx)) - return; - if (ctx->pathes[ctx->pathPtr-1] == ctx->pointCount - 1){ - //only current pos is in path - ctx->pathPtr--; - return; - } - - //set end index of current path to last point in points array - ctx->pathes[ctx->pathPtr] = ctx->pointCount - 1; - _check_pathes_array(ctx); - ctx->pathPtr += ctx->curvePtr + 1; - ctx->curvePtr = 0; + if (_current_path_is_empty(ctx)) + return; + if (ctx->pathes[ctx->pathPtr-1] == ctx->pointCount - 1){ + //only current pos is in path + ctx->pathPtr--; + return; + } + + //set end index of current path to last point in points array + ctx->pathes[ctx->pathPtr] = ctx->pointCount - 1; + _check_pathes_array(ctx); + ctx->pathPtr += ctx->curvePtr + 1; + ctx->curvePtr = 0; } void _clear_path (VkvgContext ctx){ - ctx->pathPtr = 0; - ctx->pointCount = 0; - ctx->curvePtr = 0; - _resetMinMax(ctx); + ctx->pathPtr = 0; + ctx->pointCount = 0; + ctx->curvePtr = 0; + _resetMinMax(ctx); } bool _path_is_closed (VkvgContext ctx, uint32_t ptrPath){ - return ctx->pathes[ptrPath] & PATH_CLOSED_BIT; + return ctx->pathes[ptrPath] & PATH_CLOSED_BIT; } void _resetMinMax (VkvgContext ctx) { - ctx->xMin = ctx->yMin = FLT_MAX; - ctx->xMax = ctx->yMax = FLT_MIN; + ctx->xMin = ctx->yMin = FLT_MAX; + ctx->xMax = ctx->yMax = FLT_MIN; } void _add_point (VkvgContext ctx, float x, float y){ - ctx->points[ctx->pointCount] = (vec2){x,y}; - ctx->pointCount++; - - _check_point_array(ctx); - - //bounds are computed here to scissor the painting operation - //that speed up fill drastically. - vkvg_matrix_transform_point (&ctx->pushConsts.mat, &x, &y); - - if (x < ctx->xMin) - ctx->xMin = x; - if (x > ctx->xMax) - ctx->xMax = x; - if (y < ctx->yMin) - ctx->yMin = y; - if (y > ctx->yMax) - ctx->yMax = y; + ctx->points[ctx->pointCount] = (vec2){x,y}; + ctx->pointCount++; + + _check_point_array(ctx); + + //bounds are computed here to scissor the painting operation + //that speed up fill drastically. + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &x, &y); + + if (x < ctx->xMin) + ctx->xMin = x; + if (x > ctx->xMax) + ctx->xMax = x; + if (y < ctx->yMin) + ctx->yMin = y; + if (y > ctx->yMax) + ctx->yMax = y; } float _normalizeAngle(float a) { - float res = ROUND_DOWN(fmodf(a,2.0f*M_PIF),100); - if (res < 0.0f) - return res + 2.0f*M_PIF; - else - return res; + float res = ROUND_DOWN(fmodf(a,2.0f*M_PIF),100); + if (res < 0.0f) + return res + 2.0f*M_PIF; + else + return res; } float _get_arc_step (VkvgContext ctx, float radius) { - float dx = 1, dy = 1; - vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy); - return M_PIF/sqrtf(radius)*0.35f/fmaxf(dx,dy); + float dx = 1, dy = 1; + vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy); + return M_PIF/sqrtf(radius)*0.35f/fmaxf(dx,dy); } void _create_gradient_buff (VkvgContext ctx){ - vkvg_buffer_create (ctx->pSurf->dev, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU, - sizeof(vkvg_gradient_t), &ctx->uboGrad); + vkvg_buffer_create (ctx->pSurf->dev, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU, + sizeof(vkvg_gradient_t), &ctx->uboGrad); } void _create_vertices_buff (VkvgContext ctx){ - vkvg_buffer_create (ctx->pSurf->dev, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU, - ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); - vkvg_buffer_create (ctx->pSurf->dev, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU, - ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); + vkvg_buffer_create (ctx->pSurf->dev, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU, + ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); + vkvg_buffer_create (ctx->pSurf->dev, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU, + ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); } -void _resize_vbo (VkvgContext ctx, size_t new_size) { - _wait_flush_fence (ctx);//wait previous cmd if not completed - ctx->sizeVBO = new_size; - ctx->sizeVBO += ctx->sizeVBO % VKVG_VBO_SIZE; - vkvg_buffer_destroy (&ctx->vertices); - vkvg_buffer_create (ctx->pSurf->dev, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU, - ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); +void _resize_vbo (VkvgContext ctx, uint32_t new_size) { + _wait_flush_fence (ctx);//wait previous cmd if not completed + ctx->sizeVBO = new_size; + ctx->sizeVBO += ctx->sizeVBO % VKVG_VBO_SIZE; + LOG(VKVG_LOG_DBG_ARRAYS, "resize VBO: new size: %d\n", ctx->sizeVBO); + vkvg_buffer_destroy (&ctx->vertices); + vkvg_buffer_create (ctx->pSurf->dev, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU, + ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); } void _resize_ibo (VkvgContext ctx, size_t new_size) { - _wait_flush_fence (ctx);//wait previous cmd if not completed - ctx->sizeIBO = ctx->sizeIndices; - ctx->sizeIBO += ctx->sizeIBO % VKVG_IBO_SIZE; - vkvg_buffer_destroy (&ctx->indices); - vkvg_buffer_create (ctx->pSurf->dev, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU, - ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); + _wait_flush_fence (ctx);//wait previous cmd if not completed + ctx->sizeIBO = ctx->sizeIndices; + ctx->sizeIBO += ctx->sizeIBO % VKVG_IBO_SIZE; + LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %d\n", ctx->sizeIBO); + vkvg_buffer_destroy (&ctx->indices); + vkvg_buffer_create (ctx->pSurf->dev, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU, + ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); } void _add_vertexf (VkvgContext ctx, float x, float y){ - Vertex* pVert = &ctx->vertexCache[ctx->vertCount]; - pVert->pos.x = x; - pVert->pos.y = y; - pVert->uv = (vec3){0,0,-1}; - ctx->vertCount++; + Vertex* pVert = &ctx->vertexCache[ctx->vertCount]; + pVert->pos.x = x; + pVert->pos.y = y; + pVert->uv = (vec3){0,0,-1}; + ctx->vertCount++; - _check_vbo_size(ctx); + _check_vertex_cache_size(ctx); } void _add_vertex(VkvgContext ctx, Vertex v){ - ctx->vertexCache[ctx->vertCount] = v; - ctx->vertCount++; + ctx->vertexCache[ctx->vertCount] = v; + ctx->vertCount++; - _check_vbo_size(ctx); + _check_vertex_cache_size(ctx); } void _set_vertex(VkvgContext ctx, uint32_t idx, Vertex v){ - ctx->vertexCache[idx] = v; + ctx->vertexCache[idx] = v; } void _add_tri_indices_for_rect (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i){ - VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount]; - inds[0] = i; - inds[1] = i+2; - inds[2] = i+1; - inds[3] = i+1; - inds[4] = i+2; - inds[5] = i+3; - ctx->indCount+=6; - - _check_ibo_size(ctx); - LOG(LOG_INFO, "Rectangle IDX: %d %d %d | %d %d %d (count=%d)\n", inds[0], inds[1], inds[2], inds[3], inds[4], inds[5], ctx->indCount); + VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount]; + inds[0] = i; + inds[1] = i+2; + inds[2] = i+1; + inds[3] = i+1; + inds[4] = i+2; + inds[5] = i+3; + ctx->indCount+=6; + + _check_index_cache_size(ctx); + LOG(VKVG_LOG_INFO, "Rectangle IDX: %d %d %d | %d %d %d (count=%d)\n", inds[0], inds[1], inds[2], inds[3], inds[4], inds[5], ctx->indCount); } void _add_triangle_indices(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2){ - VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount]; - inds[0] = i0; - inds[1] = i1; - inds[2] = i2; - ctx->indCount+=3; - - _check_ibo_size(ctx); - LOG(LOG_INFO, "Triangle IDX: %d %d %d (count=%d)\n", i0,i1,i2,ctx->indCount); + VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount]; + inds[0] = i0; + inds[1] = i1; + inds[2] = i2; + ctx->indCount+=3; + + _check_index_cache_size(ctx); + LOG(VKVG_LOG_INFO, "Triangle IDX: %d %d %d (count=%d)\n", i0,i1,i2,ctx->indCount); } void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float height){ - Vertex v[4] = - { - {{x,y}, {0,0,-1}}, - {{x,y+height}, {0,0,-1}}, - {{x+width,y}, {0,0,-1}}, - {{x+width,y+height},{0,0,-1}} - }; - VKVG_IBO_INDEX_TYPE firstIdx = ctx->vertCount - ctx->curVertOffset; - Vertex* pVert = &ctx->vertexCache[ctx->vertCount]; - memcpy (pVert,v,4*sizeof(Vertex)); - ctx->vertCount+=4; - - _check_vbo_size(ctx); - - _add_tri_indices_for_rect(ctx, firstIdx); + Vertex v[4] = + { + {{x,y}, {0,0,-1}}, + {{x,y+height}, {0,0,-1}}, + {{x+width,y}, {0,0,-1}}, + {{x+width,y+height},{0,0,-1}} + }; + VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + Vertex* pVert = &ctx->vertexCache[ctx->vertCount]; + memcpy (pVert,v,4*sizeof(Vertex)); + ctx->vertCount+=4; + + _check_vertex_cache_size(ctx); + + _add_tri_indices_for_rect(ctx, firstIdx); } void _check_cmd_buff_state (VkvgContext ctx) { - if (!ctx->cmdStarted) - _start_cmd_for_render_pass(ctx); - else if (ctx->pushCstDirty) - _update_push_constants(ctx); + if (!ctx->cmdStarted) + _start_cmd_for_render_pass(ctx); + else if (ctx->pushCstDirty) + _update_push_constants(ctx); } void _create_cmd_buff (VkvgContext ctx){ - vkh_cmd_buffs_create((VkhDevice)ctx->pSurf->dev, ctx->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 2, ctx->cmdBuffers); + vkh_cmd_buffs_create((VkhDevice)ctx->pSurf->dev, ctx->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 2, ctx->cmdBuffers); #if defined(DEBUG) && defined(ENABLE_VALIDATION) - vkh_device_set_object_name((VkhDevice)ctx->pSurf->dev, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)ctx->cmd, "vkvgCtxCmd"); + vkh_device_set_object_name((VkhDevice)ctx->pSurf->dev, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)ctx->cmd, "vkvgCtxCmd"); #endif } void _clear_attachment (VkvgContext ctx) { } void _wait_flush_fence (VkvgContext ctx) { - vkWaitForFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT); + vkWaitForFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT); } void _reset_flush_fence (VkvgContext ctx) { - vkResetFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence); + vkResetFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence); } void _wait_and_submit_cmd (VkvgContext ctx){ - if (!ctx->cmdStarted)//current cmd buff is empty, be aware that wait is also canceled!! - return; + if (!ctx->cmdStarted)//current cmd buff is empty, be aware that wait is also canceled!! + return; - _wait_flush_fence (ctx); - _reset_flush_fence(ctx); + _wait_flush_fence (ctx); + _reset_flush_fence(ctx); - _submit_cmd (ctx->pSurf->dev, &ctx->cmd, ctx->flushFence); + _submit_cmd (ctx->pSurf->dev, &ctx->cmd, ctx->flushFence); - if (ctx->cmd == ctx->cmdBuffers[0]) - ctx->cmd = ctx->cmdBuffers[1]; - else - ctx->cmd = ctx->cmdBuffers[0]; + if (ctx->cmd == ctx->cmdBuffers[0]) + ctx->cmd = ctx->cmdBuffers[1]; + else + ctx->cmd = ctx->cmdBuffers[0]; - vkResetCommandBuffer (ctx->cmd, 0); - ctx->cmdStarted = false; + vkResetCommandBuffer (ctx->cmd, 0); + ctx->cmdStarted = false; } /*void _explicit_ms_resolve (VkvgContext ctx){//should init cmd before calling this (unused, using automatic resolve by renderpass) - vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkImageResolve re = { - .extent = {ctx->pSurf->width, ctx->pSurf->height,1}, - .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}, - .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1} - }; - - vkCmdResolveImage(ctx->cmd, - vkh_image_get_vkimage (ctx->pSurf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (ctx->pSurf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1,&re); - vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL , - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + VkImageResolve re = { + .extent = {ctx->pSurf->width, ctx->pSurf->height,1}, + .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}, + .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1} + }; + + vkCmdResolveImage(ctx->cmd, + vkh_image_get_vkimage (ctx->pSurf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (ctx->pSurf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1,&re); + vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL , + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); }*/ //pre flush vertices because of vbo or ibo too small, all vertices except last draw call are flushed //this function expects a vertex offset > 0 void _flush_vertices_caches_until_vertex_base (VkvgContext ctx) { - _wait_flush_fence (ctx); + _wait_flush_fence (ctx); - memcpy(ctx->vertices.allocInfo.pMappedData, ctx->vertexCache, ctx->curVertOffset * sizeof (Vertex)); - memcpy(ctx->indices.allocInfo.pMappedData, ctx->indexCache, ctx->curIndStart * sizeof (VKVG_IBO_INDEX_TYPE)); + memcpy(ctx->vertices.allocInfo.pMappedData, ctx->vertexCache, ctx->curVertOffset * sizeof (Vertex)); + memcpy(ctx->indices.allocInfo.pMappedData, ctx->indexCache, ctx->curIndStart * sizeof (VKVG_IBO_INDEX_TYPE)); - //copy remaining vertices and indices to caches starts - ctx->vertCount -= ctx->curVertOffset; - ctx->indCount -= ctx->curIndStart; - memcpy(ctx->vertexCache, &ctx->vertexCache[ctx->curVertOffset], ctx->vertCount * sizeof (Vertex)); - memcpy(ctx->indexCache, &ctx->indexCache[ctx->curIndStart], ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE)); + //copy remaining vertices and indices to caches starts + ctx->vertCount -= ctx->curVertOffset; + ctx->indCount -= ctx->curIndStart; + memcpy(ctx->vertexCache, &ctx->vertexCache[ctx->curVertOffset], ctx->vertCount * sizeof (Vertex)); + memcpy(ctx->indexCache, &ctx->indexCache[ctx->curIndStart], ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE)); - ctx->curVertOffset = 0; - ctx->curIndStart = 0; + ctx->curVertOffset = 0; + ctx->curIndStart = 0; } void _flush_vertices_caches (VkvgContext ctx) { - //copy vertex and index caches to the vbo and ibo vkbuffers - _wait_flush_fence (ctx); + //copy vertex and index caches to the vbo and ibo vkbuffers + _wait_flush_fence (ctx); - memcpy(ctx->vertices.allocInfo.pMappedData, ctx->vertexCache, ctx->vertCount * sizeof (Vertex)); - memcpy(ctx->indices.allocInfo.pMappedData, ctx->indexCache, ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE)); + memcpy(ctx->vertices.allocInfo.pMappedData, ctx->vertexCache, ctx->vertCount * sizeof (Vertex)); + memcpy(ctx->indices.allocInfo.pMappedData, ctx->indexCache, ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE)); - ctx->vertCount = ctx->indCount = ctx->curIndStart = ctx->curVertOffset = 0; + ctx->vertCount = ctx->indCount = ctx->curIndStart = ctx->curVertOffset = 0; } //this func expect cmdStarted to be true void _end_render_pass (VkvgContext ctx) { - LOG(LOG_INFO, "END RENDER PASS: ctx = %lu;\n", ctx); - CmdEndRenderPass (ctx->cmd); + LOG(VKVG_LOG_INFO, "END RENDER PASS: ctx = %p;\n", ctx); + CmdEndRenderPass (ctx->cmd); #ifdef DEBUG - vkh_cmd_label_end (ctx->cmd); + vkh_cmd_label_end (ctx->cmd); #endif - ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass; } void _record_draw_cmd (VkvgContext ctx){ - if (ctx->indCount == ctx->curIndStart) - return; - - if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){ - //vbo or ibo buffers too small - 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); - _flush_vertices_caches_until_vertex_base (ctx); - vkh_cmd_end (ctx->cmd); - _wait_and_submit_cmd (ctx); - //we could resize here - _resize_vbo(ctx, ctx->sizeVertices); - _resize_ibo(ctx, ctx->sizeIndices); - }else{ - //should resize vbo here - _resize_vbo(ctx, ctx->sizeVertices); - _resize_ibo(ctx, ctx->sizeIndices); - } - } - - _check_cmd_buff_state(ctx); - CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0); - - LOG(LOG_INFO, "RECORD DRAW CMD: ctx = %lu; vertices = %d; indices = %d (vxOff = %d idxStart = %d idxTot = %d )\n", - (uint64_t)ctx, ctx->vertCount - ctx->curVertOffset, - ctx->indCount - ctx->curIndStart, ctx->curVertOffset, ctx->curIndStart, ctx->indCount); + if (ctx->indCount == ctx->curIndStart) + return; + + if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){ + //vbo or ibo buffers too small + 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); + _flush_vertices_caches_until_vertex_base (ctx); + vkh_cmd_end (ctx->cmd); + _wait_and_submit_cmd (ctx); + //we could resize here + _resize_vbo(ctx, ctx->sizeVertices); + _resize_ibo(ctx, ctx->sizeIndices); + }else{ + //should resize vbo here + _resize_vbo(ctx, ctx->sizeVertices); + _resize_ibo(ctx, ctx->sizeIndices); + } + } + + _check_cmd_buff_state(ctx); + CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0); + + LOG(VKVG_LOG_INFO, "RECORD DRAW CMD: ctx = %p; vertices = %d; indices = %d (vxOff = %d idxStart = %d idxTot = %d )\n", + ctx, ctx->vertCount - ctx->curVertOffset, + ctx->indCount - ctx->curIndStart, ctx->curVertOffset, ctx->curIndStart, ctx->indCount); #ifdef VKVG_WIRED_DEBUG - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired); - CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0); - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired); + CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); #endif - ctx->curIndStart = ctx->indCount; - ctx->curVertOffset = ctx->vertCount; + ctx->curIndStart = ctx->indCount; + ctx->curVertOffset = ctx->vertCount; } void _flush_cmd_buff (VkvgContext ctx){ - if (!ctx->cmdStarted) - return; + if (!ctx->cmdStarted) + return; - _record_draw_cmd (ctx); - _end_render_pass (ctx); - _flush_vertices_caches (ctx); - vkh_cmd_end (ctx->cmd); + _record_draw_cmd (ctx); + _end_render_pass (ctx); + _flush_vertices_caches (ctx); + vkh_cmd_end (ctx->cmd); - LOG(LOG_INFO, "FLUSH CTX: ctx = %lu; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount); - _wait_and_submit_cmd(ctx); + LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount); + _wait_and_submit_cmd(ctx); } //bind correct draw pipeline depending on current OPERATOR void _bind_draw_pipeline (VkvgContext ctx) { - switch (ctx->curOperator) { - case VKVG_OPERATOR_OVER: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); - break; - case VKVG_OPERATOR_CLEAR: - vkvg_set_source_rgba(ctx,0,0,0,0); - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_CLEAR); - break; - default: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); - break; - } + switch (ctx->curOperator) { + case VKVG_OPERATOR_OVER: + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + break; + case VKVG_OPERATOR_CLEAR: + vkvg_set_source_rgba(ctx,0,0,0,0); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_CLEAR); + break; + default: + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + break; + } } const float LAB_COLOR_RP[4] = {0,0,1,1}; void _start_cmd_for_render_pass (VkvgContext ctx) { - LOG(LOG_INFO, "START RENDER PASS: ctx = %lu\n", ctx); - vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + LOG(VKVG_LOG_INFO, "START RENDER PASS: ctx = %p\n", ctx); + vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - if (ctx->pSurf->img->layout == VK_IMAGE_LAYOUT_UNDEFINED){ - VkhImage imgMs = ctx->pSurf->imgMS; - if (imgMs != NULL) - vkh_image_set_layout(ctx->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + if (ctx->pSurf->img->layout == VK_IMAGE_LAYOUT_UNDEFINED){ + VkhImage imgMs = ctx->pSurf->imgMS; + if (imgMs != NULL) + vkh_image_set_layout(ctx->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - vkh_image_set_layout(ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - } + vkh_image_set_layout(ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + } #ifdef DEBUG - vkh_cmd_label_start(ctx->cmd, "ctx render pass", LAB_COLOR_RP); + vkh_cmd_label_start(ctx->cmd, "ctx render pass", LAB_COLOR_RP); #endif - CmdBeginRenderPass (ctx->cmd, &ctx->renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = {0,0,ctx->pSurf->width,ctx->pSurf->height,0,1}; - CmdSetViewport(ctx->cmd, 0, 1, &viewport); + CmdBeginRenderPass (ctx->cmd, &ctx->renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + VkViewport viewport = {0,0,(float)ctx->pSurf->width,(float)ctx->pSurf->height,0,1.f}; + CmdSetViewport(ctx->cmd, 0, 1, &viewport); - CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); + CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); - VkDescriptorSet dss[] = {ctx->dsFont,ctx->dsSrc,ctx->dsGrad}; - CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLayout, - 0, 3, dss, 0, NULL); + VkDescriptorSet dss[] = {ctx->dsFont,ctx->dsSrc,ctx->dsGrad}; + CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLayout, + 0, 3, dss, 0, NULL); - VkDeviceSize offsets[1] = { 0 }; - CmdBindVertexBuffers(ctx->cmd, 0, 1, &ctx->vertices.buffer, offsets); - if (sizeof (VKVG_IBO_INDEX_TYPE) == 4) - CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VK_INDEX_TYPE_UINT32); - else - CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VK_INDEX_TYPE_UINT16); + VkDeviceSize offsets[1] = { 0 }; + CmdBindVertexBuffers(ctx->cmd, 0, 1, &ctx->vertices.buffer, offsets); +#if VKVG_IBO_INDEX_TYPE == uint16_t + CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VK_INDEX_TYPE_UINT16); +#else + CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VK_INDEX_TYPE_UINT32); +#endif - _update_push_constants (ctx); + _update_push_constants (ctx); - _bind_draw_pipeline (ctx); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + _bind_draw_pipeline (ctx); + CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - ctx->cmdStarted = true; + ctx->cmdStarted = true; } //compute inverse mat used in shader when context matrix has changed //then trigger push constants command void _set_mat_inv_and_vkCmdPush (VkvgContext ctx) { - ctx->pushConsts.matInv = ctx->pushConsts.mat; - vkvg_matrix_invert (&ctx->pushConsts.matInv); - ctx->pushCstDirty = true; + ctx->pushConsts.matInv = ctx->pushConsts.mat; + vkvg_matrix_invert (&ctx->pushConsts.matInv); + ctx->pushCstDirty = true; } void _update_push_constants (VkvgContext ctx) { - CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, - VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),&ctx->pushConsts); - ctx->pushCstDirty = false; + CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),&ctx->pushConsts); + ctx->pushCstDirty = false; } void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { - VkvgPattern lastPat = ctx->pattern; - ctx->pattern = pat; - - ctx->pushConsts.patternType = pat->type; - ctx->pushCstDirty = true; - - switch (pat->type) { - case VKVG_PATTERN_TYPE_SOLID: - memcpy (&ctx->pushConsts.source, ctx->pattern->data, sizeof(vkvg_color_t)); - - if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE){ - _flush_cmd_buff (ctx); - _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); - //_init_cmd_buff (ctx);//push csts updated by init - }//else - //_update_push_constants (ctx); - - break; - case VKVG_PATTERN_TYPE_SURFACE: - { - VkvgSurface surf = (VkvgSurface)pat->data; - - //flush ctx in two steps to add the src transitioning in the cmd buff - if (ctx->cmdStarted){//transition of img without appropriate dependencies in subpass must be done outside renderpass. - _record_draw_cmd (ctx);//ensure all vertices are flushed - _end_render_pass (ctx); - _flush_vertices_caches (ctx); - }else { - vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - ctx->cmdStarted = true; - } - - //transition source surface for sampling - vkh_image_set_layout (ctx->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - - vkh_cmd_end (ctx->cmd); - _wait_and_submit_cmd (ctx); - - ctx->source = surf->img; - - //if (vkh_image_get_sampler (ctx->source) == VK_NULL_HANDLE){ - VkSamplerAddressMode addrMode; - VkFilter filter = VK_FILTER_NEAREST; - switch (pat->extend) { - case VKVG_EXTEND_NONE: - addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; - break; - case VKVG_EXTEND_PAD: - addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - break; - case VKVG_EXTEND_REPEAT: - addrMode = VK_SAMPLER_ADDRESS_MODE_REPEAT; - break; - case VKVG_EXTEND_REFLECT: - addrMode = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - break; - } - switch (pat->filter) { - case VKVG_FILTER_BILINEAR: - case VKVG_FILTER_BEST: - filter = VK_FILTER_LINEAR; - break; - } - vkh_image_create_sampler(ctx->source, filter, filter, - VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode); - //} - /*if (vkh_image_get_layout (ctx->source) != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ - vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - - vkh_image_set_layout (ctx->cmd, ctx->source, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - vkh_cmd_end (ctx->cmd); - - _submit_wait_and_reset_cmd (ctx); - }*/ - - _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); - - vec4 srcRect = {0,0,surf->width,surf->height}; - ctx->pushConsts.source = srcRect; - - //_init_cmd_buff (ctx); - break; - } - case VKVG_PATTERN_TYPE_LINEAR: - _flush_cmd_buff (ctx); - - if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE) - _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); - - vec4 bounds = {ctx->pSurf->width, ctx->pSurf->height, 0, 0};//store img bounds in unused source field - ctx->pushConsts.source = bounds; - - //transform control point with current ctx matrix - vkvg_gradient_t grad = {0}; - memcpy(&grad, pat->data, sizeof(vkvg_gradient_t)); - - vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); - vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); - //to do, scale radial radiuses in cp[2] - - memcpy(ctx->uboGrad.allocInfo.pMappedData , &grad, sizeof(vkvg_gradient_t)); - - //_init_cmd_buff (ctx); - break; - } - - if (lastPat) - vkvg_pattern_destroy (lastPat); + VkvgPattern lastPat = ctx->pattern; + ctx->pattern = pat; + + ctx->pushConsts.patternType = pat->type; + ctx->pushCstDirty = true; + + switch (pat->type) { + case VKVG_PATTERN_TYPE_SOLID: + memcpy (&ctx->pushConsts.source, ctx->pattern->data, sizeof(vkvg_color_t)); + + if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE){ + _flush_cmd_buff (ctx); + _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); + //_init_cmd_buff (ctx);//push csts updated by init + }//else + //_update_push_constants (ctx); + + break; + case VKVG_PATTERN_TYPE_SURFACE: + { + VkvgSurface surf = (VkvgSurface)pat->data; + + //flush ctx in two steps to add the src transitioning in the cmd buff + if (ctx->cmdStarted){//transition of img without appropriate dependencies in subpass must be done outside renderpass. + _record_draw_cmd (ctx);//ensure all vertices are flushed + _end_render_pass (ctx); + _flush_vertices_caches (ctx); + }else { + vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; + } + + //transition source surface for sampling + vkh_image_set_layout (ctx->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + vkh_cmd_end (ctx->cmd); + _wait_and_submit_cmd (ctx); + + ctx->source = surf->img; + + //if (vkh_image_get_sampler (ctx->source) == VK_NULL_HANDLE){ + VkSamplerAddressMode addrMode = 0; + VkFilter filter = VK_FILTER_NEAREST; + switch (pat->extend) { + case VKVG_EXTEND_NONE: + addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + break; + case VKVG_EXTEND_PAD: + addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + break; + case VKVG_EXTEND_REPEAT: + addrMode = VK_SAMPLER_ADDRESS_MODE_REPEAT; + break; + case VKVG_EXTEND_REFLECT: + addrMode = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + break; + } + switch (pat->filter) { + case VKVG_FILTER_BILINEAR: + case VKVG_FILTER_BEST: + filter = VK_FILTER_LINEAR; + break; + default: + filter = VK_FILTER_NEAREST; + break; + } + vkh_image_create_sampler(ctx->source, filter, filter, + VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode); + //} + /*if (vkh_image_get_layout (ctx->source) != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ + vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + + vkh_image_set_layout (ctx->cmd, ctx->source, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + vkh_cmd_end (ctx->cmd); + + _submit_wait_and_reset_cmd (ctx); + }*/ + + _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); + + vec4 srcRect = {{0},{0},{(float)surf->width},{(float)surf->height}}; + ctx->pushConsts.source = srcRect; + + //_init_cmd_buff (ctx); + break; + } + case VKVG_PATTERN_TYPE_LINEAR: + _flush_cmd_buff (ctx); + + if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE) + _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); + + vec4 bounds = {{(float)ctx->pSurf->width}, {(float)ctx->pSurf->height}, {0}, {0}};//store img bounds in unused source field + ctx->pushConsts.source = bounds; + + //transform control point with current ctx matrix + vkvg_gradient_t grad = {0}; + memcpy(&grad, pat->data, sizeof(vkvg_gradient_t)); + + vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); + vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); + //to do, scale radial radiuses in cp[2] + + memcpy(ctx->uboGrad.allocInfo.pMappedData , &grad, sizeof(vkvg_gradient_t)); + + //_init_cmd_buff (ctx); + break; + } + + if (lastPat) + vkvg_pattern_destroy (lastPat); } void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){ - _wait_flush_fence(ctx);//descriptorSet update invalidate cmd buffs - VkDescriptorImageInfo descSrcTex = vkh_image_get_descriptor (img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - VkWriteDescriptorSet writeDescriptorSet = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = ds, - .dstBinding = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &descSrcTex - }; - vkUpdateDescriptorSets(ctx->pSurf->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); + _wait_flush_fence(ctx);//descriptorSet update invalidate cmd buffs + VkDescriptorImageInfo descSrcTex = vkh_image_get_descriptor (img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + VkWriteDescriptorSet writeDescriptorSet = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = ds, + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &descSrcTex + }; + vkUpdateDescriptorSets(ctx->pSurf->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); } void _update_gradient_desc_set (VkvgContext ctx){ - VkDescriptorBufferInfo dbi = {ctx->uboGrad.buffer, 0, VK_WHOLE_SIZE}; - VkWriteDescriptorSet writeDescriptorSet = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = ctx->dsGrad, - .dstBinding = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .pBufferInfo = &dbi - }; - vkUpdateDescriptorSets(ctx->pSurf->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); + VkDescriptorBufferInfo dbi = {ctx->uboGrad.buffer, 0, VK_WHOLE_SIZE}; + VkWriteDescriptorSet writeDescriptorSet = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = ctx->dsGrad, + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &dbi + }; + vkUpdateDescriptorSets(ctx->pSurf->dev->vkDev, 1, &writeDescriptorSet, 0, NULL); } /* * Reset currently bound descriptor which image could be destroyed */ /*void _reset_src_descriptor_set (VkvgContext ctx){ - VkvgDevice dev = ctx->pSurf->dev; - //VkDescriptorSet dss[] = {ctx->dsSrc}; - vkFreeDescriptorSets (dev->vkDev, ctx->descriptorPool, 1, &ctx->dsSrc); - - VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = ctx->descriptorPool, - .descriptorSetCount = 1, - .pSetLayouts = &dev->dslSrc }; - VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc)); + VkvgDevice dev = ctx->pSurf->dev; + //VkDescriptorSet dss[] = {ctx->dsSrc}; + vkFreeDescriptorSets (dev->vkDev, ctx->descriptorPool, 1, &ctx->dsSrc); + + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = ctx->descriptorPool, + .descriptorSetCount = 1, + .pSetLayouts = &dev->dslSrc }; + VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc)); }*/ void _createDescriptorPool (VkvgContext ctx) { - VkvgDevice dev = ctx->pSurf->dev; - const VkDescriptorPoolSize descriptorPoolSize[] = { - {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 }, - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1 } - }; - VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = 3, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, - .poolSizeCount = 2, - .pPoolSizes = descriptorPoolSize }; - VK_CHECK_RESULT(vkCreateDescriptorPool (dev->vkDev, &descriptorPoolCreateInfo, NULL, &ctx->descriptorPool)); + VkvgDevice dev = ctx->pSurf->dev; + const VkDescriptorPoolSize descriptorPoolSize[] = { + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 }, + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1 } + }; + VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .maxSets = 3, + .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .poolSizeCount = 2, + .pPoolSizes = descriptorPoolSize }; + VK_CHECK_RESULT(vkCreateDescriptorPool (dev->vkDev, &descriptorPoolCreateInfo, NULL, &ctx->descriptorPool)); } void _init_descriptor_sets (VkvgContext ctx){ - VkvgDevice dev = ctx->pSurf->dev; - VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = ctx->descriptorPool, - .descriptorSetCount = 1, - .pSetLayouts = &dev->dslFont }; - VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsFont)); - descriptorSetAllocateInfo.pSetLayouts = &dev->dslSrc; - VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc)); - descriptorSetAllocateInfo.pSetLayouts = &dev->dslGrad; - VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad)); + VkvgDevice dev = ctx->pSurf->dev; + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = ctx->descriptorPool, + .descriptorSetCount = 1, + .pSetLayouts = &dev->dslFont }; + VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsFont)); + descriptorSetAllocateInfo.pSetLayouts = &dev->dslSrc; + VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc)); + descriptorSetAllocateInfo.pSetLayouts = &dev->dslGrad; + VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad)); } //populate vertice buff for stroke float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bool isCurve){ - Vertex v = {{0},{0,0,-1}}; - - //if two of the three points are equal, normal is null - vec2 v0n = vec2_line_norm(pL, p0); - if (vec2_isnan(v0n)) - return 0; - vec2 v1n = vec2_line_norm(p0, pR); - if (vec2_isnan(v1n)) - return 0; - - vec2 bisec = vec2_norm(vec2_add(v0n,v1n)); - - float dot = v0n.x * v1n.x + v0n.y * v1n.y; - float alpha = acosf(dot)/2; - float cross = v0n.x * v1n.y - v0n.y * v1n.x; - - if (cross<0) - alpha = -alpha; - - float lh = hw / cosf(alpha); - bisec = vec2_perp(bisec); - bisec = vec2_mult(bisec,lh); - - VKVG_IBO_INDEX_TYPE idx = ctx->vertCount - ctx->curVertOffset; - - if (ctx->lineJoin == VKVG_LINE_JOIN_MITER || isCurve){ - v.pos = vec2_add(p0, bisec); - _add_vertex(ctx, v); - v.pos = vec2_sub(p0, bisec); - _add_vertex(ctx, v); - _add_tri_indices_for_rect(ctx, idx); - }else{ - vec2 vp = vec2_perp(v0n); - if (cross<0){ - v.pos = vec2_add (p0, bisec); - _add_vertex(ctx, v); - v.pos = vec2_sub (p0, vec2_mult (vp, hw)); - }else{ - v.pos = vec2_add (p0, vec2_mult (vp, hw)); - _add_vertex(ctx, v); - v.pos = vec2_sub (p0, bisec); - } - _add_vertex(ctx, v); - - if (ctx->lineJoin == VKVG_LINE_JOIN_BEVEL){ - if (cross<0){ - _add_triangle_indices(ctx, idx, idx+2, idx+1); - _add_triangle_indices(ctx, idx+2, idx+4, idx+0); - _add_triangle_indices(ctx, idx, idx+3, idx+4); - }else{ - _add_triangle_indices(ctx, idx, idx+2, idx+1); - _add_triangle_indices(ctx, idx+2, idx+3, idx+1); - _add_triangle_indices(ctx, idx+1, idx+3, idx+4); - } - }else if (ctx->lineJoin == VKVG_LINE_JOIN_ROUND){ - float step = M_PIF / hw; - float a = acosf(vp.x); - if (vp.y < 0) - a = -a; - - if (cross<0){ - a+=M_PIF; - float a1 = a + alpha*2; - a-=step; - while (a > a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); - a-=step; - } - }else{ - float a1 = a + alpha*2; - a+=step; - while (a < a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); - a+=step; - } - } - VKVG_IBO_INDEX_TYPE p0Idx = ctx->vertCount - ctx->curVertOffset; - _add_triangle_indices(ctx, idx, idx+2, idx+1); - if (cross<0){ - for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++) - _add_triangle_indices(ctx, p, p+1, idx); - _add_triangle_indices(ctx, p0Idx, p0Idx+2, idx); - _add_triangle_indices(ctx, idx, p0Idx+1, p0Idx+2); - }else{ - for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++) - _add_triangle_indices(ctx, p, p+1, idx+1); - _add_triangle_indices(ctx, p0Idx, p0Idx+1, idx+1); - _add_triangle_indices(ctx, idx+1, p0Idx+1, p0Idx+2); - } - - } - - vp = vec2_mult (vec2_perp(v1n), hw); - if (cross<0) - v.pos = vec2_sub (p0, vp); - else - v.pos = vec2_add (p0, vp); - _add_vertex(ctx, v); - } + Vertex v = {{0},{0,0,-1}}; + + //if two of the three points are equal, normal is null + vec2 v0n = vec2_line_norm(pL, p0); + if (vec2_isnan(v0n)) + return 0; + vec2 v1n = vec2_line_norm(p0, pR); + if (vec2_isnan(v1n)) + return 0; + + vec2 bisec = vec2_norm(vec2_add(v0n,v1n)); + + float dot = v0n.x * v1n.x + v0n.y * v1n.y; + float alpha = acosf(dot)/2; + float cross = v0n.x * v1n.y - v0n.y * v1n.x; + + if (cross<0) + alpha = -alpha; + + float lh = hw / cosf(alpha); + bisec = vec2_perp(bisec); + bisec = vec2_mult(bisec,lh); + + VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + + if (ctx->lineJoin == VKVG_LINE_JOIN_MITER || isCurve){ + v.pos = vec2_add(p0, bisec); + _add_vertex(ctx, v); + v.pos = vec2_sub(p0, bisec); + _add_vertex(ctx, v); + _add_tri_indices_for_rect(ctx, idx); + }else{ + vec2 vp = vec2_perp(v0n); + if (cross<0){ + v.pos = vec2_add (p0, bisec); + _add_vertex(ctx, v); + v.pos = vec2_sub (p0, vec2_mult (vp, hw)); + }else{ + v.pos = vec2_add (p0, vec2_mult (vp, hw)); + _add_vertex(ctx, v); + v.pos = vec2_sub (p0, bisec); + } + _add_vertex(ctx, v); + + if (ctx->lineJoin == VKVG_LINE_JOIN_BEVEL){ + if (cross<0){ + _add_triangle_indices(ctx, idx, idx+2, idx+1); + _add_triangle_indices(ctx, idx+2, idx+4, idx+0); + _add_triangle_indices(ctx, idx, idx+3, idx+4); + }else{ + _add_triangle_indices(ctx, idx, idx+2, idx+1); + _add_triangle_indices(ctx, idx+2, idx+3, idx+1); + _add_triangle_indices(ctx, idx+1, idx+3, idx+4); + } + }else if (ctx->lineJoin == VKVG_LINE_JOIN_ROUND){ + float step = M_PIF / hw; + float a = acosf(vp.x); + if (vp.y < 0) + a = -a; + + if (cross<0){ + a+=M_PIF; + float a1 = a + alpha*2; + a-=step; + while (a > a1){ + _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + a-=step; + } + }else{ + float a1 = a + alpha*2; + a+=step; + while (a < a1){ + _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + a+=step; + } + } + VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + _add_triangle_indices(ctx, idx, idx+2, idx+1); + if (cross<0){ + for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++) + _add_triangle_indices(ctx, p, p+1, idx); + _add_triangle_indices(ctx, p0Idx, p0Idx+2, idx); + _add_triangle_indices(ctx, idx, p0Idx+1, p0Idx+2); + }else{ + for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++) + _add_triangle_indices(ctx, p, p+1, idx+1); + _add_triangle_indices(ctx, p0Idx, p0Idx+1, idx+1); + _add_triangle_indices(ctx, idx+1, p0Idx+1, p0Idx+2); + } + + } + + vp = vec2_mult (vec2_perp(v1n), hw); + if (cross<0) + v.pos = vec2_sub (p0, vp); + else + v.pos = vec2_add (p0, vp); + _add_vertex(ctx, v); + } /* #ifdef DEBUG - debugLinePoints[dlpCount] = p0; - debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v0n,10))); - dlpCount+=2; - debugLinePoints[dlpCount] = p0; - debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v1n,10))); - dlpCount+=2; - debugLinePoints[dlpCount] = p0; - debugLinePoints[dlpCount+1] = pR; - dlpCount+=2; + debugLinePoints[dlpCount] = p0; + debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v0n,10))); + dlpCount+=2; + debugLinePoints[dlpCount] = p0; + debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v1n,10))); + dlpCount+=2; + debugLinePoints[dlpCount] = p0; + debugLinePoints[dlpCount+1] = pR; + dlpCount+=2; #endif*/ - return cross; + return cross; } bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { - float dX = p.x-p2.x; - float dY = p.y-p2.y; - float dX21 = p2.x-p1.x; - float dY12 = p1.y-p2.y; - float D = dY12*(p0.x-p2.x) + dX21*(p0.y-p2.y); - float s = dY12*dX + dX21*dY; - float t = (p2.y-p0.y)*dX + (p0.x-p2.x)*dY; - if (D<0) - return (s<=0) && (t<=0) && (s+t>=D); - return (s>=0) && (t>=0) && (s+t<=D); + float dX = p.x-p2.x; + float dY = p.y-p2.y; + float dX21 = p2.x-p1.x; + float dY12 = p1.y-p2.y; + float D = dY12*(p0.x-p2.x) + dX21*(p0.y-p2.y); + float s = dY12*dX + dX21*dY; + float t = (p2.y-p0.y)*dX + (p0.x-p2.x)*dY; + if (D<0) + return (s<=0) && (t<=0) && (s+t>=D); + return (s>=0) && (t>=0) && (s+t<=D); } void _free_ctx_save (vkvg_context_save_t* sav){ - if (sav->dashCount > 0) - free (sav->dashes); - free(sav->selectedFont.fontFile); - free (sav); + if (sav->dashCount > 0) + free (sav->dashes); + free(sav->selectedFont.fontFile); + free (sav); } -#define m_approximation_scale 1.0 -#define m_angle_tolerance 0.01 -#define m_distance_tolerance 1.0 -#define m_cusp_limit 0.01 -#define curve_recursion_limit 10 -#define curve_collinearity_epsilon 1.7 -#define curve_angle_tolerance_epsilon 0.001 - +#define M_APPROXIMATION_SCALE 1.0 +#define M_ANGLE_TOLERANCE 0.01 +#define M_DISTANCE_TOLERANCE 1.0 +#define M_CUSP_LIMIT 0.01 +#define CURVE_RECURSION_LIMIT 10 +#define CURVE_COLLINEARITY_EPSILON 1.7 +#define CURVE_ANGLE_TOLERANCE_EPSILON 0.001 +//no floating point arithmetic operation allowed in macro. +#pragma warning(disable:4127) void _recursive_bezier (VkvgContext ctx, - float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, - unsigned level) { - if(level > curve_recursion_limit) - { - return; - } - - // Calculate all the mid-points of the line segments - //---------------------- - float x12 = (x1 + x2) / 2; - float y12 = (y1 + y2) / 2; - float x23 = (x2 + x3) / 2; - float y23 = (y2 + y3) / 2; - float x34 = (x3 + x4) / 2; - float y34 = (y3 + y4) / 2; - float x123 = (x12 + x23) / 2; - float y123 = (y12 + y23) / 2; - float x234 = (x23 + x34) / 2; - float y234 = (y23 + y34) / 2; - float x1234 = (x123 + x234) / 2; - float y1234 = (y123 + y234) / 2; - - if(level > 0) // Enforce subdivision first time - { - // Try to approximate the full cubic curve by a single straight line - //------------------ - float dx = x4-x1; - float dy = y4-y1; - - float d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx)); - float d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx)); - - float da1, da2; - - if(d2 > curve_collinearity_epsilon && d3 > curve_collinearity_epsilon) - { - // Regular care - //----------------- - if((d2 + d3)*(d2 + d3) <= m_distance_tolerance * (dx*dx + dy*dy)) - { - // If the curvature doesn't exceed the distance_tolerance value - // we tend to finish subdivisions. - //---------------------- - if(m_angle_tolerance < curve_angle_tolerance_epsilon) - { - _add_point (ctx, x1234, y1234); - return; - } - - // Angle & Cusp Condition - //---------------------- - float a23 = atan2(y3 - y2, x3 - x2); - da1 = fabs(a23 - atan2(y2 - y1, x2 - x1)); - da2 = fabs(atan2(y4 - y3, x4 - x3) - a23); - if(da1 >= M_PIF) da1 = M_2_PI - da1; - if(da2 >= M_PIF) da2 = M_2_PI - da2; - - if(da1 + da2 < m_angle_tolerance) - { - // Finally we can stop the recursion - //---------------------- - _add_point (ctx, x1234, y1234); - return; - } - - if(m_cusp_limit != 0.0) - { - if(da1 > m_cusp_limit) - { - _add_point (ctx, x2, y2); - return; - } - - if(da2 > m_cusp_limit) - { - _add_point (ctx, x3, y3); - return; - } - } - } - } else { - if(d2 > curve_collinearity_epsilon) - { - // p1,p3,p4 are collinear, p2 is considerable - //---------------------- - if(d2 * d2 <= m_distance_tolerance * (dx*dx + dy*dy)) - { - if(m_angle_tolerance < curve_angle_tolerance_epsilon) - { - _add_point (ctx, x1234, y1234); - return; - } - - // Angle Condition - //---------------------- - da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); - if(da1 >= M_PIF) da1 = M_2_PI - da1; - - if(da1 < m_angle_tolerance) - { - _add_point (ctx, x2, y2); - _add_point (ctx, x3, y3); - return; - } - - if(m_cusp_limit != 0.0) - { - if(da1 > m_cusp_limit) - { - _add_point (ctx, x2, y2); - return; - } - } - } - } else if(d3 > curve_collinearity_epsilon) { - // p1,p2,p4 are collinear, p3 is considerable - //---------------------- - if(d3 * d3 <= m_distance_tolerance * (dx*dx + dy*dy)) - { - if(m_angle_tolerance < curve_angle_tolerance_epsilon) - { - _add_point (ctx, x1234, y1234); - return; - } - - // Angle Condition - //---------------------- - da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2)); - if(da1 >= M_PIF) da1 = M_2_PI - da1; - - if(da1 < m_angle_tolerance) - { - _add_point (ctx, x2, y2); - _add_point (ctx, x3, y3); - return; - } - - if(m_cusp_limit != 0.0) - { - if(da1 > m_cusp_limit) - { - _add_point (ctx, x3, y3); - return; - } - } - } - } - else - { - // Collinear case - //----------------- - dx = x1234 - (x1 + x4) / 2; - dy = y1234 - (y1 + y4) / 2; - if(dx*dx + dy*dy <= m_distance_tolerance) - { - _add_point (ctx, x1234, y1234); - return; - } - } - } - } - - // Continue subdivision - //---------------------- - _recursive_bezier (ctx, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); - _recursive_bezier (ctx, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + unsigned level) { + if(level > CURVE_RECURSION_LIMIT) + { + return; + } + + // Calculate all the mid-points of the line segments + //---------------------- + float x12 = (x1 + x2) / 2; + float y12 = (y1 + y2) / 2; + float x23 = (x2 + x3) / 2; + float y23 = (y2 + y3) / 2; + float x34 = (x3 + x4) / 2; + float y34 = (y3 + y4) / 2; + float x123 = (x12 + x23) / 2; + float y123 = (y12 + y23) / 2; + float x234 = (x23 + x34) / 2; + float y234 = (y23 + y34) / 2; + float x1234 = (x123 + x234) / 2; + float y1234 = (y123 + y234) / 2; + + if(level > 0) // Enforce subdivision first time + { + // Try to approximate the full cubic curve by a single straight line + //------------------ + float dx = x4-x1; + float dy = y4-y1; + + float d2 = fabsf(((x2 - x4) * dy - (y2 - y4) * dx)); + float d3 = fabsf(((x3 - x4) * dy - (y3 - y4) * dx)); + + float da1, da2; + + if(d2 > CURVE_COLLINEARITY_EPSILON && d3 > CURVE_COLLINEARITY_EPSILON) + { + // Regular care + //----------------- + if((d2 + d3)*(d2 + d3) <= (dx*dx + dy*dy) * (float)M_DISTANCE_TOLERANCE) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if (M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) { + _add_point(ctx, x1234, y1234); + return; + } + + // Angle & Cusp Condition + //---------------------- + float a23 = atan2f(y3 - y2, x3 - x2); + da1 = fabsf(a23 - atan2f(y2 - y1, x2 - x1)); + da2 = fabsf(atan2f(y4 - y3, x4 - x3) - a23); + if(da1 >= M_PIF) da1 = M_2_PIF - da1; + if(da2 >= M_PIF) da2 = M_2_PIF - da2; + + if(da1 + da2 < (float)M_ANGLE_TOLERANCE) + { + // Finally we can stop the recursion + //---------------------- + _add_point (ctx, x1234, y1234); + return; + } + + if(M_CUSP_LIMIT != 0.0) + { + if(da1 > M_CUSP_LIMIT) + { + _add_point (ctx, x2, y2); + return; + } + + if(da2 > M_CUSP_LIMIT) + { + _add_point (ctx, x3, y3); + return; + } + } + } + } else { + if(d2 > CURVE_COLLINEARITY_EPSILON) + { + // p1,p3,p4 are collinear, p2 is considerable + //---------------------- + if(d2 * d2 <= (float)M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) + { + if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) + { + _add_point (ctx, x1234, y1234); + return; + } + + // Angle Condition + //---------------------- + da1 = fabsf(atan2f(y3 - y2, x3 - x2) - atan2f(y2 - y1, x2 - x1)); + if(da1 >= M_PIF) da1 = M_2_PIF - da1; + + if(da1 < M_ANGLE_TOLERANCE) + { + _add_point (ctx, x2, y2); + _add_point (ctx, x3, y3); + return; + } + + if(M_CUSP_LIMIT != 0.0) + { + if(da1 > M_CUSP_LIMIT) + { + _add_point (ctx, x2, y2); + return; + } + } + } + } else if(d3 > CURVE_COLLINEARITY_EPSILON) { + // p1,p2,p4 are collinear, p3 is considerable + //---------------------- + if(d3 * d3 <= (float)M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) + { + if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) + { + _add_point (ctx, x1234, y1234); + return; + } + + // Angle Condition + //---------------------- + da1 = fabsf(atan2f(y4 - y3, x4 - x3) - atan2f(y3 - y2, x3 - x2)); + if(da1 >= M_PIF) da1 = M_2_PIF - da1; + + if(da1 < M_ANGLE_TOLERANCE) + { + _add_point (ctx, x2, y2); + _add_point (ctx, x3, y3); + return; + } + + if(M_CUSP_LIMIT != 0.0) + { + if(da1 > M_CUSP_LIMIT) + { + _add_point (ctx, x3, y3); + return; + } + } + } + } + else + { + // Collinear case + //----------------- + dx = x1234 - (x1 + x4) / 2; + dy = y1234 - (y1 + y4) / 2; + if(dx*dx + dy*dy <= (float)M_DISTANCE_TOLERANCE) + { + _add_point (ctx, x1234, y1234); + return; + } + } + } + } + + // Continue subdivision + //---------------------- + _recursive_bezier (ctx, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); + _recursive_bezier (ctx, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); } +#pragma warning(default:4127) + void _poly_fill (VkvgContext ctx){ - //we anticipate the check for vbo buffer size - if (ctx->vertCount + ctx->pointCount > ctx->sizeVBO) { - if (ctx->cmdStarted) { - _end_render_pass(ctx); - _flush_vertices_caches(ctx); - vkh_cmd_end(ctx->cmd); - _wait_and_submit_cmd(ctx); - if (ctx->vertCount + ctx->pointCount > ctx->sizeVBO) - _resize_vbo(ctx, ctx->vertCount + ctx->pointCount); - }else - _resize_vbo(ctx, ctx->vertCount + ctx->pointCount); - - _start_cmd_for_render_pass(ctx); - }else - _check_cmd_buff_state(ctx); - - CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelinePolyFill); - - uint32_t ptrPath = 0; - Vertex v = {{0},{0,0,-1}}; - - while (ptrPath < ctx->pathPtr){ - if (ctx->pathes[ptrPath+1]&PATH_IS_CURVE_BIT){ - ptrPath += 2; - continue; - } - //close path - ctx->pathes[ptrPath] |= PATH_CLOSED_BIT; - - uint32_t firstPtIdx = ctx->pathes [ptrPath] & PATH_ELT_MASK; - uint32_t lastPtIdx = ctx->pathes [ptrPath+1] & PATH_ELT_MASK; - uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1; - - VKVG_IBO_INDEX_TYPE firstVertIdx = ctx->vertCount; - - for (uint32_t i = 0; i < pathPointCount; i++) { - v.pos = ctx->points [i+firstPtIdx]; - ctx->vertexCache[ctx->vertCount] = v; - ctx->vertCount++; - } - - LOG(LOG_INFO_PATH, "\tpoly fill: point count = %d; 1st vert = %d; vert count = %d\n", pathPointCount, firstVertIdx, ctx->vertCount - firstVertIdx); - CmdDraw (ctx->cmd, pathPointCount, 1, firstVertIdx ,0); - - ptrPath+=2; - } - ctx->curVertOffset = ctx->vertCount; + //we anticipate the check for vbo buffer size + if (ctx->vertCount + ctx->pointCount > ctx->sizeVBO) { + if (ctx->cmdStarted) { + _end_render_pass(ctx); + _flush_vertices_caches(ctx); + vkh_cmd_end(ctx->cmd); + _wait_and_submit_cmd(ctx); + if (ctx->vertCount + ctx->pointCount > ctx->sizeVBO){ + //_resize_vertex_cache(ctx, ctx->vertCount + ctx->pointCount); + _resize_vbo(ctx, ctx->vertCount + ctx->pointCount); + } + }else{ + //_resize_vertex_cache(ctx, ctx->vertCount + ctx->pointCount); + _resize_vbo(ctx, ctx->vertCount + ctx->pointCount); + } + + _start_cmd_for_render_pass(ctx); + }else + _check_cmd_buff_state(ctx); + + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelinePolyFill); + + uint32_t ptrPath = 0; + Vertex v = {{0},{0,0,-1}}; + + while (ptrPath < ctx->pathPtr){ + if (ctx->pathes[ptrPath+1]&PATH_IS_CURVE_BIT){ + ptrPath += 2; + continue; + } + //close path + ctx->pathes[ptrPath] |= PATH_CLOSED_BIT; + + uint32_t firstPtIdx = ctx->pathes [ptrPath] & PATH_ELT_MASK; + uint32_t lastPtIdx = ctx->pathes [ptrPath+1] & PATH_ELT_MASK; + uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1; + uint32_t firstVertIdx = ctx->vertCount; + + for (uint32_t i = 0; i < pathPointCount; i++) { + v.pos = ctx->points [i+firstPtIdx]; + ctx->vertexCache[ctx->vertCount] = v; + ctx->vertCount++; + + _check_vertex_cache_size(ctx); + } + + LOG(VKVG_LOG_INFO_PATH, "\tpoly fill: point count = %d; 1st vert = %d; vert count = %d\n", pathPointCount, firstVertIdx, ctx->vertCount - firstVertIdx); + CmdDraw (ctx->cmd, pathPointCount, 1, firstVertIdx , 0); + + ptrPath+=2; + } + ctx->curVertOffset = ctx->vertCount; } void _fill_ec (VkvgContext ctx){ - uint32_t ptrPath = 0;; - Vertex v = {0}; - v.uv.z = -1; - - while (ptrPath < ctx->pathPtr){ - if (ctx->pathes[ptrPath+1]&PATH_IS_CURVE_BIT){ - ptrPath += 2; - continue; - } - ctx->pathes[ptrPath]|=PATH_CLOSED_BIT;//close path - - uint32_t firstPtIdx = ctx->pathes[ptrPath]&PATH_ELT_MASK; - uint32_t lastPtIdx = ctx->pathes[ptrPath+1]&PATH_ELT_MASK; - uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1; - uint32_t firstVertIdx = ctx->vertCount-ctx->curVertOffset; - - ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point)); - uint32_t ecps_count = pathPointCount; - uint32_t i = 0; - - //init points link list - while (i < pathPointCount-1){ - v.pos = ctx->points[i+firstPtIdx]; - ear_clip_point ecp = {v.pos, i+firstVertIdx, &ecps[i+1]}; - ecps[i] = ecp; - _add_vertex(ctx, v); - i++; - } - - v.pos = ctx->points[i+firstPtIdx]; - ear_clip_point ecp = {v.pos, i+firstVertIdx, ecps}; - ecps[i] = ecp; - _add_vertex(ctx, v); - - ear_clip_point* ecp_current = ecps; - uint32_t tries = 0; - - while (ecps_count > 3) { - if (tries > ecps_count) { - break; - } - ear_clip_point* v0 = ecp_current->next, - *v1 = ecp_current, *v2 = ecp_current->next->next; - if (ecp_zcross (v0, v2, v1)<0){ - ecp_current = ecp_current->next; - tries++; - continue; - } - ear_clip_point* vP = v2->next; - bool isEar = true; - while (vP!=v1){ - if (ptInTriangle (vP->pos, v0->pos, v2->pos, v1->pos)){ - isEar = false; - break; - } - vP = vP->next; - } - if (isEar){ - _add_triangle_indices (ctx, v0->idx, v1->idx, v2->idx); - v1->next = v2; - ecps_count --; - tries = 0; - }else{ - ecp_current = ecp_current->next; - tries++; - } - } - if (ecps_count == 3) - _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx); - - ptrPath+=2; - free (ecps); - } - _record_draw_cmd(ctx); + uint32_t ptrPath = 0;; + Vertex v = {0}; + v.uv.z = -1; + + while (ptrPath < ctx->pathPtr){ + if (ctx->pathes[ptrPath+1] & PATH_IS_CURVE_BIT){ + ptrPath += 2; + continue; + } + ctx->pathes[ptrPath] |= PATH_CLOSED_BIT;//close path + + uint32_t firstPtIdx = ctx->pathes[ptrPath] &PATH_ELT_MASK; + uint32_t lastPtIdx = ctx->pathes[ptrPath+1]&PATH_ELT_MASK; + uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1; + VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + + ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point)); + uint32_t ecps_count = pathPointCount; + VKVG_IBO_INDEX_TYPE i = 0; + + //init points link list + while (i < pathPointCount-1){ + v.pos = ctx->points[i+firstPtIdx]; + ear_clip_point ecp = {v.pos, firstVertIdx+i, &ecps[i+1]}; + ecps[i] = ecp; + _add_vertex(ctx, v); + i++; + } + + v.pos = ctx->points[i+firstPtIdx]; + ear_clip_point ecp = {v.pos, firstVertIdx+i, ecps}; + ecps[i] = ecp; + _add_vertex(ctx, v); + + ear_clip_point* ecp_current = ecps; + uint32_t tries = 0; + + while (ecps_count > 3) { + if (tries > ecps_count) { + break; + } + ear_clip_point* v0 = ecp_current->next, + *v1 = ecp_current, *v2 = ecp_current->next->next; + if (ecp_zcross (v0, v2, v1)<0){ + ecp_current = ecp_current->next; + tries++; + continue; + } + ear_clip_point* vP = v2->next; + bool isEar = true; + while (vP!=v1){ + if (ptInTriangle (vP->pos, v0->pos, v2->pos, v1->pos)){ + isEar = false; + break; + } + vP = vP->next; + } + if (isEar){ + _add_triangle_indices (ctx, v0->idx, v1->idx, v2->idx); + v1->next = v2; + ecps_count --; + tries = 0; + }else{ + ecp_current = ecp_current->next; + tries++; + } + } + if (ecps_count == 3) + _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx); + + ptrPath+=2; + free (ecps); + } + _record_draw_cmd(ctx); } static const uint32_t one = 1; static const uint32_t zero = 0; void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) { - if (ctx->xMin < 0 || ctx->yMin < 0) - useScissor = false; - if (useScissor && ctx->xMin < FLT_MAX) { - VkRect2D r = {{ctx->xMin, ctx->yMin}, {ctx->xMax - ctx->xMin + 1, ctx->yMax - ctx->yMin + 1}}; - CmdSetScissor(ctx->cmd, 0, 1, &r); - } - CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, - VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&one); - CmdDraw (ctx->cmd,3,1,0,0); - CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, - VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&zero); - if (useScissor && ctx->xMin < FLT_MAX) - CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); + if (ctx->xMin < 0 || ctx->yMin < 0) + useScissor = false; + if (useScissor && ctx->xMin < FLT_MAX) { + VkRect2D r = {{(int32_t)ctx->xMin, (int32_t)ctx->yMin}, {(int32_t)ctx->xMax - (int32_t)ctx->xMin + 1, (int32_t)ctx->yMax - (int32_t)ctx->yMin + 1}}; + CmdSetScissor(ctx->cmd, 0, 1, &r); + } + CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&one); + CmdDraw (ctx->cmd,3,1,0,0); + CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&zero); + if (useScissor && ctx->xMin < FLT_MAX) + CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 3e34722..5e5b548 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -36,138 +36,139 @@ #define VKVG_IBO_INDEX_TYPE uint16_t typedef struct{ - vec2 pos; - vec3 uv; + vec2 pos; + vec3 uv; }Vertex; typedef struct { - vec4 source; - vec2 size; - uint32_t patternType; - uint32_t fullScreenQuad; - vkvg_matrix_t mat; - vkvg_matrix_t matInv; + vec4 source; + vec2 size; + uint32_t patternType; + uint32_t fullScreenQuad; + vkvg_matrix_t mat; + vkvg_matrix_t matInv; }push_constants; typedef struct _vkvg_context_save_t{ - struct _vkvg_context_save_t* pNext; + struct _vkvg_context_save_t* pNext; - float lineWidth; - 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. + float lineWidth; + 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 lineJoint; - vkvg_fill_rule_t curFillRule; + vkvg_operator_t curOperator; + vkvg_line_cap_t lineCap; + vkvg_line_join_t lineJoint; + vkvg_fill_rule_t curFillRule; - _vkvg_font_t selectedFont; //hold current face and size before cache addition - _vkvg_font_t* currentFont; //font ready for lookup - vkvg_direction_t textDirection; - push_constants pushConsts; - VkvgPattern pattern; + _vkvg_font_t selectedFont; //hold current face and size before cache addition + _vkvg_font_t* currentFont; //font ready for lookup + vkvg_direction_t textDirection; + push_constants pushConsts; + VkvgPattern pattern; }vkvg_context_save_t; typedef struct _vkvg_context_t { - VkvgContext pPrev; //double linked list of contexts - VkvgContext pNext; - uint32_t references; //reference count - - VkvgSurface pSurf; //surface bound to context, set on creation of ctx - VkFence flushFence; //context fence - VkhImage source; //source of painting operation - - VkCommandPool cmdPool; //local pools ensure thread safety - VkCommandBuffer cmdBuffers[2];//double cmd buff for context operations - VkCommandBuffer cmd; //current recording buffer - bool cmdStarted; //prevent flushing empty renderpass - bool pushCstDirty;//prevent pushing to gpu if not requested - VkDescriptorPool descriptorPool;//one pool per thread - VkDescriptorSet dsFont; //fonts glyphs texture atlas descriptor (local for thread safety) - VkDescriptorSet dsSrc; //source ds - VkDescriptorSet dsGrad; //gradient uniform buffer - - VkRect2D bounds; - - float xMin; - float xMax; - float yMin; - float yMax; - - vkvg_buff uboGrad; //uniform buff obj holdings gradient infos - - //vk buffers, holds data until flush - vkvg_buff indices; //index buffer with persistent map memory - size_t sizeIBO; //size of vk ibo size - size_t sizeIndices; //reserved size - VKVG_IBO_INDEX_TYPE indCount; //current indice count - - VKVG_IBO_INDEX_TYPE curIndStart; //last index recorded in cmd buff - VKVG_IBO_INDEX_TYPE curVertOffset; //vertex offset in draw indexed command - - vkvg_buff vertices; //vertex buffer with persistent mapped memory - size_t sizeVBO; //size of vk vbo size - size_t sizeVertices; //reserved size - VKVG_IBO_INDEX_TYPE vertCount; //effective vertices count - - Vertex* vertexCache; - VKVG_IBO_INDEX_TYPE* indexCache; - - //pathes, exists until stroke of fill - vec2* points; //points array - size_t sizePoints; //reserved size - uint32_t pointCount; //effective points count - - //pathes array is a list of couple (start,end) point idx refering to point array - //it split points list in subpathes and tell if path is closed. - uint32_t pathPtr; //pointer in the path array, even=start point;odd=end point - uint32_t* pathes; - size_t sizePathes; - - //if current path contains curves, curve's start/end points are store next to the path start/stop - //curve start point = pathPtr + curvePtr - //when closing of finishing path, pathPtr is incremented by 1 + pathPtr - //note:number of pathes can no longer be computed from pathPtr/2, the array contains now curves datas - uint32_t curvePtr; - - float lineWidth; - 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; - - _vkvg_font_t selectedFont; //hold current face and size before cache addition - _vkvg_font_t* currentFont; //font pointing to cached fonts ready for lookup - vkvg_direction_t textDirection; - - push_constants pushConsts; - VkvgPattern pattern; - vkvg_status_t status; - - 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 - - VkClearRect clearRect; - VkRenderPassBeginInfo renderPassBeginInfo; + VkvgContext pPrev; //double linked list of contexts + VkvgContext pNext; + uint32_t references; //reference count + + VkvgSurface pSurf; //surface bound to context, set on creation of ctx + VkFence flushFence; //context fence + VkhImage source; //source of painting operation + + VkCommandPool cmdPool; //local pools ensure thread safety + VkCommandBuffer cmdBuffers[2];//double cmd buff for context operations + VkCommandBuffer cmd; //current recording buffer + bool cmdStarted; //prevent flushing empty renderpass + bool pushCstDirty;//prevent pushing to gpu if not requested + VkDescriptorPool descriptorPool;//one pool per thread + VkDescriptorSet dsFont; //fonts glyphs texture atlas descriptor (local for thread safety) + VkDescriptorSet dsSrc; //source ds + VkDescriptorSet dsGrad; //gradient uniform buffer + + VkRect2D bounds; + + float xMin; + float xMax; + float yMin; + float yMax; + + vkvg_buff uboGrad; //uniform buff obj holdings gradient infos + + //vk buffers, holds data until flush + vkvg_buff indices; //index buffer with persistent map memory + uint32_t sizeIBO; //size of vk ibo size + uint32_t sizeIndices; //reserved size + uint32_t indCount; //current indice count + + uint32_t curIndStart; //last index recorded in cmd buff + uint32_t curVertOffset; //vertex offset in draw indexed command + + vkvg_buff 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 + + Vertex* vertexCache; + VKVG_IBO_INDEX_TYPE* indexCache; + + //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 couple (start,end) point idx refering to point array + //it split points list in subpathes and tell if path is closed. + uint32_t pathPtr; //pointer in the path array, even=start point;odd=end point + uint32_t* pathes; + uint32_t sizePathes; + + //if current path contains curves, curve's start/end points are store next to the path start/stop + //curve start point = pathPtr + curvePtr + //when closing of finishing path, pathPtr is incremented by 1 + pathPtr + //note:number of pathes can no longer be computed from pathPtr/2, the array contains now curves datas + uint32_t curvePtr; + + float lineWidth; + 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; + + _vkvg_font_t selectedFont; //hold current face and size before cache addition + _vkvg_font_t* currentFont; //font pointing to cached fonts ready for lookup + vkvg_direction_t textDirection; + + push_constants pushConsts; + VkvgPattern pattern; + vkvg_status_t status; + + 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 + + VkClearRect clearRect; + VkRenderPassBeginInfo renderPassBeginInfo; }vkvg_context; typedef struct _ear_clip_point{ - vec2 pos; - uint32_t idx; - struct _ear_clip_point* next; + vec2 pos; + VKVG_IBO_INDEX_TYPE idx; + struct _ear_clip_point* next; }ear_clip_point; void _check_flush_needed (VkvgContext ctx); -void _check_vbo_size (VkvgContext ctx); -void _check_ibo_size (VkvgContext ctx); +void _check_vertex_cache_size(VkvgContext ctx); +void _resize_vertex_cache (VkvgContext ctx, uint32_t newSize); +void _check_index_cache_size(VkvgContext ctx); void _check_pathes_array (VkvgContext ctx); bool _current_path_is_empty (VkvgContext ctx); @@ -223,16 +224,16 @@ void _update_gradient_desc_set(VkvgContext ctx); void _free_ctx_save (vkvg_context_save_t* sav); static inline float vec2_zcross (vec2 v1, vec2 v2){ - return v1.x*v2.y-v1.y*v2.x; + return v1.x*v2.y-v1.y*v2.x; } static inline float ecp_zcross (ear_clip_point* p0, ear_clip_point* p1, ear_clip_point* p2){ - return vec2_zcross (vec2_sub (p1->pos, p0->pos), vec2_sub (p2->pos, p0->pos)); + return vec2_zcross (vec2_sub (p1->pos, p0->pos), vec2_sub (p2->pos, p0->pos)); } void _recursive_bezier(VkvgContext ctx, - float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, - unsigned level); + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + unsigned level); void _bezier (VkvgContext ctx, - float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4); + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4); #endif diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 2f8eb1d..e680890 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -52,7 +52,7 @@ VkvgDevice vkvg_device_create(VkInstance inst, VkPhysicalDevice phy, VkDevice vk */ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve) { - LOG(LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex); + LOG(VKVG_LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex); VkvgDevice dev = (vkvg_device*)malloc(sizeof(vkvg_device)); @@ -68,7 +68,7 @@ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, VkImageTiling tiling; if (!_get_best_image_tiling (dev, format, &tiling)) { dev->status = VKVG_STATUS_INVALID_FORMAT; - LOG(LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format); + LOG(VKVG_LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format); return dev; } @@ -77,7 +77,7 @@ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL); dev->phyMemProps = phyInfos->memProps; - dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex, phyInfos->queues[qFamIdx].queueFlags); + dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex); MUTEX_INIT (&dev->gQMutex); vkh_phyinfo_destroy (phyInfos); @@ -145,7 +145,7 @@ void vkvg_device_destroy (VkvgDevice dev) if (dev->references > 0) return; - LOG(LOG_INFO, "DESTROY Device\n"); + LOG(VKVG_LOG_INFO, "DESTROY Device\n"); vkh_image_destroy (dev->emptyImg); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index feeda56..25d3ccf 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -26,6 +26,8 @@ #include "vkvg_context_internal.h" #include "shaders.h" +uint8_t vkvg_log_level = VKVG_LOG_ERR; + void _flush_all_contexes (VkvgDevice dev){ VkvgContext next = dev->lastCtx; while (next != NULL){ @@ -249,8 +251,11 @@ void _setupPipelines(VkvgDevice dev) .pVertexBindingDescriptions = &vertexInputBinding, .vertexAttributeDescriptionCount = 2, .pVertexAttributeDescriptions = vertexInputAttributs }; - +#ifdef VKVG_WIRED_DEBUG VkShaderModule modVert, modFrag, modFragWired; +#else + VkShaderModule modVert, modFrag; +#endif VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, .pCode = (uint32_t*)vkvg_main_vert_spv, .codeSize = vkvg_main_vert_spv_len }; diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index c38c303..7e87fc3 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -222,7 +222,7 @@ void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) { vkResetCommandBuffer(cache->cmd,0); vkResetFences (dev->vkDev,1,&cache->uploadFence); - memcpy(cache->buff.allocInfo.pMappedData, cache->hostBuff, (uint64_t)(f->curLine.height * FONT_PAGE_SIZE * cache->texPixelSize)); + memcpy(cache->buff.allocInfo.pMappedData, cache->hostBuff, (uint64_t)f->curLine.height * FONT_PAGE_SIZE * cache->texPixelSize); vkh_cmd_begin (cache->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); @@ -250,7 +250,7 @@ void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) { f->curLine.penX += cache->stagingX; cache->stagingX = 0; - memset(cache->hostBuff, 0, FONT_PAGE_SIZE * FONT_PAGE_SIZE * cache->texPixelSize); + memset(cache->hostBuff, 0, (uint64_t)FONT_PAGE_SIZE * FONT_PAGE_SIZE * cache->texPixelSize); } //create a new char entry and put glyph in stagging buffer, ready for upload. _char_ref* _prepare_char (VkvgDevice dev, _vkvg_font_t* f, FT_UInt gindex){ @@ -278,8 +278,8 @@ _char_ref* _prepare_char (VkvgDevice dev, _vkvg_font_t* f, FT_UInt gindex){ } int penX = dev->fontCache->stagingX; - for(int y=0; ycurLine.penX) / (float)FONT_PAGE_SIZE, (float)f->curLine.penY / (float)FONT_PAGE_SIZE, - bmpWidth, - bmp.rows}; + (float)bmpWidth, + (float)bmp.rows}; cr->bounds = uvBounds; cr->pageIdx = f->curLine.pageIdx; cr->bmpDiff.x = (int16_t)slot->bitmap_left; @@ -332,7 +332,7 @@ void _select_font_face (VkvgContext ctx, const char* name){ { if (FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile) == FcResultMatch){ memset (ctx->selectedFont.fontFile, 0, FONT_FILE_NAME_MAX_SIZE); - strcpy(ctx->selectedFont.fontFile, fontFile); + memcpy (ctx->selectedFont.fontFile, fontFile, FONT_FILE_NAME_MAX_SIZE); } } FcPatternDestroy(pat); @@ -371,7 +371,7 @@ void _update_current_font (VkvgContext ctx) { if (nf.charSize == 0) nf.charSize = defaultFontCharSize; - nf.fontFile = (char*)calloc(strlen(ctx->selectedFont.fontFile),sizeof(char)); + nf.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); strcpy (nf.fontFile, ctx->selectedFont.fontFile); FT_CHECK_RESULT(FT_New_Face(cache->library, nf.fontFile, 0, &nf.face)); @@ -397,13 +397,14 @@ hb_buffer_t * _get_hb_buffer (_vkvg_font_t* font, const char* text) { const char *lng = "fr"; hb_script_t script = HB_SCRIPT_LATIN; - script = hb_script_from_string (text, strlen (text)); + script = hb_script_from_string (text, (int)strlen (text)); + hb_direction_t dir = hb_script_get_horizontal_direction(script); //dir = HB_DIRECTION_TTB; hb_buffer_set_direction (buf, dir); hb_buffer_set_script (buf, script); - hb_buffer_set_language (buf, hb_language_from_string(lng,strlen(lng))); - hb_buffer_add_utf8 (buf, text, strlen(text), 0, strlen(text)); + hb_buffer_set_language (buf, hb_language_from_string (lng, (int)strlen(lng))); + hb_buffer_add_utf8 (buf, text, (int)strlen(text), 0, (int)strlen(text)); hb_shape (font->hb_font, buf, NULL, 0); return buf; @@ -415,11 +416,11 @@ void _font_extents (VkvgContext ctx, vkvg_font_extents_t *extents) { //TODO: ensure correct metrics are returned (scalled/unscalled, etc..) FT_BBox* bbox = &ctx->currentFont->face->bbox; FT_Size_Metrics* metrics = &ctx->currentFont->face->size->metrics; - extents->ascent = FT_MulFix(ctx->currentFont->face->ascender, metrics->y_scale) >> 6;//metrics->ascender >> 6; - extents->descent= FT_MulFix(ctx->currentFont->face->descender, metrics->y_scale) >> 6;//metrics->descender >> 6; - extents->height = FT_MulFix(ctx->currentFont->face->height, metrics->y_scale) >> 6;//metrics->height >> 6; - extents->max_x_advance = bbox->xMax >> 6; - extents->max_y_advance = bbox->yMax >> 6; + extents->ascent = (float)(FT_MulFix(ctx->currentFont->face->ascender, metrics->y_scale) >> 6);//metrics->ascender >> 6; + extents->descent= (float)(FT_MulFix(ctx->currentFont->face->descender, metrics->y_scale) >> 6);//metrics->descender >> 6; + extents->height = (float)(FT_MulFix(ctx->currentFont->face->height, metrics->y_scale) >> 6);//metrics->height >> 6; + extents->max_x_advance = (float)(bbox->xMax >> 6); + extents->max_y_advance = (float)(bbox->yMax >> 6); } //compute text extends for provided string. void _text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t *extents) { @@ -447,12 +448,12 @@ void _create_text_run (VkvgContext ctx, const char* text, VkvgText textRun) { string_width_in_pixels += textRun->glyph_pos[i].x_advance >> 6; FT_Size_Metrics* metrics = &ctx->currentFont->face->size->metrics; - textRun->extents.x_advance = string_width_in_pixels; - textRun->extents.y_advance = textRun->glyph_pos[textRun->glyph_count-1].y_advance >> 6; - textRun->extents.x_bearing = -(textRun->glyph_pos[0].x_offset >> 6); - textRun->extents.y_bearing = -(textRun->glyph_pos[0].y_offset >> 6); + textRun->extents.x_advance = (float)string_width_in_pixels; + textRun->extents.y_advance = (float)(textRun->glyph_pos[textRun->glyph_count-1].y_advance >> 6); + textRun->extents.x_bearing = -(float)(textRun->glyph_pos[0].x_offset >> 6); + textRun->extents.y_bearing = -(float)(textRun->glyph_pos[0].y_offset >> 6); - textRun->extents.height = FT_MulFix(ctx->currentFont->face->height, metrics->y_scale) >> 6;// (metrics->ascender + metrics->descender) >> 6; + textRun->extents.height = (float)(FT_MulFix(ctx->currentFont->face->height, metrics->y_scale) >> 6);// (metrics->ascender + metrics->descender) >> 6; textRun->extents.width = textRun->extents.x_advance; } void _destroy_text_run (VkvgText textRun) { @@ -468,7 +469,7 @@ void _show_text_run (VkvgContext ctx, VkvgText tr) { if (!_current_path_is_empty(ctx)) pen = _get_current_position(ctx); - for (int i=0; i < glyph_count; ++i) { + for (uint32_t i=0; i < glyph_count; ++i) { _char_ref* cr = tr->font->charLookup[glyph_info[i].codepoint]; if (cr==NULL) @@ -482,7 +483,7 @@ void _show_text_run (VkvgContext ctx, VkvgText tr) { pen.y - cr->bmpDiff.y + (tr->glyph_pos[i].y_offset >> 6)}; v.pos = p0; - uint32_t firstIdx = ctx->vertCount - ctx->curVertOffset; + VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); v.uv.x = cr->bounds.x; v.uv.y = cr->bounds.y; @@ -524,7 +525,7 @@ void _show_texture (vkvg_context* ctx){ {{FONT_PAGE_SIZE,FONT_PAGE_SIZE}, {1,1,0}} }; - int i = ctx->vertCount; + VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)ctx->vertCount; _add_vertex(ctx,vs[0]); _add_vertex(ctx,vs[1]); diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index d925545..87c4b94 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -22,6 +22,9 @@ #ifndef VKVG_FONTS_H #define VKVG_FONTS_H + //disable warning on iostream functions on windows +#define _CRT_SECURE_NO_WARNINGS + #include #include FT_FREETYPE_H @@ -38,6 +41,11 @@ #define FONT_CACHE_INIT_LAYERS 2 #define FONT_FILE_NAME_MAX_SIZE 256 +#include "vkvg_internal.h" +#include "vkvg.h" +#include "vkvg_buff.h" +#include "vkh.h" + #define FT_CHECK_RESULT(f) \ { \ FT_Error res = (f); \ @@ -48,11 +56,6 @@ } \ } -#include "vkvg_internal.h" -#include "vkvg.h" -#include "vkvg_buff.h" -#include "vkh.h" - //texture coordinates of one character in font cache array texture. typedef struct { vec4 bounds; /* normalized float bounds of character bitmap in font cache texture. */ diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index 1922614..1674e05 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -22,6 +22,9 @@ #ifndef VKVG_INTERNAL_H #define VKVG_INTERNAL_H + //disable warning on iostream functions on windows +#define _CRT_SECURE_NO_WARNINGS + #include #include #include @@ -34,6 +37,7 @@ #define M_PIF 3.14159265358979323846f /* float pi */ #define M_PIF_2 1.57079632679489661923f +#define M_2_PIF 0.63661977236758134308f // 2/pi /*#ifndef M_2_PI #define M_2_PI 0.63661977236758134308 // 2/pi diff --git a/src/vkvg_matrix.c b/src/vkvg_matrix.c index c34c53c..109b914 100644 --- a/src/vkvg_matrix.c +++ b/src/vkvg_matrix.c @@ -123,19 +123,19 @@ void vkvg_matrix_invert (vkvg_matrix_t *matrix) matrix->x0 = -matrix->x0; matrix->y0 = -matrix->y0; - if (matrix->xx != 1.) { + if (matrix->xx != 1.f) { if (matrix->xx == 0.) return; - matrix->xx = 1. / matrix->xx; + matrix->xx = 1.f / matrix->xx; matrix->x0 *= matrix->xx; } - if (matrix->yy != 1.) { + if (matrix->yy != 1.f) { if (matrix->yy == 0.) return; - matrix->yy = 1. / matrix->yy; + matrix->yy = 1.f / matrix->yy; matrix->y0 *= matrix->yy; } @@ -191,8 +191,8 @@ void vkvg_matrix_init_rotate (vkvg_matrix_t *matrix, float radians) float s; float c; - s = sin (radians); - c = cos (radians); + s = sinf (radians); + c = cosf (radians); vkvg_matrix_init (matrix, c, s, diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index a106618..9f07a71 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -326,7 +326,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, VkClearRect cr = {{{0,0},{surf->width,surf->height}},0,1}; vkCmdClearAttachments(ctx->cmd, 1, &ca, 1, &cr);*/ - vec4 srcRect = {.x=0,.y=0,.width=surf->width,.height=surf->height}; + vec4 srcRect = {.x=0,.y=0,.width=(float)surf->width,.height=(float)surf->height}; ctx->pushConsts.source = srcRect; ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE; @@ -370,6 +370,10 @@ void _svg_set_color (VkvgContext ctx, uint32_t c, float alpha) { } VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) { + if (svg == NULL) { + LOG(VKVG_LOG_ERR, "nsvg error"); + return NULL; + } VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT); if (!surf) return NULL; @@ -393,16 +397,16 @@ VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) { } VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath) { - return _svg_load(dev, nsvgParseFromFile(filePath, "px", dev->hdpi)); + return _svg_load(dev, nsvgParseFromFile(filePath, "px", (float)dev->hdpi)); } VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, char* fragment) { - return _svg_load(dev, nsvgParse(fragment, "px", dev->hdpi)); + return _svg_load(dev, nsvgParse(fragment, "px", (float)dev->hdpi)); } NSVGimage* nsvg_load_file (VkvgDevice dev, const char* filePath) { - return nsvgParseFromFile(filePath, "px", dev->hdpi); + return nsvgParseFromFile(filePath, "px", (float)dev->hdpi); } NSVGimage* nsvg_load (VkvgDevice dev, char* fragment) { - return nsvgParse (fragment, "px", dev->hdpi); + return nsvgParse (fragment, "px", (float)dev->hdpi); } void nsvg_destroy (NSVGimage* svg) { nsvgDelete(svg); diff --git a/tests/arcs.c b/tests/arcs.c index 6a3c56c..daeb48c 100644 --- a/tests/arcs.c +++ b/tests/arcs.c @@ -1,91 +1,91 @@ #include "test.h" void draw_growing_circles (VkvgContext ctx, float y, int count) { - float x = 2; - for (int i=1; irenderer; vkengine_set_key_callback (e, key_callback); vkengine_set_mouse_but_callback(e, mouse_button_callback); @@ -150,51 +159,9 @@ void init_test (uint32_t width, uint32_t height){ vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); } -void run_test_func (void(*testfunc)(void),uint32_t width, uint32_t height) { - bool deferredResolve = false; - VkhPresenter r = e->renderer; - - double start_time, stop_time, run_time, run_total = 0.0, min_run_time = -1, max_run_time; - double* run_time_values = (double*)malloc(iterations*sizeof(double)); - - int i = 0; - - while (!vkengine_should_close (e) && i < iterations) { - glfwPollEvents(); - - start_time = get_tick(); - - if (!paused) - testfunc(); - - if (deferredResolve) - vkvg_multisample_surface_resolve(surf); - if (!vkh_presenter_draw (r)) - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); - - stop_time = get_tick(); - run_time = stop_time - start_time; - run_time_values[i] = run_time; - - if (min_run_time < 0) - min_run_time = run_time; - else - min_run_time = MIN(run_time, min_run_time); - max_run_time = MAX(run_time, max_run_time); - run_total += run_time; - i++; - } - double avg_run_time = run_total / (double)i; - double med_run_time = median_run_time (run_time_values, i); - double standard_dev = standard_deviation (run_time_values, i, avg_run_time); - double avg_frames_per_second = (1.0 / avg_run_time); - avg_frames_per_second = (avg_frames_per_second<9999) ? avg_frames_per_second:9999; - - free (run_time_values); +// printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); - printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); -} void clear_test () { vkDeviceWaitIdle(e->dev->dev); @@ -208,10 +175,30 @@ void clear_test () { VkvgSurface* surfaces; #endif -void perform_test (void(*testfunc)(void), const char *testName, uint32_t width, uint32_t height) { +void perform_test (void(*testfunc)(void), const char *testName, int argc, char* argv[]) { + //init random gen + struct timeval currentTime; + gettimeofday(¤tTime, NULL); + srand((unsigned) currentTime.tv_usec); + //dumpLayerExts(); + if (argc > 1) + iterations = atoi (argv[1]); + if (argc > 2) + test_size = atoi (argv[2]); + if (iterations == 0 || test_size == 0) { + printf("usage: test [iterations] [size]\n"); + return; + } + + char* whoami; + (whoami = strrchr(argv[0], '/')) ? ++whoami : (whoami = argv[0]); + + if (test_vsync) + e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height); + else + e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, test_width, test_height); - e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, width, height); VkhPresenter r = e->renderer; vkengine_set_key_callback (e, key_callback); vkengine_set_mouse_but_callback(e, mouse_button_callback); @@ -229,15 +216,15 @@ void perform_test (void(*testfunc)(void), const char *testName, uint32_t width, for (uint32_t i=0; i < r->imgCount;i++) surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]); #else - surf = vkvg_surface_create(device, width, height); - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); + surf = vkvg_surface_create(device, test_width, test_height); + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height); #endif double start_time = 0.0, stop_time = 0.0, run_time = 0.0, run_total = 0.0, min_run_time = -1, max_run_time = 0.0; double* run_time_values = (double*)malloc(iterations*sizeof(double)); - int i = 0; + uint32_t i = 0; vkengine_set_title(e, testName); @@ -277,8 +264,14 @@ void perform_test (void(*testfunc)(void), const char *testName, uint32_t width, if (deferredResolve) vkvg_multisample_surface_resolve(surf); - if (!vkh_presenter_draw (r)) - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); + if (!vkh_presenter_draw (r)){ + vkh_presenter_get_size (r, &test_width, &test_height); + vkvg_surface_destroy (surf); + surf = vkvg_surface_create(device, test_width, test_height); + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height); + vkDeviceWaitIdle(r->dev->dev); + continue; + } #endif if (paused) @@ -305,7 +298,13 @@ void perform_test (void(*testfunc)(void), const char *testName, uint32_t width, free (run_time_values); - printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); + + //printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); + printf ("| %-15s | %-25s | ",whoami + 5, testName); + printf ("%4d | %4d | %7.2f | %6.5f | %6.5f | %6.5f |\n", + test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); + + //printf ("%s size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", whoami+5, test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); vkDeviceWaitIdle(e->dev->dev); @@ -322,3 +321,107 @@ void perform_test (void(*testfunc)(void), const char *testName, uint32_t width, vkengine_destroy (e); } +const int star_points[11][2] = { + { 0, 85 }, + { 75, 75 }, + { 100, 10 }, + { 125, 75 }, + { 200, 85 }, + { 150, 125 }, + { 160, 190 }, + { 100, 150 }, + { 40, 190 }, + { 50, 125 }, + { 0, 85 } +}; + +void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact) { + float w = (float)test_width; + float h = (float)test_height; + + float x, y, z, v, r; + + randomize_color (ctx); + + switch (shape) { + case SHAPE_LINE: + x = (float)rand()/RAND_MAX * w; + y = (float)rand()/RAND_MAX * h; + z = (float)rand()/RAND_MAX * w; + v = (float)rand()/RAND_MAX * h; + + vkvg_move_to(ctx, x, y); + vkvg_line_to(ctx, z, v); + vkvg_stroke(ctx); + break; + case SHAPE_RECTANGLE: + z = truncf((sizeFact*w*rand()/RAND_MAX)+1.f); + v = truncf((sizeFact*h*rand()/RAND_MAX)+1.f); + x = truncf((w-z)*rand()/RAND_MAX); + y = truncf((h-v)*rand()/RAND_MAX); + + vkvg_rectangle(ctx, x+1, y+1, z, v); + break; + case SHAPE_ROUNDED_RECTANGLE: + z = truncf((sizeFact*w*rand()/RAND_MAX)+1.f); + v = truncf((sizeFact*h*rand()/RAND_MAX)+1.f); + x = truncf((w-z)*rand()/RAND_MAX); + y = truncf((h-v)*rand()/RAND_MAX); + r = truncf((0.2f*z*rand()/RAND_MAX)+1.f); + + if ((r > v / 2) || (r > z / 2)) + r = MIN(v / 2, z / 2); + + vkvg_move_to(ctx, x, y + r); + vkvg_arc(ctx, x + r, y + r, r, (float)M_PI, (float)-M_PI_2); + vkvg_line_to(ctx, x + z - r, y); + vkvg_arc(ctx, x + z - r, y + r, r, (float)-M_PI_2, 0); + vkvg_line_to(ctx, x + z, y + v - r); + vkvg_arc(ctx, x + z - r, y + v - r, r, 0, (float)M_PI_2); + vkvg_line_to(ctx, x + r, y + v); + vkvg_arc(ctx, x + r, y + v - r, r, (float)M_PI_2, (float)M_PI); + vkvg_line_to(ctx, x, y + r); + vkvg_close_path(ctx); + break; + case SHAPE_CIRCLE: + /*x = truncf((float)w * rnd()/RAND_MAX); + y = truncf((float)h * rnd()/RAND_MAX); + v = truncf((float)w * rnd()/RAND_MAX * 0.2f);*/ + x = (float)rand()/RAND_MAX * w; + y = (float)rand()/RAND_MAX * h; + + r = truncf((sizeFact*MIN(w,h)*rand()/RAND_MAX)+1.f); + + /*float r = 0.5f*w*rand()/RAND_MAX; + float x = truncf(0.5f * w*rand()/RAND_MAX + r); + float y = truncf(0.5f * w*rand()/RAND_MAX + r);*/ + + vkvg_arc(ctx, x, y, r, 0, (float)M_PI * 2.0f); + break; + case SHAPE_TRIANGLE: + case SHAPE_STAR: + x = (float)rand()/RAND_MAX * w; + y = (float)rand()/RAND_MAX * h; + z = (float)rand()/RAND_MAX * sizeFact + 0.15f; //scale + + vkvg_move_to (ctx, x+star_points[0][0]*z, y+star_points[0][1]*z); + for (int s=1; s<11; s++) + vkvg_line_to (ctx, x+star_points[s][0]*z, y+star_points[s][1]*z); + vkvg_close_path (ctx); + break; + case SHAPE_RANDOM: + draw_random_shape(ctx, 1 + rand()%4, sizeFact); + break; + } +} + +/*void draw_random_shape (VkvgContext ctx, shape_t shape) { + float w = (float)test_width; + float h = (float)test_height; + randomize_color(ctx); + float z = truncf((0.5f*w*rand()/RAND_MAX)+1.f); + float v = truncf((0.5f*w*rand()/RAND_MAX)+1.f); + float x = truncf((w-z)*rand()/RAND_MAX); + float y = truncf((h-v)*rand()/RAND_MAX); + vkvg_rectangle(ctx, x, y, z, v); +}*/ diff --git a/tests/common/test.h b/tests/common/test.h index 6606b12..91b6393 100644 --- a/tests/common/test.h +++ b/tests/common/test.h @@ -21,47 +21,59 @@ # define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif -#define PERFORM_TEST(testName) perform_test(testName, #testName, 1024, 768); +#define PERFORM_TEST(testName, argc, argv) perform_test(testName, #testName, argc, argv); #if defined(_WIN32) || defined(_WIN64) - #define WIN32_LEAN_AND_MEAN - #define NOMINMAX - #include // Windows.h -> WinDef.h defines min() max() - - /* - typedef uint16_t WORD ; - typedef uint32_t DWORD; - - typedef struct _FILETIME { - DWORD dwLowDateTime; - DWORD dwHighDateTime; - } FILETIME; - - typedef struct _SYSTEMTIME { - WORD wYear; - WORD wMonth; - WORD wDayOfWeek; - WORD wDay; - WORD wHour; - WORD wMinute; - WORD wSecond; - WORD wMilliseconds; - } SYSTEMTIME, *PSYSTEMTIME; - */ - - // *sigh* Microsoft has this in winsock2.h because they are too lazy to put it in the standard location ... !?!? - typedef struct timeval { - long tv_sec; - long tv_usec; - } timeval; - - // *sigh* no gettimeofday on Win32/Win64 - int gettimeofday(struct timeval * tp, struct timezone * tzp); + #define WIN32_LEAN_AND_MEAN + #define NOMINMAX + #include // Windows.h -> WinDef.h defines min() max() + + /* + typedef uint16_t WORD ; + typedef uint32_t DWORD; + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME; + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME; + */ + + // *sigh* Microsoft has this in winsock2.h because they are too lazy to put it in the standard location ... !?!? + typedef struct timeval { + long tv_sec; + long tv_usec; + } timeval; + + // *sigh* no gettimeofday on Win32/Win64 + int gettimeofday(struct timeval * tp, void * tzp); #else - #include + #include #endif +typedef enum _shape_t { + SHAPE_LINE, + SHAPE_RECTANGLE, + SHAPE_ROUNDED_RECTANGLE, + SHAPE_CIRCLE, + SHAPE_TRIANGLE, + SHAPE_STAR, + SHAPE_RANDOM, +} shape_t; + extern uint32_t test_size; -extern int iterations; +extern uint32_t iterations; +extern uint32_t test_width; +extern uint32_t test_height; extern float panX; extern float panY; @@ -74,10 +86,11 @@ extern VkvgDevice device; extern VkvgSurface surf; //run test in one step -void perform_test (void(*testfunc)(void), const char* testName, uint32_t width, uint32_t height); -void randomize_color (VkvgContext ctx); +void perform_test (void(*testfunc)(), const char* testName, int argc, char *argv[]); + +void randomize_color (VkvgContext ctx); +void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact); //run test in 3 step: init, run, clear. void init_test (uint32_t width, uint32_t height); -void run_test_func (void(*testfunc)(void), uint32_t width, uint32_t height); void clear_test (); diff --git a/tests/common/vkengine.c b/tests/common/vkengine.c index 7d3324e..6ef5b1e 100644 --- a/tests/common/vkengine.c +++ b/tests/common/vkengine.c @@ -31,11 +31,10 @@ bool vkeCheckPhyPropBlitSource (VkEngine e) { VkFormatProperties formatProps; vkGetPhysicalDeviceFormatProperties(e->dev->phy, e->renderer->format, &formatProps); - #ifdef VKVG_TILING_OPTIMAL - assert((formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); + return formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT; #else - assert((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); + return formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT; #endif } @@ -59,7 +58,7 @@ void vkengine_dump_Infos (VkEngine e){ for (uint32_t i = 0; i < e->memory_properties.memoryHeapCount; i++) { printf("Mem Heap %d\n", i); printf("\tflags= %d\n", e->memory_properties.memoryHeaps[i].flags); - printf("\tsize = %lu Mo\n", e->memory_properties.memoryHeaps[i].size/ (uint32_t)(1024*1024)); + printf("\tsize = %lu Mo\n", (unsigned long)e->memory_properties.memoryHeaps[i].size/ (uint32_t)(1024*1024)); } for (uint32_t i = 0; i < e->memory_properties.memoryTypeCount; i++) { printf("Mem type %d\n", i); @@ -144,12 +143,12 @@ vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, VkPresentModeKHR e->window = glfwCreateWindow ((int)width, (int)height, "Window Title", NULL, NULL); VkSurfaceKHR surf; - VkResult res = glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf); + VK_CHECK_RESULT (glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf)) VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf); - VkhPhyInfo pi = NULL; - for (int i=0; iproperties.deviceType == preferedGPU) break; @@ -164,10 +163,10 @@ vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, VkPresentModeKHR VkDeviceQueueCreateInfo pQueueInfos[] = { {0},{0},{0} }; if (vkh_phyinfo_create_presentable_queues (pi, 1, qPriorities, &pQueueInfos[qCount])) qCount++; - if (vkh_phyinfo_create_compute_queues (pi, 1, qPriorities, &pQueueInfos[qCount])) + /*if (vkh_phyinfo_create_compute_queues (pi, 1, qPriorities, &pQueueInfos[qCount])) qCount++; if (vkh_phyinfo_create_transfer_queues (pi, 1, qPriorities, &pQueueInfos[qCount])) - qCount++; + qCount++;*/ char const * dex [] = {"VK_KHR_swapchain"}; enabledExtsCount = 1; diff --git a/tests/common/vkengine.h b/tests/common/vkengine.h index 9a83aba..7c4e229 100644 --- a/tests/common/vkengine.h +++ b/tests/common/vkengine.h @@ -28,10 +28,13 @@ #include #include +#undef APIENTRY + #include #include "vkh.h" + #define FENCE_TIMEOUT 100000000 typedef struct _vk_engine_t* VkEngine; diff --git a/tests/compositing.c b/tests/compositing.c index f485f92..df193a7 100644 --- a/tests/compositing.c +++ b/tests/compositing.c @@ -1,22 +1,22 @@ #include "test.h" void compositing(){ - vkvg_surface_clear(surf); + vkvg_surface_clear(surf); - VkvgContext ctx = vkvg_create(surf); + VkvgContext ctx = vkvg_create(surf); - vkvg_set_source_rgba(ctx, 1,0,0,0.5); - vkvg_rectangle(ctx,100,100,200,200); - vkvg_fill(ctx); + vkvg_set_source_rgba(ctx, 1,0,0,0.5f); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_fill(ctx); - vkvg_set_source_rgba(ctx, 0,0,1,0.5); - vkvg_rectangle(ctx,200,200,200,200); - vkvg_fill(ctx); + vkvg_set_source_rgba(ctx, 0,0,1,0.5f); + vkvg_rectangle(ctx,200,200,200,200); + vkvg_fill(ctx); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } int main(int argc, char *argv[]) { - PERFORM_TEST (compositing); - return 0; + PERFORM_TEST (compositing, argc, argv); + return 0; } diff --git a/tests/curve.c b/tests/curve.c index d6e3520..bdeaf5a 100644 --- a/tests/curve.c +++ b/tests/curve.c @@ -1,61 +1,113 @@ #include "test.h" void test(){ - VkvgContext ctx = vkvg_create(surf); - - vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); - vkvg_set_line_width(ctx, 20); - - vkvg_scale(ctx,2,2); - vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL); - - //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); - - vkvg_set_source_rgb (ctx, 0.5,0,0); - - - /*vkvg_move_to(ctx,100,100); - vkvg_line_to(ctx,300,100); - vkvg_line_to(ctx,500,300); - vkvg_line_to(ctx,300,500); - //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); - vkvg_line_to(ctx,300,700); - vkvg_line_to(ctx,100,500);*/ - - /*vkvg_arc(ctx, 300, 300, 100, 0, M_PI); - vkvg_line_to(ctx,100,200); - vkvg_line_to(ctx,200,100); - vkvg_arc(ctx, 250, 100, 50, M_PI, M_PI * 1.5f); - vkvg_line_to(ctx,350,50); - vkvg_arc(ctx, 350, 100, 50, M_PI*1.5f, M_PI * 2.0f); - - vkvg_stroke(ctx); - vkvg_translate(ctx,400,30); - - */ - vkvg_translate(ctx,200,30); - vkvg_arc(ctx, 200, 200, 20, 0, M_PI*2); - //vkvg_stroke(ctx); - - vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5); - vkvg_move_to(ctx,100,100); - vkvg_line_to(ctx,200,100); - vkvg_curve_to(ctx,250,100,300,150,300,200); - vkvg_line_to(ctx,300,300); - vkvg_curve_to(ctx,300,350,250,400,200,400); - vkvg_line_to(ctx,100,400); - vkvg_curve_to(ctx,50,400,10,350,10,300); - vkvg_line_to(ctx,10,200); - vkvg_curve_to(ctx,10,150,50,100,100,100); - vkvg_fill_preserve(ctx); - vkvg_set_source_rgba (ctx, 0.1f,0.3,0.7,0.5); - vkvg_stroke(ctx); - - - vkvg_destroy(ctx); + VkvgContext ctx = vkvg_create(surf); + + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); + vkvg_set_line_width(ctx, 20); + + vkvg_scale(ctx,2,2); + vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL); + + //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); + + vkvg_set_source_rgb (ctx, 0.5f,0,0); + + + /*vkvg_move_to(ctx,100,100); + vkvg_line_to(ctx,300,100); + vkvg_line_to(ctx,500,300); + vkvg_line_to(ctx,300,500); + //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); + vkvg_line_to(ctx,300,700); + vkvg_line_to(ctx,100,500);*/ + + /*vkvg_arc(ctx, 300, 300, 100, 0, M_PI); + vkvg_line_to(ctx,100,200); + vkvg_line_to(ctx,200,100); + vkvg_arc(ctx, 250, 100, 50, M_PI, M_PI * 1.5f); + vkvg_line_to(ctx,350,50); + vkvg_arc(ctx, 350, 100, 50, M_PI*1.5f, M_PI * 2.0f); + + vkvg_stroke(ctx); + vkvg_translate(ctx,400,30); + + */ + vkvg_translate(ctx,200,30); + vkvg_arc(ctx, 200, 200, 20, 0, M_PIF*2); + //vkvg_stroke(ctx); + + vkvg_set_source_rgba (ctx, 0.5f,0.0f,1.0f,0.5f); + vkvg_move_to(ctx,100,100); + vkvg_line_to(ctx,200,100); + vkvg_curve_to(ctx,250,100,300,150,300,200); + vkvg_line_to(ctx,300,300); + vkvg_curve_to(ctx,300,350,250,400,200,400); + vkvg_line_to(ctx,100,400); + vkvg_curve_to(ctx,50,400,10,350,10,300); + vkvg_line_to(ctx,10,200); + vkvg_curve_to(ctx,10,150,50,100,100,100); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgba (ctx, 0.1f,0.3f,0.7f,0.5f); + vkvg_stroke(ctx); + + + vkvg_destroy(ctx); +} + +void curved_rect() { + VkvgContext ctx = vkvg_create(surf); + + float x = 50, y = 50, width = 150, height = 140, radius = 30; + + vkvg_scale(ctx, 2, 2); + //vkvg_rotate(ctx,0.5f); + + vkvg_set_line_width(ctx, 15); + vkvg_set_source_rgba(ctx, 0, 0.5f, 0.4f, 1); + + + if ((radius > height / 2) || (radius > width / 2)) + radius = MIN(height / 2, width / 2); + + vkvg_move_to(ctx, x, y + radius); + vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, (float)-M_PI_2); + vkvg_line_to(ctx, x + width - radius, y); + vkvg_arc(ctx, x + width - radius, y + radius, radius, (float)-M_PI_2, 0); + vkvg_line_to(ctx, x + width, y + height - radius); + vkvg_arc(ctx, x + width - radius, y + height - radius, radius, 0, (float)M_PI_2); + vkvg_line_to(ctx, x + radius, y + height); + vkvg_arc(ctx, x + radius, y + height - radius, radius, (float)M_PI_2, M_PIF); + vkvg_line_to(ctx, x, y + radius); + vkvg_close_path(ctx); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgba(ctx, 0.5f, 0, 0, 0.5f); + vkvg_stroke(ctx); + + vkvg_destroy(ctx); } +void test2() { + VkvgContext ctx = vkvg_create(surf); + + vkvg_move_to(ctx, 100, 400); + vkvg_curve_to(ctx, 100, 100, 600, 700, 600, 400); + vkvg_curve_to(ctx, 1000, 100, 100, 800, 1000, 800); + vkvg_curve_to(ctx, 1000, 500, 700, 500, 700, 100); + vkvg_close_path(ctx); + + //vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5); + //vkvg_fill_preserve(ctx); + + vkvg_set_source_rgba(ctx, 1, 0, 0, 1); + vkvg_set_line_width(ctx, 40); + vkvg_stroke(ctx); + + vkvg_destroy(ctx); +} int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; + PERFORM_TEST(test, argc, argv); + PERFORM_TEST(test2, argc, argv); + PERFORM_TEST(curved_rect, argc, argv); + return 0; } diff --git a/tests/curve2.c b/tests/curve2.c deleted file mode 100644 index dd8e1d9..0000000 --- a/tests/curve2.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "test.h" - -void test(){ - VkvgContext ctx = vkvg_create(surf); - - vkvg_move_to (ctx, 100, 400); - vkvg_curve_to (ctx, 100, 100, 600,700,600,400); - vkvg_curve_to (ctx, 1000, 100, 100, 800, 1000, 800); - vkvg_curve_to (ctx, 1000, 500, 700, 500, 700, 100); - vkvg_close_path(ctx); - - //vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5); - //vkvg_fill_preserve(ctx); - - vkvg_set_source_rgba (ctx, 1,0,0,1); - vkvg_set_line_width(ctx, 40); - vkvg_stroke(ctx); - - vkvg_destroy(ctx); -} - -int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; -} diff --git a/tests/curved_rect.c b/tests/curved_rect.c deleted file mode 100644 index ceebfb0..0000000 --- a/tests/curved_rect.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "test.h" - -void test(){ - VkvgContext ctx = vkvg_create(surf); - - float x = 50, y = 50, width = 150, height = 140, radius = 30; - - vkvg_scale(ctx,2,2); - //vkvg_rotate(ctx,0.5f); - - vkvg_set_line_width(ctx,15); - vkvg_set_source_rgba(ctx, 0, 0.5f, 0.4f, 1); - - - if ((radius > height / 2) || (radius > width / 2)) - radius = MIN(height / 2, width / 2); - - vkvg_move_to(ctx, x, y + radius); - vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, (float)-M_PI_2); - vkvg_line_to(ctx, x + width - radius, y); - vkvg_arc(ctx, x + width - radius, y + radius, radius, (float)-M_PI_2, 0); - vkvg_line_to(ctx, x + width, y + height - radius); - vkvg_arc(ctx, x + width - radius, y + height - radius, radius, 0, (float)M_PI_2); - vkvg_line_to(ctx, x + radius, y + height); - vkvg_arc(ctx, x + radius, y + height - radius, radius, (float)M_PI_2, M_PIF); - vkvg_line_to(ctx, x, y + radius); - vkvg_close_path(ctx); - vkvg_fill_preserve(ctx); - vkvg_set_source_rgba(ctx,0.5,0,0,0.5); - vkvg_stroke(ctx); - - vkvg_destroy(ctx); -} - -int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; -} diff --git a/tests/dashes.c b/tests/dashes.c index f0fb73a..6ce59df 100644 --- a/tests/dashes.c +++ b/tests/dashes.c @@ -1,46 +1,70 @@ #include "test.h" static float offset = 0; void test(){ - offset += 0.1f; - vkvg_surface_clear(surf); - - VkvgContext ctx = vkvg_create(surf); - //const float dashes[] = {160.0f, 80}; - float dashes[] = {700.0f, 30}; - //const float dashes[] = {50, 40}; - vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND); - vkvg_set_dash(ctx, dashes, 2, offset); - vkvg_set_line_width(ctx, 20); - vkvg_set_source_rgb(ctx, 0, 0, 1); - - vkvg_move_to (ctx, 150, 50); - vkvg_rel_line_to (ctx, 500, 0); - vkvg_rel_line_to (ctx, 0, 200); - vkvg_rel_line_to (ctx, 200, 0); - vkvg_rel_line_to (ctx, 0, 500); - vkvg_rel_line_to (ctx, -700, 0); - vkvg_close_path(ctx); - vkvg_stroke (ctx); - - dashes[0] = 0; - dashes[1] = 30; - vkvg_set_dash(ctx, dashes, 2, offset); - - vkvg_set_source_rgb(ctx, 0, 1, 0); - - vkvg_move_to (ctx, 200, 100); - vkvg_rel_line_to (ctx, 400, 0); - vkvg_rel_line_to (ctx, 0, 200); - vkvg_rel_line_to (ctx, 200, 0); - vkvg_rel_line_to (ctx, 0, 400); - vkvg_rel_line_to (ctx, -600, 0); - vkvg_close_path(ctx); - vkvg_stroke (ctx); - - vkvg_destroy(ctx); + offset += 0.1f; + vkvg_surface_clear(surf); + + VkvgContext ctx = vkvg_create(surf); + //const float dashes[] = {160.0f, 80}; + float dashes[] = {700.0f, 30}; + //const float dashes[] = {50, 40}; + vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND); + vkvg_set_dash(ctx, dashes, 2, offset); + vkvg_set_line_width(ctx, 20); + vkvg_set_source_rgb(ctx, 0, 0, 1); + + vkvg_move_to (ctx, 150, 50); + vkvg_rel_line_to (ctx, 500, 0); + vkvg_rel_line_to (ctx, 0, 200); + vkvg_rel_line_to (ctx, 200, 0); + vkvg_rel_line_to (ctx, 0, 500); + vkvg_rel_line_to (ctx, -700, 0); + vkvg_close_path(ctx); + vkvg_stroke (ctx); + + dashes[0] = 0; + dashes[1] = 30; + vkvg_set_dash(ctx, dashes, 2, offset); + + vkvg_set_source_rgb(ctx, 0, 1, 0); + + vkvg_move_to (ctx, 200, 100); + vkvg_rel_line_to (ctx, 400, 0); + vkvg_rel_line_to (ctx, 0, 200); + vkvg_rel_line_to (ctx, 200, 0); + vkvg_rel_line_to (ctx, 0, 400); + vkvg_rel_line_to (ctx, -600, 0); + vkvg_close_path(ctx); + vkvg_stroke (ctx); + + vkvg_destroy(ctx); +} + +void test2() { + VkvgContext ctx = vkvg_create(surf); + + const float dashes[] = { 0, 8 }; + vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND); + vkvg_set_dash(ctx, dashes, 2, 0); + vkvg_set_line_width(ctx, 4); + + vkvg_move_to(ctx, 100, 400); + vkvg_curve_to(ctx, 100, 100, 600, 700, 600, 400); + vkvg_curve_to(ctx, 1000, 100, 100, 800, 1000, 800); + vkvg_curve_to(ctx, 1000, 500, 700, 500, 700, 100); + //vkvg_close_path(ctx); + + //vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5); + //vkvg_fill_preserve(ctx); + + vkvg_set_source_rgba(ctx, 1, 0, 0, 1); + vkvg_stroke(ctx); + + vkvg_destroy(ctx); } -int main() { - PERFORM_TEST (test); - return 0; +int main(int argc, char *argv[]) { + PERFORM_TEST(test, argc, argv); + PERFORM_TEST(test2, argc, argv); + return 0; } diff --git a/tests/dashes2.c b/tests/dashes2.c deleted file mode 100644 index fe14a76..0000000 --- a/tests/dashes2.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "test.h" - -void test(){ - VkvgContext ctx = vkvg_create(surf); - - const float dashes[] = {0, 8}; - vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND); - vkvg_set_dash(ctx, dashes, 2, 0); - vkvg_set_line_width(ctx, 4); - - vkvg_move_to (ctx, 100, 400); - vkvg_curve_to (ctx, 100, 100, 600, 700, 600, 400); - vkvg_curve_to (ctx, 1000, 100, 100, 800, 1000, 800); - vkvg_curve_to (ctx, 1000, 500, 700, 500, 700, 100); - //vkvg_close_path(ctx); - - //vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5); - //vkvg_fill_preserve(ctx); - - vkvg_set_source_rgba (ctx, 1,0,0,1); - vkvg_stroke(ctx); - - vkvg_destroy(ctx); -} - -int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; -} diff --git a/tests/fill.c b/tests/fill.c index eb3ed28..5d49946 100644 --- a/tests/fill.c +++ b/tests/fill.c @@ -1,26 +1,26 @@ #include "test.h" void test(){ - VkvgContext ctx = vkvg_create(surf); - vkvg_set_line_width(ctx,30); - vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); + VkvgContext ctx = vkvg_create(surf); + vkvg_set_line_width(ctx,30); + vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); - vkvg_set_source_rgba(ctx,0.1,0.9,0.1,1.0); - vkvg_move_to(ctx,100,100); - vkvg_rel_line_to(ctx,50,200); - vkvg_rel_line_to(ctx,150,-100); - vkvg_rel_line_to(ctx,100,200); - vkvg_rel_line_to(ctx,-100,100); - vkvg_rel_line_to(ctx,-10,-100); - vkvg_rel_line_to(ctx,-190,-50); - vkvg_close_path(ctx); + vkvg_set_source_rgba(ctx,0.1f,0.9f,0.1f,1.0f); + vkvg_move_to(ctx,100,100); + vkvg_rel_line_to(ctx,50,200); + vkvg_rel_line_to(ctx,150,-100); + vkvg_rel_line_to(ctx,100,200); + vkvg_rel_line_to(ctx,-100,100); + vkvg_rel_line_to(ctx,-10,-100); + vkvg_rel_line_to(ctx,-190,-50); + vkvg_close_path(ctx); - vkvg_stroke(ctx); + vkvg_stroke(ctx); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; + PERFORM_TEST (test, argc, argv); + return 0; } diff --git a/tests/fill_and_stroke.c b/tests/fill_and_stroke.c index a9dd8d4..1e2931f 100644 --- a/tests/fill_and_stroke.c +++ b/tests/fill_and_stroke.c @@ -1,29 +1,29 @@ #include "test.h" void test(){ - VkvgContext ctx = vkvg_create(surf); + VkvgContext ctx = vkvg_create(surf); - vkvg_move_to (ctx, 100, 100); - vkvg_rel_line_to (ctx, 50, -80); - vkvg_rel_line_to (ctx, 50, 80); - //vkvg_close_path (ctx); + vkvg_move_to (ctx, 100, 100); + vkvg_rel_line_to (ctx, 50, -80); + vkvg_rel_line_to (ctx, 50, 80); + //vkvg_close_path (ctx); - vkvg_move_to (ctx, 300, 100); - vkvg_rel_line_to (ctx, 50, -80); - vkvg_rel_line_to (ctx, 50, 80); - vkvg_close_path (ctx); + vkvg_move_to (ctx, 300, 100); + vkvg_rel_line_to (ctx, 50, -80); + vkvg_rel_line_to (ctx, 50, 80); + vkvg_close_path (ctx); - vkvg_set_line_width (ctx, 10.0); - vkvg_set_source_rgb (ctx, 0, 0, 1); - vkvg_fill_preserve (ctx); - //vkvg_fill(ctx); - vkvg_set_source_rgb (ctx, 1, 0, 0); - vkvg_stroke (ctx); + vkvg_set_line_width (ctx, 10.0); + vkvg_set_source_rgb (ctx, 0, 0, 1); + vkvg_fill_preserve (ctx); + //vkvg_fill(ctx); + vkvg_set_source_rgb (ctx, 1, 0, 0); + vkvg_stroke (ctx); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; + PERFORM_TEST (test, argc, argv); + return 0; } diff --git a/tests/gradient.c b/tests/gradient.c index a474ae8..151a9a4 100644 --- a/tests/gradient.c +++ b/tests/gradient.c @@ -1,67 +1,94 @@ #include "test.h" VkvgPattern create_grad (VkvgContext ctx) { - VkvgPattern pat = vkvg_pattern_create_linear(0,0,300,0); - vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1); - vkvg_pattern_add_color_stop(pat, 0.5, 0, 1, 0, 1); - vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1); - return pat; + VkvgPattern pat = vkvg_pattern_create_linear(0,0,300,0); + vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1); + vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1); + vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1); + return pat; } void paint(){ - VkvgContext ctx = vkvg_create(surf); - VkvgPattern pat = create_grad(ctx); - vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); - vkvg_set_source (ctx, pat); - vkvg_paint(ctx); + VkvgContext ctx = vkvg_create(surf); + VkvgPattern pat = create_grad(ctx); + vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + vkvg_set_source (ctx, pat); + vkvg_paint(ctx); - vkvg_pattern_destroy (pat); - vkvg_destroy(ctx); + vkvg_pattern_destroy (pat); + vkvg_destroy(ctx); } void paint_repeat(){ - VkvgContext ctx = vkvg_create(surf); - VkvgPattern pat = create_grad(ctx); - vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); - vkvg_set_source (ctx, pat); - vkvg_paint(ctx); + VkvgContext ctx = vkvg_create(surf); + VkvgPattern pat = create_grad(ctx); + vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); + vkvg_set_source (ctx, pat); + vkvg_paint(ctx); - vkvg_pattern_destroy (pat); - vkvg_destroy(ctx); + vkvg_pattern_destroy (pat); + vkvg_destroy(ctx); } void test(){ - VkvgContext ctx = vkvg_create(surf); - VkvgPattern pat = create_grad(ctx); - vkvg_set_source (ctx, pat); - vkvg_rectangle(ctx,100,100,200,200); - vkvg_set_line_width(ctx, 20); - //vkvg_fill (ctx); - //vkvg_paint(ctx); - vkvg_stroke (ctx); - vkvg_pattern_destroy (pat); + VkvgContext ctx = vkvg_create(surf); + VkvgPattern pat = create_grad(ctx); + vkvg_set_source (ctx, pat); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_set_line_width(ctx, 20); + //vkvg_fill (ctx); + //vkvg_paint(ctx); + vkvg_stroke (ctx); + vkvg_pattern_destroy (pat); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } void test2(){ - VkvgContext ctx = vkvg_create(surf); + VkvgContext ctx = vkvg_create(surf); - vkvg_set_source_rgb(ctx,1,0,0); - vkvg_paint(ctx); + vkvg_set_source_rgb(ctx,1,0,0); + vkvg_paint(ctx); - VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0); - vkvg_set_line_width(ctx, 20); - vkvg_pattern_add_color_stop(pat, 0, 1, 1, 1, 1); - vkvg_pattern_add_color_stop(pat, 1, 1, 1, 0, 0); - vkvg_set_source (ctx, pat); - vkvg_rectangle(ctx,100,100,200,200); - vkvg_fill (ctx); - //vkvg_stroke (ctx); - vkvg_pattern_destroy (pat); + VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0); + vkvg_set_line_width(ctx, 20); + vkvg_pattern_add_color_stop(pat, 0, 1, 1, 1, 1); + vkvg_pattern_add_color_stop(pat, 1, 1, 1, 0, 0); + vkvg_set_source (ctx, pat); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_fill (ctx); + //vkvg_stroke (ctx); + vkvg_pattern_destroy (pat); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } + +void gradient_transform() { + VkvgContext ctx = vkvg_create(surf); + + //vkvg_translate(ctx,-100,-100); + + vkvg_translate(ctx, 200, 100); + vkvg_rotate(ctx, 0.5f); + + //vkvg_scale(ctx,2,2); + VkvgPattern pat = vkvg_pattern_create_linear(0, 0, 400, 0); + vkvg_pattern_set_extend(pat, VKVG_EXTEND_NONE); + vkvg_set_line_width(ctx, 20); + vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1); + vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1); + vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1); + vkvg_set_source(ctx, pat); + vkvg_rectangle(ctx, 0, 0, 400, 200); + //vkvg_fill (ctx); + vkvg_stroke(ctx); + //vkvg_paint(ctx); + vkvg_pattern_destroy(pat); + + vkvg_destroy(ctx); +} + int main(int argc, char *argv[]) { - PERFORM_TEST(paint); - PERFORM_TEST(paint_repeat); - return 0; + PERFORM_TEST(paint, argc, argv); + PERFORM_TEST(paint_repeat, argc, argv); + PERFORM_TEST(gradient_transform, argc, argv); + return 0; } diff --git a/tests/gradient_transform.c b/tests/gradient_transform.c deleted file mode 100644 index ad7dadd..0000000 --- a/tests/gradient_transform.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "test.h" - -void test(){ - VkvgContext ctx = vkvg_create(surf); - - //vkvg_translate(ctx,-100,-100); - - vkvg_translate(ctx,200,100); - vkvg_rotate(ctx,0.5); - - //vkvg_scale(ctx,2,2); - VkvgPattern pat = vkvg_pattern_create_linear(0,0,400,0); - vkvg_pattern_set_extend(pat, VKVG_EXTEND_NONE); - vkvg_set_line_width(ctx, 20); - vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1); - vkvg_pattern_add_color_stop(pat, 0.5, 0, 1, 0, 1); - vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1); - vkvg_set_source (ctx, pat); - vkvg_rectangle(ctx,0,0,400,200); - //vkvg_fill (ctx); - vkvg_stroke (ctx); - //vkvg_paint(ctx); - vkvg_pattern_destroy (pat); - - vkvg_destroy(ctx); -} - -int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; -} diff --git a/tests/hlines.c b/tests/hlines.c index 73837b6..25322f5 100644 --- a/tests/hlines.c +++ b/tests/hlines.c @@ -29,7 +29,7 @@ void test(){ int main(int argc, char *argv[]) { - PERFORM_TEST (test); + PERFORM_TEST (test, argc, argv); return 0; } diff --git a/tests/img_surf.c b/tests/img_surf.c index a915f2c..458b232 100644 --- a/tests/img_surf.c +++ b/tests/img_surf.c @@ -1,89 +1,89 @@ #include "test.h" void paint () { - VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgContext ctx = vkvg_create(surf); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - vkvg_set_source_surface(ctx, imgSurf, 00, 00); - vkvg_paint(ctx); + vkvg_set_source_surface(ctx, imgSurf, 00, 00); + vkvg_paint(ctx); - vkvg_surface_destroy(imgSurf); - vkvg_destroy(ctx); + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); } void paint_offset () { - VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgContext ctx = vkvg_create(surf); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - vkvg_set_source_surface(ctx, imgSurf, 100, 100); - vkvg_paint(ctx); + vkvg_set_source_surface(ctx, imgSurf, 100, 100); + vkvg_paint(ctx); - vkvg_surface_destroy(imgSurf); - vkvg_destroy(ctx); + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); } void paint_pattern () { - VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); - vkvg_set_source(ctx, pat); - vkvg_paint(ctx); - vkvg_pattern_destroy(pat); - vkvg_surface_destroy(imgSurf); - vkvg_destroy(ctx); + VkvgContext ctx = vkvg_create(surf); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); + vkvg_set_source(ctx, pat); + vkvg_paint(ctx); + vkvg_pattern_destroy(pat); + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); } void paint_pattern_repeat () { - VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); - vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); - vkvg_set_source(ctx, pat); - vkvg_paint(ctx); - vkvg_pattern_destroy(pat); - vkvg_surface_destroy(imgSurf); - vkvg_destroy(ctx); + VkvgContext ctx = vkvg_create(surf); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); + vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); + vkvg_set_source(ctx, pat); + vkvg_paint(ctx); + vkvg_pattern_destroy(pat); + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); } void paint_pattern_pad () { - VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); - vkvg_pattern_set_extend(pat,VKVG_EXTEND_PAD); - vkvg_set_source(ctx, pat); - vkvg_paint(ctx); - vkvg_pattern_destroy(pat); - vkvg_surface_destroy(imgSurf); - vkvg_destroy(ctx); + VkvgContext ctx = vkvg_create(surf); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); + vkvg_pattern_set_extend(pat,VKVG_EXTEND_PAD); + vkvg_set_source(ctx, pat); + vkvg_paint(ctx); + vkvg_pattern_destroy(pat); + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); } void test(){ - VkvgContext ctx = vkvg_create(surf); - vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgContext ctx = vkvg_create(surf); + vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - vkvg_translate(ctx,200,200); - //vkvg_rotate(ctx,M_PI_4); + vkvg_translate(ctx,200,200); + //vkvg_rotate(ctx,M_PI_4); - vkvg_set_line_width(ctx,20.f); - vkvg_set_source_rgba(ctx,1,0,0,1); - vkvg_arc(ctx,200,200,200,0,2.f*M_PI); - vkvg_new_sub_path(ctx); - vkvg_arc(ctx,200,200,100,0,2.f*M_PI); + vkvg_set_line_width(ctx,20.f); + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_arc(ctx,200,200,200,0,2.f*M_PIF); + vkvg_new_sub_path(ctx); + vkvg_arc(ctx,200,200,100,0,2.f*M_PIF); - vkvg_set_source_surface(ctx, imgSurf, 00, 00); - vkvg_fill_preserve(ctx); - vkvg_set_source_rgba(ctx,0.2,0.3,0.8,1); + vkvg_set_source_surface(ctx, imgSurf, 00, 00); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgba(ctx,0.2f,0.3f,0.8f,1); - vkvg_stroke(ctx); + vkvg_stroke(ctx); - vkvg_surface_destroy(imgSurf); + vkvg_surface_destroy(imgSurf); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } int main(int argc, char *argv[]) { - PERFORM_TEST (paint); - PERFORM_TEST (paint_offset); - PERFORM_TEST (paint_pattern); - PERFORM_TEST (paint_pattern_repeat); - PERFORM_TEST (paint_pattern_pad); - PERFORM_TEST (test); + PERFORM_TEST (paint, argc, argv); + PERFORM_TEST (paint_offset, argc, argv); + PERFORM_TEST (paint_pattern, argc, argv); + PERFORM_TEST (paint_pattern_repeat, argc, argv); + PERFORM_TEST (paint_pattern_pad, argc, argv); + PERFORM_TEST (test, argc, argv); - return 0; + return 0; } diff --git a/tests/line_caps.c b/tests/line_caps.c index 5629be1..6e12983 100644 --- a/tests/line_caps.c +++ b/tests/line_caps.c @@ -1,57 +1,57 @@ #include "test.h" void test(){ - VkvgContext ctx = vkvg_create(surf); - vkvg_set_source_rgba(ctx,0.9,0.9,0.9,1); - vkvg_paint(ctx); + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0.9f,0.9f,0.9f,1); + vkvg_paint(ctx); - float x = 20, y = 20, dx = 40, dy = 60; + float x = 20, y = 20, dx = 40, dy = 60; - //vkvg_scale(ctx,5,5); - vkvg_set_line_width(ctx,30); - vkvg_set_source_rgba(ctx,0.0,0.0,0,1); - vkvg_move_to(ctx,x,y); - vkvg_rel_line_to(ctx,0,dy); - vkvg_stroke(ctx); - vkvg_set_line_cap(ctx,VKVG_LINE_CAP_SQUARE); - vkvg_move_to(ctx,x+dx,y); - vkvg_rel_line_to(ctx,0,dy); - vkvg_stroke(ctx); - vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND); - vkvg_move_to(ctx,x+2*dx,y); - vkvg_rel_line_to(ctx,0,dy); - vkvg_rel_move_to(ctx,dx,-dy); - vkvg_rel_line_to(ctx,dx,dy); - vkvg_rel_move_to(ctx,dx,-dy/2); - vkvg_rel_line_to(ctx,dx,0); - vkvg_rel_move_to(ctx,dx,dy/2); - vkvg_rel_line_to(ctx,dx,-dy); - vkvg_rel_move_to(ctx,dx,dy); - vkvg_rel_line_to(ctx,0,-dy); - vkvg_rel_move_to(ctx,2*dx,dy); - vkvg_rel_line_to(ctx,-dx,-dy); - vkvg_rel_move_to(ctx,3*dx,dy/2); - vkvg_rel_line_to(ctx,-dx,0); - //vkvg_rel_line_to(ctx,0,-dy); - //vkvg_rel_move_to(ctx,dx,dy/2); - //vkvg_rel_line_to(ctx,dx,0); - vkvg_stroke(ctx); + //vkvg_scale(ctx,5,5); + vkvg_set_line_width(ctx,30); + vkvg_set_source_rgba(ctx,0.0,0.0,0,1); + vkvg_move_to(ctx,x,y); + vkvg_rel_line_to(ctx,0,dy); + vkvg_stroke(ctx); + vkvg_set_line_cap(ctx,VKVG_LINE_CAP_SQUARE); + vkvg_move_to(ctx,x+dx,y); + vkvg_rel_line_to(ctx,0,dy); + vkvg_stroke(ctx); + vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND); + vkvg_move_to(ctx,x+2*dx,y); + vkvg_rel_line_to(ctx,0,dy); + vkvg_rel_move_to(ctx,dx,-dy); + vkvg_rel_line_to(ctx,dx,dy); + vkvg_rel_move_to(ctx,dx,-dy/2.f); + vkvg_rel_line_to(ctx,dx,0); + vkvg_rel_move_to(ctx,dx,dy/2.f); + vkvg_rel_line_to(ctx,dx,-dy); + vkvg_rel_move_to(ctx,dx,dy); + vkvg_rel_line_to(ctx,0,-dy); + vkvg_rel_move_to(ctx,dx*2.f,dy); + vkvg_rel_line_to(ctx,-dx,-dy); + vkvg_rel_move_to(ctx,dx*3.f,dy/2.f); + vkvg_rel_line_to(ctx,-dx,0); + //vkvg_rel_line_to(ctx,0,-dy); + //vkvg_rel_move_to(ctx,dx,dy/2); + //vkvg_rel_line_to(ctx,dx,0); + vkvg_stroke(ctx); - vkvg_set_line_cap(ctx,VKVG_LINE_CAP_BUTT); - vkvg_set_line_width(ctx,1); - vkvg_set_source_rgba(ctx,1,0,0,1); - vkvg_move_to(ctx,x,y); - vkvg_rel_line_to(ctx,0,dy); - vkvg_rel_move_to(ctx,dx,-dy); - vkvg_rel_line_to(ctx,0,dy); - vkvg_rel_move_to(ctx,dx,-dy); - vkvg_rel_line_to(ctx,0,dy); - vkvg_stroke(ctx); + vkvg_set_line_cap(ctx,VKVG_LINE_CAP_BUTT); + vkvg_set_line_width(ctx,1); + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_move_to(ctx,x,y); + vkvg_rel_line_to(ctx,0,dy); + vkvg_rel_move_to(ctx,dx,-dy); + vkvg_rel_line_to(ctx,0,dy); + vkvg_rel_move_to(ctx,dx,-dy); + vkvg_rel_line_to(ctx,0,dy); + vkvg_stroke(ctx); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; + PERFORM_TEST (test, argc, argv); + return 0; } diff --git a/tests/line_join.c b/tests/line_join.c index 1ef3f51..1502825 100644 --- a/tests/line_join.c +++ b/tests/line_join.c @@ -1,58 +1,59 @@ #include "test.h" void test(){ - VkvgContext ctx = vkvg_create(surf); - - float x = 250, y = 150, dx = 150, dy = 140; - - //vkvg_scale(ctx,2,2); - - vkvg_set_line_width(ctx,100); - vkvg_set_source_rgba(ctx,0,1,0,1); - - - vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); - //vkvg_rectangle(ctx,x,y,dx,dy); - - vkvg_move_to(ctx,x,y); - vkvg_rel_line_to(ctx,-50,30); - vkvg_rel_line_to(ctx,0,60); - vkvg_rel_line_to(ctx,50,30); - /* - vkvg_rel_line_to(ctx,50,-30); - vkvg_rel_line_to(ctx,50,0); - vkvg_rel_line_to(ctx,50,30); - vkvg_rel_line_to(ctx,0,60); - vkvg_rel_line_to(ctx,-50,70); - vkvg_rel_line_to(ctx,-50,0); - vkvg_rel_line_to(ctx,-50,-70); - vkvg_close_path(ctx); - vkvg_stroke(ctx); - - vkvg_set_source_rgba(ctx,1,0,0,1); - vkvg_move_to(ctx,x+200,y); - vkvg_rel_line_to(ctx,50,70); - vkvg_rel_line_to(ctx,50,0); - vkvg_rel_line_to(ctx,50,-70); - vkvg_rel_line_to(ctx,0,-60); - vkvg_rel_line_to(ctx,-50,-30); - vkvg_rel_line_to(ctx,-50,0); - vkvg_rel_line_to(ctx,-50,30);*/ - vkvg_close_path(ctx); - vkvg_stroke(ctx); - - vkvg_set_source_rgba(ctx,0,0,1,1); - vkvg_move_to(ctx,x+250,y); - vkvg_rel_line_to(ctx,50,-30); - vkvg_rel_line_to(ctx,50,0); - vkvg_rel_line_to(ctx,50,30); - vkvg_rel_line_to(ctx,0,60); - vkvg_rel_line_to(ctx,-50,70); - vkvg_rel_line_to(ctx,-50,0); - vkvg_rel_line_to(ctx,-50,-70); - vkvg_close_path(ctx); - vkvg_stroke(ctx); + VkvgContext ctx = vkvg_create(surf); + float x = 250, y = 150; + + //vkvg_scale(ctx,2,2); + + vkvg_set_line_width(ctx,100); + vkvg_set_source_rgba(ctx,0,1,0,1); + + + vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); + //vkvg_rectangle(ctx,x,y,dx,dy); + + vkvg_move_to(ctx,x,y); + vkvg_rel_line_to(ctx,-50,30); + vkvg_rel_line_to(ctx,0,60); + vkvg_rel_line_to(ctx,50,30); + /* + vkvg_rel_line_to(ctx,50,-30); + vkvg_rel_line_to(ctx,50,0); + vkvg_rel_line_to(ctx,50,30); + vkvg_rel_line_to(ctx,0,60); + vkvg_rel_line_to(ctx,-50,70); + vkvg_rel_line_to(ctx,-50,0); + vkvg_rel_line_to(ctx,-50,-70); + vkvg_close_path(ctx); + vkvg_stroke(ctx); + + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_move_to(ctx,x+200,y); + vkvg_rel_line_to(ctx,50,70); + vkvg_rel_line_to(ctx,50,0); + vkvg_rel_line_to(ctx,50,-70); + vkvg_rel_line_to(ctx,0,-60); + vkvg_rel_line_to(ctx,-50,-30); + vkvg_rel_line_to(ctx,-50,0); + vkvg_rel_line_to(ctx,-50,30);*/ + vkvg_close_path(ctx); + vkvg_stroke(ctx); + + vkvg_set_source_rgba(ctx,0,0,1,1); + vkvg_move_to(ctx,x+250,y); + vkvg_rel_line_to(ctx,50,-30); + vkvg_rel_line_to(ctx,50,0); + vkvg_rel_line_to(ctx,50,30); + vkvg_rel_line_to(ctx,0,60); + vkvg_rel_line_to(ctx,-50,70); + vkvg_rel_line_to(ctx,-50,0); + vkvg_rel_line_to(ctx,-50,-70); + vkvg_close_path(ctx); + vkvg_stroke(ctx); + +// float dx = 150, dy = 140; // vkvg_rel_line_to(ctx,dx,-dy); // vkvg_rel_line_to(ctx,dx,dy); // vkvg_stroke(ctx); @@ -68,10 +69,113 @@ void test(){ // vkvg_stroke(ctx); // vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER); - vkvg_destroy(ctx); + vkvg_destroy(ctx); } +void test2() { + VkvgContext ctx = vkvg_create(surf); + + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); + vkvg_set_line_width(ctx, 30); + + vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND); + + //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); + + vkvg_translate(ctx, -50, -50); + + vkvg_set_source_rgb(ctx, 0.5, 0, 0); + + for (int j = 0; j < 2; j++) { + int i = 0; + vkvg_move_to(ctx, 100, 100); + for (i = 0; i < 5; i++) { + vkvg_rel_line_to(ctx, 70, 50); + vkvg_rel_line_to(ctx, -70, 50); + } + vkvg_stroke(ctx); + + vkvg_move_to(ctx, 200, 600); + for (i = 0; i < 5; i++) { + vkvg_rel_line_to(ctx, 70, -50); + vkvg_rel_line_to(ctx, -70, -50); + } + vkvg_stroke(ctx); + + vkvg_move_to(ctx, 400, 100); + for (i = 0; i < 5; i++) { + vkvg_rel_line_to(ctx, -70, 50); + vkvg_rel_line_to(ctx, 70, 50); + } + vkvg_stroke(ctx); + + vkvg_move_to(ctx, 500, 600); + for (i = 0; i < 5; i++) { + vkvg_rel_line_to(ctx, -70, -50); + vkvg_rel_line_to(ctx, 70, -50); + } + vkvg_stroke(ctx); + vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL); + vkvg_translate(ctx, 500, 0); + } + + vkvg_destroy(ctx); +} + +void test3() { + VkvgContext ctx = vkvg_create(surf); + + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); + vkvg_set_line_width(ctx, 30); + + vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND); + + //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); + + vkvg_translate(ctx, -50, -50); + + vkvg_set_source_rgb(ctx, 0.5, 0, 0); + + for (int j = 0; j < 2; j++) { + int i = 0; + vkvg_move_to(ctx, 100, 100); + for (i = 0; i < 4; i++) { + vkvg_rel_line_to(ctx, 50, 70); + vkvg_rel_line_to(ctx, 50, -70); + } + vkvg_stroke(ctx); + + vkvg_move_to(ctx, 500, 200); + for (i = 0; i < 4; i++) { + vkvg_rel_line_to(ctx, -50, 70); + vkvg_rel_line_to(ctx, -50, -70); + } + vkvg_stroke(ctx); + + vkvg_move_to(ctx, 100, 400); + for (i = 0; i < 4; i++) { + vkvg_rel_line_to(ctx, 50, -70); + vkvg_rel_line_to(ctx, 50, 70); + } + vkvg_stroke(ctx); + + vkvg_move_to(ctx, 500, 500); + for (i = 0; i < 4; i++) { + vkvg_rel_line_to(ctx, -50, -70); + vkvg_rel_line_to(ctx, -50, 70); + } + vkvg_stroke(ctx); + vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL); + vkvg_translate(ctx, 450, 0); + } + + vkvg_destroy(ctx); +} + + int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; + PERFORM_TEST(test, argc, argv); + PERFORM_TEST(test2, argc, argv); + PERFORM_TEST(test3, argc, argv); + return 0; } diff --git a/tests/line_join_2.c b/tests/line_join_2.c deleted file mode 100644 index 9cf011c..0000000 --- a/tests/line_join_2.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "test.h" - -void test(){ - VkvgContext ctx = vkvg_create(surf); - - vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - vkvg_set_line_width(ctx, 30); - - vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND); - - //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); - - vkvg_translate(ctx,-50,-50); - - vkvg_set_source_rgb (ctx, 0.5,0,0); - - for (int j=0;j<2;j++) { - int i=0; - vkvg_move_to(ctx,100,100); - for (i=0;i<5;i++) { - vkvg_rel_line_to(ctx,70,50); - vkvg_rel_line_to(ctx,-70,50); - } - vkvg_stroke(ctx); - - vkvg_move_to(ctx,200,600); - for (i=0;i<5;i++) { - vkvg_rel_line_to(ctx,70,-50); - vkvg_rel_line_to(ctx,-70,-50); - } - vkvg_stroke(ctx); - - vkvg_move_to(ctx,400,100); - for (i=0;i<5;i++) { - vkvg_rel_line_to(ctx,-70,50); - vkvg_rel_line_to(ctx,70,50); - } - vkvg_stroke(ctx); - - vkvg_move_to(ctx,500,600); - for (i=0;i<5;i++) { - vkvg_rel_line_to(ctx,-70,-50); - vkvg_rel_line_to(ctx,70,-50); - } - vkvg_stroke(ctx); - vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL); - vkvg_translate(ctx,500,0); - } - - vkvg_destroy(ctx); -} - -int main(int argc, char *argv[]) { - PERFORM_TEST (test); - return 0; -} diff --git a/tests/line_join_3.c b/tests/line_join_3.c deleted file mode 100644 index 9c41714..0000000 --- a/tests/line_join_3.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "test.h" - -void test(){ - VkvgContext ctx = vkvg_create(surf); - - vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - vkvg_set_line_width(ctx, 30); - - vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND); - - //vkvg_arc (ctx, 200, 500, 100, 0, M_PI); - - vkvg_translate(ctx,-50,-50); - - vkvg_set_source_rgb (ctx, 0.5,0,0); - - for (int j=0;j<2;j++) { - int i=0; - vkvg_move_to(ctx,100,100); - for (i=0;i<4;i++) { - vkvg_rel_line_to(ctx,50,70); - vkvg_rel_line_to(ctx,50,-70); - } - vkvg_stroke(ctx); - - vkvg_move_to(ctx,500,200); - for (i=0;i<4;i++) { - vkvg_rel_line_to(ctx,-50,70); - vkvg_rel_line_to(ctx,-50,-70); - } - vkvg_stroke(ctx); - - vkvg_move_to(ctx,100,400); - for (i=0;i<4;i++) { - vkvg_rel_line_to(ctx,50,-70); - vkvg_rel_line_to(ctx,50,70); - } - vkvg_stroke(ctx); - - vkvg_move_to(ctx,500,500); - for (i=0;i<4;i++) { - vkvg_rel_line_to(ctx,-50,-70); - vkvg_rel_line_to(ctx,-50,70); - } - vkvg_stroke(ctx); - vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL); - vkvg_translate(ctx,450,0); - } - - vkvg_destroy(ctx); -} - -int main(int argc, char *argv[]) { - PERFORM_TEST(test); - return 0; -} diff --git a/tests/lines.c b/tests/lines.c index 66d493f..98bde9f 100644 --- a/tests/lines.c +++ b/tests/lines.c @@ -1,39 +1,39 @@ #include "test.h" void test(){ - vkvg_surface_clear(surf); + vkvg_surface_clear(surf); - struct timeval currentTime; - gettimeofday(¤tTime, NULL); - srand((unsigned) currentTime.tv_usec); + struct timeval currentTime; + gettimeofday(¤tTime, NULL); + srand((unsigned) currentTime.tv_usec); - const float w = 1024.f; - const float h = 800.f; + const float w = 1024.f; + const float h = 800.f; - VkvgContext ctx = vkvg_create(surf); - //vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - vkvg_set_line_width (ctx,1); - //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL); + VkvgContext ctx = vkvg_create(surf); + //vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); + vkvg_set_line_width (ctx,1); + //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL); - for (uint32_t i=0; i