Commit: e080b99dc9c1f0f62c13f1ff6aa7fe41e471860f
Parent: e1a7bae479960e5c64543c691955941fb1e05c6d
Author: Randy Palamar
Date: Mon, 26 Aug 2024 21:09:39 -0600
avoid redrawing the whole framebuffer if it hasn't updated
This is a first pass at reducing CPU usage. We still the render
texture on each frame which allows post processing to take effect.
Since this is a simple fullscreen textured quad it requires
minimal processing power.
Diffstat:
M | terminal.c | | | 7 | ++++--- |
M | util.c | | | 7 | +++++++ |
M | util.h | | | 4 | +++- |
M | vtgl.c | | | 98 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
4 files changed, 65 insertions(+), 51 deletions(-)
diff --git a/terminal.c b/terminal.c
@@ -235,7 +235,7 @@ swap_screen(Term *t)
{
t->mode ^= TM_ALTSCREEN;
t->view_idx = !!(t->mode & TM_ALTSCREEN);
- t->gl.flags |= NEEDS_FULL_BLIT;
+ t->gl.flags |= NEEDS_FULL_REFILL;
}
static void
@@ -1140,7 +1140,7 @@ blit_lines(Term *t, Arena a, size line_count)
{
TermView *tv = t->views + t->view_idx;
- if (t->gl.flags & NEEDS_FULL_BLIT) {
+ if (t->gl.flags & NEEDS_FULL_REFILL) {
term_reset(t);
line_count = t->size.h - 1;
}
@@ -1156,5 +1156,6 @@ blit_lines(Term *t, Arena a, size line_count)
push_line(t, tv->lines.buf + line_idx, a);
}
- t->gl.flags &= ~(NEEDS_FULL_BLIT|NEEDS_BLIT);
+ t->gl.flags &= ~(NEEDS_FULL_REFILL|NEEDS_REFILL);
+ t->gl.flags |= NEEDS_BLIT;
}
diff --git a/util.c b/util.c
@@ -11,6 +11,13 @@ equal_iv2(iv2 a, iv2 b)
}
static b32
+equal_uv2(uv2 a, uv2 b)
+{
+ b32 result = a.x == b.x && a.y == b.y;
+ return result;
+}
+
+static b32
is_valid_range(Range r)
{
b32 result = !equal_iv2(r.end, INVALID_RANGE_END);
diff --git a/util.h b/util.h
@@ -195,7 +195,9 @@ typedef struct {
enum gl_flags {
NEEDS_RESIZE = 1 << 0,
NEEDS_BLIT = 1 << 1,
- NEEDS_FULL_BLIT = 1 << 2,
+ NEEDS_REFILL = 1 << 2,
+ NEEDS_FULL_REFILL = 1 << 3,
+
UPDATE_RENDER_UNIFORMS = 1 << 29,
UPDATE_POST_UNIFORMS = 1 << 30,
};
diff --git a/vtgl.c b/vtgl.c
@@ -104,16 +104,19 @@ resize(Term *t)
ws.w -= 2 * g_term_pad.w;
ws.h -= 2 * g_term_pad.h;
- v2 cs = get_cell_size(t);
- t->size.w = (u32)(ws.w / cs.w);
- t->size.h = (u32)(ws.h / cs.h);
+ uv2 old_size = t->size;
+ v2 cs = get_cell_size(t);
+ t->size.w = (u32)(ws.w / cs.w);
+ t->size.h = (u32)(ws.h / cs.h);
+
+ if (!equal_uv2(old_size, t->size)) {
+ os_alloc_framebuffer(&t->views[0].fb, t->size.h, t->size.w);
+ os_alloc_framebuffer(&t->views[1].fb, t->size.h, t->size.w);
+ t->gl.flags |= NEEDS_FULL_REFILL;
+ }
- os_alloc_framebuffer(&t->views[0].fb, t->size.h, t->size.w);
- os_alloc_framebuffer(&t->views[1].fb, t->size.h, t->size.w);
os_set_term_size(t->child, t->size.h, t->size.w, ws.w, ws.h);
t->gl.flags &= ~NEEDS_RESIZE;
- /* TODO: check if we actually changed size */
- t->gl.flags |= NEEDS_FULL_BLIT;
}
static void
@@ -450,7 +453,8 @@ update_selection(Term *t)
}
}
}
- sel->range = normalize_range(sel->range);
+ sel->range = normalize_range(sel->range);
+ t->gl.flags |= NEEDS_BLIT;
}
KEYBIND_FN(copy)
@@ -535,7 +539,7 @@ KEYBIND_FN(scroll)
t->scroll_offset += a.i;
CLAMP(t->scroll_offset, 0, tv->lines.filled - (t->size.h - 1));
- t->gl.flags |= NEEDS_FULL_BLIT;
+ t->gl.flags |= NEEDS_FULL_REFILL;
return 1;
}
@@ -708,7 +712,7 @@ char_callback(GLFWwindow *win, u32 codepoint)
Term *t = glfwGetWindowUserPointer(win);
if (t->scroll_offset) {
t->scroll_offset = 0;
- t->gl.flags |= NEEDS_FULL_BLIT;
+ t->gl.flags |= NEEDS_FULL_REFILL;
}
os_child_put_char(t->child, codepoint);
}
@@ -791,58 +795,58 @@ do_terminal(Term *t)
.data = rb->buf + (rb->widx - t->unprocessed_bytes)
};
parsed_lines = split_raw_input_to_lines(t, raw);
- t->gl.flags |= NEEDS_BLIT;
+ t->gl.flags |= NEEDS_REFILL;
}
- if (t->gl.flags & (NEEDS_BLIT|NEEDS_FULL_BLIT))
+ if (t->gl.flags & (NEEDS_REFILL|NEEDS_FULL_REFILL))
blit_lines(t, t->arena_for_frame, parsed_lines);
update_selection(t);
- /* NOTE: reset the camera/viewport */
- glUseProgram(t->gl.programs[SHADER_RENDER]);
- glUniform1i(t->gl.render.texslot, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, t->gl.fb);
+ v2 ws = t->gl.window_size;
- RenderPushBuffer *rpb = alloc(&t->arena_for_frame, RenderPushBuffer, 1);
- clear_colour();
- render_framebuffer(t, rpb);
+ if (t->gl.flags & NEEDS_BLIT) {
+ glUseProgram(t->gl.programs[SHADER_RENDER]);
+ glUniform1i(t->gl.render.texslot, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, t->gl.fb);
- v2 ws = t->gl.window_size;
+ RenderPushBuffer *rpb = alloc(&t->arena_for_frame, RenderPushBuffer, 1);
+ clear_colour();
+ render_framebuffer(t, rpb);
- if (0) {
- v2 cell_size = get_cell_size(t);
- v2 cursor_pos = {
- .x = t->cursor.pos.x * cell_size.w,
- .y = ws.h - cell_size.h * (t->cursor.pos.y + 1),
- };
+ if (0) {
+ v2 cell_size = get_cell_size(t);
+ v2 cursor_pos = {
+ .x = t->cursor.pos.x * cell_size.w,
+ .y = ws.h - cell_size.h * (t->cursor.pos.y + 1),
+ };
- v2 src_bl = {0};
- v2 src_tr = { .x = ws.w, .y = src_bl.y + ws.h };
+ v2 src_bl = {0};
+ v2 src_tr = {.x = ws.w, .y = src_bl.y + ws.h};
- if (t->cursor.pos.y > t->size.h) {
- src_tr.y = cursor_pos.y + ws.h;
- src_bl.y = cursor_pos.y;
- }
+ if (t->cursor.pos.y > t->size.h) {
+ src_tr.y = cursor_pos.y + ws.h;
+ src_bl.y = cursor_pos.y;
+ }
- s8 fps = s8alloc(&t->arena_for_frame, 64);
- fps.len = snprintf((char *)fps.data, fps.len, "Render Time: %0.02f ms/f", last_frame_time * 1e3);
- v2 ts = measure_text(&t->gl, fps, 1);
- v2 pos = {
- .x = ws.w - ts.x - 10,
- .y = src_tr.y - ts.y - 10
- };
+ s8 fps = s8alloc(&t->arena_for_frame, 64);
+ fps.len = snprintf((char *)fps.data, fps.len, "Render Time: %0.02f ms/f",
+ last_frame_time * 1e3);
+ v2 ts = measure_text(&t->gl, fps, 1);
+ v2 pos = {.x = ws.w - ts.x - 10, .y = src_tr.y - ts.y - 10};
- Rect r = {
- .pos = {.x = pos.x - 0.05 * ts.x, .y = pos.y - 0.25 * ts.y},
- .size = {.w = ts.w * 1.1, .h = ts.h * 1.2},
- };
+ Rect r = {
+ .pos = {.x = pos.x - 0.05 * ts.x, .y = pos.y - 0.25 * ts.y},
+ .size = {.w = ts.w * 1.1, .h = ts.h * 1.2},
+ };
- draw_rectangle(rpb, &t->gl, r, (Colour){.rgba = 0x303030ff});
- draw_text(rpb, &t->gl, fps, pos, (Colour){.rgba = 0x1e9e33ff}, 1);
- }
+ draw_rectangle(rpb, &t->gl, r, (Colour){.rgba = 0x303030ff});
+ draw_text(rpb, &t->gl, fps, pos, (Colour){.rgba = 0x1e9e33ff}, 1);
+ }
- flush_render_push_buffer(rpb, &t->gl);
+ flush_render_push_buffer(rpb, &t->gl);
+ t->gl.flags &= ~NEEDS_BLIT;
+ }
static f32 param = 0;
static f32 p_scale = 1;