Fix sRGB blending and cleanup the relevant code (#2070)
* Fix sRGBA blending on Mac * Clean up handling of sRGB support * Assume sRGB support if any extension has sRGB in it * improve logging very slightly
This commit is contained in:
parent
4aae638e15
commit
990a8c8b44
2 changed files with 54 additions and 44 deletions
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::collapsible_else_if)]
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
@ -53,7 +54,7 @@ pub struct Painter {
|
|||
is_webgl_1: bool,
|
||||
is_embedded: bool,
|
||||
vao: crate::vao::VertexArrayObject,
|
||||
srgb_support: bool,
|
||||
srgb_textures: bool,
|
||||
post_process: Option<PostProcess>,
|
||||
vbo: glow::Buffer,
|
||||
element_array_buffer: glow::Buffer,
|
||||
|
@ -112,45 +113,41 @@ impl Painter {
|
|||
crate::check_for_gl_error_even_in_release!(&gl, "before Painter::new");
|
||||
|
||||
let max_texture_side = unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) } as usize;
|
||||
let shader = shader_version.unwrap_or_else(|| ShaderVersion::get(&gl));
|
||||
let is_webgl_1 = shader == ShaderVersion::Es100;
|
||||
let header = shader.version_declaration();
|
||||
let shader_version = shader_version.unwrap_or_else(|| ShaderVersion::get(&gl));
|
||||
let is_webgl_1 = shader_version == ShaderVersion::Es100;
|
||||
let header = shader_version.version_declaration();
|
||||
tracing::debug!("Shader header: {:?}.", header);
|
||||
// Previously checking srgb_support on WebGL only, now we have to check on other GL | ES as well.
|
||||
let srgb_support = gl.supported_extensions().contains("EXT_sRGB")
|
||||
|| gl.supported_extensions().contains("GL_EXT_sRGB")
|
||||
|| gl
|
||||
.supported_extensions()
|
||||
.contains("GL_ARB_framebuffer_sRGB");
|
||||
tracing::debug!("SRGB Support: {:?}.", srgb_support);
|
||||
|
||||
let (post_process, srgb_support_define) = match (shader, srgb_support) {
|
||||
// WebGL2 support sRGB default
|
||||
(ShaderVersion::Es300, _) | (ShaderVersion::Es100, true) => unsafe {
|
||||
// Add sRGB support marker for fragment shader
|
||||
if let Some(size) = pp_fb_extent {
|
||||
tracing::debug!("WebGL with sRGB enabled. Turning on post processing for linear framebuffer blending.");
|
||||
// install post process to correct sRGB color:
|
||||
(
|
||||
Some(PostProcess::new(
|
||||
gl.clone(),
|
||||
shader_prefix,
|
||||
is_webgl_1,
|
||||
size,
|
||||
)?),
|
||||
"#define SRGB_SUPPORTED",
|
||||
)
|
||||
} else {
|
||||
tracing::debug!("WebGL or OpenGL ES detected but PostProcess disabled because dimension is None");
|
||||
(None, "")
|
||||
}
|
||||
},
|
||||
let supported_extensions = gl.supported_extensions();
|
||||
tracing::trace!("OpenGL extensions: {supported_extensions:?}");
|
||||
let srgb_textures = shader_version == ShaderVersion::Es300 // WebGL2 always support sRGB
|
||||
|| supported_extensions.iter().any(|extension| {
|
||||
// EXT_sRGB, GL_ARB_framebuffer_sRGB, GL_EXT_sRGB, GL_EXT_texture_sRGB_decode, …
|
||||
extension.contains("sRGB")
|
||||
});
|
||||
tracing::debug!("SRGB Support: {:?}", srgb_textures);
|
||||
|
||||
// WebGL1 without sRGB support disable postprocess and use fallback shader
|
||||
(ShaderVersion::Es100, false) => (None, ""),
|
||||
let (post_process, srgb_support_define) = if shader_version.is_embedded() {
|
||||
// WebGL doesn't support linear framebuffer blending… but maybe we can emulate it with `PostProcess`?
|
||||
|
||||
// OpenGL 2.1 or above always support sRGB so add sRGB support marker
|
||||
_ => (None, "#define SRGB_SUPPORTED"),
|
||||
if let Some(size) = pp_fb_extent {
|
||||
tracing::debug!("WebGL with sRGB support. Turning on post processing for linear framebuffer blending.");
|
||||
// install post process to correct sRGB color:
|
||||
(
|
||||
Some(unsafe { PostProcess::new(gl.clone(), shader_prefix, is_webgl_1, size)? }),
|
||||
"#define SRGB_SUPPORTED",
|
||||
)
|
||||
} else {
|
||||
tracing::warn!("WebGL or OpenGL ES detected but PostProcess disabled because dimension is None. Linear framebuffer blending will not be supported.");
|
||||
(None, "")
|
||||
}
|
||||
} else {
|
||||
if srgb_textures {
|
||||
(None, "#define SRGB_SUPPORTED")
|
||||
} else {
|
||||
tracing::warn!("sRGB aware texture filtering not available");
|
||||
(None, "")
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
|
@ -161,7 +158,7 @@ impl Painter {
|
|||
"{}\n{}\n{}\n{}",
|
||||
header,
|
||||
shader_prefix,
|
||||
if shader.is_new_shader_interface() {
|
||||
if shader_version.is_new_shader_interface() {
|
||||
"#define NEW_SHADER_INTERFACE\n"
|
||||
} else {
|
||||
""
|
||||
|
@ -177,7 +174,7 @@ impl Painter {
|
|||
header,
|
||||
shader_prefix,
|
||||
srgb_support_define,
|
||||
if shader.is_new_shader_interface() {
|
||||
if shader_version.is_new_shader_interface() {
|
||||
"#define NEW_SHADER_INTERFACE\n"
|
||||
} else {
|
||||
""
|
||||
|
@ -239,9 +236,9 @@ impl Painter {
|
|||
u_screen_size,
|
||||
u_sampler,
|
||||
is_webgl_1,
|
||||
is_embedded: matches!(shader, ShaderVersion::Es100 | ShaderVersion::Es300),
|
||||
is_embedded: shader_version.is_embedded(),
|
||||
vao,
|
||||
srgb_support,
|
||||
srgb_textures,
|
||||
post_process,
|
||||
vbo,
|
||||
element_array_buffer,
|
||||
|
@ -591,16 +588,16 @@ impl Painter {
|
|||
check_for_gl_error!(&self.gl, "tex_parameter");
|
||||
|
||||
let (internal_format, src_format) = if self.is_webgl_1 {
|
||||
let format = if self.srgb_support {
|
||||
let format = if self.srgb_textures {
|
||||
glow::SRGB_ALPHA
|
||||
} else {
|
||||
glow::RGBA
|
||||
};
|
||||
(format, format)
|
||||
} else if !self.srgb_support {
|
||||
(glow::RGBA8, glow::RGBA)
|
||||
} else {
|
||||
} else if self.srgb_textures {
|
||||
(glow::SRGB8_ALPHA8, glow::RGBA)
|
||||
} else {
|
||||
(glow::RGBA8, glow::RGBA)
|
||||
};
|
||||
|
||||
self.gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
||||
|
|
|
@ -7,8 +7,14 @@ use std::convert::TryInto;
|
|||
#[allow(dead_code)]
|
||||
pub enum ShaderVersion {
|
||||
Gl120,
|
||||
|
||||
/// OpenGL 1.4 or later
|
||||
Gl140,
|
||||
|
||||
/// e.g. WebGL1
|
||||
Es100,
|
||||
|
||||
/// e.g. WebGL2
|
||||
Es300,
|
||||
}
|
||||
|
||||
|
@ -70,6 +76,13 @@ impl ShaderVersion {
|
|||
Self::Es300 | Self::Gl140 => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_embedded(&self) -> bool {
|
||||
match self {
|
||||
Self::Gl120 | Self::Gl140 => false,
|
||||
Self::Es100 | Self::Es300 => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue