Revert display buffer allocation to use LVGL backed Box
This commit is contained in:
parent
8b2879f93b
commit
46562f23cf
3 changed files with 31 additions and 40 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue