From 8b5f02bb0bcb62c48874393d8c7f045ed3642fe0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Mar 2019 12:32:05 +0530 Subject: [PATCH] Fix shader invocation for cells output during resize --- kitty/graphics.c | 12 ++++++------ kitty/shaders.c | 24 +++++++++++++++++------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/kitty/graphics.c b/kitty/graphics.c index 0216e48a8..4f619725f 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -523,8 +523,8 @@ cmp_by_zindex_and_image(const void *a_, const void *b_) { } static inline void -set_vertex_data(ImageRenderData *rd, const ImageRef *ref, const ImageRect *source_rect) { -#define R(n, a, b) rd->vertices[n*4] = ref->src_rect.a; rd->vertices[n*4 + 1] = ref->src_rect.b; rd->vertices[n*4 + 2] = source_rect->a; rd->vertices[n*4 + 3] = source_rect->b; +set_vertex_data(ImageRenderData *rd, const ImageRef *ref, const ImageRect *dest_rect) { +#define R(n, a, b) rd->vertices[n*4] = ref->src_rect.a; rd->vertices[n*4 + 1] = ref->src_rect.b; rd->vertices[n*4 + 2] = dest_rect->a; rd->vertices[n*4 + 3] = dest_rect->b; R(0, right, top); R(1, right, bottom); R(2, left, bottom); R(3, left, top); #undef R } @@ -533,10 +533,10 @@ void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height) { static const ImageRef source_rect = { .src_rect = { .left=0, .top=0, .bottom=1, .right=1 }}; const ImageRef *ref = &source_rect; - float width_frac = width / (float)screen_width_px, height_frac = height / (float)screen_height_px; - float hmargin = MAX(0, 2 - width_frac) / 2; - float vmargin = MAX(0, 2 - height_frac) / 2; - const ImageRect r = { .left = -1 + hmargin, .right = -1 + hmargin + width_frac, .top = -1 + vmargin, .bottom = -1 + vmargin + height_frac }; + float width_frac = 2 * MIN(1, width / (float)screen_width_px), height_frac = 2 * MIN(1, height / (float)screen_height_px); + float hmargin = (2 - width_frac) / 2; + float vmargin = (2 - height_frac) / 2; + const ImageRect r = { .left = -1 + hmargin, .right = -1 + hmargin + width_frac, .top = 1 - vmargin, .bottom = 1 - vmargin - height_frac }; set_vertex_data(ans, ref, &r); } diff --git a/kitty/shaders.c b/kitty/shaders.c index 0b98a2efa..62835ea06 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -217,6 +217,14 @@ struct CellUniformData { static struct CellUniformData cell_uniform_data = {0, .prev_inactive_text_alpha=-1}; +static inline void +send_graphics_data_to_gpu(size_t image_count, ssize_t gvao_idx, const ImageRenderData *render_data) { + size_t sz = sizeof(GLfloat) * 16 * image_count; + GLfloat *a = alloc_and_map_vao_buffer(gvao_idx, sz, 0, GL_STREAM_DRAW, GL_WRITE_ONLY); + for (size_t i = 0; i < image_count; i++, a += 16) memcpy(a, render_data[i].vertices, sizeof(render_data[0].vertices)); + unmap_vao_buffer(gvao_idx, 0); a = NULL; +} + static inline void cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, CursorRenderInfo *cursor, bool inverted, OSWindow *os_window) { struct CellRenderData { @@ -295,10 +303,7 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa } if (gvao_idx && grman_update_layers(screen->grman, screen->scrolled_by, xstart, ystart, dx, dy, screen->columns, screen->lines, screen->cell_size)) { - sz = sizeof(GLfloat) * 16 * screen->grman->count; - GLfloat *a = alloc_and_map_vao_buffer(gvao_idx, sz, 0, GL_STREAM_DRAW, GL_WRITE_ONLY); - for (size_t i = 0; i < screen->grman->count; i++, a += 16) memcpy(a, screen->grman->render_data[i].vertices, sizeof(screen->grman->render_data[0].vertices)); - unmap_vao_buffer(gvao_idx, 0); a = NULL; + send_graphics_data_to_gpu(screen->grman->count, gvao_idx, screen->grman->render_data); changed = true; } return changed; @@ -324,6 +329,9 @@ draw_graphics(int program, ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *d bind_vertex_array(vao_idx); } +#define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors +#define BLEND_PREMULT glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors + void draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas) { static ImageRenderData data = {.group_count=1}; @@ -342,12 +350,14 @@ draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_he glUniform1i(glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "image"), GRAPHICS_UNIT); glUniform1ui(glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "fg"), OPT(foreground)); } + glScissor(0, 0, screen_width, screen_height); + send_graphics_data_to_gpu(1, gvao_idx, &data); + glEnable(GL_BLEND); + BLEND_ONTO_OPAQUE; draw_graphics(GRAPHICS_ALPHA_MASK_PROGRAM, 0, gvao_idx, &data, 0, 1); + glDisable(GL_BLEND); } -#define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors -#define BLEND_PREMULT glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors - static void draw_cells_simple(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) { bind_program(CELL_PROGRAM);