Skip to main content

ass_renderer/debug/
util.rs

1//! Frame helper utilities for the debug renderer.
2//!
3//! Low-level helpers used by [`DebugRenderer`](crate::debug::DebugRenderer) to checksum frame
4//! buffers, persist frames as PNG files, and draw debugging overlays.
5
6use crate::{Frame, RenderError};
7
8#[cfg(feature = "nostd")]
9extern crate alloc;
10#[cfg(feature = "nostd")]
11use alloc::{format, vec::Vec};
12
13pub(crate) fn calculate_checksum(pixels: &[u8]) -> u64 {
14    #[cfg(not(feature = "nostd"))]
15    use std::collections::hash_map::DefaultHasher;
16    #[cfg(not(feature = "nostd"))]
17    use std::hash::{Hash, Hasher};
18
19    #[cfg(feature = "nostd")]
20    use core::hash::{Hash, Hasher};
21    #[cfg(feature = "nostd")]
22    struct DefaultHasher(u64);
23
24    #[cfg(feature = "nostd")]
25    impl DefaultHasher {
26        fn new() -> Self {
27            DefaultHasher(0)
28        }
29        fn finish(&self) -> u64 {
30            self.0
31        }
32    }
33
34    #[cfg(feature = "nostd")]
35    impl Hasher for DefaultHasher {
36        fn write(&mut self, bytes: &[u8]) {
37            for &b in bytes {
38                self.0 = self.0.wrapping_mul(31).wrapping_add(b as u64);
39            }
40        }
41
42        fn finish(&self) -> u64 {
43            self.0
44        }
45    }
46
47    let mut hasher = DefaultHasher::new();
48    pixels.hash(&mut hasher);
49    hasher.finish()
50}
51
52pub(crate) fn save_frame_as_png(frame: &Frame, path: &str) -> Result<(), RenderError> {
53    #[cfg(feature = "image")]
54    {
55        use image::{ImageBuffer, Rgba};
56
57        let img = ImageBuffer::<Rgba<u8>, Vec<u8>>::from_raw(
58            frame.width(),
59            frame.height(),
60            frame.pixels().to_vec(),
61        )
62        .ok_or_else(|| RenderError::BackendError("Failed to create image buffer".into()))?;
63
64        img.save(path)
65            .map_err(|e| RenderError::BackendError(format!("Failed to save PNG: {e}")))?;
66    }
67
68    #[cfg(not(feature = "image"))]
69    {
70        let _ = (frame, path);
71        // Silent no-op if image feature is not enabled
72    }
73
74    Ok(())
75}
76
77pub(crate) fn draw_rectangle(
78    frame: &mut Frame,
79    x: u32,
80    y: u32,
81    width: u32,
82    height: u32,
83    color: [u8; 4],
84) -> Result<(), RenderError> {
85    // TODO: Implement rectangle drawing
86    let _ = (frame, x, y, width, height, color);
87    Ok(())
88}
89
90pub(crate) fn draw_text_overlay(
91    frame: &mut Frame,
92    text: &str,
93    x: u32,
94    y: u32,
95) -> Result<(), RenderError> {
96    // TODO: Implement text overlay
97    let _ = (frame, text, x, y);
98    Ok(())
99}