Skip to content

Commit

Permalink
Dont use FBO's unless absolutely necessary
Browse files Browse the repository at this point in the history
Negative z-index images dont need FBO based rendering when the
background is opaque. Finishes up support for background_opacity.

Fixes #31
  • Loading branch information
kovidgoyal committed Nov 24, 2017
1 parent 6751cb5 commit 90d37ff
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ kitty is a feature full, cross-platform, *fast*, GPU based terminal emulator.
version 0.6.0 [future]
------------------------

- Support background transparency via the background_opacity option. Provided
that your OS/window manager supports transparency, you can now have kitty
render pixels that have only the default background color as
semi-transparent.

- Support multiple top level (OS) windows. These windows all share the sprite
texture cache on the GPU, further reducing overall resource usage. Use
the shortcut `ctrl+shift+n` to open anew top-level window.
the shortcut `ctrl+shift+n` to open a new top-level window.

- Add support for a *daemon* mode using the `--single-instance` command line
option. With this option you can have only a single kitty instance running.
Expand Down
23 changes: 20 additions & 3 deletions kitty/cell_fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,36 @@ vec4 calculate_foreground() {
#endif

void main() {
#if defined(BACKGROUND) || defined(SPECIAL)
#if defined(TRANSPARENT) || defined(SPECIAL)
#ifdef BACKGROUND
#ifdef TRANSPARENT
final_color = vec4(background.rgb * bg_alpha, bg_alpha);
#else
final_color = vec4(background.rgb, 1.0f);
#endif
#endif

#else
#ifdef SPECIAL
#ifdef TRANSPARENT
final_color = vec4(background.rgb * bg_alpha, bg_alpha);
#else
final_color = vec4(background.rgb, bg_alpha);
#endif
#endif

#if defined(FOREGROUND) || defined(SIMPLE)
// FOREGROUND or SIMPLE
vec4 fg = calculate_foreground(); // pre-multiplied foreground

#ifdef FOREGROUND
// FOREGROUND
#ifdef TRANSPARENT
final_color = fg;
#else
final_color = vec4(fg.rgb / fg.a, fg.a);
#endif

#else
// SIMPLE
#ifdef TRANSPARENT
final_color = alpha_blend_premul(fg.rgb, fg.a, background * bg_alpha, bg_alpha);
final_color = vec4(final_color.rgb / final_color.a, final_color.a);
Expand Down
41 changes: 34 additions & 7 deletions kitty/shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,20 +303,43 @@ 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

static void
draw_all_cells(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) {
draw_cells_simple(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) {
bind_program(CELL_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
if (screen->grman->count) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors
BLEND_ONTO_OPAQUE;
draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->count);
glDisable(GL_BLEND);
}
}

static void
draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWindow *os_window) {
draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) {
bind_program(CELL_BG_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
glEnable(GL_BLEND);
BLEND_ONTO_OPAQUE;

if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_negative_refs);

bind_program(CELL_SPECIAL_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);

bind_program(CELL_FG_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);

if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, screen->grman->num_of_negative_refs, screen->grman->num_of_positive_refs);

glDisable(GL_BLEND);
}

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) {
glGenTextures(1, &os_window->offscreen_texture_id);
glBindTexture(GL_TEXTURE_2D, os_window->offscreen_texture_id);
Expand All @@ -334,7 +357,7 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWind
bind_program(CELL_BG_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors
BLEND_PREMULT;

if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_negative_refs);

Expand Down Expand Up @@ -390,9 +413,13 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
glUniform1i(glGetUniformLocation(program_id(CELL_FG_PROGRAM), "sprites"), SPRITE_MAP_UNIT);
cell_constants_set = true;
}
bool needs_complex_rendering = screen->grman->num_of_negative_refs || (screen->grman->num_of_positive_refs && os_window->is_semi_transparent);
if (needs_complex_rendering) draw_cells_interleaved(vao_idx, gvao_idx, screen, os_window);
else draw_all_cells(vao_idx, gvao_idx, screen);
if (os_window->is_semi_transparent) {
if (screen->grman->count) draw_cells_interleaved_premult(vao_idx, gvao_idx, screen, os_window);
else draw_cells_simple(vao_idx, gvao_idx, screen);
} else {
if (screen->grman->num_of_negative_refs) draw_cells_interleaved(vao_idx, gvao_idx, screen);
else draw_cells_simple(vao_idx, gvao_idx, screen);
}
}
// }}}

Expand Down

0 comments on commit 90d37ff

Please sign in to comment.