Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
fix: put pixel buffer on heap to prevent stack overflows
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin-Niederman committed Mar 13, 2024
1 parent 528b6a9 commit 12ca546
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 36 deletions.
115 changes: 92 additions & 23 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/pros-graphics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ categories = [
[dependencies]
embedded-graphics-core = "0.4.0"
pros-devices = { version = "0.1.0", path = "../pros-devices" }
pros-sys = { version = "0.7.0", path = "../pros-sys" }

[lints]
workspace = true
44 changes: 31 additions & 13 deletions packages/pros-graphics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! An embedded_graphics driver for VEX V5 Brain displays.
//! Implemented for the [`pros-rs`](https://crates.io/crates/pros) ecosystem and implemented using [pros-devices](https://crates.io/crates/pros-devices).
#![no_std]
#![feature(new_uninit)]

extern crate alloc;

use alloc::boxed::Box;

use embedded_graphics_core::{
draw_target::DrawTarget,
Expand All @@ -14,16 +19,32 @@ use pros_devices::{color::Rgb, Screen};
/// An embedded_graphics driver for the Brain display
pub struct VexDisplay {
screen: Screen,

Check warning on line 21 in packages/pros-graphics/src/lib.rs

View workflow job for this annotation

GitHub Actions / Check

field `screen` is never read
pixel_buffer: [[Rgb; Screen::HORIZONTAL_RESOLUTION as _]; Screen::VERTICAL_RESOLUTION as _],
pixel_buffer:
Box<[u32; Screen::HORIZONTAL_RESOLUTION as usize * Screen::VERTICAL_RESOLUTION as usize]>,
}

impl VexDisplay {
/// Creates a new VexDisplay from a Screen
pub const fn new(screen: Screen) -> Self {
pub fn new(screen: Screen) -> Self {
let pixel_buffer = Box::new_zeroed();
let pixel_buffer = unsafe { pixel_buffer.assume_init() };

Self {
screen,
pixel_buffer: [[Rgb::new(0, 0, 0); Screen::HORIZONTAL_RESOLUTION as _];
Screen::VERTICAL_RESOLUTION as _],
pixel_buffer,
}
}

unsafe fn draw_buffer(&self) {
unsafe {
pros_sys::screen_copy_area(
0,
0,
Screen::HORIZONTAL_RESOLUTION,
Screen::VERTICAL_RESOLUTION,
self.pixel_buffer.as_ptr(),
Screen::HORIZONTAL_RESOLUTION as _,
);
}
}
}
Expand Down Expand Up @@ -62,18 +83,15 @@ impl DrawTarget for VexDisplay {
if !(pos.x > Screen::HORIZONTAL_RESOLUTION as _ || pos.x < 0)
&& !(pos.y > Screen::VERTICAL_RESOLUTION as _ || pos.y < 0)
{
self.pixel_buffer[pos.y as usize][pos.x as usize] = color
// SAFETY: We initialize the buffer with zeroes, so it's safe to assume it's initialized.
self.pixel_buffer[(pos.y as usize * Screen::HORIZONTAL_RESOLUTION as usize)
+ pos.x as usize] = color.into();
}
});

self.screen.draw_buffer(
0,
0,
Screen::HORIZONTAL_RESOLUTION,
Screen::VERTICAL_RESOLUTION,
self.pixel_buffer.clone().into_iter().flatten(),
Screen::HORIZONTAL_RESOLUTION as _,
)?;
unsafe {
self.draw_buffer();
}
Ok(())
}
}

0 comments on commit 12ca546

Please sign in to comment.