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 {
#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);
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);
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;
}
}
_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)
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);
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);
//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) {
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);
*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.
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)
}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;
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);