From 20c22260a66b9ab5d197580f77e4b106a52afc5e Mon Sep 17 00:00:00 2001 From: Theo Hussey Date: Thu, 19 Dec 2019 14:49:16 +0000 Subject: [PATCH] buffer contiguous pixels before sending to dislay for speed boost --- src/lib.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 87041a1..03d35ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ const HEIGHT: usize = 320; #[derive(Debug)] pub enum Error { Spi(SpiE), - OutputPin(PinE) + OutputPin(PinE), } /// The default orientation is Portrait @@ -68,7 +68,6 @@ where DC: OutputPin, RESET: OutputPin, { - pub fn new>( spi: SPI, cs: CS, @@ -126,7 +125,10 @@ where Ok(ili9341) } - fn hard_reset>(&mut self, delay: &mut DELAY) -> Result<(), Error> { + fn hard_reset>( + &mut self, + delay: &mut DELAY, + ) -> Result<(), Error> { // set high if previously low self.reset.set_high().map_err(Error::OutputPin)?; delay.delay_ms(200); @@ -150,7 +152,10 @@ where self.cs.set_high().map_err(Error::OutputPin)?; Ok(()) } - fn write_iter>(&mut self, data: I) -> Result<(), Error> { + fn write_iter>( + &mut self, + data: I, + ) -> Result<(), Error> { self.cs.set_low().map_err(Error::OutputPin)?; self.dc.set_low().map_err(Error::OutputPin)?; @@ -294,22 +299,78 @@ where SpiE: Debug, PinE: Debug, { - fn draw(&mut self, item_pixels: T) where T: IntoIterator>, { - for Pixel(pos, color) in item_pixels { - use embedded_graphics::pixelcolor::raw::RawData; + const BUF_SIZE: usize = 64; - self.draw_raw( - pos.x as u16, - pos.y as u16, - pos.x as u16, - pos.y as u16, - &embedded_graphics::pixelcolor::raw::RawU16::from(color) + let mut row: [u8; BUF_SIZE] = [0; BUF_SIZE]; + let mut i = 0; + let mut lasty = 0; + let mut startx = 0; + let mut endx = 0; + let width = self.width as i32; + let height = self.height as i32; + + // Filter out pixels that are off the screen + let on_screen_pixels = item_pixels.into_iter().filter(|drawable::Pixel(point, _)| { + point.x >= 0 && point.y >= 0 && point.x < width && point.y < height + }); + + for Pixel(pos, color) in on_screen_pixels { + use embedded_graphics::pixelcolor::raw::RawData; + // Check if pixel is contiguous with previous pixel + if i == 0 || (pos.y == lasty && (pos.x == endx + 1) && i < BUF_SIZE - 1) { + if i == 0 { + // New line of pixels + startx = pos.x; + } + // Add pixel color to buffer + for b in embedded_graphics::pixelcolor::raw::RawU16::from(color) .into_inner() - .to_be_bytes(), + .to_be_bytes() + .iter() + { + row[i] = *b; + i += 1; + } + lasty = pos.y; + endx = pos.x; + } else { + // Line of contiguous pixels has ended, so draw it now + self.draw_raw( + startx as u16, + lasty as u16, + endx as u16, + lasty as u16, + &row[0..i], + ) + .expect("Failed to communicate with device"); + + // Start new line of contiguous pixels + i = 0; + startx = pos.x; + for b in embedded_graphics::pixelcolor::raw::RawU16::from(color) + .into_inner() + .to_be_bytes() + .iter() + { + row[i] = *b; + i += 1; + } + lasty = pos.y; + endx = pos.x; + } + } + if i > 0 { + // Draw remaining pixels in buffer + self.draw_raw( + startx as u16, + lasty as u16, + endx as u16, + lasty as u16, + &row[0..i], ) .expect("Failed to communicate with device"); }