use crate::{RafxApiDef, RafxResult};
use raw_window_handle::HasRawWindowHandle;
use std::sync::Arc;
use crate::metal::{RafxDeviceContextMetal, RafxDeviceContextMetalInner};
#[derive(Default)]
pub struct RafxApiDefMetal {
pub enable_debug_names: bool,
}
pub struct RafxApiMetal {
device_context: Option<RafxDeviceContextMetal>,
}
impl Drop for RafxApiMetal {
fn drop(&mut self) {
self.destroy().unwrap();
}
}
impl RafxApiMetal {
pub fn device_context(&self) -> &RafxDeviceContextMetal {
self.device_context.as_ref().unwrap()
}
pub unsafe fn new(
_window: &dyn HasRawWindowHandle,
_api_def: &RafxApiDef,
metal_api_def: &RafxApiDefMetal,
) -> RafxResult<Self> {
let inner = Arc::new(RafxDeviceContextMetalInner::new(metal_api_def)?);
let device_context = RafxDeviceContextMetal::new(inner)?;
Ok(RafxApiMetal {
device_context: Some(device_context),
})
}
pub fn destroy(&mut self) -> RafxResult<()> {
if let Some(device_context) = self.device_context.take() {
let inner = device_context.inner.clone();
#[cfg(debug_assertions)]
#[cfg(feature = "track-device-contexts")]
let _create_index = device_context.create_index;
std::mem::drop(device_context);
let _strong_count = Arc::strong_count(&inner);
match Arc::try_unwrap(inner) {
Ok(inner) => std::mem::drop(inner),
Err(_arc) => {
Err(format!(
"Could not destroy device, {} references to it exist",
_strong_count
))?;
#[cfg(debug_assertions)]
#[cfg(feature = "track-device-contexts")]
{
let mut all_contexts = _arc.all_contexts.lock().unwrap();
all_contexts.remove(&_create_index);
for (k, v) in all_contexts.iter_mut() {
v.resolve();
println!("context allocation: {}\n{:?}", k, v);
}
}
}
}
}
Ok(())
}
}