43 lines
1.7 KiB
Rust
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();
|
|
}
|