Make gles2 renderer actually gles2

Fixes #6209.
This commit is contained in:
Kirill Chibisov 2023-02-07 22:08:24 +03:00 committed by GitHub
parent 8b3f229c3d
commit 2d27fff796
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 82 additions and 37 deletions

View File

@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Uppercase `-T` short form for `--title`
- Support for horizontal scrolling in mouse mode and alternative scrolling modes
- Support for fractional scaling on Wayland with wp-fractional-scale protocol
- Support for running on GLES context
### Changed

24
Cargo.lock generated
View File

@ -688,42 +688,42 @@ dependencies = [
[[package]]
name = "glutin"
version = "0.30.3"
version = "0.30.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524d807cd49a0c56a53ef9a6738cd15e7c8c4e9d37a3b7fdb3c250c1cd5bf7a3"
checksum = "373e3fbcfa6b9c313faa03625a08268168ba9be1003d1ecfcebd5266388aa131"
dependencies = [
"bitflags",
"cfg_aliases",
"cgl",
"cocoa",
"core-foundation",
"dispatch",
"glutin_egl_sys",
"glutin_glx_sys",
"glutin_wgl_sys",
"libloading",
"objc",
"objc2",
"once_cell",
"raw-window-handle",
"wayland-sys 0.30.0",
"windows-sys 0.36.1",
"windows-sys 0.45.0",
"x11-dl",
]
[[package]]
name = "glutin_egl_sys"
version = "0.3.1"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3adbb8fec0e18e340f990c78f79f5f0e142d0d83f46b10909aaa7d251c00afdf"
checksum = "e5aaf0abb5c4148685b33101ae326a207946b4d3764d6cdc79f8316cdaa8367d"
dependencies = [
"gl_generator",
"windows-sys 0.36.1",
"windows-sys 0.45.0",
]
[[package]]
name = "glutin_glx_sys"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "947c4850c58211c9627969c2b4e2674764b81ae5b47bab2c9a477d7942f96e0f"
checksum = "1b53cb5fe568964aa066a3ba91eac5ecbac869fb0842cd0dc9e412434f1a1494"
dependencies = [
"gl_generator",
"x11-dl",
@ -731,9 +731,9 @@ dependencies = [
[[package]]
name = "glutin_wgl_sys"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20c33975a6c9d49d72c8f032a60079bf8df536954fbf9e4cee90396ace815c57"
checksum = "ef89398e90033fc6bc65e9bd42fd29bbbfd483bda5b56dc5562f455550618165"
dependencies = [
"gl_generator",
]

View File

@ -29,7 +29,7 @@ fnv = "1"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
serde_json = "1"
glutin = { version = "0.30.3", default-features = false, features = ["egl", "wgl"] }
glutin = { version = "0.30.4", default-features = false, features = ["egl", "wgl"] }
winit = { version = "0.28.1", default-features = false, features = ["serde"] }
notify = "5.1.0"
parking_lot = "0.12.0"

View File

@ -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)
};

View File

@ -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);
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();
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)
}
// 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(

View File

@ -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);
}

View File

@ -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,

View File

@ -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(),