From 8c6d3a47e08c9f1330d2316eaa708ff097d02d2a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sun, 29 Apr 2018 03:54:29 +0200 Subject: [PATCH] add curve debug facility, measure frame rate --- CMakeLists.txt | 43 +- logo.png | Bin 0 -> 11252 bytes src/vkvg_context.c | 12 + src/vkvg_context_internal.c | 51 +- src/vkvg_context_internal.h | 10 +- tests/cairo-tests.h | 11 + tests/{ => common}/vkengine.c | 0 tests/{ => common}/vkengine.h | 0 tests/perf-test.h | 172 +++++ tests/perf_test_0.c | 147 ++++ tests/test_curves.c | 1243 +++++++++++++++++++++++++++++++++ 11 files changed, 1648 insertions(+), 41 deletions(-) create mode 100644 logo.png create mode 100644 tests/cairo-tests.h rename tests/{ => common}/vkengine.c (100%) rename tests/{ => common}/vkengine.h (100%) create mode 100644 tests/perf-test.h create mode 100644 tests/perf_test_0.c create mode 100644 tests/test_curves.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e7a29e2..99cae96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") ENDIF() OPTION(VKVG_BUILD_TESTS "build tests with glfw" ON) +SET(CAIRO_INCLUDE_DIRECTORY "/usr/include/cairo" CACHE STRING "CAIRO include directory") set(VULKAN_SDK "$ENV{VULKAN_SDK}" CACHE STRING "LunarG Vulkan SDK path") if (VULKAN_SDK) @@ -140,20 +141,30 @@ INSTALL(TARGETS vkvg LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -if (GLFW3_FOUND) - #build test app - ADD_EXECUTABLE(${PROJECT_NAME}_test tests/test1.c tests/vkengine.c) - TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}_test PRIVATE - ${Vulkan_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/src - ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include - ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src - ) - TARGET_LINK_LIBRARIES(${PROJECT_NAME}_test - ${Vulkan_LIBRARIES} - ${GLFW3_LIBRARY} - vkh_static - vkvg - ) +if (GLFW3_FOUND AND VKVG_BUILD_TESTS) + #build test apps + FILE(GLOB TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} tests/*.c) + FOREACH(TEST_FILE ${TESTS}) + GET_FILENAME_COMPONENT(TEST_NAME ${TEST_FILE} NAME_WE) + ADD_EXECUTABLE(${PROJECT_NAME}_${TEST_NAME} ${TEST_FILE} tests/common/vkengine.c) + TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}_${TEST_NAME} PRIVATE + ${CAIRO_INCLUDE_DIRECTORY} + ${Vulkan_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/tests/common/ + ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include + ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src + + ${FREETYPE_INCLUDE_DIRS} + ${HARFBUZZ_INCLUDE_DIRS} + ${FONTCONFIG_INCLUDE_DIR} + ) + TARGET_LINK_LIBRARIES(${PROJECT_NAME}_${TEST_NAME} + ${Vulkan_LIBRARIES} + ${GLFW3_LIBRARY} + vkh_static + vkvg + ) + ENDFOREACH() endif () diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..84fd6f69a935da3ef3d3e72f2de0a66935b0f521 GIT binary patch literal 11252 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 z zBj&`SLtcQSA^$N<&D4yM24N0NW&%P4lvZsBE0ltRLB=z zQ;+IlJX%-@$UONIMi2O!Hhuuvmiwd?i=wJnh{`u=p-eB)fuc?lDTtRE9)6_^*4YoY zeGtkl;Qc$nzDz?!ocXhRKvcO7_oz8J+TT@fx z$0e2j90b5BDk{RAN*(>fjjjT;nD?iGZ*3_hrUzZdzJLGzxMcr#VSRi$+Gq(7zDFB9 zGb}bUSlQM=JRaR`-$1}?WNCf(5zVn*FBY&+J%0qNn+(u28OgUR&!bA&>D%Azz4L3g zY};!X_PWSQ1iCD4I?L&q*5Hwv%vDu4%I_!Ij4yPsL<9hRxwA~Ap|;15B@Hr}P91bO z9JSLWGvnq!aFj$d&lA3&T)tfH9s7?LEBi8J^u!1Xz%qEhS<`0@4+v|&)2tGn+}Css z|Hx^=EVyI;sjho&I=+n3v=Ksd+}H>JBq-Tyfqm#_noW%xKdsAuBw>e9Q{dG+_&Wjs za9?UW5@WksvK;?q=+l{Z^vONJj5ub*N`t*#^05dE=KF(7`+9p@j%N0!eQ^FqfF=6M z&zB@9Kx6$4#WsitSm2vi2aJWtCN)%q)^qT9Q{C-3NPiIAB!5_XYIIX}ZcTA83EHbf z2P-?soFpT)DjK}thy0`@X~)0qZYM7i_?z+%ABg;QsbxY+mYKlIKCpLzrgz|m40dpB2C>?!+*#h{`P$Cb7dBrKWq<$U~g2mWQ3M#mk0T&q!@Z!e&~2T+B{tFRiTipsi`kg&mFijHjs zoRwibe|yI?qqg8!%>YmrcmkMR zn`Xc7BK~kFf8HIU;dUSIv$IS|-<;=Q4~bav$=4pIUp9R(n&vrrLqGrvDekR8 zU;l(<_@~|QhKdqA%3q+i7os(I_4nO-h~Rt2|Kuh8rH?-8W-+Lu@sydhtj&?2N1vgZfE%V`9JC7H)NKKtth|3~%e|JS>Eh24htE5@-Xh1|bJ QV|GAGO;5E(*(UP;0l1!pr~m)} literal 0 HcmV?d00001 diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 99ebcf9..6bdf6ed 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -31,6 +31,16 @@ static vec2 debugLinePoints[1000]; static uint32_t dlpCount = 0; #endif +void _init_debug_curves (VkvgContext ctx) { + ctx->m_approximation_scale = 1.0; + ctx->m_angle_tolerance = 0.05; + ctx->m_distance_tolerance = 0.1; + ctx->m_cusp_limit = 0.25; + ctx->curve_recursion_limit = 16; + ctx->curve_collinearity_epsilon = 0.001; + ctx->curve_angle_tolerance_epsilon = 0.1; +} + VkvgContext vkvg_create(VkvgSurface surf) { LOG(LOG_INFO, "CREATE Context: surf = %lu\n", surf); @@ -89,6 +99,8 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->references = 1; + _init_debug_curves (ctx); + return ctx; } void vkvg_flush (VkvgContext ctx){ diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 18ba758..b3ca6de 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -187,7 +187,7 @@ void _record_draw_cmd (VkvgContext ctx){ //DEBUG /*vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired); vkCmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1); - vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);*/ + _bind_draw_pipeline(ctx);*/ ////////// ctx->curIndStart = ctx->indCount; @@ -522,6 +522,9 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_ vec2 v0n = vec2_line_norm(ctx->points[iL], ctx->points[i]); vec2 v1n = vec2_line_norm(ctx->points[i], ctx->points[iR]); + if (vec2_equ(v0n,v1n)) + return; + vec2 bisec = vec2_norm(vec2_add(v0n,v1n)); float alpha = acos(v0n.x * v1n.x + v0n.y * v1n.y)/2; @@ -635,7 +638,7 @@ void _free_ctx_save (vkvg_context_save_t* sav){ free (sav); } - +/* #define m_approximation_scale 1.0 #define m_angle_tolerance 0.01 #define m_distance_tolerance 1.0 @@ -643,12 +646,12 @@ void _free_ctx_save (vkvg_context_save_t* sav){ #define curve_recursion_limit 10 #define curve_collinearity_epsilon 1.7 #define curve_angle_tolerance_epsilon 0.001 - +*/ 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) + if(level > ctx->curve_recursion_limit) { return; } @@ -680,16 +683,16 @@ void _recursive_bezier (VkvgContext ctx, float da1, da2; - if(d2 > curve_collinearity_epsilon && d3 > curve_collinearity_epsilon) + if(d2 > ctx->curve_collinearity_epsilon && d3 > ctx->curve_collinearity_epsilon) { // Regular care //----------------- - if((d2 + d3)*(d2 + d3) <= m_distance_tolerance * (dx*dx + dy*dy)) + if((d2 + d3)*(d2 + d3) <= ctx->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) + if(ctx->m_angle_tolerance < ctx->curve_angle_tolerance_epsilon) { _add_point (ctx, x1234, y1234); return; @@ -703,7 +706,7 @@ void _recursive_bezier (VkvgContext ctx, if(da1 >= M_PI) da1 = M_2_PI - da1; if(da2 >= M_PI) da2 = M_2_PI - da2; - if(da1 + da2 < m_angle_tolerance) + if(da1 + da2 < ctx->m_angle_tolerance) { // Finally we can stop the recursion //---------------------- @@ -711,15 +714,15 @@ void _recursive_bezier (VkvgContext ctx, return; } - if(m_cusp_limit != 0.0) + if(ctx->m_cusp_limit != 0.0) { - if(da1 > m_cusp_limit) + if(da1 > ctx->m_cusp_limit) { _add_point (ctx, x2, y2); return; } - if(da2 > m_cusp_limit) + if(da2 > ctx->m_cusp_limit) { _add_point (ctx, x3, y3); return; @@ -727,13 +730,13 @@ void _recursive_bezier (VkvgContext ctx, } } } else { - if(d2 > curve_collinearity_epsilon) + if(d2 > ctx->curve_collinearity_epsilon) { // p1,p3,p4 are collinear, p2 is considerable //---------------------- - if(d2 * d2 <= m_distance_tolerance * (dx*dx + dy*dy)) + if(d2 * d2 <= ctx->m_distance_tolerance * (dx*dx + dy*dy)) { - if(m_angle_tolerance < curve_angle_tolerance_epsilon) + if(ctx->m_angle_tolerance < ctx->curve_angle_tolerance_epsilon) { _add_point (ctx, x1234, y1234); return; @@ -744,28 +747,28 @@ void _recursive_bezier (VkvgContext ctx, da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); if(da1 >= M_PI) da1 = M_2_PI - da1; - if(da1 < m_angle_tolerance) + if(da1 < ctx->m_angle_tolerance) { _add_point (ctx, x2, y2); _add_point (ctx, x3, y3); return; } - if(m_cusp_limit != 0.0) + if(ctx->m_cusp_limit != 0.0) { - if(da1 > m_cusp_limit) + if(da1 > ctx->m_cusp_limit) { _add_point (ctx, x2, y2); return; } } } - } else if(d3 > curve_collinearity_epsilon) { + } else if(d3 > ctx->curve_collinearity_epsilon) { // p1,p2,p4 are collinear, p3 is considerable //---------------------- - if(d3 * d3 <= m_distance_tolerance * (dx*dx + dy*dy)) + if(d3 * d3 <= ctx->m_distance_tolerance * (dx*dx + dy*dy)) { - if(m_angle_tolerance < curve_angle_tolerance_epsilon) + if(ctx->m_angle_tolerance < ctx->curve_angle_tolerance_epsilon) { _add_point (ctx, x1234, y1234); return; @@ -776,16 +779,16 @@ void _recursive_bezier (VkvgContext ctx, da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2)); if(da1 >= M_PI) da1 = M_2_PI - da1; - if(da1 < m_angle_tolerance) + if(da1 < ctx->m_angle_tolerance) { _add_point (ctx, x2, y2); _add_point (ctx, x3, y3); return; } - if(m_cusp_limit != 0.0) + if(ctx->m_cusp_limit != 0.0) { - if(da1 > m_cusp_limit) + if(da1 > ctx->m_cusp_limit) { _add_point (ctx, x3, y3); return; @@ -799,7 +802,7 @@ void _recursive_bezier (VkvgContext ctx, //----------------- dx = x1234 - (x1 + x4) / 2; dy = y1234 - (y1 + y4) / 2; - if(dx*dx + dy*dy <= m_distance_tolerance) + if(dx*dx + dy*dy <= ctx->m_distance_tolerance) { _add_point (ctx, x1234, y1234); return; diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index e0282d7..0ab0e42 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -28,7 +28,7 @@ #include "vkh.h" #include "vkvg_fonts.h" -#define VKVG_PTS_SIZE 16384 +#define VKVG_PTS_SIZE 32768 #define VKVG_VBO_SIZE VKVG_PTS_SIZE * 2 #define VKVG_IBO_SIZE VKVG_VBO_SIZE * 2 #define VKVG_PATHES_SIZE 256 @@ -137,6 +137,14 @@ typedef struct _vkvg_context_t { vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr VkClearRect clearRect; + //debug curves + float m_approximation_scale; + float m_angle_tolerance; + float m_distance_tolerance; + float m_cusp_limit; + float curve_recursion_limit; + float curve_collinearity_epsilon; + float curve_angle_tolerance_epsilon; }vkvg_context; bool _current_path_is_empty (VkvgContext ctx); diff --git a/tests/cairo-tests.h b/tests/cairo-tests.h new file mode 100644 index 0000000..67fdb98 --- /dev/null +++ b/tests/cairo-tests.h @@ -0,0 +1,11 @@ +#ifndef CAIROTESTS_H +#define CAIROTESTS_H + +#include "cairo.h" + +void* createContext() { + + cairo_create(); +} + +#endif // CAIROTESTS_H diff --git a/tests/vkengine.c b/tests/common/vkengine.c similarity index 100% rename from tests/vkengine.c rename to tests/common/vkengine.c diff --git a/tests/vkengine.h b/tests/common/vkengine.h similarity index 100% rename from tests/vkengine.h rename to tests/common/vkengine.h diff --git a/tests/perf-test.h b/tests/perf-test.h new file mode 100644 index 0000000..3df035d --- /dev/null +++ b/tests/perf-test.h @@ -0,0 +1,172 @@ +#ifndef PERFTEST_H +#define PERFTEST_H + +#include "vkvg.h" +#include +#include + +enum DrawMode { + DM_FILL = 0x1, + DM_STROKE = 0x2, + DM_BOTH = 0x3 +}; + +typedef struct _results { + double run_min; + double run_max; + double avg_time; + double median_time; + double std_deriv; +} results_t; + +results_t initResults () { + results_t res = {}; + res.run_min = DBL_MAX; + res.run_max = DBL_MIN; + return res; +} + +typedef struct _options { + char* test_name; + int iterations; + int count; + int width; + int height; + enum DrawMode drawMode; +} options_t; + +options_t initOptions (int argc, char *argv[]) { + options_t opt = {}; + opt.iterations = 100; + opt.count = 1000; + opt.width = 1024; + opt.height = 800; + opt.drawMode = DM_FILL; + + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'w': + sscanf (argv[++i], "%d", &opt.width); + break; + case 'h': + sscanf (argv[++i], "%d", &opt.height); + break; + case 'i': + sscanf (argv[++i], "%d", &opt.iterations); + break; + case 'c': + sscanf (argv[++i], "%d", &opt.count); + break; + case 'f': + opt.drawMode = DM_FILL; + break; + case 's': + opt.drawMode = DM_STROKE; + break; + case 'b': + opt.drawMode = DM_BOTH; + break; + default: + break; + } + } + } + return opt; +} + + +void printHelp () { + printf ("\t-w x : Set test surface width.\n"); + printf ("\t-h x : Set test surface height.\n"); + printf ("\t-i x : Set iterations count.\n"); + printf ("\t-c x : Set shape occurence count.\n"); + printf ("\t-f : Set shape draw mode to fill.\n"); + printf ("\t-s : Set shape draw mode to stroke.\n"); + printf ("\t-b : Set shape draw mode to fill and stroke.\n"); +} +void outputResultsHeadRow (options_t* opt) { + printf ("__________________________________________________________________________________________________________\n"); + printf ("| Test Name | Iter | Cpt | Resolution |DM | Min | Max | Average | Median | Std Deriv|\n"); + printf ("|-----------------|------|------|-------------|---|----------|----------|----------|----------|----------|\n"); +} +void outputResultsOnOneLine (options_t* opt, results_t* res) { + printf ("| %.15s | %4d | %4d | %4d x %4d | ", + opt->test_name, opt->iterations, opt->count, opt->width, opt->height); + switch (opt->drawMode) { + case DM_BOTH: + printf ("B | "); + break; + case DM_FILL: + printf ("F | "); + break; + case DM_STROKE: + printf ("S | "); + break; + } + printf ("%.6f | %.6f | %.6f | %.6f | %.6f |", + res->run_min, res->run_max, res->avg_time, res->median_time, res->std_deriv); +} + +void outputResults (options_t* opt, results_t* res) { + printf ("Test name: %s\n", opt->test_name); + printf ("\nOptions\n"); + printf ("=======\n"); + printf ("Iterations = %d\n", opt->iterations); + printf ("Shape count = %d\n", opt->count); + printf ("Canva size = %d x %d\n", opt->width, opt->height); + switch (opt->drawMode) { + case DM_BOTH: + printf ("Draw Mode = FILL and STROKE\n"); + break; + case DM_FILL: + printf ("Draw Mode = FILL\n"); + break; + case DM_STROKE: + printf ("Draw Mode = STROKE\n"); + break; + } + printf ("\nResults\n"); + printf ("=======\n"); + printf ("Minimum = %f (sec)\n", res->run_min); + printf ("Maximum = %f (sec)\n", res->run_max); + printf ("Average = %f (sec)\n", res->avg_time); + printf ("Median = %f (sec)\n", res->median_time); + printf ("Std reriv = %f \n", res->std_deriv); +} + +double get_tick (void) +{ + struct timeval now; + gettimeofday (&now, NULL); + return (double)now.tv_sec + (double)now.tv_usec / 1000000.0; +} +double median_run_time (double data[], int n) +{ + double temp; + int i, j; + for (i = 0; i < n; i++) + for (j = i+1; j < n; j++) + { + if (data[i] > data[j]) + { + temp = data[j]; + data[j] = data[i]; + data[i] = temp; + } + } + if (n % 2 == 0) + return (data[n/2] + data[n/2-1])/2; + else + return data[n/2]; +} +double standard_deviation (const double data[], int n, double mean) +{ + double sum_deviation = 0.0; + int i; + for (i = 0; i < n; ++i) + sum_deviation += (data[i]-mean) * (data[i]-mean); + return sqrt (sum_deviation / n); +} + +#endif // PERFTEST_H diff --git a/tests/perf_test_0.c b/tests/perf_test_0.c new file mode 100644 index 0000000..cff9f13 --- /dev/null +++ b/tests/perf_test_0.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2018 Jean-Philippe Bruyère + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "vkengine.h" +#include "vkvg.h" +#include "vkh_device.h" +#include "vkh_presenter.h" +#include +#include + +#include "perf-test.h" + + + +VkvgDevice device; +/*VkvgSurface surf = NULL; + +void simple_paint () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_paint(ctx); + vkvg_destroy(ctx); +} +void simple_rectangle_fill () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0,1,0,1); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_fill(ctx); + vkvg_destroy(ctx); +} +void simple_rectangle_stroke () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0,0,1,1); + vkvg_set_line_width(ctx,10.f); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_stroke(ctx); + vkvg_destroy(ctx); +}*/ + +vkvg_color_t getRadomColor () { + vkvg_color_t c = { + (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX, + }; +} + +void drawRandomRectangle (options_t* opt, VkvgContext ctx) { + for (int i=0; icount; i++) { + vkvg_color_t c = getRadomColor(); + vkvg_set_source_rgba(ctx, c.r, c.g, c.b, c.a); + + float x = (float)rand()/RAND_MAX * opt->width - 10; + float y = (float)rand()/RAND_MAX * opt->height - 10; + float w = (float)rand()/RAND_MAX * 200 + 10; + float h = (float)rand()/RAND_MAX * 200 + 10; + + vkvg_rectangle(ctx, x, y, w, h); + } + if (opt->drawMode == DM_BOTH) + vkvg_fill_preserve(ctx); + else if (opt->drawMode == DM_FILL) + vkvg_fill (ctx); + if (opt->drawMode & DM_STROKE) + vkvg_stroke (ctx); +} + +results_t performTest (options_t* opt) { + results_t res = initResults(); + + double run_time_values[opt->iterations]; + double start_time, stop_time, run_time, run_total = 0; + + VkvgSurface surf = vkvg_surface_create(device, opt->width, opt->height); + void* ctx = vkvg_create(surf); + + for (int i=0; iiterations; i++) { + + start_time = get_tick(); + + drawRandomRectangle (opt, ctx); + + stop_time = get_tick(); + + run_time = stop_time - start_time; + run_time_values[i] = run_time; + + if (run_time < res.run_min) + res.run_min = run_time; + if (run_time > res.run_max) + res.run_max = run_time; + run_total += run_time; + } + + vkvg_destroy (ctx); + vkvg_surface_destroy (surf); + + res.avg_time = run_total / (double)opt->iterations; + res.median_time = median_run_time(run_time_values, opt->iterations); + res.std_deriv = standard_deviation(run_time_values,opt->iterations, res.avg_time); + + return res; +} + +int main(int argc, char *argv[]) { + srand(time(NULL)); + + options_t opt = initOptions(argc, argv); + opt.test_name = "vkvg rectangles and"; + + vk_engine_t* e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 1024, 800); + VkhPresenter r = e->renderer; + + device = vkvg_device_create (r->dev->phy, r->dev->dev, r->qFam, 0); + + results_t res = performTest (&opt); + + //outputResults(&opt, &res); + outputResultsHeadRow(&opt); + outputResultsOnOneLine(&opt, &res); + + vkvg_device_destroy (device); + + vkengine_destroy (e); + + return 0; +} diff --git a/tests/test_curves.c b/tests/test_curves.c new file mode 100644 index 0000000..27eaaeb --- /dev/null +++ b/tests/test_curves.c @@ -0,0 +1,1243 @@ +/* + * Copyright (c) 2018 Jean-Philippe Bruyère + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "vkengine.h" + +#include "vkvg.h" +#include "string.h" //for nanosvg +#define NANOSVG_IMPLEMENTATION // Expands implementation +#include "nanosvg.h" +#include "vkh_device.h" +#include "vkh_presenter.h" + +#include "vkvg_context_internal.h" +#include + +VkvgDevice device; +VkvgSurface surf = NULL; + +static float m_approximation_scale = 1.0; +static float m_angle_tolerance = 0.07; +static float m_distance_tolerance = 1.0; +static float m_cusp_limit = 0.05; +static float curve_recursion_limit = 10; +static float curve_collinearity_epsilon = 1.68; +static float curve_angle_tolerance_epsilon = 0.001; +static double frameTime = 0; + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (action == GLFW_RELEASE) + return; + float step = 0.01; + + if (mods & GLFW_MOD_SHIFT) + step = -step; + if (mods & GLFW_MOD_CONTROL) + step *= 0.1; + switch (key) { + case GLFW_KEY_F1: + m_angle_tolerance += step; + break; + case GLFW_KEY_F2: + m_distance_tolerance += step; + break; + case GLFW_KEY_F3: + m_cusp_limit += step; + break; + case GLFW_KEY_F4: + curve_recursion_limit += step * 1000.0; + break; + case GLFW_KEY_F6: + curve_collinearity_epsilon += step; + break; + case GLFW_KEY_F7: + curve_angle_tolerance_epsilon += step; + break; + case GLFW_KEY_ESCAPE : + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } +} +static void char_callback (GLFWwindow* window, uint32_t c){} +static void mouse_move_callback(GLFWwindow* window, double x, double y){} +static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){} + +void vkvg_test_gradient (VkvgContext ctx) { + VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0); + vkvg_set_line_width(ctx, 20); + vkvg_patter_add_color_stop(pat, 0, 1, 0, 0, 1); + vkvg_patter_add_color_stop(pat, 0.5, 0, 1, 0, 1); + vkvg_patter_add_color_stop(pat, 1, 0, 0, 1, 1); + vkvg_set_source (ctx, pat); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_fill (ctx); + //vkvg_stroke (ctx); + vkvg_pattern_destroy (pat); +} + +void vkvg_test_clip(VkvgContext ctx){ + vkvg_move_to(ctx,10,10); + vkvg_line_to(ctx,400,150); + vkvg_line_to(ctx,900,10); + vkvg_line_to(ctx,700,450); + vkvg_line_to(ctx,900,750); + vkvg_line_to(ctx,500,650); + vkvg_line_to(ctx,100,800); + vkvg_line_to(ctx,150,400); + vkvg_clip(ctx); +} +void vkvg_test_fill(VkvgContext ctx){ + vkvg_set_source_rgba(ctx,0.1,0.9,0.1,1.0); + vkvg_set_line_width(ctx,20); + vkvg_move_to(ctx,100,100); + vkvg_rel_line_to(ctx,100,100); + vkvg_rel_line_to(ctx,100,-50); + vkvg_rel_line_to(ctx,100,400); + vkvg_line_to(ctx,400,350); + vkvg_line_to(ctx,900,150); +// vkvg_line_to(ctx,700,450); +// vkvg_line_to(ctx,900,750); +// vkvg_line_to(ctx,500,650); +// vkvg_line_to(ctx,100,800); +// vkvg_line_to(ctx,150,400); + vkvg_close_path(ctx); + vkvg_stroke(ctx); +} +void vkvg_test_fill_and_stroke (VkvgContext 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_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, 0, 0, 0); + vkvg_stroke (ctx); +} +void vkvg_test_curves2 (VkvgContext ctx) { + vkvg_move_to (ctx, 400, 50); + vkvg_curve_to (ctx, 400, 50, 600,5,600,100); + vkvg_curve_to (ctx, 600, 5, 800,50,800,50); + + vkvg_move_to (ctx, 400, 150); + vkvg_curve_to (ctx, 0, 0, 800, 0, 300, 350); + vkvg_curve_to (ctx, 500, 500, 300, 0, 500, 700); + + //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, 0,0,0,0.5); + vkvg_set_line_width(ctx, 40); + vkvg_stroke(ctx); +} +void vkvg_test_curves (VkvgContext ctx){ + + vkvg_set_line_width(ctx, 10); + vkvg_set_source_rgb (ctx, 0,0,0); + + 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_close_path(ctx); + //vkvg_curve_to(ctx, 150,100,200,150,200,200); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgba (ctx, 0,0,0,0.5); + vkvg_stroke(ctx); + + vkvg_arc(ctx, 150, 100, 100, 0, M_PI*2); + vkvg_fill(ctx); + vkvg_arc(ctx, 200, 200, 100, 0, M_PI*2); + vkvg_stroke(ctx); + + vkvg_set_line_width(ctx, 90); + vkvg_arc(ctx, 120, 500, 100, 0, M_PI*2); + vkvg_stroke(ctx); + +} +void vkvg_test_stroke(VkvgContext ctx){ + vkvg_set_line_width(ctx, 2); + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_move_to(ctx,200.5,200.5); + vkvg_line_to(ctx,400.5,200.5); + vkvg_line_to(ctx,400.5,400.5); + vkvg_line_to(ctx,200.5,400.5); + vkvg_close_path(ctx); + vkvg_stroke_preserve(ctx); + vkvg_set_source_rgba(ctx,0,0.2,0.35,1); + vkvg_fill(ctx); + vkvg_set_source_rgba(ctx,0.5,1,0,1); + vkvg_move_to(ctx,300.5,300.5); + vkvg_line_to(ctx,500.5,300.5); + vkvg_line_to(ctx,500.5,500.5); + vkvg_line_to(ctx,300.5,500.5); + vkvg_close_path(ctx); + vkvg_stroke(ctx); + vkvg_set_line_width(ctx, 40); + vkvg_set_source_rgba(ctx,0.5,0.6,1,1.0); + vkvg_move_to(ctx,700,475); + vkvg_line_to(ctx,400,475); + vkvg_stroke(ctx); + vkvg_set_source_rgba(ctx,0,0.5,0.5,0.5); + vkvg_move_to(ctx,300,200); + vkvg_arc(ctx, 200,200,100,0, M_PI); + vkvg_stroke(ctx); + + vkvg_set_line_width(ctx, 20); + vkvg_set_source_rgba(ctx,0.1,0.1,0.1,0.5); + vkvg_move_to(ctx,100,60); + vkvg_line_to(ctx,400,600); + vkvg_stroke(ctx); +} +void test_text (VkvgContext ctx) { + int size = 19; + int penY = 50; + int penX = 10; + + /*vkvg_rectangle(ctx,30,0,100,400); + vkvg_clip(ctx);*/ + + //vkvg_select_font_face(ctx, "/usr/local/share/fonts/DroidSansMono.ttf"); + //vkvg_select_font_face(ctx, "/usr/share/fonts/truetype/unifont/unifont.ttf"); + + vkvg_set_font_size(ctx,12); + vkvg_select_font_face(ctx, "droid"); + vkvg_font_extents_t fe; + vkvg_font_extents (ctx,&fe); + vkvg_move_to(ctx, penX,penY); + vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1); + vkvg_text_extents_t te; + vkvg_text_extents(ctx,"abcdefghijk",&te); + vkvg_show_text (ctx,"abcdefghijk"); + penX+= te.x_advance; + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"*abcdefghijk2"); + penY+=2*size; + + + vkvg_select_font_face(ctx, "times"); + vkvg_set_source_rgba(ctx,0.9,0.7,0.7,1); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz"); + penY+=size; + + + + vkvg_select_font_face(ctx, "droid"); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"lmnopqrstuvwxyz123456789"); + penY+=size; + + + + vkvg_select_font_face(ctx, "times:bold"); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz"); + penY+=size; + + + vkvg_select_font_face(ctx, "droid"); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + penY+=size; + + + + vkvg_select_font_face(ctx, "arial:italic"); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz"); + penY+=size; + + + vkvg_select_font_face(ctx, "arial"); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + penY+=size; + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"this is a test"); + penY+=size; + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"this is another test to see if label is working"); + penY+=size; + + vkvg_select_font_face(ctx, "mono"); + vkvg_move_to(ctx, penX,penY); + vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + penY+=size; + + vkvg_move_to(ctx, 80,400); + vkvg_show_text (ctx,"Ленивый рыжий кот"); + + + /*vkvg_move_to(ctx, 150,250); + vkvg_show_text (ctx,"test string é€"); + vkvg_move_to(ctx, 150,300); + vkvg_show_text (ctx,"كسول الزنجبيل القط"); + vkvg_move_to(ctx, 150,350); + vkvg_show_text (ctx,"懶惰的姜貓");*/ + + //vkvg_show_text (ctx,"ABCDABCD"); + //vkvg_show_text (ctx,"j"); +} +void vkvg_test_stroke2(VkvgContext ctx){ + vkvg_set_line_width(ctx,20); + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_move_to(ctx,200,200); + vkvg_line_to(ctx,400,200); + vkvg_line_to(ctx,400,400); + vkvg_line_to(ctx,200,400); + vkvg_close_path(ctx); + vkvg_stroke(ctx); + vkvg_set_source_rgba(ctx,0.5,1,0,1); + vkvg_move_to(ctx,300,300); + vkvg_line_to(ctx,500,300); + vkvg_line_to(ctx,500,500); + vkvg_line_to(ctx,300,500); + vkvg_close_path(ctx); + vkvg_stroke(ctx); + vkvg_set_line_width(ctx,10); + vkvg_set_source_rgba(ctx,0.5,0.6,1,1); + vkvg_move_to(ctx,700,475); + vkvg_line_to(ctx,400,475); + vkvg_stroke(ctx); + vkvg_set_source_rgba(ctx,1,0,1,1); + vkvg_move_to(ctx,700,500); + + vkvg_arc(ctx, 600,500,100,M_PI, 2.0*M_PI); + vkvg_stroke(ctx); + + + vkvg_set_line_width(ctx,20); + vkvg_set_source_rgba(ctx,1,1,0,1); + vkvg_move_to(ctx,100,50); + vkvg_line_to(ctx,400,50); + vkvg_stroke(ctx); +} +void vkvg_test_fill2(VkvgContext ctx){ + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_move_to(ctx,200,200); + vkvg_line_to(ctx,250,150); + vkvg_line_to(ctx,200,100); + vkvg_line_to(ctx,300,150); + vkvg_line_to(ctx,700,100); + vkvg_line_to(ctx,400,200); + vkvg_line_to(ctx,400,400); + vkvg_line_to(ctx,200,400); + vkvg_line_to(ctx,300,300); + vkvg_close_path(ctx); + vkvg_fill(ctx); +} +void test_img_surface () { + VkvgContext ctx = vkvg_create(surf); + VkvgSurface imgSurf;// = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png"); + //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png"); + //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/path2674.png"); + //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/horse-black-head-shape-of-a-chess-piece_318-52446.jpg"); + /*vkvg_set_source_surface(ctx, imgSurf, 200, 200); + vkvg_paint(ctx); + vkvg_set_source_surface(ctx, imgSurf, 400, 400); + vkvg_paint(ctx); + vkvg_flush(ctx); + vkvg_surface_destroy(imgSurf);*/ + + imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/miroir.jpg"); + fflush(stdout); + vkvg_set_source_surface(ctx, imgSurf, 0, 0); + vkvg_paint(ctx); + //vkvg_flush(ctx); + vkvg_set_source_rgba(ctx,1,0,0,1); + + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); +} +void test_line_caps (VkvgContext ctx) { + + float x = 20, y = 20, dx = 30, dy = 60; + + //vkvg_scale(ctx,5,5); + vkvg_set_line_width(ctx,26); + vkvg_set_source_rgba(ctx,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_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); +} +void test_line_join (VkvgContext ctx){ + float x = 50, y = 150, dx = 150, dy = 140; + + //vkvg_scale(ctx,2,2); + + vkvg_set_line_width(ctx,50); + vkvg_set_source_rgba(ctx,0,0,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,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_move_to(ctx,x,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); + +// vkvg_rel_line_to(ctx,dx,-dy); +// vkvg_rel_line_to(ctx,dx,dy); +// vkvg_stroke(ctx); +// vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL); +// vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5)); +// vkvg_rel_line_to(ctx,dx,-dy); +// vkvg_rel_line_to(ctx,dx,dy); +// vkvg_stroke(ctx); +// vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); +// vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5)); +// vkvg_rel_line_to(ctx,dx,-dy); +// vkvg_rel_line_to(ctx,dx,dy); +// vkvg_stroke(ctx); + vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER); +} +void test_colinear () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1); + vkvg_paint(ctx); + + vkvg_set_source_rgba(ctx,0,0,0,0.5); + vkvg_set_line_width(ctx,30); + + vkvg_move_to(ctx,100,100); + vkvg_line_to(ctx,100,200); + vkvg_line_to(ctx,100,300); + //vkvg_line_to(ctx,100,0); + vkvg_stroke(ctx); + + vkvg_destroy(ctx); +} + +void multi_test1 () { + VkvgSurface surf2 = vkvg_surface_create (device,800,800);; + VkvgContext ctx = vkvg_create (surf2); + + vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0); + vkvg_paint(ctx); + + vkvg_test_fill(ctx); + vkvg_test_fill2(ctx); + + + //test_line_join(ctx); + + //vkvg_test_clip(ctx); + + //test_text(ctx); + + + vkvg_test_stroke(ctx); + + vkvg_translate(ctx, 100,50); +// vkvg_rotate(ctx, 0.2); + //vkvg_scale(ctx, 2,2); + + + //vkvg_test_gradient (ctx); + + vkvg_test_curves(ctx); + vkvg_test_curves2(ctx); + + /*vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR); + vkvg_rectangle(ctx,100,100,300,300); + vkvg_fill(ctx); + vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);*/ + + //test_img_surface(ctx); + //test_line_caps(ctx); + + vkvg_destroy(ctx); + ctx = vkvg_create(surf); + + vkvg_set_source_rgba(ctx,1.0,0.0,0.0,1); + vkvg_paint(ctx); +// vkvg_set_source_rgba(ctx,0.0,0.0,1.0,1); +// vkvg_rectangle(ctx,100,100,500,500); +// vkvg_fill(ctx); + + VkvgPattern pat = vkvg_pattern_create_for_surface(surf2); + vkvg_pattern_set_extend(pat, VKVG_EXTEND_REFLECT); + vkvg_pattern_set_filter(pat, VKVG_FILTER_BILINEAR); + vkvg_set_source (ctx, pat); + //vkvg_rectangle(ctx,100,100,400,400); + //vkvg_fill(ctx); + vkvg_paint(ctx); + vkvg_translate(ctx,200,200); + vkvg_paint(ctx); + vkvg_rotate(ctx,0.7); + vkvg_paint(ctx); + vkvg_pattern_destroy (pat); + vkvg_destroy(ctx); + vkvg_surface_destroy(surf2); +} + +void cairo_test_fill_rule (VkvgContext cr){ + vkvg_set_line_width (cr, 6); + + //vkvg_scale(cr,3,3); + vkvg_set_source_rgba(cr,1,0,0,1); + vkvg_move_to(cr,50,150); + vkvg_rel_line_to(cr,50,70); + vkvg_rel_line_to(cr,50,0); + vkvg_rel_line_to(cr,50,-70); + vkvg_rel_line_to(cr,0,-60); + vkvg_rel_line_to(cr,-50,-30); + vkvg_rel_line_to(cr,-50,0); + vkvg_rel_line_to(cr,-50,30); + vkvg_close_path(cr); + + +// vkvg_set_line_join(cr,VKVG_LINE_JOIN_ROUND); + vkvg_set_source_rgb (cr, 0, 0.7, 0); + vkvg_rectangle (cr, 12, 12, 232, 70); + //vkvg_stroke (cr); +// vkvg_new_sub_path (cr); + vkvg_arc (cr, 64, 64, 40, 0, M_PI*2); + //vkvg_close_path(cr); + + vkvg_new_sub_path (cr); + vkvg_arc_negative (cr, 192, 64, 40, 2*M_PI, 0); + //vkvg_close_path(cr); + + //vkvg_rectangle (cr, 30, 30, 20, 200); + //vkvg_rectangle (cr, 130, 30, 20, 200); + //vkvg_set_fill_rule (cr, vkvg_FILL_RULE_EVEN_ODD); + + vkvg_fill_preserve(cr); + + vkvg_set_source_rgb (cr, 0, 0, 0); + vkvg_stroke (cr); +} +void cairo_test_text (VkvgContext cr) { + vkvg_text_extents_t extents; + + const char *utf8 = "vkvg"; + float x,y; + + vkvg_select_font_face (cr, "times"); + vkvg_set_font_size (cr, 100.0); + vkvg_text_extents (cr, utf8, &extents); + vkvg_set_source_rgb(cr,0,0,0); + + x=25.0; + y=150.0; + + vkvg_move_to (cr, x,y); + vkvg_show_text (cr, utf8); + + /* draw helping lines */ + vkvg_set_source_rgba (cr, 1, 0.2, 0.2, 0.6); + vkvg_set_line_width (cr, 6.0); + vkvg_arc (cr, x, y, 10.0, 0, 2*M_PI); + vkvg_fill (cr); + vkvg_move_to (cr, x,y); + vkvg_rel_line_to (cr, 0, -extents.height); + vkvg_rel_line_to (cr, extents.width, 0); + vkvg_rel_line_to (cr, extents.x_bearing, -extents.y_bearing); + vkvg_stroke (cr); +} +void cairo_test_clip (VkvgContext cr){ + vkvg_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI); + vkvg_clip (cr); + //vkvg_new_path (cr); /* current path is not + // consumed by vkvg_clip() */ + vkvg_set_source_rgba(cr, 0, 0, 0, 1); + vkvg_rectangle (cr, 0, 0, 256, 256); + vkvg_fill (cr); + vkvg_set_source_rgba (cr, 0, 1, 0, 1); + vkvg_move_to (cr, -100, -100); + vkvg_line_to (cr, 256, 256); + vkvg_move_to (cr, 356, -100); + vkvg_line_to (cr, 0, 256); + vkvg_set_line_width (cr, 10.0); + vkvg_stroke (cr); +} +void cairo_test_curves (VkvgContext cr){ + float x=25.6, y=128.0; + float x1=102.4, y1=230.4, + x2=153.6, y2=25.6, + x3=230.4, y3=128.0; + + vkvg_set_source_rgb (cr, 0, 0, 0); + vkvg_move_to (cr, x, y); + vkvg_curve_to (cr, x1, y1, x2, y2, x3, y3); + + vkvg_set_line_width (cr, 10.0); + vkvg_stroke (cr); + + vkvg_set_source_rgba (cr, 1, 0.2, 0.2, 0.6); + vkvg_set_line_width (cr, 6.0); + vkvg_move_to (cr,x,y); vkvg_line_to (cr,x1,y1); + vkvg_move_to (cr,x2,y2); vkvg_line_to (cr,x3,y3); + vkvg_stroke (cr); +} +void cairo_test_rounded_rect (VkvgContext cr) { + /* a custom shape that could be wrapped in a function */ + float x0 = 25.6, /* parameters like vkvg_rectangle */ + y0 = 25.6, + rect_width = 204.8, + rect_height = 204.8, + radius = 102.4; /* and an approximate curvature radius */ + + float x1,y1; + + x1=x0+rect_width; + y1=y0+rect_height; + if (!rect_width || !rect_height) + return; + if (rect_width/2> 24 & 255) / 255.f; + float b = (c >> 16 & 255) / 255.f; + float g = (c >> 8 & 255) / 255.f; + float r = (c & 255) / 255.f; + vkvg_set_source_rgba(ctx,r,g,b,a*alpha); +} + +void test_svg (VkvgContext ctx) { + //VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0.5,0.5,0.5,1); + vkvg_paint(ctx); + + NSVGimage* svg; + NSVGshape* shape; + NSVGpath* path; + //svg = nsvgParseFromFile("/mnt/data/images/svg/tux.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/world.svg", "px", 96); + svg = nsvgParseFromFile("/mnt/data/images/svg/tiger.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/koch_curve.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/diamond1.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/diamond2.svg", "px", 96); + //svg = nsvgParseFromFile("/home/jp/yahweh-protosinaitic.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/WMD-biological.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/Skull_and_crossbones.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/IconAlerte.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/Svg_example4.svg", "px", 96); + + //vkvg_scale(ctx, 3,3); + vkvg_set_source_rgba(ctx,0.0,0.0,0.0,1); + + for (shape = svg->shapes; shape != NULL; shape = shape->next) { + + 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); + } + + nsvgDelete(svg); + + + //vkvg_destroy(ctx); +} + +void print_float (VkvgContext ctx){ + char str[50]; + float penY = 20, penX = 10, dy = 18; + + vkvg_set_source_rgb(ctx,1,1,1); + vkvg_set_font_size(ctx,14 ); + vkvg_select_font_face(ctx, "mono"); + + sprintf (str, "frame (µs): %.0lf", frameTime); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "fps: %lf", floor(1000000 / frameTime)); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "Angle tol: %f", ctx->m_angle_tolerance); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "Dist tol: %f", ctx->m_distance_tolerance); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "Cups lim: %f", ctx->m_cusp_limit); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "Recurs lim: %f", ctx->curve_recursion_limit); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "Colinear €: %f", ctx->curve_collinearity_epsilon); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); + penY += dy; + sprintf (str, "Angle tol €: %f", ctx->curve_angle_tolerance_epsilon); + vkvg_move_to(ctx,penX,penY); + vkvg_show_text(ctx, str); +} + +double time_diff(struct timeval x , struct timeval y) +{ + double x_ms , y_ms , diff; + + x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec; + y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec; + + diff = (double)y_ms - (double)x_ms; + + return diff; +} +void test_1 () { + const char* text = "This is a petit test {}"; + + VkvgContext ctx = vkvg_create (surf); + + vkvg_set_source_rgba(ctx,0,0,0,1.0); + vkvg_paint (ctx); + vkvg_set_source_rgba(ctx,1,1,1,1.0); + + vkvg_select_font_face(ctx, "mono"); + vkvg_set_font_size(ctx, 12); + + vkvg_font_extents_t f = {}; + vkvg_font_extents(ctx, &f); + + vkvg_text_extents_t t = {}; + vkvg_text_extents(ctx, text, &t); + + vkvg_move_to(ctx,100,100); + vkvg_show_text(ctx, text); + + vkvg_move_to(ctx,100,100.5 - f.ascent); + vkvg_line_to(ctx,100+t.width,100.5 - f.ascent); + + vkvg_move_to(ctx,100,100.5 - f.descent); + vkvg_line_to(ctx,100+t.width,100.5 - f.descent); + + vkvg_stroke(ctx); + + vkvg_flush(ctx); + vkvg_destroy (ctx); +} +void test_painting () { + VkvgSurface surf2 = vkvg_surface_create (device,400,400);; + VkvgContext ctx = vkvg_create (surf2); + + vkvg_set_source_rgba(ctx,1.0,0.,0.,1.0); + vkvg_paint (ctx); + + vkvg_destroy (ctx); + ctx = vkvg_create (surf); + + vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0); + vkvg_paint (ctx); + + //vkvg_set_source_surface(ctx,surf2,0,0); + + //VkvgPattern pat = vkvg_get_source (ctx); + VkvgPattern pat = vkvg_pattern_create_for_surface(surf2); + vkvg_pattern_set_extend (pat,VKVG_EXTEND_REFLECT); + vkvg_set_source(ctx,pat); + //vkvg_paint (ctx); + //vkvg_set_source_rgba(ctx,0,1,0,1.0); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_fill(ctx); + + vkvg_destroy (ctx); + vkvg_surface_destroy (surf2); + vkvg_pattern_destroy (pat); +} + +void simple_paint () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_paint(ctx); + vkvg_destroy(ctx); +} +void simple_rectangle_fill () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0,1,0,1); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_fill(ctx); + vkvg_destroy(ctx); +} +void simple_rectangle_stroke () { + VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0,0,1,1); + vkvg_set_line_width(ctx,10.f); + vkvg_rectangle(ctx,100,100,200,200); + vkvg_stroke(ctx); + vkvg_destroy(ctx); +} +int main(int argc, char *argv[]) { + + //dumpLayerExts(); + + vk_engine_t* e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 1024, 800); + VkhPresenter r = e->renderer; + vkengine_set_key_callback (e, key_callback); + + device = vkvg_device_create (r->dev->phy, r->dev->dev, r->qFam, 0); + surf = vkvg_surface_create(device, 1024, 800); + + //test_svg(); + // + + + //test_grad_transforms(); + //cairo_tests(); + //test_colinear(); + + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf)); + + /* + while (!vkengine_should_close (e)) { + glfwPollEvents(); + //test_1(); + cairo_tests(); + //simple_paint(); + //simple_rectangle_stroke(); + //simple_rectangle_fill(); + //test_img_surface(); + //multi_test1(); + //test_painting(); + if (!vkh_presenter_draw (r)) + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf)); + } + */ + struct timeval before , after; + + + while (!vkengine_should_close (e)) { + + + VkvgContext ctx = vkvg_create(surf); + + gettimeofday(&before , NULL); + + vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0); + vkvg_paint(ctx); + + ctx->m_angle_tolerance = m_angle_tolerance; + ctx->m_distance_tolerance = m_distance_tolerance; + ctx->m_cusp_limit = m_cusp_limit; + ctx->curve_recursion_limit = curve_recursion_limit; + ctx->curve_angle_tolerance_epsilon = curve_angle_tolerance_epsilon; + ctx->curve_collinearity_epsilon = curve_collinearity_epsilon; + + //vkvg_test_curves(ctx); + //vkvg_test_curves2(ctx); + test_svg(ctx); + + + print_float(ctx); + + gettimeofday(&after , NULL); + + vkvg_destroy(ctx); + + glfwPollEvents(); + if (!vkh_presenter_draw (r)) + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf)); + + frameTime = time_diff(before , after); + } + + vkDeviceWaitIdle(e->dev->dev); + + vkvg_surface_destroy (surf); + vkvg_device_destroy (device); + + vkengine_destroy (e); + + return 0; +} -- 2.47.3