aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/renderer/rects.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/renderer/rects.rs')
-rw-r--r--alacritty/src/renderer/rects.rs96
1 files changed, 55 insertions, 41 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);
+ }
}
}
}