]> O.S.I.I.S - jp/vkvg.git/commitdiff
Fill eo scissor (#101)
authorj-p <jp_bruyere@hotmail.com>
Tue, 1 Mar 2022 07:23:22 +0000 (08:23 +0100)
committerGitHub <noreply@github.com>
Tue, 1 Mar 2022 07:23:22 +0000 (08:23 +0100)
compute bounds for scissoring fill even/odd

src/vectors.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h

index a8a815f47f36dd656d1fb75eb2ab1024625b76da..090dfabb15f48a30df470966a317f7c57ebd1f41 100644 (file)
@@ -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 {
index 9b77922e6e866354392ec524c5549294ab3b4a0e..bb82857af5cc4315850fcb484b5558f5bcd83b81 100644 (file)
@@ -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);
index d88728104a24c44db38801012a55843889a775fb..7dd0a4df3b9671a61eca36c33e0935de23740031 100644 (file)
@@ -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)
index 2d22e0685c2dfa5482ca528c0b3370fc291c63ef..19283b0c5daab7cf8e58ec8cb30d5bcab2906dc4 100644 (file)
@@ -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);