diff --git a/crates/eframe/src/lib.rs b/crates/eframe/src/lib.rs index ea1d7ced951..2edc06ab290 100644 --- a/crates/eframe/src/lib.rs +++ b/crates/eframe/src/lib.rs @@ -313,6 +313,11 @@ pub enum Error { #[error("Found no glutin configs matching the template: {0:?}. Error: {1:?}")] NoGlutinConfigs(glutin::config::ConfigTemplate, Box), + /// An error from [`glutin`] when using [`glow`]. + #[cfg(feature = "glow")] + #[error("egui_glow: {0}")] + OpenGL(#[from] egui_glow::PainterError), + /// An error from [`wgpu`]. #[cfg(feature = "wgpu")] #[error("WGPU error: {0}")] diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 8f6a6db06c6..914435eda9b 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -1021,17 +1021,18 @@ mod glow_integration { .get_mut(&viewport_id) .expect("viewport doesn't exist"); - let window = viewport.window.get_or_insert_with(|| { + let window = if let Some(window) = &mut viewport.window { + window + } else { log::trace!("Window doesn't exist yet. Creating one now with finalize_window"); - Rc::new( - glutin_winit::finalize_window( + viewport + .window + .insert(Rc::new(glutin_winit::finalize_window( event_loop, create_winit_window_builder(&viewport.builder), &self.gl_config, - ) - .expect("failed to finalize glutin window"), - ) - }); + )?)) + }; { // surface attributes @@ -1330,8 +1331,7 @@ mod glow_integration { })) }; - let painter = egui_glow::Painter::new(gl, "", native_options.shader_version) - .unwrap_or_else(|err| panic!("An OpenGL error occurred: {err}\n")); + let painter = egui_glow::Painter::new(gl, "", native_options.shader_version)?; Ok((glutin_window_context, painter)) } @@ -1821,22 +1821,27 @@ mod wgpu_integration { let viewport_id = self.ids.this; - if let Ok(new_window) = create_winit_window_builder(&self.builder).build(event_loop) { - windows_id.insert(new_window.id(), viewport_id); + match create_winit_window_builder(&self.builder).build(event_loop) { + Ok(new_window) => { + windows_id.insert(new_window.id(), viewport_id); - if let Err(err) = - pollster::block_on(painter.set_window(viewport_id, Some(&new_window))) - { - log::error!("on set_window: viewport_id {viewport_id:?} {err}"); - } + if let Err(err) = + pollster::block_on(painter.set_window(viewport_id, Some(&new_window))) + { + log::error!("on set_window: viewport_id {viewport_id:?} {err}"); + } - self.egui_winit = Some(egui_winit::State::new( - event_loop, - Some(new_window.scale_factor() as f32), - painter.max_texture_side(), - )); + self.egui_winit = Some(egui_winit::State::new( + event_loop, + Some(new_window.scale_factor() as f32), + painter.max_texture_side(), + )); - self.window = Some(Rc::new(new_window)); + self.window = Some(Rc::new(new_window)); + } + Err(err) => { + log::error!("Failed to create window: {err}"); + } } } } diff --git a/crates/egui/src/load.rs b/crates/egui/src/load.rs index 717383d3109..f1c61a644e1 100644 --- a/crates/egui/src/load.rs +++ b/crates/egui/src/load.rs @@ -58,7 +58,7 @@ mod texture_loader; use std::borrow::Cow; use std::fmt::Debug; use std::ops::Deref; -use std::{error::Error as StdError, fmt::Display, sync::Arc}; +use std::{fmt::Display, sync::Arc}; use ahash::HashMap; @@ -118,7 +118,7 @@ impl Display for LoadError { } } -impl StdError for LoadError {} +impl std::error::Error for LoadError {} pub type Result = std::result::Result; diff --git a/crates/egui_glow/src/lib.rs b/crates/egui_glow/src/lib.rs index e5381952390..b12d2ff5f61 100644 --- a/crates/egui_glow/src/lib.rs +++ b/crates/egui_glow/src/lib.rs @@ -13,7 +13,7 @@ pub mod painter; pub use glow; -pub use painter::{CallbackFn, Painter}; +pub use painter::{CallbackFn, Painter, PainterError}; mod misc_util; mod shader_version; mod vao; diff --git a/crates/egui_glow/src/painter.rs b/crates/egui_glow/src/painter.rs index 842b87d76c7..2b10340105b 100644 --- a/crates/egui_glow/src/painter.rs +++ b/crates/egui_glow/src/painter.rs @@ -34,6 +34,24 @@ impl TextureFilterExt for egui::TextureFilter { } } +#[derive(Debug)] +pub struct PainterError(String); + +impl std::error::Error for PainterError {} + +impl std::fmt::Display for PainterError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "OpenGL: {}", self.0) + } +} + +impl From for PainterError { + #[inline] + fn from(value: String) -> Self { + Self(value) + } +} + /// An OpenGL painter using [`glow`]. /// /// This is responsible for painting egui and managing egui textures. @@ -103,7 +121,7 @@ impl Painter { gl: Arc, shader_prefix: &str, shader_version: Option, - ) -> Result { + ) -> Result { crate::profile_function!(); crate::check_for_gl_error_even_in_release!(&gl, "before Painter::new"); @@ -121,7 +139,7 @@ impl Painter { if gl.version().major < 2 { // this checks on desktop that we are not using opengl 1.1 microsoft sw rendering context. // ShaderVersion::get fn will segfault due to SHADING_LANGUAGE_VERSION (added in gl2.0) - return Err("egui_glow requires opengl 2.0+. ".to_owned()); + return Err(PainterError("egui_glow requires opengl 2.0+. ".to_owned())); } let max_texture_side = unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) } as usize;