mirror of https://github.com/encounter/objdiff.git
Better graphics backend fallback
This attempts the following in order: - wgpu with user-selected backend - wgpu with automatic backend - glow (fallback OpenGL backend) This should eliminate most issues where objdiff fails to launch.
This commit is contained in:
parent
09cc9952df
commit
952b6a63c3
|
@ -18,7 +18,7 @@ name = "objdiff"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["wgpu", "wsl"]
|
default = ["glow", "wgpu", "wsl"]
|
||||||
glow = ["eframe/glow"]
|
glow = ["eframe/glow"]
|
||||||
wgpu = ["eframe/wgpu", "dep:wgpu"]
|
wgpu = ["eframe/wgpu", "dep:wgpu"]
|
||||||
wsl = []
|
wsl = []
|
||||||
|
|
|
@ -275,7 +275,7 @@ impl App {
|
||||||
#[cfg(feature = "glow")]
|
#[cfg(feature = "glow")]
|
||||||
if let Some(gl) = &cc.gl {
|
if let Some(gl) = &cc.gl {
|
||||||
use eframe::glow::HasContext;
|
use eframe::glow::HasContext;
|
||||||
app.view_state.graphics_state.active_backend = "OpenGL".to_string();
|
app.view_state.graphics_state.active_backend = "OpenGL (Fallback)".to_string();
|
||||||
app.view_state.graphics_state.active_device =
|
app.view_state.graphics_state.active_device =
|
||||||
unsafe { gl.get_parameter_string(0x1F01) }; // GL_RENDERER
|
unsafe { gl.get_parameter_string(0x1F01) }; // GL_RENDERER
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ mod views;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
process::ExitCode,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
@ -37,7 +38,7 @@ const APP_NAME: &str = "objdiff";
|
||||||
|
|
||||||
// When compiling natively:
|
// When compiling natively:
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
fn main() {
|
fn main() -> ExitCode {
|
||||||
// Log to stdout (if you run with `RUST_LOG=debug`).
|
// Log to stdout (if you run with `RUST_LOG=debug`).
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
|
@ -48,7 +49,6 @@ fn main() {
|
||||||
|
|
||||||
let app_path = std::env::current_exe().ok();
|
let app_path = std::env::current_exe().ok();
|
||||||
let exec_path: Rc<Mutex<Option<PathBuf>>> = Rc::new(Mutex::new(None));
|
let exec_path: Rc<Mutex<Option<PathBuf>>> = Rc::new(Mutex::new(None));
|
||||||
let exec_path_clone = exec_path.clone();
|
|
||||||
let mut native_options =
|
let mut native_options =
|
||||||
eframe::NativeOptions { follow_system_theme: false, ..Default::default() };
|
eframe::NativeOptions { follow_system_theme: false, ..Default::default() };
|
||||||
match load_icon() {
|
match load_icon() {
|
||||||
|
@ -56,7 +56,7 @@ fn main() {
|
||||||
native_options.viewport.icon = Some(Arc::new(data));
|
native_options.viewport.icon = Some(Arc::new(data));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Failed to load application icon: {}", e);
|
log::warn!("Failed to load application icon: {e:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut graphics_config = GraphicsConfig::default();
|
let mut graphics_config = GraphicsConfig::default();
|
||||||
|
@ -69,7 +69,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to load native config: {:?}", e);
|
log::error!("Failed to load native config: {e:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphics_config_path = Some(config_path);
|
graphics_config_path = Some(config_path);
|
||||||
|
@ -87,6 +87,104 @@ fn main() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut eframe_error = None;
|
||||||
|
if let Err(e) = run_eframe(
|
||||||
|
native_options.clone(),
|
||||||
|
utc_offset,
|
||||||
|
exec_path.clone(),
|
||||||
|
app_path.clone(),
|
||||||
|
graphics_config.clone(),
|
||||||
|
graphics_config_path.clone(),
|
||||||
|
) {
|
||||||
|
eframe_error = Some(e);
|
||||||
|
}
|
||||||
|
#[cfg(feature = "wgpu")]
|
||||||
|
if let Some(e) = eframe_error {
|
||||||
|
// Attempt to relaunch using wgpu auto backend if the desired backend failed
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut should_relaunch = graphics_config.desired_backend != GraphicsBackend::Auto;
|
||||||
|
#[cfg(feature = "glow")]
|
||||||
|
{
|
||||||
|
// If the desired backend is OpenGL, we should try to relaunch using the glow renderer
|
||||||
|
should_relaunch &= graphics_config.desired_backend != GraphicsBackend::OpenGL;
|
||||||
|
}
|
||||||
|
if should_relaunch {
|
||||||
|
log::warn!("Failed to launch application: {e:?}");
|
||||||
|
log::warn!("Attempting to relaunch using auto-detected backend");
|
||||||
|
native_options.wgpu_options.supported_backends = Default::default();
|
||||||
|
if let Err(e) = run_eframe(
|
||||||
|
native_options.clone(),
|
||||||
|
utc_offset,
|
||||||
|
exec_path.clone(),
|
||||||
|
app_path.clone(),
|
||||||
|
graphics_config.clone(),
|
||||||
|
graphics_config_path.clone(),
|
||||||
|
) {
|
||||||
|
eframe_error = Some(e);
|
||||||
|
} else {
|
||||||
|
eframe_error = None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eframe_error = Some(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(all(feature = "wgpu", feature = "glow"))]
|
||||||
|
if let Some(e) = eframe_error {
|
||||||
|
// Attempt to relaunch using the glow renderer if the wgpu backend failed
|
||||||
|
log::warn!("Failed to launch application: {e:?}");
|
||||||
|
log::warn!("Attempting to relaunch using fallback OpenGL backend");
|
||||||
|
native_options.renderer = eframe::Renderer::Glow;
|
||||||
|
if let Err(e) = run_eframe(
|
||||||
|
native_options,
|
||||||
|
utc_offset,
|
||||||
|
exec_path.clone(),
|
||||||
|
app_path,
|
||||||
|
graphics_config,
|
||||||
|
graphics_config_path,
|
||||||
|
) {
|
||||||
|
eframe_error = Some(e);
|
||||||
|
} else {
|
||||||
|
eframe_error = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(e) = eframe_error {
|
||||||
|
log::error!("Failed to launch application: {e:?}");
|
||||||
|
return ExitCode::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to relaunch application from the updated path
|
||||||
|
if let Ok(mut guard) = exec_path.lock() {
|
||||||
|
if let Some(path) = guard.take() {
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
let e = exec::Command::new(path)
|
||||||
|
.args(&std::env::args().collect::<Vec<String>>())
|
||||||
|
.exec();
|
||||||
|
log::error!("Failed to relaunch: {e:?}");
|
||||||
|
return ExitCode::FAILURE;
|
||||||
|
} else {
|
||||||
|
let result = std::process::Command::new(path)
|
||||||
|
.args(std::env::args())
|
||||||
|
.spawn();
|
||||||
|
if let Err(e) = result {
|
||||||
|
log::error!("Failed to relaunch: {e:?}");
|
||||||
|
return ExitCode::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ExitCode::SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_eframe(
|
||||||
|
native_options: eframe::NativeOptions,
|
||||||
|
utc_offset: UtcOffset,
|
||||||
|
exec_path_clone: Rc<Mutex<Option<PathBuf>>>,
|
||||||
|
app_path: Option<PathBuf>,
|
||||||
|
graphics_config: GraphicsConfig,
|
||||||
|
graphics_config_path: Option<PathBuf>,
|
||||||
|
) -> Result<(), eframe::Error> {
|
||||||
eframe::run_native(
|
eframe::run_native(
|
||||||
APP_NAME,
|
APP_NAME,
|
||||||
native_options,
|
native_options,
|
||||||
|
@ -101,28 +199,6 @@ fn main() {
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.expect("Failed to run eframe application");
|
|
||||||
|
|
||||||
// Attempt to relaunch application from the updated path
|
|
||||||
if let Ok(mut guard) = exec_path.lock() {
|
|
||||||
if let Some(path) = guard.take() {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(unix)] {
|
|
||||||
let result = exec::Command::new(path)
|
|
||||||
.args(&std::env::args().collect::<Vec<String>>())
|
|
||||||
.exec();
|
|
||||||
log::error!("Failed to relaunch: {result:?}");
|
|
||||||
} else {
|
|
||||||
let result = std::process::Command::new(path)
|
|
||||||
.args(std::env::args())
|
|
||||||
.spawn();
|
|
||||||
if let Err(e) = result {
|
|
||||||
log::error!("Failed to relaunch: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// when compiling to web using trunk.
|
// when compiling to web using trunk.
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub enum GraphicsBackend {
|
||||||
OpenGL,
|
OpenGL,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||||
pub struct GraphicsConfig {
|
pub struct GraphicsConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub desired_backend: GraphicsBackend,
|
pub desired_backend: GraphicsBackend,
|
||||||
|
|
Loading…
Reference in New Issue