aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/renderer/shader.rs
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-03-02 13:05:12 +0300
committerGitHub <noreply@github.com>2022-03-02 10:05:12 +0000
commit1880522b64d9a5276acea428705c011cbbf8c04c (patch)
tree2f8a662ee0b65fcf6d6fe831949cd2cf78cabdad /alacritty/src/renderer/shader.rs
parent00383ae967fef6216396c3acaf96a7002b013298 (diff)
downloadr-alacritty-1880522b64d9a5276acea428705c011cbbf8c04c.tar.gz
r-alacritty-1880522b64d9a5276acea428705c011cbbf8c04c.tar.bz2
r-alacritty-1880522b64d9a5276acea428705c011cbbf8c04c.zip
Add fallback GLES2 renderer
Currently Alacritty only works on hardware which supports OpenGL 3.3 or more, which can become problematic with older devices. This patch adds a new GLES2 renderer, since it is much more widely supported, especially on weaker hardware like phones or a Raspberry Pi. While the GLES2 renderer is slower than the OpenGL 3.3+ version, it is still significantly faster than software rendering. However because of this performance difference it is only used when necessary and there should be no difference for machines supporting OpenGL 3.3+. The two renderers are largely independent and separated in the `renderer/text/glsl3` and `renderer/text/gles2` modules. Separate shaders are also required for text rendering. The rectangle rendering for underlines and the visual bell works identically for both versions, but does have some version-specific shader code. Fixes #128. Co-authored-by: Christian Duerr <contact@christianduerr.com>
Diffstat (limited to 'alacritty/src/renderer/shader.rs')
-rw-r--r--alacritty/src/renderer/shader.rs49
1 files changed, 40 insertions, 9 deletions
diff --git a/alacritty/src/renderer/shader.rs b/alacritty/src/renderer/shader.rs
index edb01277..9326796b 100644
--- a/alacritty/src/renderer/shader.rs
+++ b/alacritty/src/renderer/shader.rs
@@ -8,13 +8,33 @@ use crate::gl::types::*;
#[derive(Debug)]
pub struct ShaderProgram(GLuint);
+#[derive(Copy, Clone, Debug)]
+pub enum ShaderVersion {
+ /// OpenGL 3.3 core shaders.
+ Glsl3,
+
+ /// OpenGL ES 2.0 shaders.
+ Gles2,
+}
+
+impl ShaderVersion {
+ // Header to which we concatenate the entire shader. The newlines are required.
+ fn shader_header(&self) -> &'static str {
+ match self {
+ Self::Glsl3 => "#version 330 core\n",
+ Self::Gles2 => "#version 100\n#define GLES2_RENDERER\n",
+ }
+ }
+}
+
impl ShaderProgram {
pub fn new(
+ shader_version: ShaderVersion,
vertex_shader: &'static str,
fragment_shader: &'static str,
) -> Result<Self, ShaderError> {
- let vertex_shader = Shader::new(gl::VERTEX_SHADER, vertex_shader)?;
- let fragment_shader = Shader::new(gl::FRAGMENT_SHADER, fragment_shader)?;
+ 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 program = unsafe { Self(gl::CreateProgram()) };
@@ -60,23 +80,34 @@ impl Drop for ShaderProgram {
struct Shader(GLuint);
impl Shader {
- fn new(kind: GLenum, source: &'static str) -> Result<Self, ShaderError> {
- let len: [GLint; 1] = [source.len() as GLint];
+ fn new(
+ shader_version: ShaderVersion,
+ 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 shader = unsafe { Self(gl::CreateShader(kind)) };
let mut success: GLint = 0;
unsafe {
- gl::ShaderSource(shader.id(), 1, &(source.as_ptr() as *const _), len.as_ptr());
+ gl::ShaderSource(
+ shader.id(),
+ len.len() as GLint,
+ source.as_ptr() as *const _,
+ len.as_ptr(),
+ );
gl::CompileShader(shader.id());
gl::GetShaderiv(shader.id(), gl::COMPILE_STATUS, &mut success);
}
- if success != GLint::from(gl::TRUE) {
- return Err(ShaderError::Compile(get_shader_info_log(shader.id())));
+ if success == GLint::from(gl::TRUE) {
+ Ok(shader)
+ } else {
+ Err(ShaderError::Compile(get_shader_info_log(shader.id())))
}
-
- Ok(shader)
}
fn id(&self) -> GLuint {