From: Jean-Philippe Bruyère Date: Sun, 19 Dec 2021 03:27:36 +0000 (+0100) Subject: gradient stop count check, raise status if count < 2, simplify linear gradient shader X-Git-Tag: v0.2.0~13 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=861758dd1e4c4f375c7a2597c12034932b0e5ead;p=jp%2Fvkvg.git gradient stop count check, raise status if count < 2, simplify linear gradient shader --- diff --git a/CMakeLists.txt b/CMakeLists.txt index bb8fa15..6120417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,7 @@ IF(GLSLC AND XXD) ADD_CUSTOM_COMMAND ( OUTPUT ${shader-output} COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${SHADER_DIR}" - COMMAND ${GLSLC} ${shader-input} -o ${shader-output} + COMMAND ${GLSLC} ${shader-input} -o ${shader-output} --target-env=vulkan1.2 COMMENT "Compiling ${shader-input}" DEPENDS ${SHADER} VERBATIM diff --git a/include/vkvg.h b/include/vkvg.h index 5937bf5..1e0c58f 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -30,8 +30,6 @@ extern "C" { * Doxygen documentation *************************************************************************/ /** @mainpage VKVG: vulkan vector graphics - * - * Documentation of all members: vkvg.h * * VKVG is an open source 2d vector drawing library written in @b c and using [vulkan](https://www.khronos.org/vulkan/) for hardware acceleration. * Its api is modeled on the [cairo graphic library](https://www.cairographics.org/) with the following software components: @@ -100,6 +98,8 @@ extern uint8_t vkvg_log_level; * vkvg_status_t is used to indicates errors that can occur when using vkvg. Several vkvg function directely * return result, but when using a @ref context, the last error is stored in the context and can be accessed * with #vkvg_status. + * + * As soon as a status is not success, further operations will be canceled. */ typedef enum { VKVG_STATUS_SUCCESS = 0, /*!< no error occurred.*/ @@ -116,12 +116,14 @@ typedef enum { VKVG_STATUS_SURFACE_FINISHED, /*!< */ VKVG_STATUS_SURFACE_TYPE_MISMATCH, /*!< */ VKVG_STATUS_PATTERN_TYPE_MISMATCH, /*!< */ + VKVG_STATUS_PATTERN_INVALID_GRADIENT,/*!< occurs when stops count is zero */ VKVG_STATUS_INVALID_CONTENT, /*!< */ VKVG_STATUS_INVALID_FORMAT, /*!< */ VKVG_STATUS_INVALID_VISUAL, /*!< */ VKVG_STATUS_FILE_NOT_FOUND, /*!< */ VKVG_STATUS_INVALID_DASH, /*!< invalid value for a dash setting */ VKVG_STATUS_INVALID_RECT, /*!< rectangle with height or width equal to 0. */ + VKVG_STATUS_TIMEOUT, /*!< waiting for a vulkan operation to finish resulted in a fence timeout (5 seconds)*/ }vkvg_status_t; typedef enum { @@ -213,21 +215,32 @@ typedef struct { float a; } vkvg_color_t; +/** + * @brief font metrics + * + * structure defining global font metrics for a particular font. It can be retrieve by calling @ref vkvg_font_extents + * on a valid context. + */ typedef struct { - float ascent; - float descent; - float height; - float max_x_advance; - float max_y_advance; + float ascent; /*!< the distance that the font extends above the baseline. */ + float descent; /*!< the distance that the font extends below the baseline.*/ + float height; /*!< the recommended vertical distance between baselines. */ + float max_x_advance; /*!< the maximum distance in the X direction that the origin is advanced for any glyph in the font.*/ + float max_y_advance; /*!< the maximum distance in the Y direction that the origin is advanced for any glyph in the font. This will be zero for normal fonts used for horizontal writing.*/ } vkvg_font_extents_t; - +/** + * @brief text metrics + * + * structure defining metrics for a single or a string of glyphs. To measure text, call @ref vkvg_text_extents + * on a valid context. + */ typedef struct { - float x_bearing; - float y_bearing; - float width; - float height; - float x_advance; - float y_advance; + float x_bearing; /*!< the horizontal distance from the origin to the leftmost part of the glyphs as drawn. Positive if the glyphs lie entirely to the right of the origin. */ + float y_bearing; /*!< the vertical distance from the origin to the topmost part of the glyphs as drawn. Positive only if the glyphs lie completely below the origin; will usually be negative.*/ + float width; /*!< width of the glyphs as drawn*/ + float height; /*!< height of the glyphs as drawn*/ + float x_advance; /*!< distance to advance in the X direction after drawing these glyphs*/ + float y_advance; /*!< distance to advance in the Y direction after drawing these glyphs. Will typically be zero except for vertical text layout as found in East-Asian languages.*/ } vkvg_text_extents_t; /** @@ -1468,67 +1481,122 @@ uint32_t vkvg_pattern_get_reference_count (VkvgPattern pat); vkvg_public VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf); /** - * @brief + * @brief create a new linear gradient. * - * @param x0 - * @param y0 - * @param x1 - * @param y1 - * @return VkvgPattern + * Create a new linear gradient along the line defined by (x0, y0) and (x1, y1). + * Before using the gradient pattern, a number of color stops should be defined using @ref vkvg_pattern_add_color_stop. + * + * @param x0 x coordinate of the start point + * @param y0 y coordinate of the start point + * @param x1 x coordinate of the end point + * @param y1 y coordinate of the end point + * @return VkvgPattern the newly created pattern, call @ref vkvg_pattern_destroy when finished with it. */ vkvg_public VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1); /** - * @brief + * @brief edit an existing linear gradient. * - * @param cx0 - * @param cy0 - * @param radius0 - * @param cx1 - * @param cy1 - * @param radius1 - * @return VkvgPattern + * edit control points of an existing linear gradient. If supplied pattern is not a linear gradient, + * @ref VKVG_STATUS_PATTERN_TYPE_MISMATCH is set for pattern. + * + * @param x0 x coordinate of the start point + * @param y0 y coordinate of the start point + * @param x1 x coordinate of the end point + * @param y1 y coordinate of the end point + */ +vkvg_public +void vkvg_pattern_edit_linear (VkvgPattern pat, float x0, float y0, float x1, float y1); +/** + * @brief get the gradient end points for a linear gradient + * + * If supplied pattern is not a linear gradient, @ref VKVG_STATUS_PATTERN_TYPE_MISMATCH is set for pattern. + * + * @param x0 x coordinate of the start point + * @param y0 y coordinate of the start point + * @param x1 x coordinate of the end point + * @param y1 y coordinate of the end point + */ +vkvg_public +void vkvg_pattern_get_linear_points (VkvgPattern pat, float* x0, float* y0, float* x1, float* y1); +/** + * @brief create a new radial gradient. + * + * Creates a new radial gradient between the two circles defined by (cx0, cy0, radius0) and (cx1, cy1, radius1). + * Before using the gradient pattern, a number of color stops should be defined using vkvg_pattern_add_color_stop. + * + * @param cx0 x coordinate for the center of the start circle, the inner circle. Must stand inside outer circle. + * @param cy0 y coordinate for the center of the start circle, the inner circle. Must stand inside outer circle. + * @param radius0 radius for the center of the start circle, the inner circle. Can't be greater than radius1 + * @param cx1 x coordinate for the center of the end circle, the outer circle. + * @param cy1 y coordinate for the center of the end circle, the outer circle. + * @param radius1 radius for the center of the end circle, the outer circle. + * @return VkvgPattern the newly created pattern to be disposed when finished by calling @ref vkvg_pattern_destroy. */ vkvg_public VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, - float cx1, float cy1, float radius1); + float cx1, float cy1, float radius1); /** - * @brief + * @brief edit an existing radial gradient. * - * @param pat + * Edit control points of an existing radial gradient + * + * @param pat the pattern to edit + * @param cx0 x coordinate for the center of the start circle, the inner circle. Must stand inside outer circle. + * @param cy0 y coordinate for the center of the start circle, the inner circle. Must stand inside outer circle. + * @param radius0 radius for the center of the start circle, the inner circle. Can't be greater than radius1 + * @param cx1 x coordinate for the center of the end circle, the outer circle. + * @param cy1 y coordinate for the center of the end circle, the outer circle. + * @param radius1 radius for the center of the end circle, the outer circle. + */ +vkvg_public +void vkvg_pattern_edit_radial (VkvgPattern pat, + float cx0, float cy0, float radius0, + float cx1, float cy1, float radius1); +/** + * @brief dispose pattern. + * + * When you have finished using a pattern, free its ressources by calling this method. + * + * @param pat the pattern to destroy. */ vkvg_public void vkvg_pattern_destroy (VkvgPattern pat); /** - * @brief + * @brief add colors to gradients + * + * for each color step in the gradient, call this method and provide an absolute position between 0 and 1 + * and a color. * - * @param pat - * @param offset - * @param r - * @param g - * @param b - * @param a + * @param pat the gradient pattern to add a color step. + * @param offset location along the gradient's control vector, value ranging from zero (start of the gradient) to one. + * @param r the red component of the color step + * @param g the green component of the color stop + * @param b the blue component of the color stop + * @param a the alpha chanel of the color stop */ vkvg_public void vkvg_pattern_add_color_stop (VkvgPattern pat, float offset, float r, float g, float b, float a); /** - * @brief + * @brief control the extend of the pattern + * + * control whether the pattern has to be repeated or extended when painted on a surface. * - * @param pat - * @param extend + * @param pat the pattern to set extend for. + * @param extend one value of the @ref vkvg_extend_t enumeration. */ vkvg_public void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend); /** - * @brief + * @brief control the filtering when using this pattern on a surface. * - * @param pat - * @param filter + * @param pat pat the pattern to set filter for. + * @param filter one value of the @ref vkvg_filter_t enumeration. */ vkvg_public void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter); /** - * @brief + * @brief query the current extend value for a pa * * @param pat * @return vkvg_extend_t @@ -1543,8 +1611,23 @@ vkvg_extend_t vkvg_pattern_get_extend (VkvgPattern pat); */ vkvg_public vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat); +/** + * @brief get pattern type + * + * may be one of the @ref vkvg_pattern_type_t enumeration + * + * @param pat the pattern to query + * @return vkvg_pattern_type_t + */ +vkvg_public +vkvg_pattern_type_t vkvg_pattern_get_type (VkvgPattern pat); /** @}*/ +/********* EXPERIMENTAL **************/ +vkvg_public +void vkvg_set_source_color_name (VkvgContext ctx, const char* color); + +/*************************************/ #ifdef __cplusplus } diff --git a/screenshot2.png b/screenshot2.png new file mode 100644 index 0000000..7fe3694 Binary files /dev/null and b/screenshot2.png differ diff --git a/shaders/vkvg_main.frag b/shaders/vkvg_main.frag index a9025a4..f4aee07 100644 --- a/shaders/vkvg_main.frag +++ b/shaders/vkvg_main.frag @@ -23,7 +23,7 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable -#extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_scalar_block_layout : require layout (set=0, binding = 0) uniform sampler2DArray fontMap; layout (set=1, binding = 0) uniform sampler2D source; @@ -34,10 +34,10 @@ layout (std430, set=2, binding = 0) uniform _uboGrad { uint count; }uboGrad; -layout (location = 0) in vec3 inFontUV; //if it is a text drawing, inFontUV.z hold fontMap layer -layout (location = 1) in vec4 inSrc; //source bounds or color depending on pattern type -layout (location = 2) in flat int inPatType; //pattern type -layout (location = 3) in mat3x2 inMat; +layout (location = 0) in vec3 inFontUV; //if it is a text drawing, inFontUV.z hold fontMap layer +layout (location = 1) in vec4 inSrc; //source bounds or color depending on pattern type +layout (location = 2) in flat int inPatType; //pattern type +layout (location = 3) in mat3x2 inMat; layout (location = 0) out vec4 outFragColor; @@ -65,19 +65,30 @@ void main() c = texture (source, uv / inSrc.zw); break; case LINEAR: - //credit to Nikita Rokotyan for linear grad - float alpha = atan( -uboGrad.cp[0].w + uboGrad.cp[0].y, uboGrad.cp[0].z - uboGrad.cp[0].x ); - float gradientStartPosRotatedX = uboGrad.cp[0].x*cos(alpha) - uboGrad.cp[0].y*sin(alpha); - float gradientEndPosRotatedX = uboGrad.cp[0].z*cos(alpha) - uboGrad.cp[0].w*sin(alpha); - float d = gradientEndPosRotatedX - gradientStartPosRotatedX; + float dist = 1; + vec2 p0 = uboGrad.cp[0].xy / inSrc.xy; + vec2 p1 = uboGrad.cp[0].zw / inSrc.xy; + p = gl_FragCoord.xy / inSrc.xy; - float y = gl_FragCoord.y;//inSrc.y - gl_FragCoord.y; - float x = gl_FragCoord.x; - float xLocRotated = x*cos( alpha ) - y*sin( alpha ); + float l = length (p1 - p0); + vec2 u = normalize (p1 - p0); + + if (u.y == 0) + if (u.x < 0) + dist = -(p.x-p0.x) / l; + else + dist = (p.x-p0.x) / l; + else { + float m = -u.x / u.y; + float bb = p0.y - m * p0.x; + dist =((p.y - m * p.x - bb) / sqrt (1 + m * m)) / l; + if (u.y < 0) + dist = - dist; + } - c = mix(uboGrad.colors[0], uboGrad.colors[1], smoothstep( gradientStartPosRotatedX + uboGrad.stops[0]*d, gradientStartPosRotatedX + uboGrad.stops[1]*d, xLocRotated ) ); + c = mix(uboGrad.colors[0], uboGrad.colors[1], smoothstep(uboGrad.stops[0], uboGrad.stops[1], dist)); for ( int i=1; istatus) return; - _flush_cmd_buff(ctx); - _wait_flush_fence(ctx); + _flush_cmd_buff (ctx); + _wait_flush_fence (ctx); /* #ifdef DEBUG @@ -202,10 +202,10 @@ void vkvg_destroy (VkvgContext ctx) if (ctx->references > 0) return; - _flush_cmd_buff(ctx); - _wait_flush_fence(ctx); + LOG(VKVG_LOG_INFO, "DESTROY Context: ctx = %p (status:%d); surf = %p\n", ctx, ctx->status, ctx->pSurf); + + vkvg_flush (ctx); - LOG(VKVG_LOG_INFO, "DESTROY Context: ctx = %p; surf = %p\n", ctx, ctx->pSurf); LOG(VKVG_LOG_DBG_ARRAYS, "END\tctx = %p; pathes:%d pts:%d vch:%d vbo:%d ich:%d ibo:%d\n", ctx, ctx->sizePathes, ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO); if (ctx->pattern) @@ -982,7 +982,8 @@ void vkvg_save (VkvgContext ctx){ LOG(VKVG_LOG_INFO, "SAVE CONTEXT: ctx = %p\n", ctx); _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; VkvgDevice dev = ctx->pSurf->dev; vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t)); @@ -1098,7 +1099,8 @@ void vkvg_restore (VkvgContext ctx){ LOG(VKVG_LOG_INFO, "RESTORE CONTEXT: ctx = %p\n", ctx); _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; vkvg_context_save_t* sav = ctx->pSavedCtxs; ctx->pSavedCtxs = sav->pNext; @@ -1134,7 +1136,8 @@ void vkvg_restore (VkvgContext ctx){ #endif _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; uint8_t curSaveStencil = ctx->curSavBit / 6; if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//addtional save/restore stencil image have to be copied back to surf stencil first @@ -1171,7 +1174,8 @@ void vkvg_restore (VkvgContext ctx){ VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); _wait_and_submit_cmd (ctx); - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; vkh_image_destroy (savStencil); } diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 489e592..1b0a468 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -247,7 +247,8 @@ void _create_vertices_buff (VkvgContext ctx){ ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices); } void _resize_vbo (VkvgContext ctx, uint32_t new_size) { - _wait_flush_fence (ctx);//wait previous cmd if not completed + if (!_wait_flush_fence (ctx))//wait previous cmd if not completed + return; ctx->sizeVBO = new_size; uint32_t mod = ctx->sizeVBO % VKVG_VBO_SIZE; if (mod > 0) @@ -260,7 +261,8 @@ void _resize_vbo (VkvgContext ctx, uint32_t new_size) { ctx->sizeVBO * sizeof(Vertex), &ctx->vertices); } void _resize_ibo (VkvgContext ctx, size_t new_size) { - _wait_flush_fence (ctx);//wait previous cmd if not completed + if (!_wait_flush_fence (ctx))//wait previous cmd if not completed + return; ctx->sizeIBO = new_size; uint32_t mod = ctx->sizeIBO % VKVG_IBO_SIZE; if (mod > 0) @@ -348,17 +350,25 @@ void _create_cmd_buff (VkvgContext ctx){ void _clear_attachment (VkvgContext ctx) { } -void _wait_flush_fence (VkvgContext ctx) { - vkWaitForFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT); +bool _wait_flush_fence (VkvgContext ctx) { + LOG(VKVG_LOG_INFO, "CTX: _wait_flush_fence\n"); + if (vkWaitForFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) + return true; + ctx->status = VKVG_STATUS_TIMEOUT; + return false; } void _reset_flush_fence (VkvgContext ctx) { + LOG(VKVG_LOG_INFO, "CTX: _reset_flush_fence\n"); vkResetFences (ctx->pSurf->dev->vkDev, 1, &ctx->flushFence); } -void _wait_and_submit_cmd (VkvgContext ctx){ +bool _wait_and_submit_cmd (VkvgContext ctx){ if (!ctx->cmdStarted)//current cmd buff is empty, be aware that wait is also canceled!! - return; + return true; - _wait_flush_fence (ctx); + LOG(VKVG_LOG_INFO, "CTX: _wait_and_submit_cmd\n"); + + if (!_wait_flush_fence (ctx)) + return false; _reset_flush_fence(ctx); _submit_cmd (ctx->pSurf->dev, &ctx->cmd, ctx->flushFence); @@ -370,6 +380,7 @@ void _wait_and_submit_cmd (VkvgContext ctx){ vkResetCommandBuffer (ctx->cmd, 0); ctx->cmdStarted = false; + return true; } /*void _explicit_ms_resolve (VkvgContext ctx){//should init cmd before calling this (unused, using automatic resolve by renderpass) vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, @@ -414,7 +425,8 @@ void _flush_vertices_caches_until_vertex_base (VkvgContext ctx) { //copy vertex and index caches to the vbo and ibo vkbuffers used by gpu for drawing //current running cmd has to be completed to free usage of those void _flush_vertices_caches (VkvgContext ctx) { - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; memcpy(ctx->vertices.allocInfo.pMappedData, ctx->vertexCache, ctx->vertCount * sizeof (Vertex)); memcpy(ctx->indices.allocInfo.pMappedData, ctx->indexCache, ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE)); @@ -570,6 +582,8 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { uint32_t newPatternType = VKVG_PATTERN_TYPE_SOLID; + LOG(VKVG_LOG_INFO, "CTX: _update_cur_pattern: %p -> %p\n", lastPat, pat); + if (pat == NULL) {//solid color if (lastPat == NULL)//solid return;//solid to solid transition, no extra action requested @@ -579,7 +593,8 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { switch (newPatternType) { case VKVG_PATTERN_TYPE_SOLID: _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; if (lastPat->type == VKVG_PATTERN_TYPE_SURFACE)//unbind current source surface by replacing it with empty texture _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); break; @@ -605,7 +620,8 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { vkh_cmd_end (ctx->cmd); _wait_and_submit_cmd (ctx); - _wait_flush_fence (ctx); + if (!_wait_flush_fence (ctx)) + return; ctx->source = surf->img; @@ -646,7 +662,8 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { case VKVG_PATTERN_TYPE_LINEAR: case VKVG_PATTERN_TYPE_RADIAL: _flush_cmd_buff (ctx); - _wait_flush_fence(ctx); + if (!_wait_flush_fence (ctx)) + return; if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE) _update_descriptor_set (ctx, ctx->pSurf->dev->emptyImg, ctx->dsSrc); @@ -658,6 +675,11 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { vkvg_gradient_t grad = {0}; memcpy (&grad, pat->data, sizeof(vkvg_gradient_t)); + if (grad.count < 2) { + ctx->status = VKVG_STATUS_PATTERN_INVALID_GRADIENT; + return; + } + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w); //to do, scale radial radiuses in cp[2] @@ -672,7 +694,8 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { vkvg_pattern_destroy (lastPat); } void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){ - _wait_flush_fence(ctx);//descriptorSet update invalidate cmd buffs + if (!_wait_flush_fence(ctx))//descriptorSet update invalidate cmd buffs + return; VkDescriptorImageInfo descSrcTex = vkh_image_get_descriptor (img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VkWriteDescriptorSet writeDescriptorSet = { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 6a192d9..f3cad5c 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -254,9 +254,9 @@ void _ensure_renderpass_is_started (VkvgContext ctx); void _flush_cmd_buff (VkvgContext ctx); void _emit_draw_cmd_undrawn_vertices(VkvgContext ctx); void _flush_cmd_until_vx_base (VkvgContext ctx); -void _wait_flush_fence (VkvgContext ctx); +bool _wait_flush_fence (VkvgContext ctx); void _reset_flush_fence (VkvgContext ctx); -void _wait_and_submit_cmd (VkvgContext ctx); +bool _wait_and_submit_cmd (VkvgContext ctx); void _update_push_constants (VkvgContext ctx); void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat); void _set_mat_inv_and_vkCmdPush (VkvgContext ctx); diff --git a/src/vkvg_device.c b/src/vkvg_device.c index e90edef..4de3436 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -40,7 +40,7 @@ VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve) _instance_extensions_check_release(); - VkhApp app = vkh_app_create("vkvg", 0, NULL, enabledExtsCount, enabledExts); + VkhApp app = vkh_app_create(1, 1, "vkvg", 0, NULL, enabledExtsCount, enabledExts); #if defined(DEBUG) && defined (VKVG_DBG_UTILS) if (dbgUtilsSupported) diff --git a/src/vkvg_experimental.c b/src/vkvg_experimental.c new file mode 100644 index 0000000..3e3e022 --- /dev/null +++ b/src/vkvg_experimental.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2021 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 +#include "vkvg_experimental.h" +#include "vkvg_context_internal.h" + + + diff --git a/src/vkvg_experimental.h b/src/vkvg_experimental.h new file mode 100644 index 0000000..3439151 --- /dev/null +++ b/src/vkvg_experimental.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2021 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 VKVG_EXPERIMENTAL_H +#define VKVG_EXPERIMENTAL_H + +#include "vkvg_internal.h" +#include "vkvg.h" + +#endif diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index 396925a..8c9fcc8 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -70,5 +70,7 @@ #define FB_COLOR_FORMAT VK_FORMAT_B8G8R8A8_UNORM #define VKVG_SURFACE_IMGS_REQUIREMENTS VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|\ VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_BLIT_SRC_BIT -#define VKVG_FENCE_TIMEOUT UINT64_MAX +//5 seconds fence timeout +#define VKVG_FENCE_TIMEOUT 5000000000 +//#define VKVG_FENCE_TIMEOUT 10000 #endif diff --git a/src/vkvg_pattern.c b/src/vkvg_pattern.c index 128c596..d8478b3 100644 --- a/src/vkvg_pattern.c +++ b/src/vkvg_pattern.c @@ -36,27 +36,65 @@ VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf){ return pat; } +void vkvg_pattern_get_linear_points (VkvgPattern pat, float* x0, float* y0, float* x1, float* y1) { + if (pat->status) + return; + + if (pat->type != VKVG_PATTERN_TYPE_LINEAR) { + pat->status = VKVG_STATUS_PATTERN_TYPE_MISMATCH; + return; + } + vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data; + + *x0 = grad->cp[0].x; + *y0 = grad->cp[0].y; + *x1 = grad->cp[0].z; + *y1 = grad->cp[0].w; +} +void vkvg_pattern_edit_linear (VkvgPattern pat, float x0, float y0, float x1, float y1){ + if (pat->status) + return; + + if (pat->type != VKVG_PATTERN_TYPE_LINEAR) { + pat->status = VKVG_STATUS_PATTERN_TYPE_MISMATCH; + return; + } + + vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data; + + grad->cp[0] = (vec4){{x0}, {y0}, {x1}, {y1}}; +} VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1){ VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); + if (!pat) + return NULL; pat->type = VKVG_PATTERN_TYPE_LINEAR; pat->extend = VKVG_EXTEND_PAD; - vkvg_gradient_t* grad = (vkvg_gradient_t*)calloc(1,sizeof(vkvg_gradient_t)); - grad->cp[0] = (vec4){{x0}, {y0}, {x1}, {y1}}; + pat->data = (void*)calloc(1,sizeof(vkvg_gradient_t)); + if (!pat->data) { + pat->status = VKVG_STATUS_NO_MEMORY; + return pat; + } - pat->data = grad; + vkvg_pattern_edit_linear(pat, x0, y0, x1, y1); pat->references = 1; return pat; } -VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, - float cx1, float cy1, float radius1){ - VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); - pat->type = VKVG_PATTERN_TYPE_RADIAL; - pat->extend = VKVG_EXTEND_PAD; +void vkvg_pattern_edit_radial (VkvgPattern pat, + float cx0, float cy0, float radius0, + float cx1, float cy1, float radius1) { + if (pat->status) + return; - vkvg_gradient_t* grad = (vkvg_gradient_t*)calloc(1,sizeof(vkvg_gradient_t)); + if (pat->type != VKVG_PATTERN_TYPE_RADIAL) { + pat->status = VKVG_STATUS_PATTERN_TYPE_MISMATCH; + return; + } + + vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data; vec2 c0 = {cx0, cy0}; vec2 c1 = {cx1, cy1}; @@ -72,13 +110,30 @@ VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, grad->cp[0] = (vec4){{c0.x}, {c0.y},{radius0},{0}}; grad->cp[1] = (vec4){{c1.x}, {c1.y},{radius1},{0}}; +} +VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, + float cx1, float cy1, float radius1){ + VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); + if (!pat) + return NULL; + pat->type = VKVG_PATTERN_TYPE_RADIAL; + pat->extend = VKVG_EXTEND_PAD; + + pat->data = (void*)calloc(1,sizeof(vkvg_gradient_t)); + if (!pat->data) { + pat->status = VKVG_STATUS_NO_MEMORY; + return pat; + } - pat->data = grad; + vkvg_pattern_edit_radial (pat, cx0, cy0, radius0, cx1, cy1, radius1); pat->references = 1; return pat; } +vkvg_status_t vkvg_pattern_status (VkvgPattern pat) { + return pat->status; +} VkvgPattern vkvg_pattern_reference (VkvgPattern pat) { pat->references++; return pat; diff --git a/src/vkvg_pattern.h b/src/vkvg_pattern.h index 763d943..ea9a026 100644 --- a/src/vkvg_pattern.h +++ b/src/vkvg_pattern.h @@ -30,8 +30,9 @@ typedef struct _vkvg_pattern_t { vkvg_pattern_type_t type; vkvg_extend_t extend; vkvg_filter_t filter; - uint32_t references; void* data; + uint32_t references; + vkvg_status_t status; }vkvg_pattern_t; typedef struct _vkvg_gradient_t { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ce0d13f..40da768 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,9 +8,10 @@ IF (VKVG_TEST_OFFSCREEN) ADD_DEFINITIONS (-DVKVG_TEST_OFFSCREEN) ENDIF () -FUNCTION (buildtest TEST_NAME) - ADD_EXECUTABLE(test_${TEST_NAME} "${TEST_NAME}.c" ) - TARGET_INCLUDE_DIRECTORIES(test_${TEST_NAME} PRIVATE +FUNCTION (buildtest TEST_FILE) + GET_FILENAME_COMPONENT(TEST_NAME ${TEST_FILE} NAME_WE) + ADD_EXECUTABLE(${TEST_NAME} ${TEST_FILE}) + TARGET_INCLUDE_DIRECTORIES(${TEST_NAME} PRIVATE ${Vulkan_INCLUDE_DIRS} ${GLFW3_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../include @@ -19,7 +20,7 @@ FUNCTION (buildtest TEST_NAME) ${CMAKE_CURRENT_SOURCE_DIR}/../vkh/include ${CMAKE_CURRENT_SOURCE_DIR}/../vkh/src ) - TARGET_LINK_LIBRARIES(test_${TEST_NAME} + TARGET_LINK_LIBRARIES(${TEST_NAME} tests_common ) ENDFUNCTION (buildtest) @@ -38,7 +39,7 @@ TARGET_LINK_LIBRARIES(tests_common ${Vulkan_LIBRARIES} ${GLFW3_LIBRARY} vkvg_static - ) +) file(GLOB_RECURSE DATAS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/*") FOREACH(DATA_FILE ${DATAS}) @@ -56,10 +57,12 @@ ENDFOREACH() add_custom_target("${PROJECT_NAME}_DataCopy" ALL DEPENDS ${DATAS}) #build test apps -file(GLOB TESTS "*.c") +file(GLOB TESTS + "*.c" + "perfs/*.c" +) FOREACH(TEST ${TESTS}) -GET_FILENAME_COMPONENT(testname ${TEST} NAME_WE) -buildtest(${testname}) + buildtest(${TEST}) ENDFOREACH() diff --git a/tests/arcs.c b/tests/arcs.c index d3e1109..cfeb131 100644 --- a/tests/arcs.c +++ b/tests/arcs.c @@ -19,8 +19,8 @@ void scaled_up() { vkvg_paint(ctx); vkvg_set_source_rgb (ctx, 0,0,0); - vkvg_scale(ctx,100,100); - vkvg_arc(ctx, 2, 2, 0.5f, 0, M_PIF/2.f); + vkvg_scale(ctx,10,10); + vkvg_arc(ctx, 20, 20, 2.0f, 0, M_PIF/2.f); vkvg_stroke(ctx); vkvg_destroy(ctx); diff --git a/tests/common/test.c b/tests/common/test.c index bec0e4d..fc2daa5 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -399,7 +399,7 @@ void perform_test_offscreen (void(*testfunc)(void), const char *testName, int ar enabledExtsCount++; #endif - VkhApp app = vkh_app_create("vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts); + VkhApp app = vkh_app_create(1, 1, "vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts); #if defined(DEBUG) && defined (VKVG_DBG_UTILS) vkh_app_enable_debug_messenger(app , VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT diff --git a/tests/common/vkengine.c b/tests/common/vkengine.c index 78fcd3f..90884f1 100644 --- a/tests/common/vkengine.c +++ b/tests/common/vkengine.c @@ -142,14 +142,14 @@ vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, VkPresentModeKHR free(instanceExtProps); - e->app = vkh_app_create("vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts); + e->app = vkh_app_create(1 ,2 , "vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts); #if defined(DEBUG) && defined (VKVG_DBG_UTILS) vkh_app_enable_debug_messenger(e->app , VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT //| VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT //| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT - //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT , NULL); @@ -191,10 +191,17 @@ vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, VkPresentModeKHR enabledExtsCount=0; + VkPhysicalDeviceFeatures2 phyFeat2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; + VkPhysicalDeviceScalarBlockLayoutFeatures scalarBlockLayoutSupport = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES}; + phyFeat2.pNext = &scalarBlockLayoutSupport; + + vkGetPhysicalDeviceFeatures2(pi->phy, &phyFeat2); + TRY_LOAD_DEVICE_EXT (VK_KHR_swapchain) TRY_LOAD_DEVICE_EXT (VK_EXT_blend_operation_advanced) TRY_LOAD_DEVICE_EXT (VK_KHR_portability_subset) TRY_LOAD_DEVICE_EXT (VK_KHR_relaxed_block_layout) + TRY_LOAD_DEVICE_EXT (VK_EXT_scalar_block_layout) VkPhysicalDeviceFeatures enabledFeatures = { .fillModeNonSolid = true, diff --git a/tests/fill.c b/tests/fill.c index c2ab672..feeb5f1 100644 --- a/tests/fill.c +++ b/tests/fill.c @@ -2,6 +2,7 @@ void test(){ VkvgContext ctx = vkvg_create(surf); + vkvg_save(ctx); vkvg_set_line_width(ctx,30); vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); diff --git a/tests/gradient.c b/tests/gradient.c index 27d956b..3fef7db 100644 --- a/tests/gradient.c +++ b/tests/gradient.c @@ -1,7 +1,7 @@ #include "test.h" -VkvgPattern create_grad (VkvgContext ctx) { - VkvgPattern pat = vkvg_pattern_create_linear(0,0,300,0); +VkvgPattern create_grad (VkvgContext ctx, float x) { + VkvgPattern pat = vkvg_pattern_create_linear(x,0,300,0); vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1); vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1); vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1); @@ -10,28 +10,73 @@ VkvgPattern create_grad (VkvgContext ctx) { void paint(){ VkvgContext ctx = vkvg_create(surf); - VkvgPattern pat = create_grad(ctx); - vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + //vkvg_translate(ctx,100,100); + VkvgPattern pat = create_grad(ctx,0); + //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + vkvg_rectangle(ctx, 0,0,400,460); vkvg_set_source (ctx, pat); - vkvg_paint(ctx); + vkvg_pattern_destroy (pat); + vkvg_fill(ctx); + + float x = 100; + pat = create_grad(ctx,x); + //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + vkvg_rectangle(ctx, x,200,20,20); + vkvg_set_source (ctx, pat); + vkvg_pattern_destroy (pat); + vkvg_fill(ctx); + + x+=100; + + pat = create_grad(ctx,x); + //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + vkvg_rectangle(ctx, x,200,20,20); + vkvg_set_source (ctx, pat); + vkvg_pattern_destroy (pat); + vkvg_fill(ctx); + + x+=100; + pat = create_grad(ctx,x); + //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + vkvg_rectangle(ctx, x,200,20,20); + vkvg_set_source (ctx, pat); + vkvg_pattern_destroy (pat); + vkvg_fill(ctx); + + x+=100; + + pat = create_grad(ctx,x); + //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE); + vkvg_rectangle(ctx, x,200,20,20); + vkvg_set_source (ctx, pat); vkvg_pattern_destroy (pat); + vkvg_fill(ctx); + + /*vkvg_set_source_rgb(ctx, 0,1,0); + vkvg_rectangle(ctx, 100,100,200,160); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgb(ctx, 0,0,0); + vkvg_set_line_width(ctx,1.0f); + vkvg_stroke(ctx);*/ + + vkvg_destroy(ctx); } void paint_repeat(){ VkvgContext ctx = vkvg_create(surf); - VkvgPattern pat = create_grad(ctx); + VkvgPattern pat = create_grad(ctx,0); vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); vkvg_set_source (ctx, pat); + vkvg_pattern_destroy (pat); vkvg_paint(ctx); - vkvg_pattern_destroy (pat); vkvg_destroy(ctx); } void test(){ VkvgContext ctx = vkvg_create(surf); - VkvgPattern pat = create_grad(ctx); + VkvgPattern pat = create_grad(ctx,0); vkvg_set_source (ctx, pat); vkvg_rectangle(ctx,100,100,200,200); vkvg_set_line_width(ctx, 20); @@ -89,7 +134,7 @@ void gradient_transform() { int main(int argc, char *argv[]) { no_test_size = true; PERFORM_TEST(paint, argc, argv); - PERFORM_TEST(paint_repeat, argc, argv); - PERFORM_TEST(gradient_transform, argc, argv); + /*PERFORM_TEST(paint_repeat, argc, argv); + PERFORM_TEST(gradient_transform, argc, argv);*/ return 0; } diff --git a/tests/gradient2.c b/tests/gradient2.c new file mode 100644 index 0000000..46439e6 --- /dev/null +++ b/tests/gradient2.c @@ -0,0 +1,174 @@ +#include "test.h" +#include "vectors.h" + +vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO; +static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT; +float lineWidth = 50.0f; +vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER; +vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT; +bool isClosed = false; + +int ptsCount = 2; +int initPtsCount = 4; +vec2 pts[] = { + {150,150}, + {250,150}, + {125,125}, + {145,125}, +}; +int hoverPt = -1; +double pointSize = 7; + +static vkvg_pattern_type_t patternType = VKVG_PATTERN_TYPE_LINEAR; +static VkEngine e; + +void draw (){ + + VkvgContext ctx = vkvg_create(surf); + vkvg_clear(ctx); + + VkvgPattern pat; + + switch (patternType) { + case VKVG_PATTERN_TYPE_LINEAR: + pat = vkvg_pattern_create_linear(pts[0].x,pts[0].y, pts[1].x,pts[1].y); + break; + case VKVG_PATTERN_TYPE_RADIAL: + pat = vkvg_pattern_create_radial( + pts[2].x,pts[2].y, vec2_length(vec2_sub(pts[3], pts[2])), + pts[0].x,pts[0].y, vec2_length(vec2_sub(pts[1], pts[0])) + ); + break; + } + + /**/ + + vkvg_pattern_add_color_stop(pat, 0.0, 1 ,0 ,0, 0.5); + vkvg_pattern_add_color_stop(pat, 0.3, 0 ,1 ,0, 0.5); + vkvg_pattern_add_color_stop(pat, 0.6, 0 ,0 ,1, 0.5); + vkvg_pattern_add_color_stop(pat, 1.0, 0 ,0 ,0, 0.5); + + vkvg_set_source (ctx, pat); + vkvg_paint (ctx); + + vkvg_set_dash(ctx, NULL, 0, 0); + vkvg_set_line_width(ctx,1); + for (int i=0; i VKVG_PATTERN_TYPE_RADIAL) + patternType = VKVG_PATTERN_TYPE_LINEAR; + break; + case GLFW_KEY_S : + vkengine_wait_idle(e); + vkvg_surface_write_to_png(surf, "/home/jp/test.png"); + break; + case GLFW_KEY_KP_ADD : + if (ptsCount < initPtsCount) + ptsCount++; + break; + case GLFW_KEY_KP_SUBTRACT : + if (ptsCount > 1) + ptsCount--; + break; + } +} +static void mouse_move_callback(GLFWwindow* window, double x, double y){ + if (mouseDown) { + if (hoverPt < 0) + return; + pts[hoverPt].x = x; + pts[hoverPt].y = y; + } else { + for (int i=0; i pts[i].x - pointSize && + x < pts[i].x + pointSize && + y > pts[i].y - pointSize && + y < pts[i].y + pointSize) { + hoverPt = i; + return; + } + } + hoverPt = -1; + } +} +static void scroll_callback(GLFWwindow* window, double x, double y){ + if (y<0.f) + zoom *= 0.5f; + else + zoom *= 2.0f; +} +static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){ + if (but != GLFW_MOUSE_BUTTON_1) + return; + if (state == GLFW_TRUE) + mouseDown = true; + else + mouseDown = false; +} + + + +int main(int argc, char* argv[]) { + + _parse_args (argc, argv); + + e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height); + + VkhPresenter r = e->renderer; + vkengine_set_key_callback (e, key_callback); + vkengine_set_mouse_but_callback(e, mouse_button_callback); + vkengine_set_cursor_pos_callback(e, mouse_move_callback); + vkengine_set_scroll_callback(e, scroll_callback); + + bool deferredResolve = false; + + device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); + surf = vkvg_surface_create(device, test_width, test_height); + + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height); + + while (!vkengine_should_close (e)) { + glfwPollEvents(); + + draw (); + + if (!vkh_presenter_draw (r)){ + vkh_presenter_get_size (r, &test_width, &test_height); + vkvg_surface_destroy (surf); + surf = vkvg_surface_create(device, test_width, test_height); + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height); + vkDeviceWaitIdle(r->dev->dev); + continue; + } + } + vkDeviceWaitIdle(e->dev->dev); + + vkvg_surface_destroy (surf); + + vkvg_device_destroy (device); + + vkengine_destroy (e); + + return 0; +} diff --git a/tests/inverse_colinear.c b/tests/inverse_colinear.c index b2559ed..f643d4e 100644 --- a/tests/inverse_colinear.c +++ b/tests/inverse_colinear.c @@ -137,6 +137,7 @@ static void mouse_button_callback(GLFWwindow* window, int but, int state, int mo int main(int argc, char* argv[]) { + _parse_args (argc, argv); VkEngine e; e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height); diff --git a/tests/perfs/random_rects.c b/tests/perfs/random_rects.c new file mode 100644 index 0000000..fc26077 --- /dev/null +++ b/tests/perfs/random_rects.c @@ -0,0 +1,27 @@ +#include "test.h" + +void drawRandomRect (VkvgContext ctx, float s) { + float w = (float)test_width; + float h = (float)test_height; + randomize_color(ctx); + + float x = truncf(w*rndf()); + float y = truncf(h*rndf()); + + vkvg_rectangle(ctx, x, y, s, s); +} +void fixedSizeRects(){ + VkvgContext ctx = _initCtx (); + for (uint32_t i=0; i