use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use teksilo_canvas::live_image::internal::DeviceTextures;
#[derive(Clone, Debug)]
pub struct DeviceHealth {
lost: Arc<AtomicBool>,
live_textures: DeviceTextures<wgpu::Texture>,
}
impl DeviceHealth {
pub fn install(device: &wgpu::Device) -> Self {
let health = Self {
lost: Arc::new(AtomicBool::new(false)),
live_textures: DeviceTextures::new(),
};
let lost = health.lost.clone();
device.set_device_lost_callback(move |reason, message| {
if reason == wgpu::DeviceLostReason::Destroyed {
return;
}
if !lost.swap(true, Ordering::AcqRel) {
eprintln!(
"teksilo-render: the GPU device was lost ({message}): nothing more reaches \
the screen, and live images stop counting frames"
);
}
});
health
}
pub fn is_lost(&self) -> bool {
self.lost.load(Ordering::Acquire)
}
pub(crate) fn live_textures(&self) -> &DeviceTextures<wgpu::Texture> {
&self.live_textures
}
pub fn same_device(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.lost, &other.lost)
}
#[doc(hidden)]
pub fn mark_lost_for_testing(&self) {
self.lost.store(true, Ordering::Release);
}
}