From: j-p Date: Tue, 1 Mar 2022 07:23:22 +0000 (+0100) Subject: Fill eo scissor (#101) X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=888c021752120ef8cb2570c6f815629309921c11;p=jp%2Fvkvg.git Fill eo scissor (#101) compute bounds for scissoring fill even/odd --- diff --git a/src/vectors.h b/src/vectors.h index a8a815f..090dfab 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -50,21 +50,26 @@ typedef struct { union { float x; float r; + float xMin; }; union { float y; float g; + float yMin; }; union { float z; float width; float b; + float xMax; }; union { float w; float height; float a; + float yMax; }; + }vec4; typedef struct { diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 9b77922..bb82857 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -766,7 +766,7 @@ void _clip_preserve (VkvgContext ctx){ #endif if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ - _poly_fill (ctx); + _poly_fill (ctx, NULL); CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); }else{ CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); @@ -780,7 +780,7 @@ void _clip_preserve (VkvgContext ctx){ CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT); - _draw_full_screen_quad (ctx, false); + _draw_full_screen_quad (ctx, NULL); _bind_draw_pipeline (ctx); CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); @@ -801,11 +801,11 @@ void _fill_preserve (VkvgContext ctx){ if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ _emit_draw_cmd_undrawn_vertices(ctx); - - _poly_fill (ctx); - _bind_draw_pipeline (ctx); + vec4 bounds = {FLT_MAX,FLT_MAX,FLT_MIN,FLT_MIN}; + _poly_fill (ctx, &bounds); + _bind_draw_pipeline (ctx); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); - _draw_full_screen_quad (ctx, true); + _draw_full_screen_quad (ctx, &bounds); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); return; } @@ -993,7 +993,7 @@ void vkvg_paint (VkvgContext ctx){ } _ensure_renderpass_is_started (ctx); - _draw_full_screen_quad (ctx, true); + _draw_full_screen_quad (ctx, NULL); } void vkvg_set_source_color (VkvgContext ctx, uint32_t c) { if (ctx->status) @@ -1299,7 +1299,7 @@ void vkvg_save (VkvgContext ctx){ CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); - _draw_full_screen_quad (ctx, false); + _draw_full_screen_quad (ctx, NULL); _bind_draw_pipeline (ctx); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); @@ -1383,7 +1383,7 @@ void vkvg_restore (VkvgContext ctx){ CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); CmdSetStencilWriteMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - _draw_full_screen_quad (ctx, false); + _draw_full_screen_quad (ctx, NULL); _bind_draw_pipeline (ctx); CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index d887281..7dd0a4d 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -1571,7 +1571,7 @@ void _elliptic_arc (VkvgContext ctx, float x1, float y1, float x2, float y2, boo //Even-Odd inside test with stencil buffer implementation. -void _poly_fill (VkvgContext ctx){ +void _poly_fill (VkvgContext ctx, vec4* bounds){ //we anticipate the check for vbo buffer size, ibo is not used in poly_fill //the polyfill emit a single vertex for each point in the path. if (ctx->sizeVBO - VKVG_ARRAY_THRESHOLD < ctx->vertCount + ctx->pointCount) { @@ -1611,6 +1611,20 @@ void _poly_fill (VkvgContext ctx){ for (uint32_t i = 0; i < pathPointCount; i++) { v.pos = ctx->points [i+firstPtIdx]; ctx->vertexCache[ctx->vertCount++] = v; + if (!bounds) + continue; + //bounds are computed here to scissor the painting operation + //that speed up fill drastically. + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &v.pos.x, &v.pos.y); + + if (v.pos.x < bounds->xMin) + bounds->xMin = v.pos.x; + if (v.pos.x > bounds->xMax) + bounds->xMax = v.pos.x; + if (v.pos.y < bounds->yMin) + bounds->yMin = v.pos.y; + if (v.pos.y > bounds->yMax) + bounds->yMax = v.pos.y; } LOG(VKVG_LOG_INFO_PATH, "\tpoly fill: point count = %d; 1st vert = %d; vert count = %d\n", pathPointCount, firstVertIdx, ctx->vertCount - firstVertIdx); @@ -1900,20 +1914,16 @@ void _vkvg_path_extents (VkvgContext ctx, bool transformed, float *x1, float *y1 *y2 = yMax; } -void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) { +void _draw_full_screen_quad (VkvgContext ctx, vec4* scissor) { #if defined(DEBUG) && defined (VKVG_DBG_UTILS) vkh_cmd_label_start(ctx->cmd, "_draw_full_screen_quad", DBG_LAB_COLOR_FSQ); #endif - bool us = false;//=useScissor//bounds must be computed for even odd fill - if (us) { - float x1, y1, x2, y2; - _vkvg_path_extents(ctx, true, &x1, &y1, &x2, &y2); - if (x1 < 0 || y1 < 0 || EQUF(x1,x2) || EQUF(y1, y2)) - us = false; - else { - VkRect2D r = {{(int32_t)x1, (int32_t)y1}, {(int32_t)x2 - (int32_t)x1 + 1, (int32_t)y2 - (int32_t)y1 + 1}}; - CmdSetScissor(ctx->cmd, 0, 1, &r); - } + if (scissor) { + VkRect2D r = { + {(int32_t)MAX(scissor->xMin, 0), (int32_t)MAX(scissor->yMin, 0)}, + {(int32_t)MAX(scissor->xMax - (int32_t)scissor->xMin + 1, 1), (int32_t)MAX(scissor->yMax - (int32_t)scissor->yMin + 1, 1)} + }; + CmdSetScissor(ctx->cmd, 0, 1, &r); } uint32_t firstVertIdx = ctx->vertCount;//TODO:vxCache size is tested 3 times, must be optimized with only one check. @@ -1929,7 +1939,7 @@ void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) { ctx->pushConsts.fsq_patternType &= ~FULLSCREEN_BIT; CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType); - if (us) + if (scissor) CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); #if defined(DEBUG) && defined (VKVG_DBG_UTILS) diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 2d22e06..19283b0 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -125,8 +125,6 @@ typedef struct _vkvg_context_save_t { }vkvg_context_save_t; typedef struct _vkvg_context_t { - //VkvgContext pPrev; //double linked list of contexts - //VkvgContext pNext; uint32_t references; //reference count VkvgDevice dev; @@ -281,9 +279,9 @@ void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart void _draw_segment (VkvgContext ctx, float hw, stroke_context_t* str, dash_context_t* dc, bool isCurve); float _draw_dashed_segment (VkvgContext ctx, float hw, stroke_context_t *str, dash_context_t* dc, bool isCurve); -void _poly_fill (VkvgContext ctx); +void _poly_fill (VkvgContext ctx, vec4 *bounds); void _fill_non_zero (VkvgContext ctx); -void _draw_full_screen_quad (VkvgContext ctx, bool useScissor); +void _draw_full_screen_quad (VkvgContext ctx, vec4 *scissor); void _create_gradient_buff (VkvgContext ctx); void _create_vertices_buff (VkvgContext ctx);