Only use an extra draw call for the background when drawing interleaved cells if it is actually required
This commit is contained in:
parent
91673642b3
commit
714bee7f45
@ -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.
|
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
|
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
|
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.
|
colors.
|
||||||
|
|
||||||
Deleting images
|
Deleting images
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#define WHICH_PROGRAM
|
#define WHICH_PROGRAM
|
||||||
#define NOT_TRANSPARENT
|
#define NOT_TRANSPARENT
|
||||||
|
|
||||||
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL) || defined(DEFAULTBG)
|
#if defined(SIMPLE) || defined(BACKGROUND) || defined(SPECIAL)
|
||||||
#define NEEDS_BACKROUND
|
#define NEEDS_BACKROUND
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#ifdef NEEDS_BACKROUND
|
#ifdef NEEDS_BACKROUND
|
||||||
in vec3 background;
|
in vec3 background;
|
||||||
in float bgfac;
|
in float draw_bg;
|
||||||
#if defined(TRANSPARENT) || defined(SPECIAL)
|
#if defined(TRANSPARENT) || defined(SPECIAL)
|
||||||
in float bg_alpha;
|
in float bg_alpha;
|
||||||
#endif
|
#endif
|
||||||
@ -128,15 +128,11 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(DEFAULTBG) || defined(BACKGROUND))
|
#ifdef BACKGROUND
|
||||||
#if defined(TRANSPARENT)
|
#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
|
#else
|
||||||
#if defined(DEFAULTBG)
|
final_color = vec4(background.rgb, draw_bg);
|
||||||
final_color = vec4(bgfac * background.rgb, 1.0f);
|
|
||||||
#else
|
|
||||||
final_color = vec4(bgfac * background.rgb, 1.0f * bgfac);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,9 @@ layout(std140) uniform CellRenderData {
|
|||||||
|
|
||||||
uint color_table[256];
|
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
|
// Have to use fixed locations here as all variants of the cell program share the same VAO
|
||||||
layout(location=0) in uvec3 colors;
|
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
|
#define NEEDS_BACKROUND
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ const uvec2 cell_pos_map[] = uvec2[4](
|
|||||||
|
|
||||||
#ifdef NEEDS_BACKROUND
|
#ifdef NEEDS_BACKROUND
|
||||||
out vec3 background;
|
out vec3 background;
|
||||||
out float bgfac;
|
out float draw_bg;
|
||||||
#if defined(TRANSPARENT) || defined(SPECIAL)
|
#if defined(TRANSPARENT) || defined(SPECIAL)
|
||||||
out float bg_alpha;
|
out float bg_alpha;
|
||||||
#endif
|
#endif
|
||||||
@ -159,7 +162,8 @@ void main() {
|
|||||||
float cell_has_cursor = is_cursor(c, r);
|
float cell_has_cursor = is_cursor(c, r);
|
||||||
float is_block_cursor = step(float(cursor_fg_sprite_idx), 0.5);
|
float is_block_cursor = step(float(cursor_fg_sprite_idx), 0.5);
|
||||||
float cell_has_block_cursor = cell_has_cursor * is_block_cursor;
|
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 {{{
|
// Foreground {{{
|
||||||
@ -198,13 +202,13 @@ void main() {
|
|||||||
// Background {{{
|
// Background {{{
|
||||||
#ifdef NEEDS_BACKROUND
|
#ifdef NEEDS_BACKROUND
|
||||||
|
|
||||||
#if defined(BACKGROUND) || defined(DEFAULTBG)
|
#if defined(BACKGROUND)
|
||||||
background = bg;
|
background = bg;
|
||||||
vec3 defaultbg = to_color(colors[2], default_colors[bg_index]);
|
uint defaultbg = resolve_color(colors[2], default_colors[bg_index]);
|
||||||
bgfac = 1-float(equal(background, defaultbg));
|
float cell_has_non_default_bg = abs(defaultbg - bg_as_uint);
|
||||||
#if defined(DEFAULTBG)
|
// draw background only if it is either non-default or the draw_default_bg
|
||||||
bgfac += 1;
|
// uniform is set
|
||||||
#endif
|
draw_bg = step(ONE, draw_default_bg + cell_has_non_default_bg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TRANSPARENT)
|
#if defined(TRANSPARENT)
|
||||||
|
|||||||
@ -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
|
GLint
|
||||||
get_uniform_information(int program, const char *name, GLenum information_type) {
|
get_uniform_information(int program, const char *name, GLenum information_type) {
|
||||||
GLint q; GLuint t;
|
GLint q; GLuint t;
|
||||||
|
|||||||
@ -41,6 +41,7 @@ GLuint program_id(int program);
|
|||||||
Program* program_ptr(int program);
|
Program* program_ptr(int program);
|
||||||
GLuint block_index(int program, const char *name);
|
GLuint block_index(int program, const char *name);
|
||||||
GLint block_size(int program, GLuint block_index);
|
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 get_uniform_information(int program, const char *name, GLenum information_type);
|
||||||
GLint attrib_location(int program, const char *name);
|
GLint attrib_location(int program, const char *name);
|
||||||
ssize_t create_vao(void);
|
ssize_t create_vao(void);
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
#include "gl.h"
|
#include "gl.h"
|
||||||
#include <stddef.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 };
|
enum { SPRITE_MAP_UNIT, GRAPHICS_UNIT, BLIT_UNIT };
|
||||||
|
|
||||||
// Sprites {{{
|
// Sprites {{{
|
||||||
@ -150,6 +150,7 @@ send_image_to_gpu(GLuint *tex_id, const void* data, GLsizei width, GLsizei heigh
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
UniformBlock render_data;
|
UniformBlock render_data;
|
||||||
ArrayInformation color_table;
|
ArrayInformation color_table;
|
||||||
|
GLint draw_default_bg_location;
|
||||||
} CellProgramLayout;
|
} CellProgramLayout;
|
||||||
|
|
||||||
static CellProgramLayout cell_program_layouts[NUM_PROGRAMS];
|
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.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[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
|
// 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); }
|
#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++) {
|
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);
|
glEnable(GL_BLEND);
|
||||||
BLEND_ONTO_OPAQUE;
|
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);
|
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);
|
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);
|
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);
|
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);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, offscreen_framebuffer);
|
||||||
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, os_window->offscreen_texture_id, 0);
|
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"); */
|
/* 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);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
BLEND_PREMULT;
|
BLEND_PREMULT;
|
||||||
|
|
||||||
if (screen->grman->num_of_below_refs) {
|
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);
|
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);
|
bind_program(CELL_BG_PROGRAM);
|
||||||
@ -706,7 +715,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
bool
|
bool
|
||||||
init_shaders(PyObject *module) {
|
init_shaders(PyObject *module) {
|
||||||
#define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; }
|
#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(GLSL_VERSION);
|
||||||
C(GL_VERSION);
|
C(GL_VERSION);
|
||||||
C(GL_VENDOR);
|
C(GL_VENDOR);
|
||||||
|
|||||||
@ -15,7 +15,7 @@ from .constants import (
|
|||||||
ScreenGeometry, WindowGeometry, appname, get_boss, wakeup
|
ScreenGeometry, WindowGeometry, appname, get_boss, wakeup
|
||||||
)
|
)
|
||||||
from .fast_data_types import (
|
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,
|
CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, DIM,
|
||||||
GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM,
|
GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM,
|
||||||
OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, STRIKETHROUGH, Screen,
|
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 {
|
for which, p in {
|
||||||
'SIMPLE': CELL_PROGRAM,
|
'SIMPLE': CELL_PROGRAM,
|
||||||
'BACKGROUND': CELL_BG_PROGRAM,
|
'BACKGROUND': CELL_BG_PROGRAM,
|
||||||
'DEFAULTBG': CELL_DEFAULT_BG_PROGRAM,
|
|
||||||
'SPECIAL': CELL_SPECIAL_PROGRAM,
|
'SPECIAL': CELL_SPECIAL_PROGRAM,
|
||||||
'FOREGROUND': CELL_FG_PROGRAM,
|
'FOREGROUND': CELL_FG_PROGRAM,
|
||||||
}.items():
|
}.items():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user