Improve OpenGL error detection and reporting in egui_glow
May help to diagnose https://github.com/emilk/egui/issues/1087
This commit is contained in:
parent
611eaa52e8
commit
650057dd4a
5 changed files with 43 additions and 36 deletions
|
@ -4,7 +4,7 @@ use std::option::Option::Some;
|
||||||
|
|
||||||
use crate::painter::TextureFilter;
|
use crate::painter::TextureFilter;
|
||||||
|
|
||||||
pub(crate) fn srgbtexture2d(
|
pub(crate) fn srgb_texture2d(
|
||||||
gl: &glow::Context,
|
gl: &glow::Context,
|
||||||
is_webgl_1: bool,
|
is_webgl_1: bool,
|
||||||
srgb_support: bool,
|
srgb_support: bool,
|
||||||
|
@ -71,24 +71,41 @@ pub(crate) fn srgbtexture2d(
|
||||||
glow::PixelUnpackData::Slice(data),
|
glow::PixelUnpackData::Slice(data),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
assert_eq!(gl.get_error(), glow::NO_ERROR, "OpenGL error occurred!");
|
check_for_gl_error(gl, "srgb_texture2d");
|
||||||
tex
|
tex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_for_gl_error(gl: &glow::Context, context: &str) {
|
||||||
|
let error_code = unsafe { gl.get_error() };
|
||||||
|
if error_code != glow::NO_ERROR {
|
||||||
|
glow_print_error(format!(
|
||||||
|
"GL error, at: '{}', code: {} (0x{:X})",
|
||||||
|
context, error_code, error_code
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn as_u8_slice<T>(s: &[T]) -> &[u8] {
|
pub(crate) unsafe fn as_u8_slice<T>(s: &[T]) -> &[u8] {
|
||||||
std::slice::from_raw_parts(s.as_ptr().cast::<u8>(), s.len() * std::mem::size_of::<T>())
|
std::slice::from_raw_parts(s.as_ptr().cast::<u8>(), s.len() * std::mem::size_of::<T>())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
pub(crate) fn glow_print(s: impl std::fmt::Display) {
|
||||||
pub(crate) fn glow_debug_print(s: impl std::fmt::Display) {
|
#[cfg(target_arch = "wasm32")]
|
||||||
web_sys::console::log_1(&format!("egui_glow: {}", s).into());
|
web_sys::console::log_1(&format!("egui_glow: {}", s).into());
|
||||||
}
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub(crate) fn glow_debug_print(s: impl std::fmt::Display) {
|
|
||||||
eprintln!("egui_glow: {}", s);
|
eprintln!("egui_glow: {}", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn glow_print_error(s: impl std::fmt::Display) {
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
web_sys::console::error_1(&format!("egui_glow: {}", s).into());
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
eprintln!("egui_glow ERROR: {}", s);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn compile_shader(
|
pub(crate) unsafe fn compile_shader(
|
||||||
gl: &glow::Context,
|
gl: &glow::Context,
|
||||||
shader_type: u32,
|
shader_type: u32,
|
||||||
|
@ -192,7 +209,7 @@ pub(crate) fn supports_vao(gl: &glow::Context) -> bool {
|
||||||
let version_string = unsafe { gl.get_parameter_string(glow::VERSION) };
|
let version_string = unsafe { gl.get_parameter_string(glow::VERSION) };
|
||||||
if let Some(pos) = version_string.rfind(web_sig) {
|
if let Some(pos) = version_string.rfind(web_sig) {
|
||||||
let version_str = &version_string[pos + web_sig.len()..];
|
let version_str = &version_string[pos + web_sig.len()..];
|
||||||
glow_debug_print(format!(
|
glow_print(format!(
|
||||||
"detected WebGL prefix at {}:{}",
|
"detected WebGL prefix at {}:{}",
|
||||||
pos + web_sig.len(),
|
pos + web_sig.len(),
|
||||||
version_str
|
version_str
|
||||||
|
@ -206,7 +223,7 @@ pub(crate) fn supports_vao(gl: &glow::Context) -> bool {
|
||||||
}
|
}
|
||||||
} else if let Some(pos) = version_string.rfind(es_sig) {
|
} else if let Some(pos) = version_string.rfind(es_sig) {
|
||||||
//glow targets es2.0+ so we don't concern about OpenGL ES-CM,OpenGL ES-CL
|
//glow targets es2.0+ so we don't concern about OpenGL ES-CM,OpenGL ES-CL
|
||||||
glow_debug_print(format!(
|
glow_print(format!(
|
||||||
"detected OpenGL ES prefix at {}:{}",
|
"detected OpenGL ES prefix at {}:{}",
|
||||||
pos + es_sig.len(),
|
pos + es_sig.len(),
|
||||||
&version_string[pos + es_sig.len()..]
|
&version_string[pos + es_sig.len()..]
|
||||||
|
@ -219,7 +236,7 @@ pub(crate) fn supports_vao(gl: &glow::Context) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
glow_debug_print(format!("detected OpenGL: {:?}", version_string));
|
glow_print(format!("detected OpenGL: {:?}", version_string));
|
||||||
//from OpenGL 3 vao into core
|
//from OpenGL 3 vao into core
|
||||||
if version_string.starts_with('2') {
|
if version_string.starts_with('2') {
|
||||||
// I found APPLE_vertex_array_object , GL_ATI_vertex_array_object ,ARB_vertex_array_object
|
// I found APPLE_vertex_array_object , GL_ATI_vertex_array_object ,ARB_vertex_array_object
|
||||||
|
|
|
@ -10,7 +10,7 @@ use glow::HasContext;
|
||||||
use memoffset::offset_of;
|
use memoffset::offset_of;
|
||||||
|
|
||||||
use crate::misc_util::{
|
use crate::misc_util::{
|
||||||
as_u8_slice, compile_shader, glow_debug_print, link_program, srgbtexture2d,
|
as_u8_slice, check_for_gl_error, compile_shader, glow_print, link_program, srgb_texture2d,
|
||||||
};
|
};
|
||||||
use crate::post_process::PostProcess;
|
use crate::post_process::PostProcess;
|
||||||
use crate::shader_version::ShaderVersion;
|
use crate::shader_version::ShaderVersion;
|
||||||
|
@ -93,11 +93,13 @@ impl Painter {
|
||||||
pp_fb_extent: Option<[i32; 2]>,
|
pp_fb_extent: Option<[i32; 2]>,
|
||||||
shader_prefix: &str,
|
shader_prefix: &str,
|
||||||
) -> Result<Painter, String> {
|
) -> Result<Painter, String> {
|
||||||
|
check_for_gl_error(gl, "before Painter::new");
|
||||||
|
|
||||||
let support_vao = crate::misc_util::supports_vao(gl);
|
let support_vao = crate::misc_util::supports_vao(gl);
|
||||||
let shader_version = ShaderVersion::get(gl);
|
let shader_version = ShaderVersion::get(gl);
|
||||||
let is_webgl_1 = shader_version == ShaderVersion::Es100;
|
let is_webgl_1 = shader_version == ShaderVersion::Es100;
|
||||||
let header = shader_version.version();
|
let header = shader_version.version();
|
||||||
glow_debug_print(format!("Shader header: {:?}", header));
|
glow_print(format!("Shader header: {:?}", header));
|
||||||
let srgb_support = gl.supported_extensions().contains("EXT_sRGB");
|
let srgb_support = gl.supported_extensions().contains("EXT_sRGB");
|
||||||
|
|
||||||
let (post_process, srgb_support_define) = match (shader_version, srgb_support) {
|
let (post_process, srgb_support_define) = match (shader_version, srgb_support) {
|
||||||
|
@ -105,7 +107,7 @@ impl Painter {
|
||||||
(ShaderVersion::Es300, _) | (ShaderVersion::Es100, true) => unsafe {
|
(ShaderVersion::Es300, _) | (ShaderVersion::Es100, true) => unsafe {
|
||||||
//Add sRGB support marker for fragment shader
|
//Add sRGB support marker for fragment shader
|
||||||
if let Some([width, height]) = pp_fb_extent {
|
if let Some([width, height]) = pp_fb_extent {
|
||||||
glow_debug_print("WebGL with sRGB enabled so turn on post process");
|
glow_print("WebGL with sRGB enabled so turn on post process");
|
||||||
//install post process to correct sRGB color
|
//install post process to correct sRGB color
|
||||||
(
|
(
|
||||||
Some(PostProcess::new(
|
Some(PostProcess::new(
|
||||||
|
@ -119,7 +121,7 @@ impl Painter {
|
||||||
"#define SRGB_SUPPORTED",
|
"#define SRGB_SUPPORTED",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
glow_debug_print("WebGL or OpenGL ES detected but PostProcess disabled because dimension is None");
|
glow_print("WebGL or OpenGL ES detected but PostProcess disabled because dimension is None");
|
||||||
(None, "")
|
(None, "")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -201,7 +203,7 @@ impl Painter {
|
||||||
vertex_array.add_new_attribute(gl, position_buffer_info);
|
vertex_array.add_new_attribute(gl, position_buffer_info);
|
||||||
vertex_array.add_new_attribute(gl, tex_coord_buffer_info);
|
vertex_array.add_new_attribute(gl, tex_coord_buffer_info);
|
||||||
vertex_array.add_new_attribute(gl, color_buffer_info);
|
vertex_array.add_new_attribute(gl, color_buffer_info);
|
||||||
assert_eq!(gl.get_error(), glow::NO_ERROR, "OpenGL error occurred!");
|
check_for_gl_error(gl, "after Painter::new");
|
||||||
|
|
||||||
Ok(Painter {
|
Ok(Painter {
|
||||||
program,
|
program,
|
||||||
|
@ -244,7 +246,7 @@ impl Painter {
|
||||||
|
|
||||||
if let Some(old_tex) = std::mem::replace(
|
if let Some(old_tex) = std::mem::replace(
|
||||||
&mut self.egui_texture,
|
&mut self.egui_texture,
|
||||||
Some(srgbtexture2d(
|
Some(srgb_texture2d(
|
||||||
gl,
|
gl,
|
||||||
self.is_webgl_1,
|
self.is_webgl_1,
|
||||||
self.srgb_support,
|
self.srgb_support,
|
||||||
|
@ -346,7 +348,7 @@ impl Painter {
|
||||||
|
|
||||||
gl.disable(glow::SCISSOR_TEST);
|
gl.disable(glow::SCISSOR_TEST);
|
||||||
|
|
||||||
assert_eq!(glow::NO_ERROR, gl.get_error(), "GL error occurred!");
|
check_for_gl_error(gl, "painting");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +439,7 @@ impl Painter {
|
||||||
.flat_map(|srgba| Vec::from(srgba.to_array()))
|
.flat_map(|srgba| Vec::from(srgba.to_array()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let gl_texture = srgbtexture2d(
|
let gl_texture = srgb_texture2d(
|
||||||
gl,
|
gl,
|
||||||
self.is_webgl_1,
|
self.is_webgl_1,
|
||||||
self.srgb_support,
|
self.srgb_support,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
use crate::misc_util::{compile_shader, link_program};
|
use crate::misc_util::{check_for_gl_error, compile_shader, link_program};
|
||||||
use crate::vao_emulate::BufferInfo;
|
use crate::vao_emulate::BufferInfo;
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
|
|
||||||
|
@ -76,13 +76,7 @@ impl PostProcess {
|
||||||
glow::UNSIGNED_BYTE,
|
glow::UNSIGNED_BYTE,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let error_code = gl.get_error();
|
check_for_gl_error(gl, "post process texture initialization");
|
||||||
assert_eq!(
|
|
||||||
error_code,
|
|
||||||
glow::NO_ERROR,
|
|
||||||
"Error occurred in post process texture initialization. code : 0x{:x}",
|
|
||||||
error_code
|
|
||||||
);
|
|
||||||
|
|
||||||
gl.framebuffer_texture_2d(
|
gl.framebuffer_texture_2d(
|
||||||
glow::FRAMEBUFFER,
|
glow::FRAMEBUFFER,
|
||||||
|
@ -151,13 +145,7 @@ impl PostProcess {
|
||||||
gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, &indices, glow::STATIC_DRAW);
|
gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, &indices, glow::STATIC_DRAW);
|
||||||
|
|
||||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
||||||
let error_code = gl.get_error();
|
check_for_gl_error(gl, "post process initialization");
|
||||||
assert_eq!(
|
|
||||||
error_code,
|
|
||||||
glow::NO_ERROR,
|
|
||||||
"Error occurred in post process initialization. code : 0x{:x}",
|
|
||||||
error_code
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(PostProcess {
|
Ok(PostProcess {
|
||||||
pos_buffer,
|
pos_buffer,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
use crate::misc_util::glow_debug_print;
|
use crate::misc_util::glow_print;
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ impl ShaderVersion {
|
||||||
let shading_lang_string =
|
let shading_lang_string =
|
||||||
unsafe { gl.get_parameter_string(glow::SHADING_LANGUAGE_VERSION) };
|
unsafe { gl.get_parameter_string(glow::SHADING_LANGUAGE_VERSION) };
|
||||||
let shader_version = Self::parse(&shading_lang_string);
|
let shader_version = Self::parse(&shading_lang_string);
|
||||||
glow_debug_print(format!(
|
glow_print(format!(
|
||||||
"Shader version: {:?} ({:?})",
|
"Shader version: {:?} ({:?})",
|
||||||
shader_version, shading_lang_string
|
shader_version, shading_lang_string
|
||||||
));
|
));
|
||||||
|
|
|
@ -132,7 +132,7 @@ pub fn init_glow_context_from_canvas(canvas: &HtmlCanvasElement) -> glow::Contex
|
||||||
.expect("Failed to query about WebGL1 context");
|
.expect("Failed to query about WebGL1 context");
|
||||||
|
|
||||||
if let Some(gl1) = gl1 {
|
if let Some(gl1) = gl1 {
|
||||||
crate::console_log("WebGL2 not available - falling back to WebGL2");
|
crate::console_log("WebGL2 not available - falling back to WebGL1");
|
||||||
let gl1_ctx = gl1.dyn_into::<web_sys::WebGlRenderingContext>().unwrap();
|
let gl1_ctx = gl1.dyn_into::<web_sys::WebGlRenderingContext>().unwrap();
|
||||||
glow::Context::from_webgl1_context(gl1_ctx)
|
glow::Context::from_webgl1_context(gl1_ctx)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue