aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-10-21 22:19:42 +0300
committerGitHub <noreply@github.com>2022-10-21 22:19:42 +0300
commit5b1dd38806eeb625f45303ab8981f3975f1b7b24 (patch)
tree866202a0b6bbf0f7f2152aaaca1ff22da54e006e /alacritty/src
parentc3b915b6952f0fa47d362d8f2474b6b8464ac8a7 (diff)
downloadr-alacritty-5b1dd38806eeb625f45303ab8981f3975f1b7b24.tar.gz
r-alacritty-5b1dd38806eeb625f45303ab8981f3975f1b7b24.tar.bz2
r-alacritty-5b1dd38806eeb625f45303ab8981f3975f1b7b24.zip
Fix cursor and underlines always being black
Some old hardware doesn't like universal shader approach for all the rectangle kinds leading to ALU instruction limits. This commit fixes it by splitting the shader per rectangle kind. Fixes #6417.
Diffstat (limited to 'alacritty/src')
-rw-r--r--alacritty/src/renderer/rects.rs96
-rw-r--r--alacritty/src/renderer/shader.rs30
-rw-r--r--alacritty/src/renderer/text/gles2.rs2
-rw-r--r--alacritty/src/renderer/text/glsl3.rs2
4 files changed, 79 insertions, 51 deletions
diff --git a/alacritty/src/renderer/rects.rs b/alacritty/src/renderer/rects.rs
index 8fc29f88..31818f60 100644
--- a/alacritty/src/renderer/rects.rs
+++ b/alacritty/src/renderer/rects.rs
@@ -249,8 +249,7 @@ pub struct RectRenderer {
vao: GLuint,
vbo: GLuint,
- program: RectShaderProgram,
-
+ programs: [RectShaderProgram; 4],
vertices: [Vec<Vertex>; 4],
}
@@ -258,7 +257,11 @@ impl RectRenderer {
pub fn new(shader_version: ShaderVersion) -> Result<Self, renderer::Error> {
let mut vao: GLuint = 0;
let mut vbo: GLuint = 0;
- let program = RectShaderProgram::new(shader_version)?;
+
+ let rect_program = RectShaderProgram::new(shader_version, RectKind::Normal)?;
+ let undercurl_program = RectShaderProgram::new(shader_version, RectKind::Undercurl)?;
+ let dotted_program = RectShaderProgram::new(shader_version, RectKind::DottedUnderline)?;
+ let dashed_program = RectShaderProgram::new(shader_version, RectKind::DashedUnderline)?;
unsafe {
// Allocate buffers.
@@ -300,7 +303,8 @@ impl RectRenderer {
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
}
- Ok(Self { vao, vbo, program, vertices: Default::default() })
+ let programs = [rect_program, undercurl_program, dotted_program, dashed_program];
+ Ok(Self { vao, vbo, programs, vertices: Default::default() })
}
pub fn draw(&mut self, size_info: &SizeInfo, metrics: &Metrics, rects: Vec<RenderRect>) {
@@ -310,9 +314,6 @@ impl RectRenderer {
// Bind VBO only once for buffer data upload only.
gl::BindBuffer(gl::ARRAY_BUFFER, self.vbo);
-
- gl::UseProgram(self.program.id());
- self.program.update_uniforms(size_info, metrics);
}
let half_width = size_info.width() / 2.;
@@ -333,7 +334,9 @@ impl RectRenderer {
continue;
}
- self.program.set_rect_kind(rect_kind);
+ let program = &self.programs[rect_kind as usize];
+ gl::UseProgram(program.id());
+ program.update_uniforms(size_info, metrics);
// Upload accumulated undercurl vertices.
gl::BufferData(
@@ -399,44 +402,47 @@ pub struct RectShaderProgram {
/// Shader program.
program: ShaderProgram,
- /// Kind of rect we're drawing.
- u_rect_kind: GLint,
-
/// Cell width.
- u_cell_width: GLint,
+ u_cell_width: Option<GLint>,
/// Cell height.
- u_cell_height: GLint,
+ u_cell_height: Option<GLint>,
/// Terminal padding.
- u_padding_x: GLint,
+ u_padding_x: Option<GLint>,
/// A padding from the bottom of the screen to viewport.
- u_padding_y: GLint,
+ u_padding_y: Option<GLint>,
/// Underline position.
- u_underline_position: GLint,
+ u_underline_position: Option<GLint>,
/// Underline thickness.
- u_underline_thickness: GLint,
+ u_underline_thickness: Option<GLint>,
/// Undercurl position.
- u_undercurl_position: GLint,
+ u_undercurl_position: Option<GLint>,
}
impl RectShaderProgram {
- pub fn new(shader_version: ShaderVersion) -> Result<Self, ShaderError> {
- let program = ShaderProgram::new(shader_version, RECT_SHADER_V, RECT_SHADER_F)?;
+ pub fn new(shader_version: ShaderVersion, kind: RectKind) -> Result<Self, ShaderError> {
+ // XXX: This must be in-sync with fragment shader defines.
+ let header = match kind {
+ RectKind::Undercurl => Some("#define DRAW_UNDERCURL\n"),
+ RectKind::DottedUnderline => Some("#define DRAW_DOTTED\n"),
+ RectKind::DashedUnderline => Some("#define DRAW_DASHED\n"),
+ _ => None,
+ };
+ let program = ShaderProgram::new(shader_version, header, RECT_SHADER_V, RECT_SHADER_F)?;
Ok(Self {
- u_rect_kind: program.get_uniform_location(cstr!("rectKind"))?,
- u_cell_width: program.get_uniform_location(cstr!("cellWidth"))?,
- u_cell_height: program.get_uniform_location(cstr!("cellHeight"))?,
- u_padding_x: program.get_uniform_location(cstr!("paddingX"))?,
- u_padding_y: program.get_uniform_location(cstr!("paddingY"))?,
- u_underline_position: program.get_uniform_location(cstr!("underlinePosition"))?,
- u_underline_thickness: program.get_uniform_location(cstr!("underlineThickness"))?,
- u_undercurl_position: program.get_uniform_location(cstr!("undercurlPosition"))?,
+ u_cell_width: program.get_uniform_location(cstr!("cellWidth")).ok(),
+ u_cell_height: program.get_uniform_location(cstr!("cellHeight")).ok(),
+ u_padding_x: program.get_uniform_location(cstr!("paddingX")).ok(),
+ u_padding_y: program.get_uniform_location(cstr!("paddingY")).ok(),
+ u_underline_position: program.get_uniform_location(cstr!("underlinePosition")).ok(),
+ u_underline_thickness: program.get_uniform_location(cstr!("underlineThickness")).ok(),
+ u_undercurl_position: program.get_uniform_location(cstr!("undercurlPosition")).ok(),
program,
})
}
@@ -445,12 +451,6 @@ impl RectShaderProgram {
self.program.id()
}
- fn set_rect_kind(&self, ty: u8) {
- unsafe {
- gl::Uniform1i(self.u_rect_kind, ty as i32);
- }
- }
-
pub fn update_uniforms(&self, size_info: &SizeInfo, metrics: &Metrics) {
let position = (0.5 * metrics.descent).abs();
let underline_position = metrics.descent.abs() - metrics.underline_position.abs();
@@ -460,13 +460,27 @@ impl RectShaderProgram {
- (viewport_height / size_info.cell_height()).floor() * size_info.cell_height();
unsafe {
- gl::Uniform1f(self.u_cell_width, size_info.cell_width());
- gl::Uniform1f(self.u_cell_height, size_info.cell_height());
- gl::Uniform1f(self.u_padding_y, padding_y);
- gl::Uniform1f(self.u_padding_x, size_info.padding_x());
- gl::Uniform1f(self.u_underline_position, underline_position);
- gl::Uniform1f(self.u_underline_thickness, metrics.underline_thickness);
- gl::Uniform1f(self.u_undercurl_position, position);
+ if let Some(u_cell_width) = self.u_cell_width {
+ gl::Uniform1f(u_cell_width, size_info.cell_width());
+ }
+ if let Some(u_cell_height) = self.u_cell_height {
+ gl::Uniform1f(u_cell_height, size_info.cell_height());
+ }
+ if let Some(u_padding_y) = self.u_padding_y {
+ gl::Uniform1f(u_padding_y, padding_y);
+ }
+ if let Some(u_padding_x) = self.u_padding_x {
+ gl::Uniform1f(u_padding_x, size_info.padding_x());
+ }
+ if let Some(u_underline_position) = self.u_underline_position {
+ gl::Uniform1f(u_underline_position, underline_position);
+ }
+ if let Some(u_underline_thickness) = self.u_underline_thickness {
+ gl::Uniform1f(u_underline_thickness, metrics.underline_thickness);
+ }
+ if let Some(u_undercurl_position) = self.u_undercurl_position {
+ gl::Uniform1f(u_undercurl_position, position);
+ }
}
}
}
diff --git a/alacritty/src/renderer/shader.rs b/alacritty/src/renderer/shader.rs
index 9326796b..588937cc 100644
--- a/alacritty/src/renderer/shader.rs
+++ b/alacritty/src/renderer/shader.rs
@@ -30,11 +30,14 @@ impl ShaderVersion {
impl ShaderProgram {
pub fn new(
shader_version: ShaderVersion,
+ shader_header: Option<&str>,
vertex_shader: &'static str,
fragment_shader: &'static str,
) -> Result<Self, ShaderError> {
- let vertex_shader = Shader::new(shader_version, gl::VERTEX_SHADER, vertex_shader)?;
- let fragment_shader = Shader::new(shader_version, gl::FRAGMENT_SHADER, fragment_shader)?;
+ let vertex_shader =
+ Shader::new(shader_version, shader_header, gl::VERTEX_SHADER, vertex_shader)?;
+ let fragment_shader =
+ Shader::new(shader_version, shader_header, gl::FRAGMENT_SHADER, fragment_shader)?;
let program = unsafe { Self(gl::CreateProgram()) };
@@ -82,12 +85,23 @@ struct Shader(GLuint);
impl Shader {
fn new(
shader_version: ShaderVersion,
+ shader_header: Option<&str>,
kind: GLenum,
source: &'static str,
) -> Result<Self, ShaderError> {
- let header = shader_version.shader_header();
- let len: [GLint; 2] = [header.len() as GLint, source.len() as GLint];
- let source = [header.as_ptr() as *const _, source.as_ptr() as *const _];
+ let version_header = shader_version.shader_header();
+ let mut sources = Vec::<*const GLchar>::with_capacity(3);
+ let mut lengthes = Vec::<GLint>::with_capacity(3);
+ sources.push(version_header.as_ptr().cast());
+ lengthes.push(version_header.len() as GLint);
+
+ if let Some(shader_header) = shader_header {
+ sources.push(shader_header.as_ptr().cast());
+ lengthes.push(shader_header.len() as GLint);
+ }
+
+ sources.push(source.as_ptr().cast());
+ lengthes.push(source.len() as GLint);
let shader = unsafe { Self(gl::CreateShader(kind)) };
@@ -95,9 +109,9 @@ impl Shader {
unsafe {
gl::ShaderSource(
shader.id(),
- len.len() as GLint,
- source.as_ptr() as *const _,
- len.as_ptr(),
+ lengthes.len() as GLint,
+ sources.as_ptr().cast(),
+ lengthes.as_ptr(),
);
gl::CompileShader(shader.id());
gl::GetShaderiv(shader.id(), gl::COMPILE_STATUS, &mut success);
diff --git a/alacritty/src/renderer/text/gles2.rs b/alacritty/src/renderer/text/gles2.rs
index 01470813..29a80e98 100644
--- a/alacritty/src/renderer/text/gles2.rs
+++ b/alacritty/src/renderer/text/gles2.rs
@@ -474,7 +474,7 @@ impl TextShaderProgram {
let fragment_shader =
if dual_source_blending { &glsl3::TEXT_SHADER_F } else { &TEXT_SHADER_F };
- let program = ShaderProgram::new(shader_version, TEXT_SHADER_V, fragment_shader)?;
+ let program = ShaderProgram::new(shader_version, None, TEXT_SHADER_V, fragment_shader)?;
Ok(Self {
u_projection: program.get_uniform_location(cstr!("projection"))?,
diff --git a/alacritty/src/renderer/text/glsl3.rs b/alacritty/src/renderer/text/glsl3.rs
index 6783c215..885023a0 100644
--- a/alacritty/src/renderer/text/glsl3.rs
+++ b/alacritty/src/renderer/text/glsl3.rs
@@ -424,7 +424,7 @@ pub struct TextShaderProgram {
impl TextShaderProgram {
pub fn new(shader_version: ShaderVersion) -> Result<TextShaderProgram, Error> {
- let program = ShaderProgram::new(shader_version, TEXT_SHADER_V, TEXT_SHADER_F)?;
+ let program = ShaderProgram::new(shader_version, None, TEXT_SHADER_V, TEXT_SHADER_F)?;
Ok(Self {
u_projection: program.get_uniform_location(cstr!("projection"))?,
u_cell_dim: program.get_uniform_location(cstr!("cellDim"))?,