Files
renderbug-bike/src/tasks/oled_render.rs

43 lines
1.7 KiB
Rust

use display_interface::DisplayError;
use embassy_time::{Duration, Instant, Timer};
use embedded_graphics::{pixelcolor::BinaryColor, prelude::DrawTarget};
use figments::render::RenderSource;
use figments_render::output::OutputAsync;
use log::*;
use crate::{backoff::Backoff, graphics::ssd1306::SsdOutput, tasks::oled::{LockedUniforms, OledUiSurfacePool}};
#[embassy_executor::task]
pub async fn oled_render(mut output: SsdOutput, mut surfaces: OledUiSurfacePool, uniforms: LockedUniforms) {
warn!("Starting OLED rendering task");
Backoff::from_secs(1).forever().attempt::<_, (), DisplayError>(async || {
const FPS: u64 = 30;
const RENDER_BUDGET: Duration = Duration::from_millis(1000 / FPS);
const ANIMATION_TPS: u64 = 30;
const ANIMATION_FRAME_TIME: Duration = Duration::from_millis(1000 / ANIMATION_TPS);
info!("Starting Oled display driver");
output.init().await?;
loop {
let start = Instant::now();
surfaces.commit();
{
let mut locked = uniforms.lock().await;
output.clear(BinaryColor::Off).unwrap();
locked.frame = (Instant::now().as_millis() / ANIMATION_FRAME_TIME.as_millis()) as usize;
locked.current_screen.render_to(&mut output, &locked);
surfaces.render_to(&mut output, &locked);
}
output.commit_async().await?;
let frame_time = Instant::now() - start;
if frame_time < RENDER_BUDGET {
Timer::after(RENDER_BUDGET - frame_time).await;
} else {
//warn!("OLED Frame took too long to render! {}ms", frame_time.as_millis());
}
}
}).await.unwrap();
}