diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | alacritty/res/rect.f.glsl | 33 | ||||
-rw-r--r-- | alacritty/src/renderer/rects.rs | 96 | ||||
-rw-r--r-- | alacritty/src/renderer/shader.rs | 30 | ||||
-rw-r--r-- | alacritty/src/renderer/text/gles2.rs | 2 | ||||
-rw-r--r-- | alacritty/src/renderer/text/glsl3.rs | 2 |
6 files changed, 97 insertions, 67 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a8c9ba..56045e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - `--help` output for `--class` does not match man pages +- Cursor and underlines always being black on very old hardware ## 0.11.0 diff --git a/alacritty/res/rect.f.glsl b/alacritty/res/rect.f.glsl index d29c8b28..65701da3 100644 --- a/alacritty/res/rect.f.glsl +++ b/alacritty/res/rect.f.glsl @@ -16,7 +16,6 @@ flat in color_t color; #endif -uniform int rectKind; uniform float_t cellWidth; uniform float_t cellHeight; uniform float_t paddingY; @@ -27,12 +26,9 @@ uniform float_t underlineThickness; uniform float_t undercurlPosition; -#define UNDERCURL 1 -#define DOTTED 2 -#define DASHED 3 - #define PI 3.1415926538 +#if defined(DRAW_UNDERCURL) color_t draw_undercurl(float_t x, float_t y) { // We use `undercurlPosition` as an amplitude, since it's half of the descent // value. @@ -55,7 +51,9 @@ color_t draw_undercurl(float_t x, float_t y) { // The result is an alpha mask on a rect, which leaves only curve opaque. return vec4(color.rgb, alpha); } +#endif +#if defined(DRAW_DOTTED) // When the dot size increases we can use AA to make spacing look even and the // dots rounded. color_t draw_dotted_aliased(float_t x, float_t y) { @@ -96,7 +94,9 @@ color_t draw_dotted(float_t x, float_t y) { return vec4(color.rgb, alpha); } +#endif +#if defined(DRAW_DASHED) color_t draw_dashed(float_t x) { // Since dashes of adjacent cells connect with each other our dash length is // half of the desired total length. @@ -111,22 +111,23 @@ color_t draw_dashed(float_t x) { return vec4(color.rgb, alpha); } +#endif void main() { float_t x = floor(mod(gl_FragCoord.x - paddingX, cellWidth)); float_t y = floor(mod(gl_FragCoord.y - paddingY, cellHeight)); - if (rectKind == UNDERCURL) { - FRAG_COLOR = draw_undercurl(x, y); - } else if (rectKind == DOTTED) { - if (underlineThickness < 2.) { - FRAG_COLOR = draw_dotted(x, y); - } else { - FRAG_COLOR = draw_dotted_aliased(x, y); - } - } else if (rectKind == DASHED) { - FRAG_COLOR = draw_dashed(x); +#if defined(DRAW_UNDERCURL) + FRAG_COLOR = draw_undercurl(x, y); +#elif defined(DRAW_DOTTED) + if (underlineThickness < 2.) { + FRAG_COLOR = draw_dotted(x, y); } else { - FRAG_COLOR = color; + FRAG_COLOR = draw_dotted_aliased(x, y); } +#elif defined(DRAW_DASHED) + FRAG_COLOR = draw_dashed(x); +#else + FRAG_COLOR = color; +#endif } 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"))?, |