Skip to content

Commit 952b6a6

Browse files
committed
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.
1 parent 09cc995 commit 952b6a6

File tree

4 files changed

+100
-24
lines changed

4 files changed

+100
-24
lines changed

objdiff-gui/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ name = "objdiff"
1818
path = "src/main.rs"
1919

2020
[features]
21-
default = ["wgpu", "wsl"]
21+
default = ["glow", "wgpu", "wsl"]
2222
glow = ["eframe/glow"]
2323
wgpu = ["eframe/wgpu", "dep:wgpu"]
2424
wsl = []

objdiff-gui/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ impl App {
275275
#[cfg(feature = "glow")]
276276
if let Some(gl) = &cc.gl {
277277
use eframe::glow::HasContext;
278-
app.view_state.graphics_state.active_backend = "OpenGL".to_string();
278+
app.view_state.graphics_state.active_backend = "OpenGL (Fallback)".to_string();
279279
app.view_state.graphics_state.active_device =
280280
unsafe { gl.get_parameter_string(0x1F01) }; // GL_RENDERER
281281
}

objdiff-gui/src/main.rs

Lines changed: 97 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod views;
1111

1212
use std::{
1313
path::PathBuf,
14+
process::ExitCode,
1415
rc::Rc,
1516
sync::{Arc, Mutex},
1617
};
@@ -37,7 +38,7 @@ const APP_NAME: &str = "objdiff";
3738

3839
// When compiling natively:
3940
#[cfg(not(target_arch = "wasm32"))]
40-
fn main() {
41+
fn main() -> ExitCode {
4142
// Log to stdout (if you run with `RUST_LOG=debug`).
4243
tracing_subscriber::fmt::init();
4344

@@ -48,15 +49,14 @@ fn main() {
4849

4950
let app_path = std::env::current_exe().ok();
5051
let exec_path: Rc<Mutex<Option<PathBuf>>> = Rc::new(Mutex::new(None));
51-
let exec_path_clone = exec_path.clone();
5252
let mut native_options =
5353
eframe::NativeOptions { follow_system_theme: false, ..Default::default() };
5454
match load_icon() {
5555
Ok(data) => {
5656
native_options.viewport.icon = Some(Arc::new(data));
5757
}
5858
Err(e) => {
59-
log::warn!("Failed to load application icon: {}", e);
59+
log::warn!("Failed to load application icon: {e:?}");
6060
}
6161
}
6262
let mut graphics_config = GraphicsConfig::default();
@@ -69,7 +69,7 @@ fn main() {
6969
}
7070
Ok(None) => {}
7171
Err(e) => {
72-
log::error!("Failed to load native config: {:?}", e);
72+
log::error!("Failed to load native config: {e:?}");
7373
}
7474
}
7575
graphics_config_path = Some(config_path);
@@ -87,42 +87,118 @@ fn main() {
8787
};
8888
}
8989
}
90-
eframe::run_native(
91-
APP_NAME,
92-
native_options,
93-
Box::new(move |cc| {
94-
Box::new(app::App::new(
95-
cc,
90+
let mut eframe_error = None;
91+
if let Err(e) = run_eframe(
92+
native_options.clone(),
93+
utc_offset,
94+
exec_path.clone(),
95+
app_path.clone(),
96+
graphics_config.clone(),
97+
graphics_config_path.clone(),
98+
) {
99+
eframe_error = Some(e);
100+
}
101+
#[cfg(feature = "wgpu")]
102+
if let Some(e) = eframe_error {
103+
// Attempt to relaunch using wgpu auto backend if the desired backend failed
104+
#[allow(unused_mut)]
105+
let mut should_relaunch = graphics_config.desired_backend != GraphicsBackend::Auto;
106+
#[cfg(feature = "glow")]
107+
{
108+
// If the desired backend is OpenGL, we should try to relaunch using the glow renderer
109+
should_relaunch &= graphics_config.desired_backend != GraphicsBackend::OpenGL;
110+
}
111+
if should_relaunch {
112+
log::warn!("Failed to launch application: {e:?}");
113+
log::warn!("Attempting to relaunch using auto-detected backend");
114+
native_options.wgpu_options.supported_backends = Default::default();
115+
if let Err(e) = run_eframe(
116+
native_options.clone(),
96117
utc_offset,
97-
exec_path_clone,
98-
app_path,
99-
graphics_config,
100-
graphics_config_path,
101-
))
102-
}),
103-
)
104-
.expect("Failed to run eframe application");
118+
exec_path.clone(),
119+
app_path.clone(),
120+
graphics_config.clone(),
121+
graphics_config_path.clone(),
122+
) {
123+
eframe_error = Some(e);
124+
} else {
125+
eframe_error = None;
126+
}
127+
} else {
128+
eframe_error = Some(e);
129+
}
130+
}
131+
#[cfg(all(feature = "wgpu", feature = "glow"))]
132+
if let Some(e) = eframe_error {
133+
// Attempt to relaunch using the glow renderer if the wgpu backend failed
134+
log::warn!("Failed to launch application: {e:?}");
135+
log::warn!("Attempting to relaunch using fallback OpenGL backend");
136+
native_options.renderer = eframe::Renderer::Glow;
137+
if let Err(e) = run_eframe(
138+
native_options,
139+
utc_offset,
140+
exec_path.clone(),
141+
app_path,
142+
graphics_config,
143+
graphics_config_path,
144+
) {
145+
eframe_error = Some(e);
146+
} else {
147+
eframe_error = None;
148+
}
149+
}
150+
if let Some(e) = eframe_error {
151+
log::error!("Failed to launch application: {e:?}");
152+
return ExitCode::FAILURE;
153+
}
105154

106155
// Attempt to relaunch application from the updated path
107156
if let Ok(mut guard) = exec_path.lock() {
108157
if let Some(path) = guard.take() {
109158
cfg_if! {
110159
if #[cfg(unix)] {
111-
let result = exec::Command::new(path)
160+
let e = exec::Command::new(path)
112161
.args(&std::env::args().collect::<Vec<String>>())
113162
.exec();
114-
log::error!("Failed to relaunch: {result:?}");
163+
log::error!("Failed to relaunch: {e:?}");
164+
return ExitCode::FAILURE;
115165
} else {
116166
let result = std::process::Command::new(path)
117167
.args(std::env::args())
118168
.spawn();
119169
if let Err(e) = result {
120-
log::error!("Failed to relaunch: {:?}", e);
170+
log::error!("Failed to relaunch: {e:?}");
171+
return ExitCode::FAILURE;
121172
}
122173
}
123174
}
124175
}
125176
};
177+
ExitCode::SUCCESS
178+
}
179+
180+
fn run_eframe(
181+
native_options: eframe::NativeOptions,
182+
utc_offset: UtcOffset,
183+
exec_path_clone: Rc<Mutex<Option<PathBuf>>>,
184+
app_path: Option<PathBuf>,
185+
graphics_config: GraphicsConfig,
186+
graphics_config_path: Option<PathBuf>,
187+
) -> Result<(), eframe::Error> {
188+
eframe::run_native(
189+
APP_NAME,
190+
native_options,
191+
Box::new(move |cc| {
192+
Box::new(app::App::new(
193+
cc,
194+
utc_offset,
195+
exec_path_clone,
196+
app_path,
197+
graphics_config,
198+
graphics_config_path,
199+
))
200+
}),
201+
)
126202
}
127203

128204
// when compiling to web using trunk.

objdiff-gui/src/views/graphics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub enum GraphicsBackend {
3636
OpenGL,
3737
}
3838

39-
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
39+
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
4040
pub struct GraphicsConfig {
4141
#[serde(default)]
4242
pub desired_backend: GraphicsBackend,

0 commit comments

Comments
 (0)