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}