#define VKVG_VERSION_REVISION 1
/*! @} */
+#ifndef cairo_public
+# if defined (_MSC_VER)
+# define vkvg_public __declspec(dllimport)
+# else
+# define vkvg_public
+# endif
+#endif
+
+#define VKVG_LOG_ERR 0x10
+#define VKVG_LOG_DEBUG 0x20
+#define VKVG_LOG_INFO 0x40
+#define VKVG_LOG_INFO_PATH 0x41
+#define VKVG_LOG_DBG_ARRAYS 0x80
+#define VKVG_LOG_FULL 0xff
+
#ifdef DEBUG
extern uint8_t vkvg_log_level;
#endif
ctx->curOperator = VKVG_OPERATOR_OVER;
ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO;
ctx->pSurf = surf;
-
+
ctx->bounds = (VkRect2D) {{0,0},{ctx->pSurf->width,ctx->pSurf->height}};
ctx->pushConsts = (push_constants) {
{.height=1},
0,
VKVG_IDENTITY_MATRIX,
VKVG_IDENTITY_MATRIX
- };
+ };
ctx->clearRect = (VkClearRect) {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1};
ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
}
void vkvg_show_text (VkvgContext ctx, const char* text){
- _ensure_renderpass_is_started(ctx);
+ //_ensure_renderpass_is_started(ctx);
_show_text (ctx, text);
- _flush_undrawn_vertices (ctx);
+ //_flush_undrawn_vertices (ctx);
}
VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text) {
}
//start render pass if not yet started or update push const if requested
void _ensure_renderpass_is_started (VkvgContext ctx) {
+ LOG(VKVG_LOG_INFO, "_ensure_renderpass_is_started\n");
if (!ctx->cmdStarted)
_start_cmd_for_render_pass(ctx);
else if (ctx->pushCstDirty)
void _check_vao_size (VkvgContext ctx) {
if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){
//vbo or ibo buffers too small
- if (ctx->cmdStarted) {
+ if (ctx->cmdStarted)
//if cmd is started buffers, are already bound, so no resize is possible
//instead we flush, and clear vbo and ibo caches
- _end_render_pass (ctx);
- if (ctx->curVertOffset > 0)
- _flush_vertices_caches_until_vertex_base (ctx);
- vkh_cmd_end (ctx->cmd);
- _wait_and_submit_cmd (ctx);
- }
+ _flush_cmd_until_vx_base (ctx);
+
_resize_vbo(ctx, ctx->sizeVertices);
_resize_ibo(ctx, ctx->sizeIndices);
}
ctx->curIndStart = ctx->indCount;
ctx->curVertOffset = ctx->vertCount;
}
-
+//preflush vertices with drawcommand already emited
+void _flush_cmd_until_vx_base (VkvgContext ctx){
+ _end_render_pass (ctx);
+ if (ctx->curVertOffset > 0){
+ LOG(VKVG_LOG_INFO, "FLUSH UNTIL VX BASE CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
+ _flush_vertices_caches_until_vertex_base (ctx);
+ }
+ vkh_cmd_end (ctx->cmd);
+ _wait_and_submit_cmd (ctx);
+}
void _flush_cmd_buff (VkvgContext ctx){
_flush_undrawn_vertices (ctx);
if (!ctx->cmdStarted)
return;
_end_render_pass (ctx);
+ LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
_flush_vertices_caches (ctx);
vkh_cmd_end (ctx->cmd);
- LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
_wait_and_submit_cmd(ctx);
}
void _ensure_renderpass_is_started (VkvgContext ctx);
void _flush_cmd_buff (VkvgContext ctx);
void _flush_undrawn_vertices(VkvgContext ctx);
+void _flush_cmd_until_vx_base (VkvgContext ctx);
void _wait_flush_fence (VkvgContext ctx);
void _reset_flush_fence (VkvgContext ctx);
void _wait_and_submit_cmd (VkvgContext ctx);
PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSet;
void _flush_all_contexes (VkvgDevice dev){
- VkvgContext next = dev->lastCtx;
- while (next != NULL){
- _flush_cmd_buff(next);
- next = next->pPrev;
+ VkvgContext ctx = dev->lastCtx;
+ while (ctx != NULL){
+ if (ctx->cmdStarted)
+ _flush_cmd_until_vx_base (ctx);
+
+ ctx = ctx->pPrev;
}
}
}
///increase layer count of 2d texture array used as font cache.
void _increase_font_tex_array (VkvgDevice dev){
+ LOG(VKVG_LOG_INFO, "_increase_font_tex_array\n");
+
+ _flush_all_contexes (dev);
+
_font_cache_t* cache = dev->fontCache;
vkWaitForFences (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
_submit_cmd (dev, &cache->cmd, cache->uploadFence);
vkWaitForFences (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
- _flush_all_contexes (dev);
-
cache->pensY = (int*)realloc(cache->pensY, newSize * sizeof(int));
- memset (cache->pensY + cache->texLength * sizeof(int),0,FONT_CACHE_INIT_LAYERS*sizeof(int));
+ void* tmp = memset (&cache->pensY[cache->texLength],0,FONT_CACHE_INIT_LAYERS*sizeof(int));
vkh_image_destroy (cache->texture);
cache->texLength = newSize;
cache->texture = newImg;
- /*VkvgContext next = dev->lastCtx;
+ VkvgContext next = dev->lastCtx;
while (next != NULL){
- _update_descriptor_set (next, next->source, next->dsSrc);
+ _update_descriptor_set (next, cache->texture, next->dsFont);
next = next->pPrev;
- }*/
+ }
+ _wait_idle(dev);
}
///Start a new line in font cache, increase texture layer count if needed.
void _init_next_line_in_tex_cache (VkvgDevice dev, _vkvg_font_t* f){
if (cache->stagingX == 0)
return;
+ LOG(VKVG_LOG_INFO, "_flush_chars_to_tex pen(%d, %d)\n",f->curLine.penX, f->curLine.penY);
vkWaitForFences (dev->vkDev,1,&cache->uploadFence,VK_TRUE,UINT64_MAX);
vkResetCommandBuffer(cache->cmd,0);
vkResetFences (dev->vkDev,1,&cache->uploadFence);
#include <fontconfig/fontconfig.h>
-#define FONT_PAGE_SIZE 2048
-#define FONT_CACHE_INIT_LAYERS 2
-#define FONT_FILE_NAME_MAX_SIZE 256
+#define FONT_PAGE_SIZE 1024
+#define FONT_CACHE_INIT_LAYERS 1
+#define FONT_FILE_NAME_MAX_SIZE 1024
#include "vkvg_internal.h"
#include "vkvg.h"
#define FT_CHECK_RESULT(f) \
{ \
- FT_Error res = (f); \
- if (res != 0) \
- { \
- fprintf(stderr,"Fatal : FreeType error is %d in %s at line %d\n", res, __FILE__, __LINE__); \
- assert(res == 0); \
- } \
+ FT_Error res = (f); \
+ if (res != 0) \
+ { \
+ fprintf(stderr,"Fatal : FreeType error is %d in %s at line %d\n", res, __FILE__, __LINE__); \
+ assert(res == 0); \
+ } \
}
//texture coordinates of one character in font cache array texture.
typedef struct {
- vec4 bounds; /* normalized float bounds of character bitmap in font cache texture. */
- vec2i16 bmpDiff; /* Difference in pixel between char bitmap top left corner and char glyph*/
- uint8_t pageIdx; /* Page index in font cache texture array */
+ vec4 bounds; /* normalized float bounds of character bitmap in font cache texture. */
+ vec2i16 bmpDiff; /* Difference in pixel between char bitmap top left corner and char glyph*/
+ uint8_t pageIdx; /* Page index in font cache texture array */
}_char_ref;
// Current location in font cache texture array for new character addition. Each font holds such structure to locate
// where to upload new chars.
typedef struct {
- uint8_t pageIdx; /* Current page number in font cache */
- int penX; /* Current X in cache for next char addition */
- int penY; /* Current Y in cache for next char addition */
- int height; /* Height of current line pointed by this structure */
+ uint8_t pageIdx; /* Current page number in font cache */
+ int penX; /* Current X in cache for next char addition */
+ int penY; /* Current Y in cache for next char addition */
+ int height; /* Height of current line pointed by this structure */
}_tex_ref_t;
// Loaded font structure, holds informations for glyphes upload in cache and the lookup table of characters.
typedef struct {
- char* fontFile; /* Font file full path*/
- FT_F26Dot6 charSize; /* Font size*/
- hb_font_t* hb_font; /* HarfBuzz font instance*/
- FT_Face face; /* FreeType face*/
- _char_ref** charLookup; /* Lookup table of characteres in cache, if not found, upload is queued*/
+ char* fontFile; /* Font file full path*/
+ FT_F26Dot6 charSize; /* Font size*/
+ hb_font_t* hb_font; /* HarfBuzz font instance*/
+ FT_Face face; /* FreeType face*/
+ _char_ref** charLookup; /* Lookup table of characteres in cache, if not found, upload is queued*/
- _tex_ref_t curLine; /* tex coord where to add new char bmp's */
+ _tex_ref_t curLine; /* tex coord where to add new char bmp's */
}_vkvg_font_t;
// Font cache global structure, entry point for all font related operations.
typedef struct {
- FT_Library library; /* FreeType library*/
- FcConfig* config; /* Font config, used to find font files by font names*/
+ FT_Library library; /* FreeType library*/
+ FcConfig* config; /* Font config, used to find font files by font names*/
- int stagingX; /* x pen in host buffer */
- uint8_t* hostBuff; /* host memory where bitmaps are first loaded */
+ int stagingX; /* x pen in host buffer */
+ uint8_t* hostBuff; /* host memory where bitmaps are first loaded */
- VkCommandBuffer cmd; /* vulkan command buffer for font textures upload */
- vkvg_buff buff; /* stagin buffer */
- VkhImage texture; /* 2d array texture used by contexts to draw characteres */
- VkFormat texFormat; /* Format of the fonts texture array */
- uint8_t texPixelSize; /* Size in byte of a single pixel in a font texture */
- uint8_t texLength; /* layer count of 2d array texture, starts with FONT_CACHE_INIT_LAYERS count and increased when needed */
- int* pensY; /* array of current y pen positions for each texture in cache 2d array */
- VkFence uploadFence; /* Signaled when upload is finished */
+ VkCommandBuffer cmd; /* vulkan command buffer for font textures upload */
+ vkvg_buff buff; /* stagin buffer */
+ VkhImage texture; /* 2d array texture used by contexts to draw characteres */
+ VkFormat texFormat; /* Format of the fonts texture array */
+ uint8_t texPixelSize; /* Size in byte of a single pixel in a font texture */
+ uint8_t texLength; /* layer count of 2d array texture, starts with FONT_CACHE_INIT_LAYERS count and increased when needed */
+ int* pensY; /* array of current y pen positions for each texture in cache 2d array */
+ VkFence uploadFence; /* Signaled when upload is finished */
- _vkvg_font_t* fonts; /* Loaded fonts structure array */
- uint8_t fontsCount; /* Loaded fonts array count*/
+ _vkvg_font_t* fonts; /* Loaded fonts structure array */
+ uint8_t fontsCount; /* Loaded fonts array count*/
}_font_cache_t;
// Precompute everything necessary to draw one line of text, usefull to draw the same text multiple times.
typedef struct _vkvg_text_run_t {
- hb_buffer_t* hbBuf; /* HarfBuzz buffer of text */
- _vkvg_font_t* font; /* vkvg font structure pointer */
- VkvgDevice dev; /* vkvg device associated with this text run */
- vkvg_text_extents_t extents; /* store computed text extends */
- const char* text; /* utf8 char array of text*/
- unsigned int glyph_count;/* Total glyph count */
- hb_glyph_position_t *glyph_pos; /* HarfBuzz computed glyph positions array */
+ hb_buffer_t* hbBuf; /* HarfBuzz buffer of text */
+ _vkvg_font_t* font; /* vkvg font structure pointer */
+ VkvgDevice dev; /* vkvg device associated with this text run */
+ vkvg_text_extents_t extents; /* store computed text extends */
+ const char* text; /* utf8 char array of text*/
+ unsigned int glyph_count;/* Total glyph count */
+ hb_glyph_position_t *glyph_pos; /* HarfBuzz computed glyph positions array */
} vkvg_text_run_t;
//Create font cache.
void _init_fonts_cache (VkvgDevice dev);
#define LOG
#endif
-#define VKVG_LOG_ERR 0x10
-#define VKVG_LOG_DEBUG 0x20
-#define VKVG_LOG_INFO 0x40
-#define VKVG_LOG_INFO_PATH 0x41
-#define VKVG_LOG_DBG_ARRAYS 0x80
-#define VKVG_LOG_FULL 0xff
-
-
#define PATH_CLOSED_BIT 0x80000000 /* most significant bit of path elmts is closed/open path state */
#define PATH_HAS_CURVES_BIT 0x40000000 /* 2d most significant bit of path elmts if curve data are present,
stored to avoid emiting joins in curves */
VkvgDevice device = NULL;
VkvgSurface surf = NULL;
-uint32_t test_size = 100; // items drawn in one run, or complexity
-uint32_t iterations = 1000;// repeat test n times
+uint32_t test_size = 500; // items drawn in one run, or complexity
+uint32_t iterations = 500;// repeat test n times
uint32_t test_width = 1024;
uint32_t test_height= 768;
bool test_vsync = false;
vkvg_destroy(ctx);
}
-
-void test_mono () {
+void random_text () {
VkvgContext ctx = vkvg_create(surf);
- vkvg_set_source_rgb(ctx,1,1,1);
+ vkvg_clear(ctx);
vkvg_select_font_face(ctx,"mono");
- vkvg_set_font_size(ctx, 20);
- vkvg_move_to(ctx,100,100);
- vkvg_show_text(ctx,"This is a test string!");
+ for (uint32_t i=0; i<test_size; i++) {
+ randomize_color(ctx);
+ float x = (float)rand()/RAND_MAX * test_width;
+ float y = (float)rand()/RAND_MAX * test_height;
+ uint32_t c = (uint32_t)((float)rand()/RAND_MAX * 80)+1;
+
+ vkvg_set_font_size(ctx, c);
+ vkvg_move_to(ctx,x,y);
+ vkvg_show_text(ctx,"This is a test string!");
+ }
vkvg_destroy(ctx);
}
-
int main(int argc, char *argv[]) {
- PERFORM_TEST (test_mono, argc, argv);
- /*PERFORM_TEST (test, argc, argv);
+ //vkvg_log_level = VKVG_LOG_INFO;
+ PERFORM_TEST (random_text, argc, argv);
+ PERFORM_TEST (test, argc, argv);
PERFORM_TEST (test1, argc, argv);
- PERFORM_TEST (test2, argc, argv);*/
+ PERFORM_TEST (test2, argc, argv);
return 0;
}