Commit: 216c2baee2b37bcc99db63176fbbb5f71cda4c63
Parent: 106916dc7f689fcdf4961d3da1f57a52582ac88d
Author: Randy Palamar
Date: Mon, 2 Dec 2024 05:38:11 -0700
don't clobber pending renders when the input and render threads overlap
Diffstat:
M | util.h | | | 3 | ++- |
M | vtgl.c | | | 50 | ++++++++++++++++++++++++-------------------------- |
2 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/util.h b/util.h
@@ -166,7 +166,6 @@ typedef struct {
enum gl_flags {
NEEDS_RESIZE = 1 << 0,
NEEDS_REFILL = 1 << 1,
- UPDATE_RENDER_BUFFER = 1 << 2,
DRAW_DEBUG_OVERLAY = 1 << 30,
};
@@ -219,6 +218,8 @@ typedef struct {
u32 glyph_bitmap_tex;
u32 flags;
+
+ u32 queued_render;
} GLCtx;
typedef struct {
diff --git a/vtgl.c b/vtgl.c
@@ -237,12 +237,11 @@ get_terminal_top_left(Term *t)
static void
resize_terminal(Term *t, PlatformAPI *platform, iv2 window_size)
{
- iv2 old_size = t->size;
-
v2 ws = v2_from_iv2(window_size);
ws.w -= 2 * g_term_margin.w;
ws.h -= 2 * g_term_margin.h;
+ iv2 old_size = t->size;
v2 cs = get_cell_size(&t->fa);
t->size.w = (i32)(ws.w / cs.w);
t->size.h = (i32)(ws.h / cs.h);
@@ -288,12 +287,16 @@ resize(Term *t, PlatformAPI *platform, iv2 window_size)
glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_size, 0, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, gl->render_shader_ssbo);
LABEL_GL_OBJECT(GL_BUFFER, gl->render_shader_ssbo, s8("RenderCells"));
- gl->flags |= UPDATE_RENDER_BUFFER;
+ gl->queued_render = 1;
v2 cs = get_cell_size(&t->fa);
ShaderParameters *sp = &gl->shader_parameters;
sp->cell_size = (iv2){.w = cs.w, .h = cs.h};
+ sp->strike_min = (t->fa.info.baseline + 0.40 * t->fa.info.h);
+ sp->strike_max = (t->fa.info.baseline + 0.48 * t->fa.info.h);
+ sp->underline_min = (0.89 * t->fa.info.h);
+ sp->underline_max = (0.96 * t->fa.info.h);
sp->top_left_margin = g_term_margin;
sp->margin_colour = g_colours.data[g_colours.bgidx].rgba;
//sp->margin_colour = 0x7f003f00;
@@ -511,24 +514,23 @@ render_framebuffer(Term *t, RenderCell *render_buf, TerminalInput *input, Arena
/* NOTE: draw whole framebuffer */
for (u32 row = 0; row < t->size.h; row++) {
for (u32 col = 0; col < t->size.w; col++) {
- Cell *c = &tv->fb.rows[row][col];
+ Cell c = tv->fb.rows[row][col];
RenderCell *rc = render_buf + (row * t->size.w + col);
CachedGlyph *cg;
- rc->gpu_glyph = get_gpu_glyph_index(arena, &t->gl, &t->fa, c->cp, 0,
- c->bg & FS_MASK, &cg);
- rc->fg = c->fg;
- rc->bg = c->bg;
+ rc->gpu_glyph = get_gpu_glyph_index(arena, &t->gl, &t->fa, c.cp, 0,
+ c.bg & FS_MASK, &cg);
+ rc->fg = c.fg;
+ rc->bg = c.bg;
/* TODO: there is probably a better way to do this */
u32 tiles = cg->tile_count;
if (tiles > 1) {
- for (u32 i = 1; i < tiles; i++) {
- rc[i].gpu_glyph = rc->gpu_glyph + i;
- rc[i].fg = rc->fg;
- rc[i].bg = rc->bg;
- }
- col += tiles - 1;
+ ASSERT(tiles == 2);
+ rc[1].gpu_glyph = rc->gpu_glyph + 1;
+ rc[1].fg = rc->fg;
+ rc[1].bg = rc->bg;
+ col++;
}
}
}
@@ -645,7 +647,7 @@ begin_selection(Term *t, u32 click_count, v2 mouse)
case SS_NONE: break;
}
- t->gl.flags |= UPDATE_RENDER_BUFFER;
+ t->gl.queued_render = 1;
}
static void
@@ -684,7 +686,7 @@ update_selection(Term *t, TerminalInput *input)
sel->range = normalize_range(sel->range);
if (!equal_range(old_range, sel->range))
- t->gl.flags |= UPDATE_RENDER_BUFFER;
+ t->gl.queued_render = 1;
}
KEYBIND_FN(copy)
@@ -1231,6 +1233,8 @@ DEBUG_EXPORT VTGL_RENDER_FRAME_FN(vtgl_render_frame)
dt_for_frame = input->dt;
+ b32 update_render_buffer = __atomic_exchange_n(&t->gl.queued_render, 0, __ATOMIC_SEQ_CST);
+
TempArena temp_arena = begin_temp_arena(&arena);
if (t->gl.flags & NEEDS_RESIZE || !equal_iv2(input->window_size, t->gl.window_size))
@@ -1259,23 +1263,17 @@ DEBUG_EXPORT VTGL_RENDER_FRAME_FN(vtgl_render_frame)
glBindFramebuffer(GL_FRAMEBUFFER, t->gl.fb);
clear_colour();
- if (t->gl.flags & UPDATE_RENDER_BUFFER) {
+ if (update_render_buffer) {
u32 cell_count = t->size.h * t->size.w;
RenderCell *render_buf = alloc(&arena, RenderCell, cell_count);
render_framebuffer(t, render_buf, input, arena);
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, cell_count * sizeof(*render_buf), render_buf);
- t->gl.flags &= ~UPDATE_RENDER_BUFFER;
}
render_cursor(t, input->window_focused, arena);
ShaderParameters *sp = &t->gl.shader_parameters;
sp->blink_parameter += 2 * PI * g_blink_speed * dt_for_frame;
if (sp->blink_parameter > 2 * PI) sp->blink_parameter -= 2 * PI;
- sp->strike_min = (t->fa.info.baseline + 0.40 * t->fa.info.h);
- sp->strike_max = (t->fa.info.baseline + 0.48 * t->fa.info.h);
- sp->underline_min = (0.89 * t->fa.info.h);
- sp->underline_max = (0.96 * t->fa.info.h);
-
sp->reverse_video_mask = REVERSE_VIDEO_MASK * !!(t->mode.win & WM_REVERSE);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(*sp), sp);
@@ -1340,7 +1338,7 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step)
if (t->gl.flags & NEEDS_REFILL) {
blit_lines(t, t->arena_for_frame);
- t->gl.flags |= UPDATE_RENDER_BUFFER;
+ t->gl.queued_render = 1;
}
BEGIN_NAMED_BLOCK(input_from_child);
@@ -1358,7 +1356,7 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step)
.data = rb->buf + (rb->widx - t->unprocessed_bytes)
};
handle_input(t, t->arena_for_frame, raw);
- t->gl.flags |= UPDATE_RENDER_BUFFER;
+ t->gl.queued_render = 1;
}
END_NAMED_BLOCK(input_from_child);
@@ -1370,7 +1368,7 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step)
END_TIMED_BLOCK();
- return (t->gl.flags & UPDATE_RENDER_BUFFER) || input->window_refreshed;
+ return t->gl.queued_render || input->window_refreshed;
}
#ifdef _DEBUG