Start with HDR off after a start that died switching it on

HDR output now writes horizon-hdr-pending before it is switched on and removes it after the first presented HDR frame. A start that finds the file turns hdr off in horizon-graphics.txt and logs it, so a native crash in HDR output costs one start, not every start.
This commit is contained in:
Kacpherek committed 2026-10-27 22:02:16 +01:00
1 parent b8f0cde900
commit dddcc99726
3 files changed
+33 -3

No files matched your search

@@ -273,6 +273,7 @@ impl Game<'_> {
s.horizon.hdr,
s.horizon.hdr_paper_white as f32,
s.horizon.hdr_peak as f32,
&Self::options_path().with_file_name(horizon_client::graphics::HDR_MARKER),
);
}
// Window.updateFullscreenIfChanged: only a changed option asks the
+19 -1
View File
@@ -537,6 +537,9 @@ pub struct Renderer {
hdr: Option<hdr::Hdr>,
/// The HDR output the window's surface can present.
hdr_output: Option<hdr::Output>,
/// The marker file of an HDR output that has not presented a frame yet
/// (`graphics::HDR_MARKER`).
hdr_marker: Option<std::path::PathBuf>,
/// The shader pack's post-processing, and the dimension (legacy id) it was loaded for.
pack_post: Option<(i32, Option<pack_post::PackPost>)>,
/// The post passes of one of Horizon's own shader packs; never beside `pack_post`'s.
@@ -2642,6 +2645,7 @@ impl Renderer {
world_post,
hdr: None,
hdr_output,
hdr_marker: None,
pack_post: None,
native: None,
pass_timing: pack_timing::PassTiming::logging(),
@@ -3200,9 +3204,17 @@ impl Renderer {
}
/// HDR output (Horizon setting): HDR10 or scRGB at `paper_white` nits, the world's
/// highlights expanded up to `peak` nits. Off where the surface can't present it.
pub fn set_hdr(&mut self, on: bool, paper_white: f32, peak: f32) {
pub fn set_hdr(&mut self, on: bool, paper_white: f32, peak: f32, marker: &std::path::Path) {
let output = self.hdr_output.filter(|_| on && self.surface.is_some());
if output.is_some() != self.hdr.is_some() {
// If the game dies before HDR output shows a frame, the marker is still there at
// the next start, which then comes up with HDR off.
if output.is_some() {
let _ = std::fs::write(marker, "HDR output was being switched on\n");
self.hdr_marker = Some(marker.to_owned());
} else if let Some(marker) = self.hdr_marker.take() {
let _ = std::fs::remove_file(marker);
}
let format = self.config.format.remove_srgb_suffix();
self.hdr = output.map(|output| hdr::Hdr::new(&self.device, format, output));
self.configure_surface();
@@ -5229,6 +5241,12 @@ impl Renderer {
startup_step(format_args!("presenting the first frame"));
}
self.queue.present(surface_frame);
if self.hdr.is_some()
&& let Some(marker) = self.hdr_marker.take()
{
let _ = std::fs::remove_file(marker);
log::info!("Horizon renderer: HDR output presented its first frame");
}
if reconfigure && let Some(surface) = &self.surface {
Self::configure(
&self.device,
+13 -2
View File
@@ -5,6 +5,9 @@
use std::{fs, path::Path};
pub const FILE: &str = "horizon-graphics.txt";
/// Written beside it before HDR output is switched on and removed once the first HDR frame is
/// presented. Found at the next start, it means HDR output took the game down, so HDR starts off.
pub const HDR_MARKER: &str = "horizon-hdr-pending";
/// Simple-level presets. `Custom` leaves every option as the player set it.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
@@ -310,9 +313,17 @@ fn bool_text(v: bool) -> &'static str {
}
impl Graphics {
pub fn load(dir: &Path) -> Self {
fs::read_to_string(dir.join(FILE))
let mut g: Self = fs::read_to_string(dir.join(FILE))
.map(|t| Self::parse(&t))
.unwrap_or_default()
.unwrap_or_default();
if fs::remove_file(dir.join(HDR_MARKER)).is_ok() && g.hdr {
g.hdr = false;
g.save(dir);
log::warn!(
"the last start ended before HDR output showed a frame; HDR is off now (graphics option hdr, in {FILE})"
);
}
g
}
pub fn parse(text: &str) -> Self {
let mut g = Self::default();