Commit: 60fa5e65f199607d3edda83635fc75f7906201c7
Parent: 841511e052f412d9738758c36f15d59b4973e431
Author: Randy Palamar
Date: Wed, 23 Oct 2024 09:40:17 -0600
group render parameters into a RenderCtx struct
Diffstat:
M | terminal.c | | | 1 | + |
M | util.c | | | 9 | +++++++++ |
M | util.h | | | 16 | ++++++++-------- |
M | vtgl.c | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
4 files changed, 71 insertions(+), 47 deletions(-)
diff --git a/terminal.c b/terminal.c
@@ -174,6 +174,7 @@ fb_clear_region(Term *t, u32 r1, u32 r2, u32 c1, u32 c2)
for (u32 c = c1; c <= c2; c++) {
tv->fb.rows[r][c].style = t->cursor.style;
tv->fb.rows[r][c].cp = ' ';
+ /* TODO: this shouldn't be in this loop; make a region intersection test */
if (is_selected(&t->selection, c, r))
selection_clear(&t->selection);
}
diff --git a/util.c b/util.c
@@ -84,6 +84,15 @@ alloc_(Arena *a, size len, size align, size count)
return mem_clear(p, 0, count * len);
}
+static Arena
+make_arena(Arena *a, size size)
+{
+ Arena result;
+ result.beg = alloc_(a, size, 64, 1);
+ result.end = result.beg + size;
+ return result;
+}
+
/* NOTE: This performs wrapping of the ring buffer as needed; since a line could be in
* progress this must also adjust the start and end of the current line */
static void
diff --git a/util.h b/util.h
@@ -266,7 +266,7 @@ typedef struct {
/* TODO: try different sizes; largely depends on how many things we want to batch together */
#define RENDER_PUSH_BUFFER_CAP 8192
-typedef struct {
+typedef __attribute__((aligned(64))) struct {
v2 positions[RENDER_PUSH_BUFFER_CAP];
v2 texture_coordinates[RENDER_PUSH_BUFFER_CAP];
v4 colours[RENDER_PUSH_BUFFER_CAP];
@@ -327,13 +327,6 @@ typedef struct {
} FontInfo;
typedef struct {
- /* distance to shift glyph from bounding box origin */
- iv2 delta;
- /* rendered glyph bitmap data (pixels) */
- uv2 size;
-} Glyph;
-
-typedef struct {
u32 cp;
u32 next_with_same_hash;
u32 prev;
@@ -423,6 +416,13 @@ enum terminal_mode {
};
typedef struct {
+ RenderPushBuffer *rpb;
+ GLCtx *gl;
+ FontAtlas *fa;
+ Arena a;
+} RenderCtx;
+
+typedef struct {
GLCtx gl;
FontAtlas fa;
diff --git a/vtgl.c b/vtgl.c
@@ -14,7 +14,7 @@ static u32 get_gpu_glyph_index(Arena, GLCtx *, FontAtlas *, u32, u32, enum face_
#ifdef _DEBUG
#include "debug.c"
-static void draw_debug_overlay(Term *, RenderPushBuffer *);
+static void draw_debug_overlay(Term *, RenderCtx *);
#endif
#define REVERSE_VIDEO_MASK (Colour){.r = 0xff, .g = 0xff, .b = 0xff}.rgba
@@ -139,6 +139,17 @@ update_uniforms(Term *t, enum shader_stages stage)
}
}
+static RenderCtx
+make_render_ctx(Arena *a, GLCtx *gl, FontAtlas *fa)
+{
+ RenderCtx result;
+ result.gl = gl;
+ result.fa = fa;
+ result.rpb = alloc(a, RenderPushBuffer, 1);
+ result.a = make_arena(a, 4 * MEGABYTE);
+ return result;
+}
+
static iv2
get_gpu_texture_position(v2 cs, u32 gpu_tile_index)
{
@@ -171,10 +182,12 @@ get_gpu_glyph_index(Arena a, GLCtx *gl, FontAtlas *fa, u32 codepoint, u32 font_i
/* NOTE: this function assumes we are drawing quads */
static void
-flush_render_push_buffer(RenderPushBuffer *rpb, GLCtx *gl)
+flush_render_push_buffer(RenderCtx *rc)
{
- if (rpb->count > 0) {
- u32 n = rpb->count;
+ if (rc->rpb->count > 0) {
+ u32 n = rc->rpb->count;
+ GLCtx *gl = rc->gl;
+ RenderPushBuffer *rpb = rc->rpb;
ASSERT((n % 4) == 0);
glBindBuffer(GL_ARRAY_BUFFER, gl->vbos[0]);
@@ -186,26 +199,27 @@ flush_render_push_buffer(RenderPushBuffer *rpb, GLCtx *gl)
glDrawElements(GL_TRIANGLES, 6 * n / 4, GL_UNSIGNED_INT, 0);
}
- rpb->count = 0;
+ rc->rpb->count = 0;
}
static u32
-get_render_push_buffer_idx(RenderPushBuffer *rpb, GLCtx *gl, u32 count)
+get_render_push_buffer_idx(RenderCtx *rc, u32 count)
{
- if (rpb->count + count > RENDER_PUSH_BUFFER_CAP)
- flush_render_push_buffer(rpb, gl);
- u32 result = rpb->count;
- rpb->count += count;
+ if (rc->rpb->count + count > RENDER_PUSH_BUFFER_CAP)
+ flush_render_push_buffer(rc);
+ u32 result = rc->rpb->count;
+ rc->rpb->count += count;
return result;
}
static void
-push_rect_full(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, v2 min_tex_coord, v2 max_tex_coord)
+push_rect_full(RenderCtx *rc, Rect r, v4 colour, v2 min_tex_coord, v2 max_tex_coord)
{
- u32 idx = get_render_push_buffer_idx(rpb, gl, 4);
+ u32 idx = get_render_push_buffer_idx(rc, 4);
v2 start = r.pos;
v2 end = {.x = r.pos.x + r.size.w, .y = r.pos.y + r.size.h};
+ RenderPushBuffer *rpb = rc->rpb;
rpb->positions[idx + 0] = (v2){.x = end.x, .y = end.y };
rpb->positions[idx + 1] = (v2){.x = end.x, .y = start.y};
rpb->positions[idx + 2] = (v2){.x = start.x, .y = start.y};
@@ -223,7 +237,7 @@ push_rect_full(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, v2 min_tex_c
}
static void
-push_rect_textured(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, b32 flip_texture)
+push_rect_textured(RenderCtx *rc, Rect r, v4 colour, b32 flip_texture)
{
v2 min_tex_coord, max_tex_coord;
if (!flip_texture) {
@@ -233,37 +247,37 @@ push_rect_textured(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour, b32 flip
max_tex_coord = (v2){.x = 1.0f, .y = 0.0f};
min_tex_coord = (v2){.x = 0.0f, .y = 1.0f};
}
- push_rect_full(rpb, gl, r, colour, min_tex_coord, max_tex_coord);
+ push_rect_full(rc, r, colour, min_tex_coord, max_tex_coord);
}
static void
-push_rect(RenderPushBuffer *rpb, GLCtx *gl, Rect r, v4 colour)
+push_rect(RenderCtx *rc, Rect r, v4 colour)
{
- f32 max_x = 1.0f / gl->glyph_bitmap_dim.x;
- f32 max_y = 1.0f / gl->glyph_bitmap_dim.y;
- push_rect_full(rpb, gl, r, colour, (v2){0}, (v2){.x = max_x, .y = max_y});
+ f32 max_x = 1.0f / rc->gl->glyph_bitmap_dim.x;
+ f32 max_y = 1.0f / rc->gl->glyph_bitmap_dim.y;
+ push_rect_full(rc, r, colour, (v2){0}, (v2){.x = max_x, .y = max_y});
}
static v2
-push_s8(RenderPushBuffer *rpb, Arena a, GLCtx *gl, FontAtlas *fa, v2 pos, v4 colour, u32 font_id, s8 s)
+push_s8(RenderCtx *rc, v2 pos, v4 colour, u32 font_id, s8 s)
{
CachedGlyph *cg;
v2 start, end, text_size = {0};
- v2 scale = {.x = 1.0f / gl->glyph_bitmap_dim.x, .y = 1.0f / gl->glyph_bitmap_dim.y};
+ v2 scale = {.x = 1.0f / rc->gl->glyph_bitmap_dim.x, .y = 1.0f / rc->gl->glyph_bitmap_dim.y};
while (s.len) {
u32 cp = get_utf8(&s);
if (cp == (u32)-1)
break;
- get_gpu_glyph_index(a, gl, fa, cp, font_id, FS_NORMAL, &cg);
- cached_glyph_to_uv(fa, cg, &start, &end, scale);
+ get_gpu_glyph_index(rc->a, rc->gl, rc->fa, cp, font_id, FS_NORMAL, &cg);
+ cached_glyph_to_uv(rc->fa, cg, &start, &end, scale);
Rect r = {.pos = pos, .size = {.x = cg->width, .y = cg->height}};
r.pos.x += cg->x0;
r.pos.y -= (cg->height + cg->y0);
- push_rect_full(rpb, gl, r, colour, start, end);
+ push_rect_full(rc, r, colour, start, end);
text_size.x += cg->advance;
pos.x += cg->advance;
@@ -277,7 +291,7 @@ push_s8(RenderPushBuffer *rpb, Arena a, GLCtx *gl, FontAtlas *fa, v2 pos, v4 col
}
static v2
-measure_text(Arena a, GLCtx *gl, FontAtlas *fa, u32 font_id, s8 text)
+measure_text(RenderCtx *rc, u32 font_id, s8 text)
{
v2 result = {0};
@@ -287,7 +301,7 @@ measure_text(Arena a, GLCtx *gl, FontAtlas *fa, u32 font_id, s8 text)
cp = get_utf8(&text);
if (cp == (u32)-1)
break;
- get_gpu_glyph_index(a, gl, fa, cp, font_id, FS_NORMAL, &cg);
+ get_gpu_glyph_index(rc->a, rc->gl, rc->fa, cp, font_id, FS_NORMAL, &cg);
if (cg->height > result.y)
result.y = cg->height;
result.x += cg->advance;
@@ -842,7 +856,7 @@ do_terminal(Term *t, f32 dt)
set_projection_matrix(&t->gl);
- RenderPushBuffer *rpb = alloc(&t->arena_for_frame, RenderPushBuffer, 1);
+ RenderCtx rc = make_render_ctx(&t->arena_for_frame, &t->gl, &t->fa);
glUseProgram(t->gl.programs[SHADER_RENDER]);
glBindFramebuffer(GL_FRAMEBUFFER, t->gl.fb);
@@ -871,8 +885,8 @@ do_terminal(Term *t, f32 dt)
glBindBufferBase(GL_UNIFORM_BUFFER, 0, t->gl.render_shader_ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*sp), sp);
- push_rect_textured(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 0);
- flush_render_push_buffer(rpb, &t->gl);
+ push_rect_textured(&rc, (Rect){.size = t->gl.window_size}, (v4){0}, 0);
+ flush_render_push_buffer(&rc);
static f32 param = 0;
static f32 p_scale = 1;
@@ -887,8 +901,8 @@ do_terminal(Term *t, f32 dt)
glUniform1i(t->gl.post.texslot, t->gl.fb_tex_unit);
glUniform1f(t->gl.post.param, param);
- push_rect_textured(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 1);
- flush_render_push_buffer(rpb, &t->gl);
+ push_rect_textured(&rc, (Rect){.size = t->gl.window_size}, (v4){0}, 1);
+ flush_render_push_buffer(&rc);
/* TODO: update debug info at the start of the frame so that this function can
* be properly included */
@@ -897,15 +911,15 @@ do_terminal(Term *t, f32 dt)
/* NOTE: this happens at the end so that ui stuff doesn't go through the post
* processing/effects shader */
glUseProgram(t->gl.programs[SHADER_RECTS]);
- draw_debug_overlay(t, rpb);
- flush_render_push_buffer(rpb, &t->gl);
+ draw_debug_overlay(t, &rc);
+ flush_render_push_buffer(&rc);
}
#ifdef _DEBUG
DebugRecord debug_records[__COUNTER__];
static void
-draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
+draw_debug_overlay(Term *t, RenderCtx *rc)
{
static u64 cycs[ARRAY_COUNT(debug_records)];
static u32 hits[ARRAY_COUNT(debug_records)];
@@ -936,7 +950,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
v4 fg = normalize_colour((Colour){.rgba = 0x1e9e33ff});
v4 bg = normalize_colour((Colour){.rgba = 0x090909bf});
- push_rect(rpb, &t->gl, r, bg);
+ push_rect(rc, r, bg);
u32 font_id = g_ui_debug_font_id;
f32 line_pad = 5;
@@ -945,9 +959,9 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
{
s8 txt = buf;
txt.len = snprintf((char *)txt.data, buf.len, "Render Time: %0.02f ms/f", dt_for_frame * 1e3);
- v2 ts = measure_text(t->arena_for_frame, &t->gl, &t->fa, font_id, txt);
+ v2 ts = measure_text(rc, font_id, txt);
txt_pos.y = (u32)(txt_pos.y - ts.h - line_pad);
- push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, txt);
+ push_s8(rc, txt_pos, fg, font_id, txt);
if (ts.w > max_text_width) max_text_width = ts.w;
if (ts.h > line_height) line_height = ts.h;
@@ -964,7 +978,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
dr->function_name, hits[i], hits[i] > 1? "hits" : "hit",
(f32)cycs[i]/(f32)hits[i]);
txt_pos.y = (u32)(txt_pos.y - line_height - line_pad);
- v2 ts = push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, txt);
+ v2 ts = push_s8(rc, txt_pos, fg, font_id, txt);
if (ts.w > max_text_width) max_text_width = ts.w;
if (ts.h > line_height) line_height = ts.h;
@@ -976,7 +990,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
{
s8 header = s8("Glyph Cache Stats:");
txt_pos.y = (u32)(txt_pos.y - line_height - line_pad);
- v2 ts = push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, header);
+ v2 ts = push_s8(rc, txt_pos, fg, font_id, header);
/* TODO: This doesn't really work when we are redrawing on every frame */
static char *fmts[ARRAY_COUNT(glyph_stats.E)] = {
@@ -988,7 +1002,7 @@ draw_debug_overlay(Term *t, RenderPushBuffer *rpb)
s8 txt = buf;
txt.len = snprintf((char *)txt.data, buf.len, fmts[i], glyph_stats.E[i]);
txt_pos.y = (u32)(txt_pos.y - line_height - line_pad);
- ts = push_s8(rpb, t->arena_for_frame, &t->gl, &t->fa, txt_pos, fg, font_id, txt);
+ ts = push_s8(rc, txt_pos, fg, font_id, txt);
if (ts.w > max_text_width) max_text_width = ts.w;
if (ts.h > line_height) line_height = ts.h;