ctx->pSurf = surf;
ctx->curOperator = VKVG_OPERATOR_OVER;
ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO;
- ctx->curSavBit = 0x4;
+ ctx->curSavBit = 0;
ctx->vertCount = 0;
ctx->indCount = 0;
ctx->curIndStart = 0;
+ ctx->savedStencils = malloc(0);
push_constants pc = {
{.height=1},
surf->dev->lastCtx = ctx;
ctx->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char));
+ ctx->currentFont = NULL;
ctx->flushFence = vkh_fence_create((VkhDevice)dev);
if (cur->pattern)
vkvg_pattern_destroy (cur->pattern);
}
+ //free additional stencil use in save/restore process
+ uint8_t curSaveStencil = ctx->curSavBit / 6;
+ for (int i=curSaveStencil;i>0;i--)
+ vkh_image_destroy(ctx->savedStencils[i-1]);
+
+ free(ctx->savedStencils);
//remove context from double linked list of context in device
if (ctx->pSurf->dev->lastCtx == ctx){
VkvgDevice dev = ctx->pSurf->dev;
vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t));
+ uint8_t curSaveStencil = ctx->curSavBit / 6;
+
+ if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//new save/restore stencil image have to be created
+ ctx->savedStencils = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof (VkhImage));
+ VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev,FB_STENCIL_FORMAT, dev->samples, ctx->pSurf->width, ctx->pSurf->height,
+ VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+ ctx->savedStencils[curSaveStencil-1] = savStencil;
+
+ vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ ctx->cmdStarted = true;
+
+ vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+ vkh_image_set_layout (ctx->cmd, savStencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+ VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+ .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+ .extent = {ctx->pSurf->width,ctx->pSurf->height,1}};
+ vkCmdCopyImage(ctx->cmd,
+ vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ vkh_image_get_vkimage (savStencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ 1, &cregion);
+
+ vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+
+ VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd));
+ _submit_wait_and_reset_cmd(ctx);
+ }
+
+ uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2);
+
_start_cmd_for_render_pass(ctx);
CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping);
- CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|ctx->curSavBit);
+ CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit);
CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
- CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curSavBit);
+ CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit);
_draw_full_screen_quad(ctx);
sav->pNext = ctx->pSavedCtxs;
ctx->pSavedCtxs = sav;
- ctx->curSavBit = (ctx->curSavBit << 1);
+ ctx->curSavBit++;
if (ctx->pattern)
vkvg_pattern_reference (ctx->pattern);
_flush_cmd_buff(ctx);
- ctx->curSavBit = (ctx->curSavBit >> 1);
+ ctx->curSavBit--;
+
+ uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2);
_start_cmd_for_render_pass(ctx);
CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping);
- CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|ctx->curSavBit);
- CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curSavBit);
+ CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit);
+ CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit);
CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
_draw_full_screen_quad(ctx);
_bind_draw_pipeline (ctx);
CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+ _flush_cmd_buff(ctx);
+
+ uint8_t curSaveStencil = ctx->curSavBit / 6;
+ if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//addtional save/restore stencil image have to be copied back to surf stencil first
+ VkhImage savStencil = ctx->savedStencils[curSaveStencil-1];
+
+ vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ ctx->cmdStarted = true;
+
+ vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+ vkh_image_set_layout (ctx->cmd, savStencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+ VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+ .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+ .extent = {ctx->pSurf->width,ctx->pSurf->height,1}};
+ vkCmdCopyImage(ctx->cmd,
+ vkh_image_get_vkimage (savStencil), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ 1, &cregion);
+ vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+
+ VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd));
+ _submit_wait_and_reset_cmd(ctx);
+
+ vkh_image_destroy(savStencil);
+ }
+
ctx->lineWidth = sav->lineWidth;
ctx->curOperator= sav->curOperator;
ctx->lineCap = sav->lineCap;
void _free_ctx_save (vkvg_context_save_t* sav){
free(sav->selectedFont.fontFile);
- vkh_image_destroy (sav->stencil);
free (sav);
}
#include "vkh.h"
#include "vkvg_fonts.h"
-#define VKVG_PTS_SIZE 10000
-#define VKVG_VBO_SIZE VKVG_PTS_SIZE * 2
-#define VKVG_IBO_SIZE VKVG_VBO_SIZE * 2
+#define VKVG_PTS_SIZE 4096
+#define VKVG_VBO_SIZE 4096 * 8
+#define VKVG_IBO_SIZE VKVG_VBO_SIZE * 6
#define VKVG_PATHES_SIZE 16
#define VKVG_ARRAY_THRESHOLD 4
typedef struct _vkvg_context_save_t{
struct _vkvg_context_save_t* pNext;
- VkhImage stencil;
- uint32_t stencilRef;
-
float lineWidth;
vkvg_operator_t curOperator;
VkvgPattern pattern;
vkvg_status_t status;
- vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr
- unsigned char curSavBit;//current stencil bit used to save context
+ vkvg_context_save_t* pSavedCtxs; //last ctx saved ptr
+ uint8_t curSavBit; //current stencil bit used to save context, 6 bits used by stencil for save/restore
+ VkhImage* savedStencils; //additional image for saving contexes once more than 6 save/restore are reached
VkClearRect clearRect;
VkRenderPassBeginInfo renderPassBeginInfo;
void _init_descriptor_sets (VkvgContext ctx);
void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds);
void _update_gradient_desc_set(VkvgContext ctx);
-//void _reset_src_descriptor_set(VkvgContext ctx);
void _free_ctx_save (vkvg_context_save_t* sav);
static inline float vec2_zcross (vec2 v1, vec2 v2){
void _update_current_font (VkvgContext ctx) {
VkvgDevice dev = ctx->pSurf->dev;
if (ctx->currentFont == NULL){
+ if (ctx->selectedFont.fontFile[0] == 0) {
+ ctx->selectedFont.charSize = 10 << 6;
+ _select_font_face (ctx, "sans");
+ }
ctx->currentFont = _tryFindVkvgFont (ctx);
if (ctx->currentFont == NULL){
//create new font in cache
surf = vkvg_surface_create(device, width, height);
- vkvg_surface_clear(surf);
+ //vkvg_surface_clear(surf);
vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="102.07465"
+ height="71.185143"
+ viewBox="0 0 27.007252 18.834403"
+ version="1.1"
+ id="svg852"
+ inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+ sodipodi:docname="vkvg.svg"
+ inkscape:export-filename="/mnt/devel/gts/vkvg/logo.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs846">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient845">
+ <stop
+ style="stop-color:#2d8dad;stop-opacity:1"
+ offset="0"
+ id="stop841" />
+ <stop
+ style="stop-color:#83deff;stop-opacity:0"
+ offset="1"
+ id="stop843" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient845"
+ id="linearGradient847"
+ x1="110.68917"
+ y1="31.07439"
+ x2="91.910088"
+ y2="2.6321857"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.0000001"
+ inkscape:cx="55.543792"
+ inkscape:cy="-18.195561"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1600"
+ inkscape:window-height="881"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ units="px"
+ fit-margin-top="2"
+ fit-margin-left="2"
+ fit-margin-right="2"
+ fit-margin-bottom="2">
+ <inkscape:grid
+ type="xygrid"
+ id="grid1397"
+ originx="-8.7505678"
+ originy="-329.84273" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata849">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-36.983507,-7.4244837)">
+ <g
+ id="g854"
+ inkscape:export-xdpi="90.02018"
+ inkscape:export-ydpi="90.02018"
+ inkscape:export-filename="logo.png">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ id="path838"
+ d="M 124.35416,29.770833 99.054233,36.549929 80.5334,18.029095 89.823048,2.0986798 l 25.299922,-6.779096 16.01029,9.1513207 z"
+ inkscape:transform-center-x="2.1421585e-06"
+ style="opacity:1;fill:url(#linearGradient847);fill-opacity:1;stroke:#7d7d7d;stroke-width:0.53889078;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
+ transform="matrix(0.47424803,0.12707438,-0.12707438,0.47424803,1.7254712,-4.3235598)" />
+ <path
+ id="path849"
+ style="fill:none;stroke:#848484;stroke-width:0.5291667;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 46.493561,17.443984 v 6.614583 m 0.79151,-7.493167 c 0,0.437128 -0.35436,0.791491 -0.79149,0.791491 -0.43713,0 -0.7915,-0.354363 -0.7915,-0.791491 0,-0.437128 0.35437,-0.791491 0.7915,-0.791491 0.43713,0 0.79149,0.354363 0.79149,0.791491 z m -0.79149,-3.35475 -2e-5,2.55625 m 10.58341,3.000001 h 2.64585 l -2.64585,5.291666 -2.64585,-5.291666 m 2.64585,-5.291668 -5.29169,10.583334 -3.17504,-6.35 m 3.17504,-4.233334 c -5.29172,5.291667 -5.2917,10.583334 -5.2917,10.583334 m -5.2917,-10.583334 c 5.29168,5.291667 5.2917,10.583334 5.2917,10.583334"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsssssccccccccccccc" />
+ <path
+ sodipodi:nodetypes="ccsssssccccccccccccc"
+ inkscape:connector-curvature="0"
+ d="M 45.964394,16.914817 V 23.5294 m 0.79151,-7.493167 c 0,0.437128 -0.35436,0.791491 -0.79149,0.791491 -0.43713,0 -0.7915,-0.354363 -0.7915,-0.791491 0,-0.437128 0.35437,-0.791491 0.7915,-0.791491 0.43713,0 0.79149,0.354363 0.79149,0.791491 z m -0.79149,-3.35475 -2e-5,2.55625 m 10.58341,3.000001 h 2.64585 l -2.64585,5.291666 -2.64585,-5.291666 m 2.64585,-5.291668 -5.29169,10.583334 -3.17504,-6.35 m 3.17504,-4.233334 c -5.29172,5.291667 -5.2917,10.583334 -5.2917,10.583334 m -5.2917,-10.583334 c 5.29168,5.291667 5.2917,10.583334 5.2917,10.583334"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5291667;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path836" />
+ </g>
+ </g>
+</svg>
}
int main(int argc, char *argv[]) {
- perform_test (test2, 1024, 768);
+ perform_test (test, 1024, 768);
return 0;
}
#include "test.h"
-void test(){
- VkvgContext ctx = vkvg_create(surf);
+void recurse_draw(VkvgContext ctx, int depth) {
+ depth++;
+ vkvg_save(ctx);
- vkvg_set_source_rgba(ctx,1,0,0,1);
- vkvg_set_line_width(ctx,10);
- vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_translate (ctx, 5,5);
+ vkvg_rectangle(ctx, depth,depth,200,200);
+ vkvg_clip_preserve(ctx);
+ vkvg_set_source_rgb(ctx, 1.f/depth, 1.f / depth, 1.f / depth);
+ vkvg_fill_preserve(ctx);
+ vkvg_set_source_rgb(ctx, 0,0,0);
vkvg_stroke(ctx);
- vkvg_set_source_rgba(ctx,0,1,0,1);
- vkvg_save(ctx);
-
- vkvg_set_source_rgba(ctx,0,1,1,1);
- vkvg_set_line_width(ctx,1);
- vkvg_rectangle(ctx,200,200,200,200);
- vkvg_fill(ctx);
+ if (depth < 20)
+ recurse_draw (ctx, depth);
vkvg_restore(ctx);
+}
- vkvg_rectangle(ctx,100,100,200,200);
- vkvg_stroke(ctx);
+
+void test(){
+ VkvgContext ctx = vkvg_create(surf);
+
+ recurse_draw(ctx, 0);
vkvg_destroy(ctx);
}
VkvgContext ctx = vkvg_create(surf);
vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
- vkvg_set_source_rgba(ctx,0.7f,0.7f,0.7f,1);
+ vkvg_set_source_rgba(ctx,1.0f,1.0f,1.0f,1);
vkvg_paint(ctx);
vkvg_set_matrix(ctx,&mat);