use alloc::vec::Vec;
use crate::{BackendKind, BackendRequest};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DecodeStage {
Parse,
EntropyDecode,
InverseScan,
CoefficientRemap,
DcLowPassPrediction,
DequantizeAndFirstInverseTransform,
FirstOverlap,
HighPassPrediction,
SecondInverseTransform,
SecondOverlap,
ChromaReconstruction,
ColorAndAlphaConversion,
CropClipAndPack,
HostReadback,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum StageExecutor {
CpuScalar,
CpuSimd,
Metal,
Cuda,
}
impl StageExecutor {
#[must_use]
pub const fn backend(self) -> BackendKind {
match self {
Self::CpuScalar | Self::CpuSimd => BackendKind::Cpu,
Self::Metal => BackendKind::Metal,
Self::Cuda => BackendKind::Cuda,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StageReport {
pub stage: DecodeStage,
pub executor: StageExecutor,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FallbackReason {
WorkloadBelowThreshold,
BackendNotCompiled,
DeviceUnavailable,
UnsupportedFormat,
PipelineIncomplete,
ResourceLimit,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DecodeReport {
pub requested: BackendRequest,
pub selected: BackendKind,
pub fallback: Option<FallbackReason>,
pub stages: Vec<StageReport>,
}
impl DecodeReport {
#[must_use]
pub fn cpu(requested: BackendRequest) -> Self {
Self {
requested,
selected: BackendKind::Cpu,
fallback: None,
stages: Vec::new(),
}
}
#[must_use]
pub fn executor_for(&self, stage: DecodeStage) -> Option<StageExecutor> {
self.stages
.iter()
.find(|entry| entry.stage == stage)
.map(|entry| entry.executor)
}
}