vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

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:
Mvtgl.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 {