vtgl

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

Commit: 15c48ce51d89671e39703c1634590433d72aba7e
Parent: 541b0c45d05a1fc54fc98824b8ca8b202e480aa9
Author: Randy Palamar
Date:   Mon,  4 Nov 2024 21:51:33 -0700

named block debug timing and cleanup terminal resetting

Diffstat:
Mdebug.c | 23++++++++++++++---------
Mdebug.h | 40+++++++++++++++++++++++++---------------
Mmain.c | 21++++++++++-----------
Mutil.h | 3+--
Mvtgl.c | 65++++++++++++++++++++++++++++-------------------------------------
5 files changed, 78 insertions(+), 74 deletions(-)

diff --git a/debug.c b/debug.c @@ -54,12 +54,6 @@ dump_lines_to_file(Term *t) os_close(file); } -static void -debug_init(Term *t, Arena a) -{ - /* NOTE: this used to be useful but for now its not */ -} - static OpenDebugBlock * get_open_debug_block(DebugState *ds, DebugEvent *de) { @@ -255,8 +249,7 @@ draw_debug_bar_chart(Term *t, DebugState *ds, RenderCtx *rc, v2 bar_chart_top_le stream_push_u64(&txt, record->end_clock - record->start_clock); stream_push_s8(&txt, s8(" [cycs]")); v2 txt_s = measure_text(rc, g_ui_debug_font_id, stream_to_s8(&txt)); - v2 txt_p = pos; - txt_p.x -= txt_s.w + 10; + v2 txt_p = {.x = pos.x - txt_s.w - 10, .y = pos.y}; push_s8(rc, txt_p, fg, g_ui_debug_font_id, stream_to_s8(&txt)); txt.widx = 0; } @@ -277,7 +270,7 @@ draw_debug_bar_chart(Term *t, DebugState *ds, RenderCtx *rc, v2 bar_chart_top_le if (hot_region) { DebugMetadata *txt_meta = hot_region->meta; txt.widx = 0; - stream_push_s8(&txt, c_str_to_s8(txt_meta->function_name)); + stream_push_s8(&txt, c_str_to_s8(txt_meta->block_name)); stream_push_s8(&txt, s8(": ")); stream_push_f64(&txt, hot_region_secs * 1e3, 100); stream_push_s8(&txt, s8(" [ms] ")); @@ -378,7 +371,19 @@ draw_debug_overlay(Term *t, RenderCtx *rc) END_TIMED_BLOCK(); } +static void +debug_init(DebugState *ds) +{ + ds->temp_memory = begin_temp_arena(&ds->memory); + ds->initialized = 1; + ds->bar_thickness = 14; + ds->frame_target_time = 4e-3; + restart_collation(ds, g_debug_table.snapshot_index); +} + DEBUG_EXPORT DEBUG_BEGIN_FRAME_FN(debug_begin_frame) { + if (!debug_state->initialized) + debug_init(debug_state); FRAME_MARK(wall_clock_elapsed); } diff --git a/debug.h b/debug.h @@ -2,9 +2,9 @@ #define MAX_DEBUG_EVENT_COUNT (16 * 65536) /* TODO: this is way too high and it only seems to be necessary when resizing */ -#define MAX_DEBUG_REGION_COUNT 80 * 1024 +#define MAX_DEBUG_REGION_COUNT 16 * 1024 #define MAX_DEBUG_META_COUNT 4096 -#define MAX_DEBUG_RECORD_COUNT 16 +#define MAX_DEBUG_RECORD_COUNT 32 typedef __attribute__((aligned(16))) struct { u64 clock; @@ -19,9 +19,8 @@ typedef __attribute__((aligned(16))) struct { typedef struct { char *file_name; - char *function_name; - - u32 line_number; + char *block_name; + u32 line_number; } DebugMetadata; typedef struct { @@ -42,7 +41,7 @@ typedef struct OpenDebugBlock { typedef struct { u64 start_clock; u64 end_clock; - DebugRegion *regions; + DebugRegion *regions; u32 region_count; f32 wall_time; OpenDebugBlock *first_block; @@ -86,6 +85,9 @@ typedef DEBUG_END_FRAME_FN(debug_end_frame_fn); #define BEGIN_TIMED_BLOCK(...) #define END_TIMED_BLOCK(...) +#define BEGIN_NAMED_BLOCK(...) +#define END_NAMED_BLOCK(...) + #define debug_init(...) #define draw_debug_overlay(...) @@ -134,21 +136,29 @@ static DebugTable g_debug_table; event->wall_clock_time = wall_seconds_elapsed; \ } -#define BEGIN_TIMED_BLOCK(...) \ - u16 __counter = __COUNTER__; \ - { \ - DebugMetadata *meta = g_debug_table.metadata + __counter; \ - meta->file_name = __FILE__; \ - meta->function_name = (char *)__FUNCTION__; \ - meta->line_number = __LINE__; \ - RECORD_DEBUG_EVENT(__counter, DE_BEGIN); \ +#define RECORD_DEBUG_META_COMMON(counter, blockname) \ + { \ + DebugMetadata *meta = g_debug_table.metadata + counter; \ + meta->file_name = __FILE__; \ + meta->block_name = (char *)blockname; \ + meta->line_number = __LINE__; \ + RECORD_DEBUG_EVENT(counter, DE_BEGIN); \ } +#define BEGIN_TIMED_BLOCK(...) \ + u16 __counter = __COUNTER__; \ + RECORD_DEBUG_META_COMMON(__counter, __FUNCTION__) #define END_TIMED_BLOCK(...) RECORD_DEBUG_EVENT(__counter, DE_END); +#define BEGIN_NAMED_BLOCK(name) \ + u16 __counter_##name = __COUNTER__; \ + RECORD_DEBUG_META_COMMON(__counter_##name, #name) +#define END_NAMED_BLOCK(name) RECORD_DEBUG_EVENT(__counter_##name, DE_END) + + typedef struct Term Term; typedef struct RenderCtx RenderCtx; -static void debug_init(Term *t, Arena a); +static void debug_init(DebugState *ds); static void dump_lines_to_file(Term *t); static void draw_debug_overlay(Term *t, RenderCtx *rc); #endif diff --git a/main.c b/main.c @@ -19,15 +19,16 @@ static char *libname = "./vtgl.so"; static void *libhandle; typedef void do_terminal_fn(Term *, f32); -typedef void init_callbacks_fn(GLCtx *); +typedef void reset_terminal_fn(Term *); typedef iv2 init_term_fn(Term *, Arena *, iv2); #define LIB_FNS \ X(debug_begin_frame) \ X(debug_end_frame) \ X(do_terminal) \ - X(init_callbacks) \ - X(init_term) + X(init_term) \ + X(reset_terminal) + #define X(name) static name ## _fn *name; LIB_FNS #undef X @@ -51,7 +52,7 @@ load_library(const char *lib, Stream *err) } static void -do_debug(GLCtx *gl, Stream *err) +do_debug(Term *t, Stream *err) { static os_file_stats updated; os_file_stats test = os_get_file_stats(libname); @@ -62,9 +63,7 @@ do_debug(GLCtx *gl, Stream *err) struct timespec sleep_time = { .tv_nsec = 100e6 }; nanosleep(&sleep_time, &sleep_time); load_library(libname, err); - if (gl) { - init_callbacks(gl); - } + if (t) reset_terminal(t); stream_push_s8(err, s8("Reloaded Main Program\n")); } @@ -223,8 +222,6 @@ init_window(Term *t, Arena arena, iv2 window_size) glBindBufferBase(GL_UNIFORM_BUFFER, 0, t->gl.render_shader_ubo); glActiveTexture(GL_TEXTURE0); - - t->gl.flags |= INIT_DEBUG; } static u32 @@ -426,7 +423,6 @@ main(i32 argc, char *argv[], char *envp[]) } init_window(&term, memory, ws); - init_callbacks(&term.gl); os_alloc_ring_buffer(&term.views[0].log, BACKLOG_SIZE); line_buf_alloc(&term.views[0].lines, &memory, term.views[0].log.buf, term.cursor.style, @@ -437,9 +433,11 @@ main(i32 argc, char *argv[], char *envp[]) term.child = os_fork_child("/bin/sh"); + reset_terminal(&term); + f64 last_time = os_get_time(); while (!glfwWindowShouldClose(term.gl.window)) { - do_debug(&term.gl, &term.error_stream); + do_debug(&term, &term.error_stream); /* TODO: cpu time excluding waiting for the vblank */ f64 current_time = os_get_time(); @@ -453,6 +451,7 @@ main(i32 argc, char *argv[], char *envp[]) term.arena_for_frame = memory; glfwPollEvents(); + do_terminal(&term, dt); debug_end_frame(term.debug_state, term.gl.window_size); diff --git a/util.h b/util.h @@ -218,8 +218,7 @@ enum gl_flags { NEEDS_FULL_REFILL = 1 << 2, UPDATE_RENDER_BUFFER = 1 << 3, - UPDATE_POST_UNIFORMS = 1 << 28, - INIT_DEBUG = 1 << 29, + UPDATE_POST_UNIFORMS = 1 << 29, DRAW_DEBUG_OVERLAY = 1 << 30, }; diff --git a/vtgl.c b/vtgl.c @@ -804,14 +804,17 @@ init_term(Term *t, Arena *a, iv2 cells) } DEBUG_EXPORT void -init_callbacks(GLCtx *gl) +reset_terminal(Term *t) { - glfwSetCharCallback(gl->window, char_callback); - glfwSetFramebufferSizeCallback(gl->window, fb_callback); - glfwSetKeyCallback(gl->window, key_callback); - glfwSetMouseButtonCallback(gl->window, mouse_button_callback); - //glfwSetWindowRefreshCallback(gl->window, refresh_callback); - glfwSetScrollCallback(gl->window, scroll_callback); + glfwSetCharCallback(t->gl.window, char_callback); + glfwSetFramebufferSizeCallback(t->gl.window, fb_callback); + glfwSetKeyCallback(t->gl.window, key_callback); + glfwSetMouseButtonCallback(t->gl.window, mouse_button_callback); + //glfwSetWindowRefreshCallback(t->gl.window, refresh_callback); + glfwSetScrollCallback(t->gl.window, scroll_callback); + + resize(t); + term_reset(t); } DEBUG_EXPORT void @@ -827,40 +830,33 @@ do_terminal(Term *t, f32 dt) if (t->gl.flags & NEEDS_RESIZE) resize(t); - if (t->gl.flags & INIT_DEBUG) { - /* TODO: cleanup this needs a better place */ - term_reset(t); - debug_init(t, t->arena_for_frame); - t->gl.flags &= ~INIT_DEBUG; - } - /* NOTE: this needs to be bound for blitting lines because that function can * access the font cache. * TODO: cleanup */ glBindTexture(GL_TEXTURE_2D, t->gl.glyph_bitmap_tex); + BEGIN_NAMED_BLOCK(input_from_child); + size parsed_lines = 0; if (os_child_data_available(t->child)) { RingBuf *rb = &t->views[t->view_idx].log; if (os_child_exited(t->child)) { glfwSetWindowShouldClose(t->gl.window, GL_TRUE); - goto end; + t->gl.flags = 0; + } else { + t->unprocessed_bytes += os_read_from_child(t->child, t->views + t->view_idx, + t->unprocessed_bytes); + s8 raw = { + .len = t->unprocessed_bytes, + .data = rb->buf + (rb->widx - t->unprocessed_bytes) + }; + handle_input(t, t->arena_for_frame, raw); + t->gl.flags |= UPDATE_RENDER_BUFFER; } - t->unprocessed_bytes += os_read_from_child(t->child, t->views + t->view_idx, - t->unprocessed_bytes); - s8 raw = { - .len = t->unprocessed_bytes, - .data = rb->buf + (rb->widx - t->unprocessed_bytes) - }; - #if 1 - handle_input(t, t->arena_for_frame, raw); - t->gl.flags |= UPDATE_RENDER_BUFFER; - #else - parsed_lines = split_raw_input_to_lines(t, raw); - t->gl.flags |= NEEDS_REFILL; - #endif } + END_NAMED_BLOCK(input_from_child); + if (t->gl.flags & (NEEDS_REFILL|NEEDS_FULL_REFILL)) { blit_lines(t, t->arena_for_frame, parsed_lines); t->gl.flags |= UPDATE_RENDER_BUFFER; @@ -870,6 +866,8 @@ do_terminal(Term *t, f32 dt) set_projection_matrix(&t->gl); + BEGIN_NAMED_BLOCK(update_render); + RenderCtx rc = make_render_ctx(&t->arena_for_frame, &t->gl, &t->fa); glUseProgram(t->gl.programs[SHADER_RENDER]); @@ -904,6 +902,8 @@ do_terminal(Term *t, f32 dt) push_rect_textured(&rc, (Rect){.size = t->gl.window_size}, (v4){0}, 0); flush_render_push_buffer(&rc); + END_NAMED_BLOCK(update_render); + static f32 param = 0; static f32 p_scale = 1; param += p_scale * 0.005 * dt_for_frame; @@ -926,7 +926,6 @@ do_terminal(Term *t, f32 dt) draw_debug_overlay(t, &rc); flush_render_push_buffer(&rc); -end: END_TIMED_BLOCK(); } @@ -948,14 +947,6 @@ DEBUG_EXPORT DEBUG_END_FRAME_FN(debug_end_frame) g_debug_table.events_count[array_index] = event_count; g_debug_table.metadata_count = __COUNTER__; - if (!debug_state->initialized) { - debug_state->temp_memory = begin_temp_arena(&debug_state->memory); - debug_state->initialized = 1; - debug_state->bar_thickness = 14; - debug_state->frame_target_time = 4e-3; - restart_collation(debug_state, g_debug_table.snapshot_index); - } - if (!debug_state->paused) { if (debug_state->record_count >= 2*MAX_DEBUG_RECORD_COUNT) restart_collation(debug_state, g_debug_table.snapshot_index);