Skip to main content

motion_core/
pixels.rs

1//! Immutable image sampling contracts, independent of decoding and rendering.
2
3use std::{any::Any, fmt::Debug};
4
5/// Texture reconstruction requested by a drawing command.
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
7pub enum Sampling {
8    /// Nearest base-level texel.
9    Nearest,
10    /// Bilinear base-level reconstruction.
11    Bilinear,
12    /// Bilinear reconstruction between adjacent mip levels.
13    #[default]
14    Trilinear,
15}
16
17/// A predecoded immutable linear-premultiplied image mip chain.
18/// Content owns decoding/storage; backends consume this shared logical contract.
19pub trait ImagePixels: Any + Debug + Send + Sync {
20    /// Base-level width in texels.
21    fn width(&self) -> u32;
22
23    /// Base-level height in texels.
24    fn height(&self) -> u32;
25
26    /// Number of immutable mip levels.
27    fn level_count(&self) -> usize;
28
29    /// Width/height of an existing mip level.
30    fn level_size(&self, level: usize) -> (u32, u32);
31
32    /// One in-bounds finite linear-premultiplied texel.
33    fn texel(&self, level: usize, column: usize, row: usize) -> [f32; 4];
34
35    /// Appends every texel of an existing level in row-major order, four `f32` each.
36    /// Overriding this avoids one dynamic call per texel for backends that upload whole levels.
37    fn extend_level(&self, level: usize, out: &mut Vec<f32>) {
38        let (width, height) = self.level_size(level);
39        out.reserve(width as usize * height as usize * 4);
40        for row in 0..height as usize {
41            for column in 0..width as usize {
42                out.extend(self.texel(level, column, row));
43            }
44        }
45    }
46
47    /// Whether another implementation owns the same immutable pixel content.
48    fn content_eq(&self, other: &dyn ImagePixels) -> bool;
49
50    /// Concrete storage identity, resolved only by its owning content implementation.
51    fn as_any(&self) -> &dyn Any;
52}