mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Fix wrong gamma in WebkitGTK (#888)
Closes https://github.com/emilk/egui/issues/794 Also refactor and improve VAO support detection Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
use crate::web_sys::{WebGl2RenderingContext, WebGlRenderingContext};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::web_sys::WebGl2RenderingContext;
|
||||
use crate::web_sys::WebGlRenderingContext;
|
||||
use crate::{canvas_element_or_die, console_error};
|
||||
use egui::{ClippedMesh, Rgba, Texture};
|
||||
use egui_glow::glow;
|
||||
use epi::TextureAllocator;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::HtmlCanvasElement;
|
||||
|
||||
@@ -16,9 +19,29 @@ pub(crate) struct WrappedGlowPainter {
|
||||
impl WrappedGlowPainter {
|
||||
pub fn new(canvas_id: &str) -> Self {
|
||||
let canvas = canvas_element_or_die(canvas_id);
|
||||
// detect WebKitGTK
|
||||
//WebKitGTK currently support only webgl,so request webgl context.
|
||||
// WebKitGTK use WebKit default unmasked vendor and renderer
|
||||
// but safari use same vendor and renderer
|
||||
// so exclude "Mac OS X" user-agent.
|
||||
let gl = canvas
|
||||
.get_context("webgl")
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.dyn_into::<WebGlRenderingContext>()
|
||||
.unwrap();
|
||||
let user_agent = web_sys::window().unwrap().navigator().user_agent().unwrap();
|
||||
let webkit_gtk_wr = if !user_agent.contains("Mac OS X")
|
||||
&& crate::webgl1::detect_safari_and_webkit_gtk(&gl)
|
||||
{
|
||||
"#define WEBKITGTK_WORKAROUND"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let gl_ctx = init_glow_context_from_canvas(&canvas);
|
||||
let dimension = [canvas.width() as i32, canvas.height() as i32];
|
||||
let painter = egui_glow::Painter::new(&gl_ctx, Some(dimension))
|
||||
let painter = egui_glow::Painter::new(&gl_ctx, Some(dimension), webkit_gtk_wr)
|
||||
.map_err(|error| {
|
||||
console_error(format!(
|
||||
"some error occurred in initializing glow painter\n {}",
|
||||
@@ -82,7 +105,6 @@ impl crate::Painter for WrappedGlowPainter {
|
||||
}
|
||||
|
||||
pub fn init_glow_context_from_canvas(canvas: &HtmlCanvasElement) -> glow::Context {
|
||||
use wasm_bindgen::JsCast;
|
||||
let ctx = canvas.get_context("webgl2");
|
||||
if let Ok(ctx) = ctx {
|
||||
crate::console_log("webgl found");
|
||||
|
||||
@@ -19,4 +19,8 @@ void main() {
|
||||
gl_FragColor = texture2D(u_sampler, v_tc);
|
||||
|
||||
gl_FragColor = srgba_from_linear(gl_FragColor) / 255.;
|
||||
#ifdef WEBKITGTK_WORKAROUND
|
||||
//this is better than double apply
|
||||
gl_FragColor = vec4(pow(gl_FragColor.rgb,vec3(1.0/2.2)),gl_FragColor.a);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ use {
|
||||
wasm_bindgen::{prelude::*, JsCast},
|
||||
web_sys::{
|
||||
ExtSRgb, WebGlBuffer, WebGlFramebuffer, WebGlProgram, WebGlRenderingContext, WebGlShader,
|
||||
WebGlTexture,
|
||||
WebGlTexture, WebglDebugRendererInfo,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::console_log;
|
||||
use egui::{
|
||||
emath::vec2,
|
||||
epaint::{Color32, Texture},
|
||||
@@ -591,6 +592,17 @@ impl PostProcess {
|
||||
|
||||
gl.bind_texture(Gl::TEXTURE_2D, None);
|
||||
gl.bind_framebuffer(Gl::FRAMEBUFFER, None);
|
||||
// detect WebKitGTK
|
||||
// WebKitGTK use WebKit default unmasked vendor and renderer
|
||||
// but safari use same vendor and renderer
|
||||
// so exclude "Mac OS X " user-agent.
|
||||
let user_agent = web_sys::window().unwrap().navigator().user_agent().unwrap();
|
||||
let webkit_gtk_wr = if !user_agent.contains("Mac OS X") && detect_safari_and_webkit_gtk(&gl)
|
||||
{
|
||||
"#define WEBKITGTK_WORKAROUND"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let vert_shader = compile_shader(
|
||||
&gl,
|
||||
@@ -600,7 +612,11 @@ impl PostProcess {
|
||||
let frag_shader = compile_shader(
|
||||
&gl,
|
||||
Gl::FRAGMENT_SHADER,
|
||||
include_str!("shader/post_fragment_100es.glsl"),
|
||||
&format!(
|
||||
"{}{}",
|
||||
webkit_gtk_wr,
|
||||
include_str!("shader/post_fragment_100es.glsl")
|
||||
),
|
||||
)?;
|
||||
let program = link_program(&gl, [vert_shader, frag_shader].iter())?;
|
||||
|
||||
@@ -750,3 +766,27 @@ fn link_program<'a, T: IntoIterator<Item = &'a WebGlShader>>(
|
||||
.unwrap_or_else(|| "Unknown error creating program object".into()))
|
||||
}
|
||||
}
|
||||
|
||||
/// detecting Safari and webkitGTK.
|
||||
///
|
||||
/// Safari and webkitGTK use unmasked renderer :Apple GPU
|
||||
///
|
||||
/// If we detect safari or webkitGTK returns true.
|
||||
///
|
||||
/// This function used to avoid displaying linear color with `sRGB` supported systems.
|
||||
pub(crate) fn detect_safari_and_webkit_gtk(gl: &web_sys::WebGlRenderingContext) -> bool {
|
||||
if gl
|
||||
.get_extension("WEBGL_debug_renderer_info")
|
||||
.unwrap()
|
||||
.is_some()
|
||||
{
|
||||
let renderer: JsValue = gl
|
||||
.get_parameter(WebglDebugRendererInfo::UNMASKED_RENDERER_WEBGL)
|
||||
.unwrap();
|
||||
if renderer.as_string().unwrap().contains("Apple") {
|
||||
console_log("Enabling webkitGTK workaround");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user