Revert display buffer allocation to use LVGL backed Box

This commit is contained in:
Rafael Caricio 2020-06-16 23:42:21 +02:00 committed by Rafael Carício
parent 8b2879f93b
commit 46562f23cf
3 changed files with 31 additions and 40 deletions

View file

@ -1,11 +1,12 @@
use cstr_core::CString;
use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::*; use embedded_graphics::prelude::*;
use embedded_graphics_simulator::{ use embedded_graphics_simulator::{
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
}; };
use lvgl::style::Style; use lvgl::style::Style;
use lvgl::widgets::{Arc, ArcPart, Label, LabelAlign}; use lvgl::widgets::{Arc, Label, LabelAlign};
use lvgl::{self, Align, Color, DisplayDriver, Part, State, UI}; use lvgl::{self, Align, Color, Part, State, UI};
use lvgl::{LvError, Widget}; use lvgl::{LvError, Widget};
use lvgl_sys; use lvgl_sys;
use std::sync::{mpsc, Arc as StdArc, Mutex}; use std::sync::{mpsc, Arc as StdArc, Mutex};
@ -13,7 +14,7 @@ use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
fn main() -> Result<(), LvError> { fn main() -> Result<(), LvError> {
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new( let display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(
lvgl_sys::LV_HOR_RES_MAX, lvgl_sys::LV_HOR_RES_MAX,
lvgl_sys::LV_VER_RES_MAX, lvgl_sys::LV_VER_RES_MAX,
)); ));
@ -24,8 +25,7 @@ fn main() -> Result<(), LvError> {
let mut ui = UI::init()?; let mut ui = UI::init()?;
// Implement and register your display: // Implement and register your display:
let display_driver = DisplayDriver::new(&mut display); ui.disp_drv_register(display)?;
ui.disp_drv_register(display_driver);
// Create screen and widgets // Create screen and widgets
let mut screen = ui.scr_act()?; let mut screen = ui.scr_act()?;
@ -43,7 +43,7 @@ fn main() -> Result<(), LvError> {
arc.set_end_angle(135)?; arc.set_end_angle(135)?;
let mut loading_lbl = Label::new(&mut screen)?; let mut loading_lbl = Label::new(&mut screen)?;
loading_lbl.set_text("Loading...")?; loading_lbl.set_text(CString::new("Loading...").unwrap().as_c_str())?;
loading_lbl.set_align(&mut arc, Align::OutTopMid, 0, -10)?; loading_lbl.set_align(&mut arc, Align::OutTopMid, 0, -10)?;
loading_lbl.set_label_align(LabelAlign::Center)?; loading_lbl.set_label_align(LabelAlign::Center)?;
@ -78,11 +78,13 @@ fn main() -> Result<(), LvError> {
arc.set_end_angle(angle + 135)?; arc.set_end_angle(angle + 135)?;
i += 1; i += 1;
sleep(Duration::from_millis(10)); sleep(Duration::from_millis(50));
threaded_ui.lock().unwrap().task_handler(); let mut ui = threaded_ui.lock().unwrap();
ui.task_handler();
window.update(&display); if let Some(disp) = ui.get_display_ref() {
window.update(disp);
}
for event in window.events() { for event in window.events() {
match event { match event {

View file

@ -4,15 +4,15 @@ use embedded_graphics_simulator::{
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
}; };
use lvgl::style::{Opacity, Style}; use lvgl::style::{Opacity, Style};
use lvgl::widgets::{Gauge, GaugePart}; use lvgl::widgets::Gauge;
use lvgl::{self, Align, Color, DisplayDriver, LvError, Part, State, Widget, UI}; use lvgl::{self, Align, Color, LvError, Part, State, Widget, UI};
use lvgl_sys; use lvgl_sys;
use std::sync::{mpsc, Arc, Mutex}; use std::sync::{mpsc, Arc, Mutex};
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
fn main() -> Result<(), LvError> { fn main() -> Result<(), LvError> {
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new( let display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(
lvgl_sys::LV_HOR_RES_MAX, lvgl_sys::LV_HOR_RES_MAX,
lvgl_sys::LV_VER_RES_MAX, lvgl_sys::LV_VER_RES_MAX,
)); ));
@ -23,8 +23,7 @@ fn main() -> Result<(), LvError> {
let mut ui = UI::init()?; let mut ui = UI::init()?;
// Implement and register your display: // Implement and register your display:
let display_driver = DisplayDriver::new(&mut display); ui.disp_drv_register(display)?;
ui.disp_drv_register(display_driver);
// Create screen and widgets // Create screen and widgets
let mut screen = ui.scr_act()?; let mut screen = ui.scr_act()?;
@ -75,9 +74,12 @@ fn main() -> Result<(), LvError> {
let mut i = 0; let mut i = 0;
'running: loop { 'running: loop {
threaded_ui.lock().unwrap().task_handler(); let mut ui = threaded_ui.lock().unwrap();
ui.task_handler();
if let Some(disp) = ui.get_display_ref() {
window.update(disp);
}
window.update(&display);
for event in window.events() { for event in window.events() {
match event { match event {
SimulatorEvent::MouseButtonUp { SimulatorEvent::MouseButtonUp {

View file

@ -1,6 +1,6 @@
use crate::mem::Box;
use crate::{Color, Event, LvError, LvResult, Obj, Widget}; use crate::{Color, Event, LvError, LvResult, Obj, Widget};
use core::marker::PhantomData; use core::marker::PhantomData;
use core::mem;
use core::mem::{ManuallyDrop, MaybeUninit}; use core::mem::{ManuallyDrop, MaybeUninit};
use core::ptr; use core::ptr;
use core::ptr::NonNull; use core::ptr::NonNull;
@ -18,8 +18,6 @@ const REFRESH_BUFFER_LEN: usize = 2;
// Declare a buffer for the refresh rate // Declare a buffer for the refresh rate
const BUF_SIZE: usize = lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN; const BUF_SIZE: usize = lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN;
type RefreshBuffer = [lvgl_sys::lv_color_t; BUF_SIZE];
pub struct UI<T, C> pub struct UI<T, C>
where where
T: DrawTarget<C>, T: DrawTarget<C>,
@ -66,30 +64,19 @@ where
unsafe { unsafe {
// Create a display buffer for LittlevGL // Create a display buffer for LittlevGL
// Never initialized in Rust side (don't call `assume_init`, this is C managed memory)!
let disp_buf = lvgl_sys::lv_mem_alloc(
mem::size_of::<lvgl_sys::lv_disp_buf_t>() as lvgl_sys::size_t
) as *mut lvgl_sys::lv_disp_buf_t;
// Initialize the display buffer // Initialize the display buffer
let buffer_size = mem::size_of::<RefreshBuffer>(); let refresh_buffer1 = [Color::from_rgb((0, 0, 0)).raw; BUF_SIZE];
let buf1 = lvgl_sys::lv_mem_alloc(buffer_size as lvgl_sys::size_t); let refresh_buffer2 = [Color::from_rgb((0, 0, 0)).raw; BUF_SIZE];
if buf1.is_null() {
lvgl_sys::lv_mem_free(disp_buf as *mut cty::c_void); let mut disp_buf = MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit();
return Err(LvError::LvOOMemory);
}
let buf2 = lvgl_sys::lv_mem_alloc(buffer_size as lvgl_sys::size_t);
if buf2.is_null() {
lvgl_sys::lv_mem_free(disp_buf as *mut cty::c_void);
lvgl_sys::lv_mem_free(buf1);
return Err(LvError::LvOOMemory);
}
lvgl_sys::lv_disp_buf_init( lvgl_sys::lv_disp_buf_init(
disp_buf, disp_buf.as_mut_ptr(),
buf1, Box::into_raw(Box::new(refresh_buffer1)?) as *mut cty::c_void,
buf2, Box::into_raw(Box::new(refresh_buffer2)?) as *mut cty::c_void,
lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32, lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32,
); );
let disp_buf = Box::new(disp_buf.assume_init())?;
// Basic initialization of the display driver // Basic initialization of the display driver
let mut disp_drv = MaybeUninit::<lvgl_sys::lv_disp_drv_t>::uninit(); let mut disp_drv = MaybeUninit::<lvgl_sys::lv_disp_drv_t>::uninit();
@ -97,7 +84,7 @@ where
// Since this is C managed memory, we don't want to drop it using Rust, thus `ManuallyDrop` wrapping. // Since this is C managed memory, we don't want to drop it using Rust, thus `ManuallyDrop` wrapping.
let mut disp_drv = ManuallyDrop::new(disp_drv.assume_init()); let mut disp_drv = ManuallyDrop::new(disp_drv.assume_init());
// Assign the buffer to the display // Assign the buffer to the display
disp_drv.buffer = disp_buf; disp_drv.buffer = Box::into_raw(disp_buf);
// Set your driver function // Set your driver function
disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>); disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>);
// TODO: DrawHandler type here // TODO: DrawHandler type here