use super::{
final_picture::{RenderedImage, render_image_rgba},
types::AccumulationCarry,
};
use crate::{
bridge::export_thread::{
ExportOutcome, ExportProgress, SceneSnapshot,
params::{ExportParams, RemoteSelection},
tonemap_png::save_png,
},
settings::LocalComputeTarget,
};
use indicatrix::{color::ColorSpace, renderer::gpu_backend::GpuBackend};
use std::{path::Path, sync::atomic::AtomicBool};
#[expect(
clippy::too_many_arguments,
reason = "every argument is a distinct piece of one export request's own identity \
(scene, output params/path/color-space, the remote selection, the \
local-compute choice, cancellation, and progress reporting) -- bundling \
them into a struct would just move the same count into field access, \
not reduce it"
)]
pub fn run_export(
scene: &SceneSnapshot,
params: ExportParams,
color_space: ColorSpace,
output_path: &Path,
remote: &RemoteSelection,
local_compute: LocalComputeTarget,
cancel: &AtomicBool,
report_progress: impl FnMut(ExportProgress),
) -> ExportOutcome {
let local_compute = if remote.compute_target.pauses_live_viewport() {
local_compute
} else {
LocalComputeTarget::Cpu
};
let gpu = match local_compute {
LocalComputeTarget::Cpu => GpuBackend::disabled(),
LocalComputeTarget::CpuGpu | LocalComputeTarget::Gpu => GpuBackend::acquire(),
};
let mut carry = AccumulationCarry::default();
let rgba = match render_image_rgba(
scene,
scene.yaw,
scene.pitch,
params,
color_space,
remote,
&gpu,
local_compute,
&mut carry,
cancel,
report_progress,
) {
RenderedImage::Cancelled => return ExportOutcome::Cancelled,
RenderedImage::Failed(message) => return ExportOutcome::Failed(message),
RenderedImage::Rgba(rgba) => rgba,
};
if let Some(parent) = output_path.parent()
&& let Err(e) = std::fs::create_dir_all(parent)
{
return ExportOutcome::Failed(format!("Could not create output directory: {e}"));
}
match save_png(output_path, params.width, params.height, &rgba, color_space) {
Ok(()) => ExportOutcome::Completed(output_path.to_path_buf()),
Err(e) => ExportOutcome::Failed(format!("Failed to write PNG: {e}")),
}
}