From: Jean-Philippe Bruyère Date: Sun, 29 Apr 2018 01:54:29 +0000 (+0200) Subject: add curve debug facility, measure frame rate X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=refs%2Fheads%2FCurvesDebug;p=jp%2Fvkvg.git add curve debug facility, measure frame rate --- 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 0000000..84fd6f6 Binary files /dev/null and b/logo.png differ 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/common/vkengine.c b/tests/common/vkengine.c new file mode 100644 index 0000000..e4f04fb --- /dev/null +++ b/tests/common/vkengine.c @@ -0,0 +1,245 @@ +/* + * 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 "vkh.h" +#include "vkengine.h" +#include "vkh_app.h" +#include "vkh_phyinfo.h" +#include "vkh_presenter.h" +#include "vkh_image.h" +#include "vkh_device.h" + +bool vkeCheckPhyPropBlitSource (VkEngine e) { + VkFormatProperties formatProps; + vkGetPhysicalDeviceFormatProperties(e->dev->phy, e->renderer->format, &formatProps); + assert((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); +} + +VkSampleCountFlagBits getMaxUsableSampleCount(VkSampleCountFlags counts) +{ + if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; } + if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; } + if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; } + if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; } + if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; } + if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; } + return VK_SAMPLE_COUNT_1_BIT; +} + +void vkengine_dump_Infos (VkEngine e){ + printf("max samples = %d\n", getMaxUsableSampleCount(e->gpu_props.limits.framebufferColorSampleCounts)); + printf("max tex2d size = %d\n", e->gpu_props.limits.maxImageDimension2D); + printf("max tex array layers = %d\n", e->gpu_props.limits.maxImageArrayLayers); + printf("max mem alloc count = %d\n", e->gpu_props.limits.maxMemoryAllocationCount); + + for (int 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 = %d Mo\n", e->memory_properties.memoryHeaps[i].size/ (1024*1024)); + } + for (int i = 0; i < e->memory_properties.memoryTypeCount; i++) { + printf("Mem type %d\n", i); + printf("\theap %d: ", e->memory_properties.memoryTypes[i].heapIndex); + if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + printf("VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|"); + if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + printf("VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|"); + if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + printf("VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|"); + if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) + printf("VK_MEMORY_PROPERTY_HOST_CACHED_BIT|"); + if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) + printf("VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT|"); + printf("\n"); + } +} +vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, uint32_t width, uint32_t height) { + vk_engine_t* e = (vk_engine_t*)calloc(1,sizeof(vk_engine_t)); + + glfwInit(); + assert (glfwVulkanSupported()==GLFW_TRUE); + + uint32_t enabledExtsCount = 0, phyCount = 0; + const char ** enabledExts = glfwGetRequiredInstanceExtensions (&enabledExtsCount); + + e->app = vkh_app_create("vkvgTest", enabledExtsCount, enabledExts); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); + glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); + + e->window = glfwCreateWindow (width, height, "Window Title", NULL, NULL); + VkSurfaceKHR surf; + + assert (glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf)==VK_SUCCESS); + + + VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf); + + VkhPhyInfo pi = NULL; + for (int i=0; iproperties.deviceType == preferedGPU) + break; + } + + e->memory_properties = pi->memProps; + e->gpu_props = pi->properties; + + uint32_t qCount = 0; + VkDeviceQueueCreateInfo pQueueInfos[3]; + float queue_priorities[] = {0.0}; + + VkDeviceQueueCreateInfo qiG = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueCount = 1, + .queueFamilyIndex = pi->gQueue, + .pQueuePriorities = queue_priorities }; + VkDeviceQueueCreateInfo qiC = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueCount = 1, + .queueFamilyIndex = pi->cQueue, + .pQueuePriorities = queue_priorities }; + VkDeviceQueueCreateInfo qiT = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueCount = 1, + .queueFamilyIndex = pi->tQueue, + .pQueuePriorities = queue_priorities }; + + if (pi->gQueue == pi->cQueue){ + if(pi->gQueue == pi->tQueue){ + qCount=1; + pQueueInfos[0] = qiG; + }else{ + qCount=2; + pQueueInfos[0] = qiG; + pQueueInfos[1] = qiT; + } + }else{ + if((pi->gQueue == pi->tQueue) || (pi->cQueue==pi->tQueue)){ + qCount=2; + pQueueInfos[0] = qiG; + pQueueInfos[1] = qiC; + }else{ + qCount=3; + pQueueInfos[0] = qiG; + pQueueInfos[1] = qiC; + pQueueInfos[2] = qiT; + } + } + + char const * dex [] = {"VK_KHR_swapchain"}; +/*#if DEBUG + uint32_t dlayCpt = 1; + static char const * dlay [] = {"VK_LAYER_LUNARG_standard_validation"}; +#else*/ + uint32_t dlayCpt = 0; + static char const * dlay [] = {}; +//#endif + VkPhysicalDeviceFeatures enabledFeatures = { + .fillModeNonSolid = true, + }; + + VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = qCount, + .pQueueCreateInfos = &pQueueInfos, + .enabledLayerCount = dlayCpt, + .ppEnabledLayerNames = dlay, + .enabledExtensionCount = 1, + .ppEnabledExtensionNames = dex, + .pEnabledFeatures = &enabledFeatures + }; + + VkDevice dev; + VK_CHECK_RESULT(vkCreateDevice (pi->phy, &device_info, NULL, &dev)); + e->dev = vkh_device_create(pi->phy, dev); + + e->renderer = vkh_presenter_create + (e->dev, pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, VK_PRESENT_MODE_FIFO_KHR); + + + vkh_app_free_phyinfos (phyCount, phys); + + return e; +} + +void vkengine_destroy (VkEngine e) { + vkDeviceWaitIdle(e->dev->dev); + + VkSurfaceKHR surf = e->renderer->surface; + + vkh_presenter_destroy (e->renderer); + vkDestroySurfaceKHR (e->app->inst, surf, NULL); + + vkDestroyDevice (e->dev->dev, NULL); + + glfwDestroyWindow (e->window); + glfwTerminate (); + + vkh_app_destroy (e->app); + + free(e); +} +void vkengine_close (VkEngine e) { + glfwSetWindowShouldClose(e->window, GLFW_TRUE); +} +void vkengine_blitter_run (VkEngine e, VkImage img) { + VkhPresenter p = e->renderer; + vkh_presenter_build_blit_cmd (p, img); + + while (!vkengine_should_close (e)) { + glfwPollEvents(); + if (!vkh_presenter_draw (p)) + vkh_presenter_build_blit_cmd (p, img); + } +} +inline bool vkengine_should_close (VkEngine e) { + return glfwWindowShouldClose (e->window); +} + +VkDevice vkengine_get_device (VkEngine e){ + return e->dev->dev; +} +VkPhysicalDevice vkengine_get_physical_device (VkEngine e){ + return e->dev->phy; +} +VkQueue vkengine_get_queue (VkEngine e){ + return e->renderer->queue; +} +uint32_t vkengine_get_queue_fam_idx (VkEngine e){ + return e->renderer->qFam; +} + +void vkengine_set_key_callback (VkEngine e, GLFWkeyfun key_callback){ + glfwSetKeyCallback (e->window, key_callback); +} +void vkengine_set_mouse_but_callback (VkEngine e, GLFWmousebuttonfun onMouseBut){ + glfwSetMouseButtonCallback(e->window, onMouseBut); +} +void vkengine_set_cursor_pos_callback (VkEngine e, GLFWcursorposfun onMouseMove){ + glfwSetCursorPosCallback(e->window, onMouseMove); +} +void vkengine_set_scroll_callback (VkEngine e, GLFWscrollfun onScroll){ + glfwSetScrollCallback(e->window, onScroll); +} +void vkengine_set_char_callback (VkEngine e, GLFWcharfun onChar){ + glfwSetCharCallback(e->window, onChar); +} + diff --git a/tests/common/vkengine.h b/tests/common/vkengine.h new file mode 100644 index 0000000..1bf33a8 --- /dev/null +++ b/tests/common/vkengine.h @@ -0,0 +1,68 @@ +/* + * 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. + */ +#ifndef VKENGINE_H +#define VKENGINE_H + +#include +#include +#include +#include + +#include +#include + +#include "vkh.h" + +/* Number of samples needs to be the same at image creation, */ +/* renderpass creation and pipeline creation. */ +#define FENCE_TIMEOUT 100000000 + +typedef struct _vk_engine_t* VkEngine; + +typedef struct _vk_engine_t { + VkhApp app; + VkPhysicalDeviceMemoryProperties memory_properties; + VkPhysicalDeviceProperties gpu_props; + VkhDevice dev; + GLFWwindow* window; + VkhPresenter renderer; +}vk_engine_t; + +vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, uint32_t width, uint32_t height); + +void vkengine_destroy (VkEngine e); +bool vkengine_should_close (VkEngine e); +void vkengine_close (VkEngine e); +void vkengine_dump_Infos (VkEngine e); +VkDevice vkengine_get_device (VkEngine e); +VkPhysicalDevice vkengine_get_physical_device(VkEngine e); +VkQueue vkengine_get_queue (VkEngine e); +uint32_t vkengine_get_queue_fam_idx (VkEngine e); + +void vkengine_get_queues_properties (vk_engine_t* e, VkQueueFamilyProperties** qFamProps, uint32_t* count); + +void vkengine_set_key_callback (VkEngine e, GLFWkeyfun key_callback); +void vkengine_set_mouse_but_callback (VkEngine e, GLFWmousebuttonfun onMouseBut); +void vkengine_set_cursor_pos_callback (VkEngine e, GLFWcursorposfun onMouseMove); +void vkengine_set_scroll_callback (VkEngine e, GLFWscrollfun onScroll); +void vkengine_set_char_callback (VkEngine e, GLFWcharfun onChar); +#endif 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; +} diff --git a/tests/vkengine.c b/tests/vkengine.c deleted file mode 100644 index e4f04fb..0000000 --- a/tests/vkengine.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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 "vkh.h" -#include "vkengine.h" -#include "vkh_app.h" -#include "vkh_phyinfo.h" -#include "vkh_presenter.h" -#include "vkh_image.h" -#include "vkh_device.h" - -bool vkeCheckPhyPropBlitSource (VkEngine e) { - VkFormatProperties formatProps; - vkGetPhysicalDeviceFormatProperties(e->dev->phy, e->renderer->format, &formatProps); - assert((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); -} - -VkSampleCountFlagBits getMaxUsableSampleCount(VkSampleCountFlags counts) -{ - if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; } - if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; } - if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; } - if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; } - if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; } - if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; } - return VK_SAMPLE_COUNT_1_BIT; -} - -void vkengine_dump_Infos (VkEngine e){ - printf("max samples = %d\n", getMaxUsableSampleCount(e->gpu_props.limits.framebufferColorSampleCounts)); - printf("max tex2d size = %d\n", e->gpu_props.limits.maxImageDimension2D); - printf("max tex array layers = %d\n", e->gpu_props.limits.maxImageArrayLayers); - printf("max mem alloc count = %d\n", e->gpu_props.limits.maxMemoryAllocationCount); - - for (int 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 = %d Mo\n", e->memory_properties.memoryHeaps[i].size/ (1024*1024)); - } - for (int i = 0; i < e->memory_properties.memoryTypeCount; i++) { - printf("Mem type %d\n", i); - printf("\theap %d: ", e->memory_properties.memoryTypes[i].heapIndex); - if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) - printf("VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|"); - if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - printf("VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|"); - if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) - printf("VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|"); - if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) - printf("VK_MEMORY_PROPERTY_HOST_CACHED_BIT|"); - if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) - printf("VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT|"); - printf("\n"); - } -} -vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, uint32_t width, uint32_t height) { - vk_engine_t* e = (vk_engine_t*)calloc(1,sizeof(vk_engine_t)); - - glfwInit(); - assert (glfwVulkanSupported()==GLFW_TRUE); - - uint32_t enabledExtsCount = 0, phyCount = 0; - const char ** enabledExts = glfwGetRequiredInstanceExtensions (&enabledExtsCount); - - e->app = vkh_app_create("vkvgTest", enabledExtsCount, enabledExts); - - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); - glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); - - e->window = glfwCreateWindow (width, height, "Window Title", NULL, NULL); - VkSurfaceKHR surf; - - assert (glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf)==VK_SUCCESS); - - - VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf); - - VkhPhyInfo pi = NULL; - for (int i=0; iproperties.deviceType == preferedGPU) - break; - } - - e->memory_properties = pi->memProps; - e->gpu_props = pi->properties; - - uint32_t qCount = 0; - VkDeviceQueueCreateInfo pQueueInfos[3]; - float queue_priorities[] = {0.0}; - - VkDeviceQueueCreateInfo qiG = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueCount = 1, - .queueFamilyIndex = pi->gQueue, - .pQueuePriorities = queue_priorities }; - VkDeviceQueueCreateInfo qiC = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueCount = 1, - .queueFamilyIndex = pi->cQueue, - .pQueuePriorities = queue_priorities }; - VkDeviceQueueCreateInfo qiT = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueCount = 1, - .queueFamilyIndex = pi->tQueue, - .pQueuePriorities = queue_priorities }; - - if (pi->gQueue == pi->cQueue){ - if(pi->gQueue == pi->tQueue){ - qCount=1; - pQueueInfos[0] = qiG; - }else{ - qCount=2; - pQueueInfos[0] = qiG; - pQueueInfos[1] = qiT; - } - }else{ - if((pi->gQueue == pi->tQueue) || (pi->cQueue==pi->tQueue)){ - qCount=2; - pQueueInfos[0] = qiG; - pQueueInfos[1] = qiC; - }else{ - qCount=3; - pQueueInfos[0] = qiG; - pQueueInfos[1] = qiC; - pQueueInfos[2] = qiT; - } - } - - char const * dex [] = {"VK_KHR_swapchain"}; -/*#if DEBUG - uint32_t dlayCpt = 1; - static char const * dlay [] = {"VK_LAYER_LUNARG_standard_validation"}; -#else*/ - uint32_t dlayCpt = 0; - static char const * dlay [] = {}; -//#endif - VkPhysicalDeviceFeatures enabledFeatures = { - .fillModeNonSolid = true, - }; - - VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .queueCreateInfoCount = qCount, - .pQueueCreateInfos = &pQueueInfos, - .enabledLayerCount = dlayCpt, - .ppEnabledLayerNames = dlay, - .enabledExtensionCount = 1, - .ppEnabledExtensionNames = dex, - .pEnabledFeatures = &enabledFeatures - }; - - VkDevice dev; - VK_CHECK_RESULT(vkCreateDevice (pi->phy, &device_info, NULL, &dev)); - e->dev = vkh_device_create(pi->phy, dev); - - e->renderer = vkh_presenter_create - (e->dev, pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, VK_PRESENT_MODE_FIFO_KHR); - - - vkh_app_free_phyinfos (phyCount, phys); - - return e; -} - -void vkengine_destroy (VkEngine e) { - vkDeviceWaitIdle(e->dev->dev); - - VkSurfaceKHR surf = e->renderer->surface; - - vkh_presenter_destroy (e->renderer); - vkDestroySurfaceKHR (e->app->inst, surf, NULL); - - vkDestroyDevice (e->dev->dev, NULL); - - glfwDestroyWindow (e->window); - glfwTerminate (); - - vkh_app_destroy (e->app); - - free(e); -} -void vkengine_close (VkEngine e) { - glfwSetWindowShouldClose(e->window, GLFW_TRUE); -} -void vkengine_blitter_run (VkEngine e, VkImage img) { - VkhPresenter p = e->renderer; - vkh_presenter_build_blit_cmd (p, img); - - while (!vkengine_should_close (e)) { - glfwPollEvents(); - if (!vkh_presenter_draw (p)) - vkh_presenter_build_blit_cmd (p, img); - } -} -inline bool vkengine_should_close (VkEngine e) { - return glfwWindowShouldClose (e->window); -} - -VkDevice vkengine_get_device (VkEngine e){ - return e->dev->dev; -} -VkPhysicalDevice vkengine_get_physical_device (VkEngine e){ - return e->dev->phy; -} -VkQueue vkengine_get_queue (VkEngine e){ - return e->renderer->queue; -} -uint32_t vkengine_get_queue_fam_idx (VkEngine e){ - return e->renderer->qFam; -} - -void vkengine_set_key_callback (VkEngine e, GLFWkeyfun key_callback){ - glfwSetKeyCallback (e->window, key_callback); -} -void vkengine_set_mouse_but_callback (VkEngine e, GLFWmousebuttonfun onMouseBut){ - glfwSetMouseButtonCallback(e->window, onMouseBut); -} -void vkengine_set_cursor_pos_callback (VkEngine e, GLFWcursorposfun onMouseMove){ - glfwSetCursorPosCallback(e->window, onMouseMove); -} -void vkengine_set_scroll_callback (VkEngine e, GLFWscrollfun onScroll){ - glfwSetScrollCallback(e->window, onScroll); -} -void vkengine_set_char_callback (VkEngine e, GLFWcharfun onChar){ - glfwSetCharCallback(e->window, onChar); -} - diff --git a/tests/vkengine.h b/tests/vkengine.h deleted file mode 100644 index 1bf33a8..0000000 --- a/tests/vkengine.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - */ -#ifndef VKENGINE_H -#define VKENGINE_H - -#include -#include -#include -#include - -#include -#include - -#include "vkh.h" - -/* Number of samples needs to be the same at image creation, */ -/* renderpass creation and pipeline creation. */ -#define FENCE_TIMEOUT 100000000 - -typedef struct _vk_engine_t* VkEngine; - -typedef struct _vk_engine_t { - VkhApp app; - VkPhysicalDeviceMemoryProperties memory_properties; - VkPhysicalDeviceProperties gpu_props; - VkhDevice dev; - GLFWwindow* window; - VkhPresenter renderer; -}vk_engine_t; - -vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, uint32_t width, uint32_t height); - -void vkengine_destroy (VkEngine e); -bool vkengine_should_close (VkEngine e); -void vkengine_close (VkEngine e); -void vkengine_dump_Infos (VkEngine e); -VkDevice vkengine_get_device (VkEngine e); -VkPhysicalDevice vkengine_get_physical_device(VkEngine e); -VkQueue vkengine_get_queue (VkEngine e); -uint32_t vkengine_get_queue_fam_idx (VkEngine e); - -void vkengine_get_queues_properties (vk_engine_t* e, VkQueueFamilyProperties** qFamProps, uint32_t* count); - -void vkengine_set_key_callback (VkEngine e, GLFWkeyfun key_callback); -void vkengine_set_mouse_but_callback (VkEngine e, GLFWmousebuttonfun onMouseBut); -void vkengine_set_cursor_pos_callback (VkEngine e, GLFWcursorposfun onMouseMove); -void vkengine_set_scroll_callback (VkEngine e, GLFWscrollfun onScroll); -void vkengine_set_char_callback (VkEngine e, GLFWcharfun onChar); -#endif