Commit: 5598a7bf48dc0f834bf5f792d3767a1bff47e57e
Parent: f7448063875eb0c1cbbaa86e7c02b4754f59128c
Author: Randy Palamar
Date: Sun, 8 Dec 2024 20:56:48 -0700
use a spin lock in render thread to prevent a missed redraw
Diffstat:
M | vtgl.c | | | 39 | ++++++++++++++++++++------------------- |
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/vtgl.c b/vtgl.c
@@ -1259,24 +1259,24 @@ DEBUG_EXPORT VTGL_RENDER_FRAME_FN(vtgl_render_frame)
glBindFramebuffer(GL_FRAMEBUFFER, t->gl.fb);
clear_colour();
- b32 can_render_term = atomic_exchange_n(&t->resize_lock, 1) == 0;
- if (can_render_term) {
- if (t->gl.flags & RESIZE_RENDERER)
- resize(t, &memory->platform_api, input->window_size);
-
- if (t->gl.queued_render) {
- t->gl.queued_render = 0;
- 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);
- }
- render_cursor(t, input->window_focused, arena);
- t->resize_lock = 0;
- } else if (t->gl.queued_render) {
- input->pending_updates = 1;
+ /* NOTE(rnp): spin lock here so that we don't have to deal with rescheduling
+ * a redraw. Remember that this failing is already unlikely. */
+ while (atomic_exchange_n(&t->resize_lock, 1) != 0);
+
+ if (t->gl.flags & RESIZE_RENDERER)
+ resize(t, &memory->platform_api, input->window_size);
+
+ if (t->gl.queued_render) {
+ t->gl.queued_render = 0;
+ 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);
}
+ render_cursor(t, input->window_focused, arena);
+
+ t->resize_lock = 0;
ShaderParameters *sp = &t->gl.shader_parameters;
sp->blink_parameter += 2 * PI * g_blink_speed * dt_for_frame;
@@ -1333,8 +1333,9 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step)
t->temp_arena = begin_temp_arena(&t->arena_for_frame);
if (t->gl.flags & NEEDS_RESIZE || !equal_iv2(input->window_size, t->gl.window_size)) {
- b32 can_resize_term = atomic_exchange_n(&t->resize_lock, 1) == 0;
- if (can_resize_term) {
+ /* NOTE(rnp): we skip the resize this time through so that we don't add
+ * input latency waiting for the render thread to release this lock */
+ if (atomic_exchange_n(&t->resize_lock, 1) == 0) {
resize_terminal(t, &memory->platform_api, input->window_size);
t->resize_lock = 0;
} else {