use super::{DecompositionStorage, OutputRegion, TileDecodeContext};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum CpuDecodeParallelism {
#[default]
Auto,
Serial,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct DecoderWorkspaceStats {
decode_calls: u64,
component_owner_reuses: u64,
tier1_owner_reuses: u64,
idwt_owner_reuses: u64,
scratch_capacity_retries: u64,
retained_component_bytes: usize,
retained_tier1_bytes: usize,
retained_idwt_bytes: usize,
}
impl DecoderWorkspaceStats {
#[must_use]
pub const fn decode_calls(self) -> u64 {
self.decode_calls
}
#[must_use]
pub const fn component_owner_reuses(self) -> u64 {
self.component_owner_reuses
}
#[must_use]
pub const fn tier1_owner_reuses(self) -> u64 {
self.tier1_owner_reuses
}
#[must_use]
pub const fn idwt_owner_reuses(self) -> u64 {
self.idwt_owner_reuses
}
#[must_use]
pub const fn scratch_capacity_retries(self) -> u64 {
self.scratch_capacity_retries
}
#[must_use]
pub const fn retained_component_bytes(self) -> usize {
self.retained_component_bytes
}
#[must_use]
pub const fn retained_tier1_bytes(self) -> usize {
self.retained_tier1_bytes
}
#[must_use]
pub const fn retained_idwt_bytes(self) -> usize {
self.retained_idwt_bytes
}
#[must_use]
pub const fn retained_scratch_bytes(self) -> usize {
self.retained_tier1_bytes
.saturating_add(self.retained_idwt_bytes)
}
}
#[derive(Default)]
pub struct DecoderWorkspace {
tile_decode_context: TileDecodeContext,
pub(super) cpu_decode_parallelism: CpuDecodeParallelism,
stats: DecoderWorkspaceStats,
}
impl DecoderWorkspace {
#[must_use]
pub const fn stats(&self) -> DecoderWorkspaceStats {
self.stats
}
}
pub struct DecoderContext<'a> {
pub(crate) tile_decode_context: TileDecodeContext,
pub(crate) storage: DecompositionStorage<'a>,
pub(super) cpu_decode_parallelism: CpuDecodeParallelism,
workspace_stats: DecoderWorkspaceStats,
}
impl Default for DecoderContext<'_> {
fn default() -> Self {
Self {
tile_decode_context: TileDecodeContext::default(),
storage: DecompositionStorage::default(),
cpu_decode_parallelism: CpuDecodeParallelism::Auto,
workspace_stats: DecoderWorkspaceStats::default(),
}
}
}
impl DecoderContext<'_> {
#[must_use]
pub fn from_workspace(workspace: DecoderWorkspace) -> Self {
Self {
tile_decode_context: workspace.tile_decode_context,
storage: DecompositionStorage::default(),
cpu_decode_parallelism: workspace.cpu_decode_parallelism,
workspace_stats: workspace.stats,
}
}
#[must_use]
pub fn into_workspace(mut self) -> DecoderWorkspace {
self.storage.release_all_allocations();
DecoderWorkspace {
tile_decode_context: self.tile_decode_context,
cpu_decode_parallelism: self.cpu_decode_parallelism,
stats: self.workspace_stats,
}
}
#[must_use]
pub const fn workspace_stats(&self) -> DecoderWorkspaceStats {
self.workspace_stats
}
pub(super) fn record_decode_start(
&mut self,
retained_component_bytes: usize,
retained_tier1_bytes: usize,
retained_idwt_bytes: usize,
) {
self.workspace_stats.decode_calls = self.workspace_stats.decode_calls.saturating_add(1);
if retained_component_bytes != 0 {
self.workspace_stats.component_owner_reuses = self
.workspace_stats
.component_owner_reuses
.saturating_add(1);
}
if retained_tier1_bytes != 0 {
self.workspace_stats.tier1_owner_reuses =
self.workspace_stats.tier1_owner_reuses.saturating_add(1);
}
if retained_idwt_bytes != 0 {
self.workspace_stats.idwt_owner_reuses =
self.workspace_stats.idwt_owner_reuses.saturating_add(1);
}
}
pub(super) fn record_scratch_capacity_retry(&mut self) {
self.workspace_stats.scratch_capacity_retries = self
.workspace_stats
.scratch_capacity_retries
.saturating_add(1);
}
pub(super) fn record_decode_complete(
&mut self,
retained_component_bytes: usize,
retained_tier1_bytes: usize,
retained_idwt_bytes: usize,
) {
self.workspace_stats.retained_component_bytes = retained_component_bytes;
self.workspace_stats.retained_tier1_bytes = retained_tier1_bytes;
self.workspace_stats.retained_idwt_bytes = retained_idwt_bytes;
}
pub(crate) fn release_reusable_allocations(&mut self) {
self.tile_decode_context.release_all_allocations();
self.storage.release_all_allocations();
}
pub(crate) fn set_output_region(&mut self, output_region: Option<(u32, u32, u32, u32)>) {
self.tile_decode_context.output_region = output_region.map(OutputRegion::from_tuple);
}
#[must_use]
pub fn cpu_decode_parallelism(&self) -> CpuDecodeParallelism {
self.cpu_decode_parallelism
}
pub fn set_cpu_decode_parallelism(&mut self, parallelism: CpuDecodeParallelism) {
self.cpu_decode_parallelism = parallelism;
}
}