From 65a7b19f4029bd6466c03f3556a5ab2fcb351d27 Mon Sep 17 00:00:00 2001 From: Fredrick Brennan Date: Fri, 24 Jan 2020 16:06:57 +0800 Subject: [PATCH] Make each OS window have its own framebuffer This commit fixes graphics rendering when more than one OS window is open, all OS windows are semi-transparent, and multiple windows contain graphics. This commit closes #2310. --- docs/changelog.rst | 2 ++ kitty/gl.c | 5 +++++ kitty/gl.h | 1 + kitty/shaders.c | 5 ++--- kitty/state.c | 1 + kitty/state.h | 2 ++ 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 74482920d..b1291567b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -45,6 +45,8 @@ To update |kitty|, :doc:`follow the instructions `. - Fix URL detection not working for urls of the form scheme:///url (:iss:`2292`) +- When windows are semi-transparent and all contain graphics, correctly render + them. (:iss:`2310`) 0.15.1 [2019-12-21] -------------------- diff --git a/kitty/gl.c b/kitty/gl.c index cd623c8eb..cab14738a 100644 --- a/kitty/gl.c +++ b/kitty/gl.c @@ -81,6 +81,11 @@ free_texture(GLuint *tex_id) { *tex_id = 0; } +void +free_framebuffer(GLuint *fb_id) { + glDeleteFramebuffers(1, fb_id); + *fb_id = 0; +} // }}} diff --git a/kitty/gl.h b/kitty/gl.h index 2a6981cd0..520a5ae25 100644 --- a/kitty/gl.h +++ b/kitty/gl.h @@ -35,6 +35,7 @@ typedef struct { void gl_init(void); void update_surface_size(int w, int h, GLuint offscreen_texture_id); void free_texture(GLuint *tex_id); +void free_framebuffer(GLuint *fb_id); void remove_vao(ssize_t vao_idx); void init_uniforms(int program); GLuint program_id(int program); diff --git a/kitty/shaders.c b/kitty/shaders.c index fff135352..83a0c8c42 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -154,7 +154,6 @@ typedef struct { } CellProgramLayout; static CellProgramLayout cell_program_layouts[NUM_PROGRAMS]; -static GLuint offscreen_framebuffer = 0; static ssize_t blit_vertex_array; static void @@ -173,7 +172,6 @@ init_cell_program(void) { C(p, colors, 0); C(p, sprite_coords, 1); C(p, is_selected, 2); } #undef C - glGenFramebuffers(1, &offscreen_framebuffer); blit_vertex_array = create_vao(); } @@ -424,6 +422,7 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) { static void draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWindow *os_window) { if (!os_window->offscreen_texture_id) { + glGenFramebuffers(1, &os_window->offscreen_framebuffer); glGenTextures(1, &os_window->offscreen_texture_id); glBindTexture(GL_TEXTURE_2D, os_window->offscreen_texture_id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, os_window->viewport_width, os_window->viewport_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); @@ -433,7 +432,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, offscreen_framebuffer); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, os_window->offscreen_framebuffer); 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); diff --git a/kitty/state.c b/kitty/state.c index 04a37d53b..df83e0ecf 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -255,6 +255,7 @@ destroy_os_window_item(OSWindow *w) { } Py_CLEAR(w->window_title); Py_CLEAR(w->tab_bar_render_data.screen); if (w->offscreen_texture_id) free_texture(&w->offscreen_texture_id); + if (w->offscreen_framebuffer) free_framebuffer(&w->offscreen_framebuffer); remove_vao(w->tab_bar_render_data.vao_idx); remove_vao(w->gvao_idx); free(w->tabs); w->tabs = NULL; diff --git a/kitty/state.h b/kitty/state.h index 5600dfe67..5ea22b4ff 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -131,6 +131,7 @@ typedef struct { typedef struct { void *handle; id_type id; + uint32_t offscreen_framebuffer; OSWindowGeometry before_fullscreen; int viewport_width, viewport_height, window_width, window_height; double viewport_x_ratio, viewport_y_ratio; @@ -221,6 +222,7 @@ void draw_cells(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow void draw_centered_alpha_mask(OSWindow *w, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas); void update_surface_size(int, int, uint32_t); void free_texture(uint32_t*); +void free_framebuffer(uint32_t*); void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool); void send_sprite_to_gpu(FONTS_DATA_HANDLE fg, unsigned int, unsigned int, unsigned int, pixel*); void blank_canvas(float, color_type);