Skip to content
Snippets Groups Projects
buffered_display.rs 1.83 KiB
Newer Older
// Uses too much RAM to be useful ):
// 320 * 240 * 2 * 2 bytes/pixel = 307KB of RAM

Stephen D's avatar
Stephen D committed
use core::convert::Infallible;

use embedded_graphics::{
    draw_target::DrawTarget,
    geometry::{Dimensions, Point, Size},
    pixelcolor::{raw::ToBytes, Rgb565},
    primitives::Rectangle,
    Pixel,
};
use crate::{
    app::{HEIGHT, WIDTH},
    drivers::st7789::St7789,
};
pub struct BufferedDisplay {
    target: St7789,
    cur: Option<&'static mut [u8; WIDTH * HEIGHT * 2]>,
}
impl BufferedDisplay {
    pub fn new(target: St7789, cur: &'static mut [u8; WIDTH * HEIGHT * 2]) -> Self {
Stephen D's avatar
Stephen D committed
        Self {
            cur: Some(cur),
    pub fn flush(&mut self) {
        let buf = self.target.write_framebuffer(self.cur.take().unwrap());
        self.cur = Some(buf);
impl Dimensions for BufferedDisplay {
    fn bounding_box(&self) -> Rectangle {
        Rectangle {
            top_left: Point::zero(),
            size: Size::new(WIDTH.try_into().unwrap(), HEIGHT.try_into().unwrap()),
        }
impl DrawTarget for BufferedDisplay {
    type Color = Rgb565;
Stephen D's avatar
Stephen D committed
    type Error = Infallible;

    fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
    where
        I: IntoIterator<Item = embedded_graphics::prelude::Pixel<Self::Color>>,
    {
Stephen D's avatar
Stephen D committed
        for Pixel(p, c) in pixels {
            if let Some(idx) = index(p.x, p.y) {
                let bytes = c.to_be_bytes();
                self.cur.as_mut().unwrap()[idx] = bytes[0];
                self.cur.as_mut().unwrap()[idx + 1] = bytes[1];
Stephen D's avatar
Stephen D committed
            }
        }
Stephen D's avatar
Stephen D committed

Stephen D's avatar
Stephen D committed
        Ok(())
Stephen D's avatar
Stephen D committed
#[inline(always)]
fn index<X: TryInto<usize>, Y: TryInto<usize>>(x: X, y: Y) -> Option<usize> {
Stephen D's avatar
Stephen D committed
    let x: usize = x.try_into().ok()?;
    let y: usize = y.try_into().ok()?;

    if y >= HEIGHT || x >= WIDTH {
Stephen D's avatar
Stephen D committed
        return None;
    Some((x * HEIGHT + y) * 2)