Skip to content

Commit

Permalink
feat: add glScissor for dirty rect
Browse files Browse the repository at this point in the history
  • Loading branch information
tale committed Feb 16, 2024
1 parent 120919a commit 4249735
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 22 deletions.
2 changes: 2 additions & 0 deletions include/term.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ typedef struct {
GLuint program;
GLuint vao;
GLuint vbo;
VTermRect scissor;
VTermRect damage;
} gl_state;
} term_t;

Expand Down
23 changes: 21 additions & 2 deletions src/term/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,27 @@ void sig_handler(int sig_type) {
}

int damage(VTermRect rect, void *user) {
// printf("damage: [%d, %d, %d, %d]\n", rect.start_col,
// rect.start_row, rect.end_col, rect.end_row);
term_t *state = (term_t *)user;
state->gl_state.damage = rect;

// The idea is to append to the scissor, so that redraw is minimized
// If the bounds of damage are past the scissor, increase scissor size
if (rect.start_col < state->gl_state.scissor.start_col) {
state->gl_state.scissor.start_col = rect.start_col;
}

if (rect.start_row < state->gl_state.scissor.start_row) {
state->gl_state.scissor.start_row = rect.start_row;
}

if (rect.end_col > state->gl_state.scissor.end_col) {
state->gl_state.scissor.end_col = rect.end_col;
}

if (rect.end_row > state->gl_state.scissor.end_row) {
state->gl_state.scissor.end_row = rect.end_row;
}

return 1;
}

Expand Down
45 changes: 26 additions & 19 deletions src/term/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@ void render_term(term_t *state) {
glClearColor(0, 0, 0, state->config->opacity);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// if (state->states.resize) {
// int draw_width, draw_height;
// glfwGetFramebufferSize(state->glfw_window, &draw_width, &draw_height);
// resize_term(state, draw_width, draw_height);
// state->states.resize = false;
// }
VTermRect rect = state->gl_state.scissor;
int x_advance = state->font.face->size->metrics.max_advance >> 6;
int ascent = state->font.face->size->metrics.ascender >> 6;
int descent = state->font.face->size->metrics.descender >> 6;
int linespace = (ascent - descent);

int x = rect.start_col * x_advance;
int y = state->config->height - (rect.start_row * linespace);

int width = (rect.end_col) * x_advance;
int height = (rect.end_row) * linespace;

glEnable(GL_SCISSOR_TEST);
glScissor(x, y - height, width, height);
glDisable(GL_SCISSOR_TEST);

// This is the 2nd part of the scissor optimization
// On each render pass, we reset scissor back to the damage size
state->gl_state.scissor = state->gl_state.damage;

int x_offset = 0;

Expand All @@ -21,27 +34,21 @@ void render_term(term_t *state) {
x_offset = 0;
}

// Render cursor block with pure white bar skulley
int font_width = state->font.face->size->metrics.max_advance >> 6;
int ascent = state->font.face->size->metrics.ascender >> 6;
int descent = state->font.face->size->metrics.descender >> 6;
int font_height = ascent - descent;

glBindBuffer(GL_ARRAY_BUFFER, state->gl_state.vbo);
glBindVertexArray(state->gl_state.vao);

coord_t cursor = {
.x = state->cursor.x * font_width,
.y = state->cursor.y * font_height,
.width = font_width,
.height = font_height,
.x = state->cursor.x * x_advance,
.y = state->cursor.y * linespace,
.width = x_advance,
.height = linespace,
};

cell_vertex_t cursor_vertices[4] = {
{cursor.x, cursor.y, 0.0f, 1.0f},
{cursor.x, cursor.y + font_height, 0.0f, 0.0f},
{cursor.x + font_width, cursor.y, 1.0f, 1.0f},
{cursor.x + font_width, cursor.y + font_height, 1.0f, 0.0f},
{cursor.x, cursor.y + linespace, 0.0f, 0.0f},
{cursor.x + x_advance, cursor.y, 1.0f, 1.0f},
{cursor.x + x_advance, cursor.y + linespace, 1.0f, 0.0f},
};

glBufferData(GL_ARRAY_BUFFER, sizeof(cursor_vertices), cursor_vertices, GL_DYNAMIC_DRAW);
Expand Down
2 changes: 1 addition & 1 deletion src/term/render/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Called inside of the thread as a bootstrap
int init_gl_context(term_t *state) {
glfwMakeContextCurrent(state->glfw_window);
glfwSwapInterval(0);
glfwSwapInterval(1);

log_info("OpenGL Version: %s", glGetString(GL_VERSION));
log_info("OpenGL Renderer: %s", glGetString(GL_RENDERER));
Expand Down
1 change: 1 addition & 0 deletions src/term/resize.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ void resize_term(term_t *state, int width, int height) {
state->config->width = width;
state->config->height = height;
update_projection(state);
glScissor(0, 0, width, height);

int ascent = state->font.face->size->metrics.ascender >> 6;
int descent = state->font.face->size->metrics.descender >> 6;
Expand Down

0 comments on commit 4249735

Please sign in to comment.