diff --git a/abi/src/lib.rs b/abi/src/lib.rs index e8b4f40..f549a93 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -65,8 +65,9 @@ pub mod display { abi_sys::lock_display(lock); } - const BUF_SIZE: usize = 250 * 1024; // tune this for performance + // const BUF_SIZE: usize = 15 * 1024; // tune this for performance // static mut BUF: [CPixel; BUF_SIZE] = [CPixel::new(); BUF_SIZE]; + const BUF_SIZE: usize = 250 * 1024; // tune this for performance static mut BUF: Lazy> = Lazy::new(|| vec![const { CPixel::new() }; BUF_SIZE]); pub struct Display; diff --git a/kernel/pimoroni2w.x b/kernel/pimoroni2w.x index 56e741f..a8beacb 100644 --- a/kernel/pimoroni2w.x +++ b/kernel/pimoroni2w.x @@ -2,7 +2,7 @@ MEMORY { FLASH : ORIGIN = 0x10000000, LENGTH = 16M - 4K RAM : ORIGIN = 0x20000000, LENGTH = 512K - SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K + # SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K SRAM5 : ORIGIN = 0x20081000, LENGTH = 4K } diff --git a/kernel/src/display.rs b/kernel/src/display.rs index 8269e85..a30c2ba 100644 --- a/kernel/src/display.rs +++ b/kernel/src/display.rs @@ -1,6 +1,6 @@ +use crate::framebuffer::{self, AtomicFrameBuffer}; +use alloc::vec; use core::sync::atomic::{AtomicBool, Ordering}; - -use crate::framebuffer::AtomicFrameBuffer; use embassy_rp::{ Peri, gpio::{Level, Output}, @@ -44,6 +44,10 @@ pub async fn init_display( unsafe { FRAMEBUFFER.draw(&mut display).await.unwrap() } display.set_on().await.unwrap(); + // create double buffer if board has psram + #[cfg(feature = "pimoroni2w")] + framebuffer::init_double_buffer(); + display } @@ -59,6 +63,13 @@ pub async fn display_handler(mut display: DISPLAY) { } } - Timer::after_millis(10).await; + // Only do swap if feature enabled + #[cfg(feature = "pimoroni2w")] + { + framebuffer::swap_buffers(); + } + + // small yield to allow other tasks to run + Timer::after_nanos(100).await; } } diff --git a/kernel/src/framebuffer.rs b/kernel/src/framebuffer.rs index b72d94d..63f9ce8 100644 --- a/kernel/src/framebuffer.rs +++ b/kernel/src/framebuffer.rs @@ -26,6 +26,24 @@ const SIZE: usize = SCREEN_HEIGHT * SCREEN_WIDTH; static mut BUFFER: [u16; SIZE] = [0; SIZE]; +#[cfg(feature = "pimoroni2w")] +static mut DOUBLE_BUFFER: Option> = None; + +#[cfg(feature = "pimoroni2w")] +pub fn init_double_buffer() { + unsafe { DOUBLE_BUFFER = Some(alloc::vec![0_u16; SIZE]) }; +} + +#[cfg(feature = "pimoroni2w")] +pub fn swap_buffers() { + unsafe { + core::mem::swap( + &mut BUFFER[..].as_mut_ptr(), + &mut DOUBLE_BUFFER.as_mut().unwrap().as_mut_slice().as_mut_ptr(), + ); + } +} + static mut DIRTY_TILES: LazyLock> = LazyLock::new(|| { let mut tiles = Vec::new(); for _ in 0..TILE_COUNT { diff --git a/user-apps/gif/src/main.rs b/user-apps/gif/src/main.rs index edeba0c..25a6d3a 100644 --- a/user-apps/gif/src/main.rs +++ b/user-apps/gif/src/main.rs @@ -37,7 +37,7 @@ pub fn main() { let gif = Gif::::from_slice(&buf).unwrap(); - let mut frame_num = 0; + // let mut frame_num = 0; loop { for frame in gif.frames() { let start = get_ms(); @@ -46,18 +46,19 @@ pub fn main() { frame.draw(&mut display).unwrap(); lock_display(false); - frame_num += 1; - print!("drew {}", frame_num); + // frame_num += 1; sleep(((frame.delay_centis as u64) * 10).saturating_sub(start)); - let event = get_key(); - if event.state != KeyState::Idle { - match event.key { - KeyCode::Esc => return, - _ => (), - }; - }; + // if frame_num % 100 == 0 { + // let event = get_key(); + // if event.state != KeyState::Idle { + // match event.key { + // KeyCode::Esc => return, + // _ => (), + // }; + // }; + // } } } }