From df8b8b427712d31461d3bfb82964b7ed63343e8b Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Mon, 13 Apr 2020 00:25:51 +0200 Subject: [PATCH] Improved demo --- examples/demo/lv_conf.h | 2 +- examples/demo/src/main.rs | 65 ++++++++++++++++++++++++--------------- lvgl-sys/src/bindings.rs | 2 +- lvgl/Cargo.toml | 2 +- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/examples/demo/lv_conf.h b/examples/demo/lv_conf.h index 400ec60..d8e9e57 100644 --- a/examples/demo/lv_conf.h +++ b/examples/demo/lv_conf.h @@ -51,7 +51,7 @@ /* Default display refresh period. * Can be changed in the display driver (`lv_disp_drv_t`).*/ -#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ +#define LV_DISP_DEF_REFR_PERIOD 1 /*[ms]*/ /* Dot Per Inch: used to initialize default sizes. * E.g. a button with width = LV_DPI / 2 -> half inch wide diff --git a/examples/demo/src/main.rs b/examples/demo/src/main.rs index 92bcd5e..5f5b2ed 100644 --- a/examples/demo/src/main.rs +++ b/examples/demo/src/main.rs @@ -12,6 +12,10 @@ use std::time::Duration; fn main() -> Result<(), String> { let sdl_context = sdl2::init()?; let video_subsystem = sdl_context.video()?; + let mut framebuffer = [ + [Color::from((255, 255, 255)); lvgl_sys::LV_VER_RES_MAX as usize]; + lvgl_sys::LV_HOR_RES_MAX as usize + ]; let window = video_subsystem .window( @@ -33,36 +37,25 @@ fn main() -> Result<(), String> { unsafe { lvgl_sys::lv_init(); } - // Create a display buffer for LittlevGL - let mut disp_buf = MaybeUninit::::uninit(); - let mut buf: [MaybeUninit; lvgl_sys::LV_HOR_RES_MAX as usize * 10] = - unsafe { MaybeUninit::uninit().assume_init() }; /*Declare a buffer for 10 lines*/ - unsafe { - // Initialize the display buffer - lvgl_sys::lv_disp_buf_init( - disp_buf.as_mut_ptr(), - buf.as_mut_ptr() as *mut c_void, - std::ptr::null_mut(), - (lvgl_sys::LV_HOR_RES_MAX * 10) as u32, - ); - } // Implement and register a function which can copy a pixel array to an area of your display: let mut display_driver = DisplayDriver::new(move |points, colors| { for (i, point) in points.into_iter().enumerate() { - canvas.set_draw_color(colors[i]); - canvas.draw_point(point).unwrap(); + let color = &mut framebuffer[point.x() as usize][point.y() as usize]; + *color = colors[i].clone(); + } + canvas.clear(); + for (x, line) in framebuffer.iter().enumerate() { + for (y, color) in line.iter().enumerate() { + canvas.set_draw_color(color.clone()); + canvas.draw_point(Point::new(x as i32, y as i32)).unwrap(); + } } canvas.present(); }); - display_driver.raw.buffer = disp_buf.as_mut_ptr(); // Assign the buffer to the display - unsafe { - lvgl_sys::lv_disp_drv_register(&mut display_driver.raw); // Finally register the driver - } - // Create screen and widgets - let mut screen = lvgl::display::get_active_screen(); + let mut screen = display_driver.get_active_screen(); let mut button = lvgl::Button::new(&mut screen); button.set_pos(50, 50); @@ -86,8 +79,7 @@ fn main() -> Result<(), String> { } } - ::std::thread::sleep(Duration::from_millis(300)); - // The rest of the game loop goes here... + ::std::thread::sleep(Duration::from_millis(lvgl_sys::LV_DISP_DEF_REFR_PERIOD as u64)); unsafe { lvgl_sys::lv_task_handler(); @@ -103,6 +95,8 @@ where { pub raw: lvgl_sys::lv_disp_drv_t, callback: F, + display_buffer: MaybeUninit, + refresh_buffer: [MaybeUninit; lvgl_sys::LV_HOR_RES_MAX as usize * 10], } impl DisplayDriver @@ -110,18 +104,41 @@ where F: FnMut(Vec, Vec), { fn new(mut callback: F) -> Self { - let disp_drv = unsafe { + // Create a display buffer for LittlevGL + let mut display_buffer = MaybeUninit::::uninit(); + let mut refresh_buffer: [MaybeUninit; lvgl_sys::LV_HOR_RES_MAX as usize * 10] = + unsafe { MaybeUninit::uninit().assume_init() }; /*Declare a buffer for 10 lines*/ + unsafe { + // Initialize the display buffer + lvgl_sys::lv_disp_buf_init( + display_buffer.as_mut_ptr(), + refresh_buffer.as_mut_ptr() as *mut c_void, + std::ptr::null_mut(), + (lvgl_sys::LV_HOR_RES_MAX * 10) as u32, + ); + } + let mut disp_drv = unsafe { let mut disp_drv = MaybeUninit::::uninit().assume_init(); /*Descriptor of a display driver*/ lvgl_sys::lv_disp_drv_init(&mut disp_drv); // Basic initialization disp_drv.flush_cb = Some(display_callback_wrapper::); // Set your driver function disp_drv.user_data = &mut callback as *mut _ as *mut c_void; disp_drv }; + disp_drv.buffer = display_buffer.as_mut_ptr(); // Assign the buffer to the display + unsafe { + lvgl_sys::lv_disp_drv_register(&mut disp_drv); // Finally register the driver + } Self { raw: disp_drv, callback, + display_buffer, + refresh_buffer, } } + + fn get_active_screen(&mut self) -> lvgl::Object { + lvgl::display::get_active_screen() + } } unsafe extern "C" fn display_callback_wrapper( diff --git a/lvgl-sys/src/bindings.rs b/lvgl-sys/src/bindings.rs index fabe43c..cfc2100 100644 --- a/lvgl-sys/src/bindings.rs +++ b/lvgl-sys/src/bindings.rs @@ -178,7 +178,7 @@ pub const LV_COLOR_16_SWAP: u32 = 0; pub const LV_COLOR_SCREEN_TRANSP: u32 = 0; pub const LV_INDEXED_CHROMA: u32 = 1; pub const LV_ANTIALIAS: u32 = 1; -pub const LV_DISP_DEF_REFR_PERIOD: u32 = 30; +pub const LV_DISP_DEF_REFR_PERIOD: u32 = 1; pub const LV_DPI: u32 = 100; pub const LV_MEM_CUSTOM: u32 = 0; pub const LV_MEM_SIZE: u32 = 131072; diff --git a/lvgl/Cargo.toml b/lvgl/Cargo.toml index 5b34ec3..f1e3bf2 100644 --- a/lvgl/Cargo.toml +++ b/lvgl/Cargo.toml @@ -13,5 +13,5 @@ keywords = ["littlevgl", "lvgl", "graphical_interfaces"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lvgl-sys = "0.1.1" +lvgl-sys = {path="../lvgl-sys", version="0.1.1"} cty = "0.2.1"