1use alloc::vec::Vec;
4
5use crate::{BackendKind, BackendRequest};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum DecodeStage {
10 Parse,
11 EntropyDecode,
12 InverseScan,
13 CoefficientRemap,
14 DcLowPassPrediction,
15 DequantizeAndFirstInverseTransform,
16 FirstOverlap,
17 HighPassPrediction,
18 SecondInverseTransform,
19 SecondOverlap,
20 ChromaReconstruction,
21 ColorAndAlphaConversion,
22 CropClipAndPack,
23 HostReadback,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub enum StageExecutor {
29 CpuScalar,
30 CpuSimd,
31 Metal,
32 Cuda,
33}
34
35impl StageExecutor {
36 #[must_use]
37 pub const fn backend(self) -> BackendKind {
38 match self {
39 Self::CpuScalar | Self::CpuSimd => BackendKind::Cpu,
40 Self::Metal => BackendKind::Metal,
41 Self::Cuda => BackendKind::Cuda,
42 }
43 }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47pub struct StageReport {
48 pub stage: DecodeStage,
49 pub executor: StageExecutor,
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
54pub enum FallbackReason {
55 WorkloadBelowThreshold,
56 BackendNotCompiled,
57 DeviceUnavailable,
58 UnsupportedFormat,
59 PipelineIncomplete,
60 ResourceLimit,
61}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct DecodeReport {
66 pub requested: BackendRequest,
67 pub selected: BackendKind,
68 pub fallback: Option<FallbackReason>,
69 pub stages: Vec<StageReport>,
70}
71
72impl DecodeReport {
73 #[must_use]
74 pub fn cpu(requested: BackendRequest) -> Self {
75 Self {
76 requested,
77 selected: BackendKind::Cpu,
78 fallback: None,
79 stages: Vec::new(),
80 }
81 }
82
83 #[must_use]
84 pub fn executor_for(&self, stage: DecodeStage) -> Option<StageExecutor> {
85 self.stages
86 .iter()
87 .find(|entry| entry.stage == stage)
88 .map(|entry| entry.executor)
89 }
90}