Only use an extra draw call for the background when drawing interleaved cells if it is actually required

This commit is contained in:
Kovid Goyal 2020-01-12 09:37:16 +05:30
parent 91673642b3
commit 714bee7f45
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 44 additions and 29 deletions

View File

@ -335,7 +335,7 @@ placed in the same location with different z-index values will be blended if
they are semi-transparent. You can specify z-index values using the ``z`` key.
Negative z-index values mean that the images will be drawn under the text. This
allows rendering of text on top of images. Negative z-index values below
INT32_MIN/2 (-1073741824) will be drawn under cells with non-default background
INT32_MIN/2 (-1,073,741,824) will be drawn under cells with non-default background
colors.
Deleting images

View File

@ -2,7 +2,7 @@
#define WHICH_PROGRAM
#define NOT_TRANSPARENT
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL) || defined(DEFAULTBG)
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL)
#define NEEDS_BACKROUND
#endif
@ -12,7 +12,7 @@
#ifdef NEEDS_BACKROUND
in vec3 background;
in float bgfac;
in float draw_bg;
#if defined(TRANSPARENT) || defined(SPECIAL)
in float bg_alpha;
#endif
@ -128,15 +128,11 @@ void main() {
#endif
#endif
#if (defined(DEFAULTBG) || defined(BACKGROUND))
#ifdef BACKGROUND
#if defined(TRANSPARENT)
final_color = vec4(bgfac * background.rgb * bg_alpha, bg_alpha * bgfac);
final_color = vec4(background.rgb * bg_alpha, bg_alpha * draw_bg);
#else
#if defined(DEFAULTBG)
final_color = vec4(bgfac * background.rgb, 1.0f);
#else
final_color = vec4(bgfac * background.rgb, 1.0f * bgfac);
#endif
final_color = vec4(background.rgb, draw_bg);
#endif
#endif

View File

@ -18,6 +18,9 @@ layout(std140) uniform CellRenderData {
uint color_table[256];
};
#ifdef BACKGROUND
uniform float draw_default_bg;
#endif
// Have to use fixed locations here as all variants of the cell program share the same VAO
layout(location=0) in uvec3 colors;
@ -35,7 +38,7 @@ const uvec2 cell_pos_map[] = uvec2[4](
// }}}
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL) || defined(DEFAULTBG)
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL)
#define NEEDS_BACKROUND
#endif
@ -45,7 +48,7 @@ const uvec2 cell_pos_map[] = uvec2[4](
#ifdef NEEDS_BACKROUND
out vec3 background;
out float bgfac;
out float draw_bg;
#if defined(TRANSPARENT) || defined(SPECIAL)
out float bg_alpha;
#endif
@ -159,7 +162,8 @@ void main() {
float cell_has_cursor = is_cursor(c, r);
float is_block_cursor = step(float(cursor_fg_sprite_idx), 0.5);
float cell_has_block_cursor = cell_has_cursor * is_block_cursor;
vec3 bg = to_color(colors[bg_index], default_colors[bg_index]);
uint bg_as_uint = resolve_color(colors[bg_index], default_colors[bg_index]);
vec3 bg = color_to_vec(bg_as_uint);
// }}}
// Foreground {{{
@ -198,13 +202,13 @@ void main() {
// Background {{{
#ifdef NEEDS_BACKROUND
#if defined(BACKGROUND) || defined(DEFAULTBG)
#if defined(BACKGROUND)
background = bg;
vec3 defaultbg = to_color(colors[2], default_colors[bg_index]);
bgfac = 1-float(equal(background, defaultbg));
#if defined(DEFAULTBG)
bgfac += 1;
#endif
uint defaultbg = resolve_color(colors[2], default_colors[bg_index]);
float cell_has_non_default_bg = abs(defaultbg - bg_as_uint);
// 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);
#endif
#if defined(TRANSPARENT)

View File

@ -126,6 +126,12 @@ init_uniforms(int program) {
}
}
GLint
get_uniform_location(int program, const char *name) {
Program *p = programs + program;
return glGetUniformLocation(p->id, name);
}
GLint
get_uniform_information(int program, const char *name, GLenum information_type) {
GLint q; GLuint t;

View File

@ -41,6 +41,7 @@ GLuint program_id(int program);
Program* program_ptr(int program);
GLuint block_index(int program, const char *name);
GLint block_size(int program, GLuint block_index);
GLint get_uniform_location(int program, const char *name);
GLint get_uniform_information(int program, const char *name, GLenum information_type);
GLint attrib_location(int program, const char *name);
ssize_t create_vao(void);

View File

@ -9,7 +9,7 @@
#include "gl.h"
#include <stddef.h>
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_DEFAULT_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, NUM_PROGRAMS };
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, NUM_PROGRAMS };
enum { SPRITE_MAP_UNIT, GRAPHICS_UNIT, BLIT_UNIT };
// Sprites {{{
@ -150,6 +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;
} CellProgramLayout;
static CellProgramLayout cell_program_layouts[NUM_PROGRAMS];
@ -165,6 +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");
// 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++) {
@ -393,14 +395,17 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) {
glEnable(GL_BLEND);
BLEND_ONTO_OPAQUE;
bind_program(CELL_DEFAULT_BG_PROGRAM);
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, 1.f);
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);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
}
if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs);
bind_program(CELL_SPECIAL_PROGRAM);
@ -429,13 +434,17 @@ draw_cells_interleaved_premult(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 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_DEFAULT_BG_PROGRAM);
bind_program(CELL_BG_PROGRAM);
glUniform1f(cell_program_layouts[CELL_BG_PROGRAM].draw_default_bg_location, 1.f);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
glEnable(GL_BLEND);
BLEND_PREMULT;
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);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
}
bind_program(CELL_BG_PROGRAM);
@ -706,7 +715,7 @@ static PyMethodDef module_methods[] = {
bool
init_shaders(PyObject *module) {
#define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; }
C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_DEFAULT_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(GRAPHICS_ALPHA_MASK_PROGRAM); C(BLIT_PROGRAM);
C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(GRAPHICS_ALPHA_MASK_PROGRAM); C(BLIT_PROGRAM);
C(GLSL_VERSION);
C(GL_VERSION);
C(GL_VENDOR);

View File

@ -15,7 +15,7 @@ from .constants import (
ScreenGeometry, WindowGeometry, appname, get_boss, wakeup
)
from .fast_data_types import (
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_DEFAULT_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, DIM,
GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM,
OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, STRIKETHROUGH, Screen,
@ -63,7 +63,6 @@ def load_shader_programs(semi_transparent=False):
for which, p in {
'SIMPLE': CELL_PROGRAM,
'BACKGROUND': CELL_BG_PROGRAM,
'DEFAULTBG': CELL_DEFAULT_BG_PROGRAM,
'SPECIAL': CELL_SPECIAL_PROGRAM,
'FOREGROUND': CELL_FG_PROGRAM,
}.items():