From d8ed135b46709d5f6d7202196f2d4470c93272a7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 12 Jan 2020 13:18:25 +0530 Subject: [PATCH] Clean up rendering of cell backgrounds --- kitty/cell_fragment.glsl | 2 +- kitty/cell_vertex.glsl | 10 +++++----- kitty/shaders.c | 16 ++++++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/kitty/cell_fragment.glsl b/kitty/cell_fragment.glsl index fb3143652..6a745c188 100644 --- a/kitty/cell_fragment.glsl +++ b/kitty/cell_fragment.glsl @@ -77,7 +77,7 @@ vec4 blend_onto_opaque_premul(vec3 over, float over_alpha, vec3 under) { * * 2a) Opaque bg with images under text * There are multiple passes, each pass is blended onto the previous using the opaque blend func (alpha, 1- alpha): - * 1) Draw only the default background + * 1) Draw background for all cells * 2) Draw the images that are supposed to be below both the background and text, if any. This happens in the graphics shader * 3) Draw the background of cells that don't have the default background if any images were drawn in 2 above 4) Draw the images that are supposed to be below text but not background, again in graphics shader. diff --git a/kitty/cell_vertex.glsl b/kitty/cell_vertex.glsl index deb9eeff0..325d8d453 100644 --- a/kitty/cell_vertex.glsl +++ b/kitty/cell_vertex.glsl @@ -19,7 +19,7 @@ layout(std140) uniform CellRenderData { uint color_table[256]; }; #ifdef BACKGROUND -uniform float draw_default_bg; +uniform uint draw_bg_bitfield; #endif // Have to use fixed locations here as all variants of the cell program share the same VAO @@ -204,12 +204,12 @@ void main() { #if defined(BACKGROUND) background = bg; - // draw background only if it is either non-default or the draw_default_bg - // uniform is set - draw_bg = step(ONE, draw_default_bg + cell_has_non_default_bg); + // draw_bg_bitfield has bit 0 set to draw default bg cells and bit 1 set to draw non-default bg cells + uint draw_bg_mask = uint(2 * cell_has_non_default_bg + (1 - cell_has_non_default_bg)); + draw_bg = step(ONE, draw_bg_bitfield & draw_bg_mask); #endif -#if defined(TRANSPARENT) +#ifdef TRANSPARENT // Set bg_alpha to background_opacity on cells that have the default background color // Which means they must not have a block cursor or a selection or reverse video // On other cells it should be 1. For the SPECIAL program it should be 1 on cells with diff --git a/kitty/shaders.c b/kitty/shaders.c index 271b3b624..818895b56 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -150,7 +150,7 @@ send_image_to_gpu(GLuint *tex_id, const void* data, GLsizei width, GLsizei heigh typedef struct { UniformBlock render_data; ArrayInformation color_table; - GLint draw_default_bg_location; + GLint draw_bg_bitfield_location; } CellProgramLayout; static CellProgramLayout cell_program_layouts[NUM_PROGRAMS]; @@ -166,7 +166,7 @@ init_cell_program(void) { cell_program_layouts[i].color_table.offset = get_uniform_information(i, "color_table[0]", GL_UNIFORM_OFFSET); cell_program_layouts[i].color_table.stride = get_uniform_information(i, "color_table[0]", GL_UNIFORM_ARRAY_STRIDE); } - cell_program_layouts[CELL_BG_PROGRAM].draw_default_bg_location = get_uniform_location(CELL_BG_PROGRAM, "draw_default_bg"); + cell_program_layouts[CELL_BG_PROGRAM].draw_bg_bitfield_location = get_uniform_location(CELL_BG_PROGRAM, "draw_bg_bitfield"); // Sanity check to ensure the attribute location binding worked #define C(p, name, expected) { int aloc = attrib_location(p, #name); if (aloc != expected && aloc != -1) fatal("The attribute location for %s is %d != %d in program: %d", #name, aloc, expected, p); } for (int p = CELL_PROGRAM; p < BORDERS_PROGRAM; p++) { @@ -396,13 +396,15 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) { BLEND_ONTO_OPAQUE; bind_program(CELL_BG_PROGRAM); - glUniform1f(cell_program_layouts[CELL_BG_PROGRAM].draw_default_bg_location, 1.f); + // draw background for all cells + glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].draw_bg_bitfield_location, 3); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); if (screen->grman->num_of_below_refs) { draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_below_refs); bind_program(CELL_BG_PROGRAM); - glUniform1f(cell_program_layouts[CELL_BG_PROGRAM].draw_default_bg_location, 0.f); + // draw background for non-default bg cells + glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].draw_bg_bitfield_location, 2); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); } @@ -435,7 +437,8 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, os_window->offscreen_texture_id, 0); /* if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) fatal("Offscreen framebuffer not complete"); */ bind_program(CELL_BG_PROGRAM); - glUniform1f(cell_program_layouts[CELL_BG_PROGRAM].draw_default_bg_location, 1.f); + // draw background for all cells + glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].draw_bg_bitfield_location, 3); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); glEnable(GL_BLEND); BLEND_PREMULT; @@ -443,7 +446,8 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen if (screen->grman->num_of_below_refs) { draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_below_refs); bind_program(CELL_BG_PROGRAM); - glUniform1f(cell_program_layouts[CELL_BG_PROGRAM].draw_default_bg_location, 0.f); + // Draw background for non-default bg cells + glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].draw_bg_bitfield_location, 2); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); }