From 802504ff9dab0e35cf21c3a50a842a8d279f7991 Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Sun, 30 May 2021 00:51:25 +0200 Subject: [PATCH] Use old approach, write directly to DrawTarget --- examples/app.rs | 15 ++++----- lvgl/src/display.rs | 72 +++++++++++++++++++++++++------------------ lvgl/src/functions.rs | 4 +-- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/examples/app.rs b/examples/app.rs index c7119c6..b7acdf6 100644 --- a/examples/app.rs +++ b/examples/app.rs @@ -7,9 +7,10 @@ use lvgl::display::{Display, DisplayBuffer, DisplayDriver}; type ColorSpace = Rgb565; fn main() { - let mut embedded_graphics_display: SimulatorDisplay = SimulatorDisplay::new( - Size::new(lvgl_sys::LV_HOR_RES_MAX, lvgl_sys::LV_VER_RES_MAX), - ); + let embedded_graphics_display: SimulatorDisplay = SimulatorDisplay::new(Size::new( + lvgl_sys::LV_HOR_RES_MAX, + lvgl_sys::LV_VER_RES_MAX, + )); let output_settings = OutputSettingsBuilder::new().scale(2).build(); let mut window = Window::new("App Example", &output_settings); @@ -17,10 +18,6 @@ fn main() { // LVGL usage lvgl::init(); - let mut display_diver: DisplayDriver = - DisplayDriver::new(DisplayBuffer::new(), |pixels| { - // Here we draw to the external display - let _ = embedded_graphics_display.draw_iter(pixels); - }); - let _display = lvgl::disp_drv_register(&mut display_diver).unwrap(); + let mut display_diver = DisplayDriver::new(DisplayBuffer::new(), embedded_graphics_display); + let gui = lvgl::disp_drv_register(&mut display_diver).unwrap(); } diff --git a/lvgl/src/display.rs b/lvgl/src/display.rs index 2efb3d4..335b4e8 100644 --- a/lvgl/src/display.rs +++ b/lvgl/src/display.rs @@ -11,6 +11,7 @@ const REFRESH_BUFFER_LEN: usize = 2; // Declare a buffer for the refresh rate pub(crate) const BUF_SIZE: usize = lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN; +#[derive(Debug, Copy, Clone)] pub enum DisplayError { FailedToRegister, NotRegistered, @@ -61,67 +62,64 @@ impl DisplayBuffer { } #[derive(Copy, Clone)] -pub struct DisplayDriver +pub struct DisplayDriver where + T: DrawTarget, C: PixelColor + From, { pub(crate) disp_drv: lvgl_sys::lv_disp_drv_t, - phantom: PhantomData, + phantom_display: PhantomData, + phantom_color: PhantomData, } -impl DisplayDriver +impl DisplayDriver where + T: DrawTarget, C: PixelColor + From, { - pub fn new(display_buffer: DisplayBuffer, callback: F) -> Self - where - I: IntoIterator>, - F: FnMut(I) + 'static, - { + pub fn new(display_buffer: DisplayBuffer, native_display: T) -> Self { let mut disp_buf = ManuallyDrop::new(display_buffer.disp_buf); - let mut callback = ManuallyDrop::new(callback); + let mut native_display = ManuallyDrop::new(DisplayUserData { + display: native_display, + phantom: PhantomData, + }); let mut disp_drv = unsafe { let mut disp_drv = MaybeUninit::uninit(); lvgl_sys::lv_disp_drv_init(disp_drv.as_mut_ptr()); disp_drv.assume_init() }; disp_drv.buffer = &mut *disp_buf as *mut lvgl_sys::lv_disp_buf_t; - disp_drv.user_data = &mut callback as *mut _ as lvgl_sys::lv_disp_drv_user_data_t; - disp_drv.flush_cb = Some(disp_flush_trampoline::); + disp_drv.user_data = &mut native_display as *mut _ as lvgl_sys::lv_disp_drv_user_data_t; + disp_drv.flush_cb = Some(disp_flush_trampoline::); Self { disp_drv, - phantom: PhantomData, + phantom_color: PhantomData, + phantom_display: PhantomData, } } } -// impl Default for DisplayDriver { -// fn default() -> Self { -// Self::new(DisplayBuffer::new()) -// } -// } - -pub struct DisplayDriverBuilder { - disp_buf: Option, +pub(crate) struct DisplayUserData +where + T: DrawTarget, + C: PixelColor + From, +{ + display: T, + phantom: PhantomData, } -impl DisplayDriverBuilder { - pub fn with_callback() {} -} - -unsafe extern "C" fn disp_flush_trampoline( +unsafe extern "C" fn disp_flush_trampoline( disp_drv: *mut lvgl_sys::lv_disp_drv_t, area: *const lvgl_sys::lv_area_t, color_p: *mut lvgl_sys::lv_color_t, ) where + T: DrawTarget, C: PixelColor + From, - I: IntoIterator>, - F: FnMut(I) + 'static, { let display_driver = *disp_drv; if !display_driver.user_data.is_null() { - let callback = &mut *(display_driver.user_data as *mut F); + let user_data = &mut *(display_driver.user_data as *mut DisplayUserData); let x1 = (*area).x1; let x2 = (*area).x2; let y1 = (*area).y1; @@ -140,11 +138,25 @@ unsafe extern "C" fn disp_flush_trampoline( let color_len = x_len * iy + ix; let lv_color = unsafe { *color_p.add(color_len) }; let raw_color = Color::from_raw(lv_color); - drawable::Pixel(Point::new(x as i32, y as i32), raw_color.into()) + drawable::Pixel::(Point::new(x as i32, y as i32), raw_color.into()) }) }) .flatten(); - callback(pixels); + let _ = user_data.display.draw_iter(pixels); } } + +// impl Default for DisplayDriver { +// fn default() -> Self { +// Self::new(DisplayBuffer::new()) +// } +// } + +pub struct DisplayDriverBuilder { + disp_buf: Option, +} + +impl DisplayDriverBuilder { + pub fn with_callback() {} +} diff --git a/lvgl/src/functions.rs b/lvgl/src/functions.rs index 1a8f242..e942dc1 100644 --- a/lvgl/src/functions.rs +++ b/lvgl/src/functions.rs @@ -4,8 +4,8 @@ use core::ptr::NonNull; use embedded_graphics::drawable; use embedded_graphics::prelude::*; -pub fn disp_drv_register>( - disp_drv: &mut DisplayDriver, +pub fn disp_drv_register, T: DrawTarget>( + disp_drv: &mut DisplayDriver, ) -> Result { let disp_ptr = unsafe { lvgl_sys::lv_disp_drv_register(&mut disp_drv.disp_drv as *mut lvgl_sys::lv_disp_drv_t)