Commit: 44c66d713476841767a1ea3ab1804160535651a7
Parent: ce58f33b0b4890f4d698377161a5eee187e29dac
Author: Randy Palamar
Date: Tue, 27 Aug 2024 06:56:33 -0600
use a static buffer for render_glyph and cleanup some misuse of Term *
Diffstat:
M | font.c | | | 31 | +++++++++++++++++-------------- |
M | vtgl.c | | | 54 | ++++++++++++++++++++++++++---------------------------- |
2 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/font.c b/font.c
@@ -159,8 +159,10 @@ get_and_clear_glyph_cache_stats(GlyphCache *gc)
return result;
}
+static u32 glyph_buf[MAX_FONT_SIZE * MAX_FONT_SIZE * sizeof(u32)];
+
static u32 *
-render_glyph(FontAtlas *fa, Arena a, u32 cp, Glyph *out_glyph, u32 *out_idx)
+render_glyph(FontAtlas *fa, u32 cp, Glyph *out_glyph, u32 *out_idx)
{
/* NOTE: first check if glyph is in the cache and valid */
u32 idx = get_glyph_entry_index(&fa->glyph_cache, cp);
@@ -194,7 +196,7 @@ render_glyph(FontAtlas *fa, Arena a, u32 cp, Glyph *out_glyph, u32 *out_idx)
cg->g.delta.x = gs->bitmap_left;
cg->g.delta.y = gs->bitmap_top - cg->g.size.h;
- u32 *rgba_bitmap = alloc(&a, u32, cg->g.size.h * cg->g.size.w);
+ u32 *rgba_bitmap = mem_clear((u8 *)glyph_buf, 0, sizeof(glyph_buf));
for (u32 i = 0; i < cg->g.size.h; i++) {
for (u32 j = 0; j < cg->g.size.w; j++) {
/* TODO: handled coloured glyphs */
@@ -211,27 +213,28 @@ render_glyph(FontAtlas *fa, Arena a, u32 cp, Glyph *out_glyph, u32 *out_idx)
}
static void
-update_font_metrics(Term *t)
+update_font_metrics(FontAtlas *fa)
{
- t->fa.size.h = 0;
- t->fa.size.w = 0;
- t->fa.deltay = 0;
+ fa->size.h = 0;
+ fa->size.w = 0;
+ fa->deltay = 0;
Glyph g;
u32 index;
for (u32 i = ' '; i <= '~'; i++) {
- render_glyph(&t->fa, t->arena_for_frame, i, &g, &index);
- t->fa.size.h = MAX(t->fa.size.h, g.size.h);
- t->fa.size.w = MAX(t->fa.size.w, g.size.w);
- t->fa.deltay = MAX(t->fa.deltay, -g.delta.y);
+ render_glyph(fa, i, &g, &index);
+ fa->size.h = MAX(fa->size.h, g.size.h);
+ fa->size.w = MAX(fa->size.w, g.size.w);
+ fa->deltay = MAX(fa->deltay, -g.delta.y);
}
/* NOTE: ' ' has 0 size in freetype but we need it to have a width! */
- render_glyph(&t->fa, t->arena_for_frame, ' ', &g, &index);
- t->fa.glyph_cache.glyphs[index].g.size.w = t->fa.size.w;
+ render_glyph(fa, ' ', &g, &index);
+ fa->glyph_cache.glyphs[index].g.size.w = fa->size.w;
}
static void
-initialize_glyph_cache(GlyphCache *gc)
+initialize_glyph_cache(FontAtlas *fa)
{
+ GlyphCache *gc = &fa->glyph_cache;
mem_clear((u8 *)gc->glyphs, 0, sizeof(*gc->glyphs) * gc->cache_len);
mem_clear((u8 *)gc->hash_table, 0, sizeof(*gc->hash_table) * gc->cache_len);
for(u32 i = 0; i < gc->cache_len - 1; i++)
@@ -275,5 +278,5 @@ init_fonts(Term *t, Arena *a)
t->fa.glyph_cache.glyphs = alloc(a, CachedGlyph, t->fa.glyph_cache.cache_len);
t->fa.glyph_cache.hash_table = alloc(a, u32, t->fa.glyph_cache.cache_len);
- initialize_glyph_cache(&t->fa.glyph_cache);
+ initialize_glyph_cache(&t->fa);
}
diff --git a/vtgl.c b/vtgl.c
@@ -120,20 +120,20 @@ resize(Term *t)
}
static void
-update_font_textures(Term *t)
+update_font_textures(GLCtx *gl, FontAtlas *fa)
{
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D_ARRAY, t->gl.glyph_tex);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, gl->glyph_tex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8,
MAX_FONT_SIZE, MAX_FONT_SIZE, TEXTURE_GLYPH_COUNT,
0, GL_RED, GL_UNSIGNED_BYTE, 0);
- initialize_glyph_cache(&t->fa.glyph_cache);
+ initialize_glyph_cache(fa);
for (u32 i = ' '; i <= '~'; i++) {
u32 depth_idx;
Glyph g;
- u32 *data = render_glyph(&t->fa, t->arena_for_frame, i, &g, &depth_idx);
+ u32 *data = render_glyph(fa, i, &g, &depth_idx);
if (data) {
ASSERT(depth_idx);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, depth_idx,
@@ -141,7 +141,7 @@ update_font_textures(Term *t)
GL_UNSIGNED_BYTE, data);
}
}
- update_font_metrics(t);
+ update_font_metrics(fa);
}
static void
@@ -171,14 +171,14 @@ update_uniforms(Term *t, enum shader_stages stage)
set_projection_matrix(&t->gl);
/* TODO: this doesn't need to be called so often */
- update_font_textures(t);
+ update_font_textures(&t->gl, &t->fa);
}
static i32
-get_gpu_glyph_index(Term *t, u32 codepoint, Glyph *out_glyph)
+get_gpu_glyph_index(FontAtlas *fa, u32 codepoint, Glyph *out_glyph)
{
u32 depth_idx;
- u32 *data = render_glyph(&t->fa, t->arena_for_frame, codepoint, out_glyph, &depth_idx);
+ u32 *data = render_glyph(fa, codepoint, out_glyph, &depth_idx);
if (data) {
ASSERT(depth_idx);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, depth_idx,
@@ -189,19 +189,19 @@ get_gpu_glyph_index(Term *t, u32 codepoint, Glyph *out_glyph)
}
static v2
-measure_text(GLCtx *gl, s8 text, b32 monospaced)
+measure_text(FontAtlas *fa, s8 text, b32 monospaced)
{
v2 result = {0};
-#if 0
- f32 single_space_width = gl->glyph_cache[0].size.w;
+ Glyph g;
+ get_gpu_glyph_index(fa, ' ', &g);
+ f32 single_space_width = g.size.w;
for (size i = 0; i < text.len; i++) {
- Glyph g = gl->glyph_cache[text.data[i] - ' '];
+ get_gpu_glyph_index(fa, text.data[i], &g);
/* TODO: should we consider offset characters in y? */
if (g.size.h > result.y)
result.y = g.size.h;
result.x += monospaced? single_space_width : g.size.w;
}
-#endif
return result;
}
@@ -254,21 +254,20 @@ push_empty_cell_rect(RenderPushBuffer *rpb, Term *t, u32 minrow, u32 maxrow, u32
}
static void
-draw_text(RenderPushBuffer *rpb, GLCtx *gl, s8 text, v2 position, Colour colour, b32 monospaced)
+draw_text(RenderPushBuffer *rpb, GLCtx *gl, FontAtlas *fa, s8 text, v2 position, Colour colour, b32 monospaced)
{
- #if 0
- f32 single_space_width = gl->glyph_cache[0].size.w;
+ Glyph g;
+ get_gpu_glyph_index(fa, ' ', &g);
+ f32 single_space_width = g.size.w;
for (size i = 0; i < text.len; i++) {
- Glyph g;
u32 cp = text.data[i];
- i32 glyph_idx = get_gpu_glyph_index(gl, cp, &g);
+ i32 glyph_idx = get_gpu_glyph_index(fa, cp, &g);
v2 texscale = {.x = g.size.w / MAX_FONT_SIZE, .y = g.size.h / MAX_FONT_SIZE};
v2 vertscale = {.x = g.size.w, .y = g.size.h};
v2 vertoff = {.x = position.x + g.delta.x, .y = position.y + g.delta.y};
push_char(rpb, gl, vertscale, vertoff, texscale, (uv2){.x = colour.rgba}, glyph_idx);
position.x += monospaced? single_space_width : g.size.w;
}
- #endif
}
static void
@@ -277,15 +276,14 @@ draw_rectangle(RenderPushBuffer *rpb, GLCtx *gl, Rect r, Colour colour)
push_char(rpb, gl, r.size, r.pos, (v2){0}, (uv2){.y = colour.rgba}, 0);
}
-/* TODO: this doesn't need to take the whole Term * */
static void
-push_cell(RenderPushBuffer *rpb, Term *t, Cell c, Rect r, f32 font_text_dy)
+push_cell(RenderPushBuffer *rpb, GLCtx *gl, FontAtlas *fa, Cell c, Rect r, f32 font_text_dy)
{
- u32 idx = get_render_push_buffer_idx(rpb, &t->gl, 2);
+ u32 idx = get_render_push_buffer_idx(rpb, gl, 2);
ASSERT(c.cp);
Glyph g;
- i32 depth_idx = get_gpu_glyph_index(t, c.cp, &g);
+ i32 depth_idx = get_gpu_glyph_index(fa, c.cp, &g);
rpb->vertscales[idx + 0] = r.size;
rpb->vertscales[idx + 1] = (v2){.x = g.size.w, .y = g.size.h};
@@ -330,7 +328,7 @@ push_cell_row(Term *t, Cell *row, u32 len, b32 inverse, Rect cr, RenderPushBuffe
if (cell.style.attr & ATTR_WIDE) cr.size = csw;
else cr.size = cs;
cell.style.attr ^= inverse * ATTR_INVERSE;
- push_cell(rpb, t, cell, cr, t->fa.deltay);
+ push_cell(rpb, &t->gl, &t->fa, cell, cr, t->fa.deltay);
cr.pos.x += cr.size.w;
}
}
@@ -384,7 +382,7 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb)
if (cursor.style.attr & ATTR_WIDE)
cr.size.w *= 2;
cursor.style.attr ^= ATTR_INVERSE;
- push_cell(rpb, t, cursor, cr, t->fa.deltay);
+ push_cell(rpb, &t->gl, &t->fa, cursor, cr, t->fa.deltay);
}
}
@@ -547,7 +545,7 @@ KEYBIND_FN(scroll)
KEYBIND_FN(zoom)
{
shift_font_sizes(&t->fa, a.i);
- update_font_textures(t);
+ update_font_textures(&t->gl, &t->fa);
t->gl.flags |= NEEDS_RESIZE;
return 1;
}
@@ -832,7 +830,7 @@ do_terminal(Term *t)
s8 fps = s8alloc(&t->arena_for_frame, 64);
fps.len = snprintf((char *)fps.data, fps.len, "Render Time: %0.02f ms/f",
last_frame_time * 1e3);
- v2 ts = measure_text(&t->gl, fps, 1);
+ v2 ts = measure_text(&t->fa, fps, 1);
v2 pos = {.x = ws.w - ts.x - 10, .y = src_tr.y - ts.y - 10};
Rect r = {
@@ -841,7 +839,7 @@ do_terminal(Term *t)
};
draw_rectangle(rpb, &t->gl, r, (Colour){.rgba = 0x303030ff});
- draw_text(rpb, &t->gl, fps, pos, (Colour){.rgba = 0x1e9e33ff}, 1);
+ draw_text(rpb, &t->gl, &t->fa, fps, pos, (Colour){.rgba = 0x1e9e33ff}, 1);
}
flush_render_push_buffer(rpb, &t->gl);