Improve refresh performance

This commit is contained in:
Rafael Caricio 2020-05-31 00:06:28 +02:00
parent 9f1be5b1f4
commit e6140c55c8
2 changed files with 35 additions and 29 deletions

View file

@ -34,6 +34,7 @@ fn main() -> Result<(), String> {
let mut screen_style = lvgl::Style::new();
screen_style.set_body_main_color(lvgl::Color::from_rgb((0, 0, 0)));
screen_style.set_body_grad_color(lvgl::Color::from_rgb((0, 0, 0)));
screen_style.set_body_radius(0);
screen.set_style(screen_style);
let mut time = lvgl::Label::new(&mut screen);
@ -72,7 +73,7 @@ fn main() -> Result<(), String> {
let (stop_ch, read_ch) = mpsc::channel();
let closure_ui = threaded_ui.clone();
let tick_thr = std::thread::spawn(move || loop {
let period = Duration::from_millis(5);
let period = Duration::from_millis(250);
closure_ui.lock().unwrap().tick_inc(period);
sleep(period);

View file

@ -1,6 +1,5 @@
use crate::Color;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::mem::MaybeUninit;
use embedded_graphics;
use embedded_graphics::prelude::*;
@ -23,22 +22,28 @@ impl DisplayDriver {
Box::new(MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit().assume_init());
// Declare a buffer for the refresh rate
let refresh_buffer =
Box::new(
MaybeUninit::<
[MaybeUninit<lvgl_sys::lv_color_t>; lvgl_sys::LV_HOR_RES_MAX as usize],
>::uninit()
.assume_init(),
);
let refresh_buffer_len = refresh_buffer.len();
const REFRESH_BUFFER_LEN: usize = 2;
let refresh_buffer1 = Box::new(
MaybeUninit::<
[MaybeUninit<lvgl_sys::lv_color_t>;
lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN],
>::uninit()
.assume_init(),
);
let refresh_buffer2 = Box::new(
MaybeUninit::<
[MaybeUninit<lvgl_sys::lv_color_t>;
lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN],
>::uninit()
.assume_init(),
);
// Initialize the display buffer
lvgl_sys::lv_disp_buf_init(
display_buffer.as_mut(),
Box::into_raw(refresh_buffer) as *mut cty::c_void,
core::ptr::null_mut(),
refresh_buffer_len as u32,
Box::into_raw(refresh_buffer1) as *mut cty::c_void,
Box::into_raw(refresh_buffer2) as *mut cty::c_void,
lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32,
);
// Descriptor of a display driver
@ -92,26 +97,26 @@ unsafe extern "C" fn display_callback_wrapper<T, C>(
{
// We need to make sure panics can't escape across the FFI boundary.
//let _ = std::panic::catch_unwind(|| {
let mut i = 0;
let display_driver = *disp_drv;
// Rust code closure reference
let device = &mut *(display_driver.user_data as *mut T);
// TODO: create a fixed image buffer iterator somehow, maybe a fixed size array
let mut image_buffer = Vec::new();
for y in (*area).y1..=(*area).y2 {
for x in (*area).x1..=(*area).x2 {
let raw_color = Color::from_raw(*color_p.add(i));
i = i + 1;
image_buffer.push(drawable::Pixel(
Point::new(x as i32, y as i32),
raw_color.into(),
));
}
}
let _ = device.draw_iter(image_buffer.into_iter());
let ys = (*area).y1..=(*area).y2;
let xs = ((*area).x1..=(*area).x2).enumerate();
let x_len = ((*area).x2 - (*area).x1 + 1) as usize;
let pixels = ys
.enumerate()
.map(|(iy, y)| {
xs.clone().map(move |(ix, x)| {
let color_len = x_len * iy + ix;
let raw_color = Color::from_raw(*color_p.add(color_len));
drawable::Pixel(Point::new(x as i32, y as i32), raw_color.into())
})
})
.flatten();
// TODO: Maybe find a way to use `draw_image` method on the device instance.
let _ = device.draw_iter(pixels.into_iter());
// Indicate to LittlevGL that you are ready with the flushing
lvgl_sys::lv_disp_flush_ready(disp_drv);