aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src')
-rw-r--r--alacritty/src/renderer/mod.rs9
-rw-r--r--alacritty/src/renderer/platform.rs38
-rw-r--r--alacritty/src/renderer/text/atlas.rs37
-rw-r--r--alacritty/src/renderer/text/gles2.rs8
-rw-r--r--alacritty/src/renderer/text/glsl3.rs2
5 files changed, 69 insertions, 25 deletions
diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs
index fc6c357f..8f708d33 100644
--- a/alacritty/src/renderer/mod.rs
+++ b/alacritty/src/renderer/mod.rs
@@ -4,7 +4,7 @@ use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering};
use crossfont::Metrics;
-use glutin::context::PossiblyCurrentContext;
+use glutin::context::{ContextApi, GlContext, PossiblyCurrentContext};
use glutin::display::{GetGlDisplay, GlDisplay};
use log::info;
use once_cell::sync::OnceCell;
@@ -110,12 +110,14 @@ impl Renderer {
info!("Running on {}", renderer);
+ let is_gles_context = matches!(context.context_api(), ContextApi::Gles(_));
+
// Use the config option to enforce a particular renderer configuration.
let (use_glsl3, allow_dsb) = match renderer_prefernce {
Some(RendererPreference::Glsl3) => (true, true),
Some(RendererPreference::Gles2) => (false, true),
Some(RendererPreference::Gles2Pure) => (false, false),
- None => (version.as_ref() >= "3.3", true),
+ None => (version.as_ref() >= "3.3" && !is_gles_context, true),
};
let (text_renderer, rect_renderer) = if use_glsl3 {
@@ -123,7 +125,8 @@ impl Renderer {
let rect_renderer = RectRenderer::new(ShaderVersion::Glsl3)?;
(text_renderer, rect_renderer)
} else {
- let text_renderer = TextRendererProvider::Gles2(Gles2Renderer::new(allow_dsb)?);
+ let text_renderer =
+ TextRendererProvider::Gles2(Gles2Renderer::new(allow_dsb, is_gles_context)?);
let rect_renderer = RectRenderer::new(ShaderVersion::Gles2)?;
(text_renderer, rect_renderer)
};
diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs
index 77826100..c9802e0a 100644
--- a/alacritty/src/renderer/platform.rs
+++ b/alacritty/src/renderer/platform.rs
@@ -81,21 +81,31 @@ pub fn create_gl_context(
gl_config: &Config,
raw_window_handle: Option<RawWindowHandle>,
) -> GlutinResult<NotCurrentContext> {
- let context_attributes = ContextAttributesBuilder::new()
- .with_context_api(ContextApi::OpenGl(Some(Version::new(3, 3))))
- .build(raw_window_handle);
-
- unsafe {
- if let Ok(gl_context) = gl_display.create_context(gl_config, &context_attributes) {
- Ok(gl_context)
- } else {
- let context_attributes = ContextAttributesBuilder::new()
- .with_profile(GlProfile::Compatibility)
- .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1))))
- .build(raw_window_handle);
- gl_display.create_context(gl_config, &context_attributes)
- }
+ let mut profiles = [
+ ContextAttributesBuilder::new()
+ .with_context_api(ContextApi::OpenGl(Some(Version::new(3, 3))))
+ .build(raw_window_handle),
+ // Try gles before OpenGL 2.1 as it tends to be more stable.
+ ContextAttributesBuilder::new()
+ .with_context_api(ContextApi::Gles(Some(Version::new(2, 0))))
+ .build(raw_window_handle),
+ ContextAttributesBuilder::new()
+ .with_profile(GlProfile::Compatibility)
+ .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1))))
+ .build(raw_window_handle),
+ ]
+ .into_iter();
+
+ // Try the optimal config first.
+ let mut picked_context =
+ unsafe { gl_display.create_context(gl_config, &profiles.next().unwrap()) };
+
+ // Try the fallback ones.
+ while let (Err(_), Some(profile)) = (picked_context.as_ref(), profiles.next()) {
+ picked_context = unsafe { gl_display.create_context(gl_config, &profile) };
}
+
+ picked_context
}
pub fn create_gl_surface(
diff --git a/alacritty/src/renderer/text/atlas.rs b/alacritty/src/renderer/text/atlas.rs
index 662d767b..0d9b6cfd 100644
--- a/alacritty/src/renderer/text/atlas.rs
+++ b/alacritty/src/renderer/text/atlas.rs
@@ -1,3 +1,4 @@
+use std::borrow::Cow;
use std::ptr;
use crossfont::{BitmapBuffer, RasterizedGlyph};
@@ -52,6 +53,11 @@ pub struct Atlas {
///
/// This is used as the advance when end of row is reached.
row_tallest: i32,
+
+ /// Gles context.
+ ///
+ /// This affects the texture loading.
+ is_gles_context: bool,
}
/// Error that can happen when inserting a texture to the Atlas.
@@ -64,7 +70,7 @@ pub enum AtlasInsertError {
}
impl Atlas {
- pub fn new(size: i32) -> Self {
+ pub fn new(size: i32, is_gles_context: bool) -> Self {
let mut id: GLuint = 0;
unsafe {
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);
@@ -92,7 +98,15 @@ impl Atlas {
gl::BindTexture(gl::TEXTURE_2D, 0);
}
- Self { id, width: size, height: size, row_extent: 0, row_baseline: 0, row_tallest: 0 }
+ Self {
+ id,
+ width: size,
+ height: size,
+ row_extent: 0,
+ row_baseline: 0,
+ row_tallest: 0,
+ is_gles_context,
+ }
}
pub fn clear(&mut self) {
@@ -144,11 +158,24 @@ impl Atlas {
let (format, buffer) = match &glyph.buffer {
BitmapBuffer::Rgb(buffer) => {
multicolor = false;
- (gl::RGB, buffer)
+ // Gles context doesn't allow uploading RGB data into RGBA texture, so need
+ // explicit copy.
+ if self.is_gles_context {
+ let mut new_buffer = Vec::with_capacity(buffer.len() / 3 * 4);
+ for rgb in buffer.chunks_exact(3) {
+ new_buffer.push(rgb[0]);
+ new_buffer.push(rgb[1]);
+ new_buffer.push(rgb[2]);
+ new_buffer.push(u8::MAX);
+ }
+ (gl::RGBA, Cow::Owned(new_buffer))
+ } else {
+ (gl::RGB, Cow::Borrowed(buffer))
+ }
},
BitmapBuffer::Rgba(buffer) => {
multicolor = true;
- (gl::RGBA, buffer)
+ (gl::RGBA, Cow::Borrowed(buffer))
},
};
@@ -234,7 +261,7 @@ impl Atlas {
Err(AtlasInsertError::Full) => {
*current_atlas += 1;
if *current_atlas == atlas.len() {
- let new = Atlas::new(ATLAS_SIZE);
+ let new = Atlas::new(ATLAS_SIZE, atlas[*current_atlas].is_gles_context);
*active_tex = 0; // Atlas::new binds a texture. Ugh this is sloppy.
atlas.push(new);
}
diff --git a/alacritty/src/renderer/text/gles2.rs b/alacritty/src/renderer/text/gles2.rs
index 2f537e5c..427a60e3 100644
--- a/alacritty/src/renderer/text/gles2.rs
+++ b/alacritty/src/renderer/text/gles2.rs
@@ -37,13 +37,17 @@ pub struct Gles2Renderer {
}
impl Gles2Renderer {
- pub fn new(allow_dsb: bool) -> Result<Self, Error> {
+ pub fn new(allow_dsb: bool, is_gles_context: bool) -> Result<Self, Error> {
info!("Using OpenGL ES 2.0 renderer");
let dual_source_blending = allow_dsb
&& (GlExtensions::contains("GL_EXT_blend_func_extended")
|| GlExtensions::contains("GL_ARB_blend_func_extended"));
+ if is_gles_context {
+ info!("Running on OpenGL ES context");
+ }
+
if dual_source_blending {
info!("Using dual source blending");
}
@@ -145,7 +149,7 @@ impl Gles2Renderer {
vao,
vbo,
ebo,
- atlas: vec![Atlas::new(ATLAS_SIZE)],
+ atlas: vec![Atlas::new(ATLAS_SIZE, is_gles_context)],
batch: Batch::new(),
current_atlas: 0,
active_tex: 0,
diff --git a/alacritty/src/renderer/text/glsl3.rs b/alacritty/src/renderer/text/glsl3.rs
index 885023a0..7c32bf9f 100644
--- a/alacritty/src/renderer/text/glsl3.rs
+++ b/alacritty/src/renderer/text/glsl3.rs
@@ -137,7 +137,7 @@ impl Glsl3Renderer {
vao,
ebo,
vbo_instance,
- atlas: vec![Atlas::new(ATLAS_SIZE)],
+ atlas: vec![Atlas::new(ATLAS_SIZE, false)],
current_atlas: 0,
active_tex: 0,
batch: Batch::new(),