refactor(platform): remove lvgl dependency from screen preview

This commit is contained in:
admin
2026-03-01 12:59:39 +08:00
parent dd108e2658
commit e553cf7835
5 changed files with 42 additions and 182 deletions

View File

@@ -15,6 +15,8 @@ idf_component_register(
"include"
PRIV_INCLUDE_DIRS
"internal"
PRIV_REQUIRES
esp_timer
REQUIRES
esp_wifi
esp_netif
@@ -25,7 +27,6 @@ idf_component_register(
esp_adc
esp_driver_gpio
esp_driver_spi
lvgl
espressif__libpng
espressif__button
esp_codec_dev

View File

@@ -8,7 +8,6 @@
#include "esp_check.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "lvgl.h"
#include "png.h"
static const char *TAG = "lcd_png_dec";
@@ -23,6 +22,13 @@ static void lcd_fill_err(char *err, size_t err_len, const char *msg)
}
}
static inline uint16_t lcd_rgb888_to_rgb565(uint8_t r, uint8_t g, uint8_t b)
{
return (uint16_t)((((uint16_t)r & 0xF8u) << 8) |
(((uint16_t)g & 0xFCu) << 3) |
(((uint16_t)b & 0xF8u) >> 3));
}
esp_err_t platform_lcd_decode_png_rgb565(const uint8_t *png,
size_t png_len,
uint16_t **out_pixels,
@@ -102,8 +108,7 @@ esp_err_t platform_lcd_decode_png_rgb565(const uint8_t *png,
g = (uint8_t)((((uint32_t)g * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u);
b = (uint8_t)((((uint32_t)b * (uint32_t)a) + (255u * (255u - (uint32_t)a)) + 127u) / 255u);
}
lv_color_t color = lv_color_make(r, g, b);
pixels[i] = (uint16_t)color.full;
pixels[i] = lcd_rgb888_to_rgb565(r, g, b);
}
heap_caps_free(rgba);

View File

@@ -11,7 +11,6 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "lvgl.h"
#include "sdkconfig.h"
#include "display_lcd_decode_image.h"
#include "display_st7789p3.h"
@@ -24,6 +23,8 @@ static const char *TAG = "lcd_module";
#define LCD_DEFAULT_DRAW_LINES 20
#define LCD_PREVIEW_FADE_DURATION_MS 150
#define LCD_PREVIEW_FADE_STEPS 3
#define LCD_RGB565_BLACK 0x0000u
#define LCD_RGB565_WHITE 0xFFFFu
#ifndef CONFIG_TQ_SCREEN_PIXEL_CLOCK_HZ
#define CONFIG_TQ_SCREEN_PIXEL_CLOCK_HZ (10 * 1000 * 1000)
@@ -101,16 +102,9 @@ static const char *TAG = "lcd_module";
typedef struct {
st7789p3_handle_t panel;
SemaphoreHandle_t lock;
lv_disp_draw_buf_t lv_draw_buf;
lv_disp_drv_t lv_drv;
lv_disp_t *lv_disp;
lv_obj_t *preview_img;
lv_color_t *draw_buf_1;
lv_color_t *draw_buf_2;
uint16_t *preview_pixels;
lv_img_dsc_t preview_dsc;
bool lvgl_inited;
bool lvgl_ready;
uint16_t preview_w;
uint16_t preview_h;
bool initialized;
bool shared_spi_dirty;
} lcd_state_t;
@@ -174,27 +168,6 @@ static void lcd_lock_give(void)
}
}
static void *lcd_alloc_fb(size_t bytes)
{
void *buf = heap_caps_malloc(bytes, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
if (buf == NULL) {
buf = heap_caps_malloc(bytes, MALLOC_CAP_8BIT);
}
return buf;
}
static void lcd_free_lvgl_buffers(void)
{
if (s_lcd.draw_buf_1 != NULL) {
heap_caps_free(s_lcd.draw_buf_1);
s_lcd.draw_buf_1 = NULL;
}
if (s_lcd.draw_buf_2 != NULL) {
heap_caps_free(s_lcd.draw_buf_2);
s_lcd.draw_buf_2 = NULL;
}
}
static esp_err_t lcd_recover_panel_for_shared_spi(void)
{
if (!s_lcd.initialized || s_lcd.panel == NULL) {
@@ -223,82 +196,6 @@ static esp_err_t lcd_recover_panel_for_shared_spi(void)
return lcd_module_init();
}
static void lcd_lvgl_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_map)
{
st7789p3_handle_t panel = (st7789p3_handle_t)disp_drv->user_data;
if (panel == NULL || area == NULL || color_map == NULL) {
lv_disp_flush_ready(disp_drv);
return;
}
if (area->x1 < 0 || area->y1 < 0 || area->x2 < area->x1 || area->y2 < area->y1) {
lv_disp_flush_ready(disp_drv);
return;
}
esp_err_t err = st7789p3_draw_bitmap(panel,
(uint16_t)area->x1,
(uint16_t)area->y1,
(uint16_t)(area->x2 + 1),
(uint16_t)(area->y2 + 1),
(const uint16_t *)color_map);
if (err != ESP_OK) {
ESP_LOGW(TAG, "lvgl flush failed: %s", esp_err_to_name(err));
}
lv_disp_flush_ready(disp_drv);
}
static esp_err_t lcd_lvgl_init_locked(void)
{
if (s_lcd.lvgl_ready) {
return ESP_OK;
}
if (!s_lcd.lvgl_inited) {
lv_init();
s_lcd.lvgl_inited = true;
}
const size_t draw_buf_pixels = LCD_PANEL_H_RES * CONFIG_TQ_SCREEN_DRAW_LINES;
const size_t draw_buf_bytes = draw_buf_pixels * sizeof(lv_color_t);
s_lcd.draw_buf_1 = (lv_color_t *)lcd_alloc_fb(draw_buf_bytes);
if (s_lcd.draw_buf_1 == NULL) {
return ESP_ERR_NO_MEM;
}
s_lcd.draw_buf_2 = (lv_color_t *)lcd_alloc_fb(draw_buf_bytes);
if (s_lcd.draw_buf_2 == NULL) {
lcd_free_lvgl_buffers();
return ESP_ERR_NO_MEM;
}
lv_disp_draw_buf_init(&s_lcd.lv_draw_buf, s_lcd.draw_buf_1, s_lcd.draw_buf_2, draw_buf_pixels);
lv_disp_drv_init(&s_lcd.lv_drv);
s_lcd.lv_drv.hor_res = LCD_PANEL_H_RES;
s_lcd.lv_drv.ver_res = LCD_PANEL_V_RES;
s_lcd.lv_drv.flush_cb = lcd_lvgl_flush_cb;
s_lcd.lv_drv.draw_buf = &s_lcd.lv_draw_buf;
s_lcd.lv_drv.user_data = s_lcd.panel;
s_lcd.lv_disp = lv_disp_drv_register(&s_lcd.lv_drv);
if (s_lcd.lv_disp == NULL) {
lcd_free_lvgl_buffers();
ESP_LOGE(TAG, "lvgl display register failed");
return ESP_FAIL;
}
lv_obj_t *screen = lv_scr_act();
lv_obj_set_style_bg_color(screen, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_clear_flag(screen, LV_OBJ_FLAG_SCROLLABLE);
s_lcd.preview_img = lv_img_create(screen);
lv_obj_add_flag(s_lcd.preview_img, LV_OBJ_FLAG_HIDDEN);
lv_obj_center(s_lcd.preview_img);
s_lcd.lvgl_ready = true;
lv_refr_now(s_lcd.lv_disp);
return ESP_OK;
}
static void lcd_calc_preview_size(uint16_t src_w, uint16_t src_h, uint16_t *out_w, uint16_t *out_h)
{
if (src_w == 0 || src_h == 0 || out_w == NULL || out_h == NULL) {
@@ -489,7 +386,7 @@ static esp_err_t lcd_apply_preview_locked(const uint16_t *prev_pixels,
uint16_t prev_w,
uint16_t prev_h,
bool clear_before_draw,
lv_color_t bg_color,
uint16_t bg_color,
char *err,
size_t err_len)
{
@@ -498,15 +395,15 @@ static esp_err_t lcd_apply_preview_locked(const uint16_t *prev_pixels,
return ESP_ERR_INVALID_STATE;
}
uint16_t preview_w = s_lcd.preview_dsc.header.w;
uint16_t preview_h = s_lcd.preview_dsc.header.h;
uint16_t preview_w = s_lcd.preview_w;
uint16_t preview_h = s_lcd.preview_h;
if (preview_w == 0 || preview_h == 0 || preview_w > LCD_PANEL_H_RES || preview_h > LCD_PANEL_V_RES) {
lcd_fill_err(err, err_len, "invalid preview size");
return ESP_ERR_INVALID_SIZE;
}
if (clear_before_draw) {
esp_err_t clear_rc = st7789p3_fill_color(s_lcd.panel, (uint16_t)bg_color.full);
esp_err_t clear_rc = st7789p3_fill_color(s_lcd.panel, bg_color);
if (clear_rc != ESP_OK) {
lcd_fill_err(err, err_len, "display clear failed");
return clear_rc;
@@ -582,17 +479,12 @@ void lcd_module_deinit(void)
}
}
if (s_lcd.lv_disp != NULL) {
lv_disp_remove(s_lcd.lv_disp);
s_lcd.lv_disp = NULL;
}
if (s_lcd.preview_pixels != NULL) {
heap_caps_free(s_lcd.preview_pixels);
s_lcd.preview_pixels = NULL;
}
lcd_free_lvgl_buffers();
s_lcd.preview_img = NULL;
s_lcd.lvgl_ready = false;
s_lcd.preview_w = 0;
s_lcd.preview_h = 0;
if (s_lcd.lock != NULL) {
xSemaphoreGive(s_lcd.lock);
@@ -655,17 +547,6 @@ esp_err_t lcd_module_init(void)
return ESP_ERR_NO_MEM;
}
if (!lcd_lock_take(LCD_LOCK_TIMEOUT_MS)) {
lcd_module_deinit();
return ESP_ERR_TIMEOUT;
}
err = lcd_lvgl_init_locked();
lcd_lock_give();
if (err != ESP_OK) {
lcd_module_deinit();
return err;
}
s_lcd.initialized = true;
s_lcd.shared_spi_dirty = false;
ESP_LOGI(TAG,
@@ -731,26 +612,20 @@ esp_err_t lcd_module_show_raster_1bpp(const uint8_t *raster,
}
uint16_t *prev_pixels = s_lcd.preview_pixels;
uint16_t prev_w = s_lcd.preview_dsc.header.w;
uint16_t prev_h = s_lcd.preview_dsc.header.h;
uint16_t prev_w = s_lcd.preview_w;
uint16_t prev_h = s_lcd.preview_h;
bool clear_before_draw = (s_lcd.preview_pixels == NULL ||
s_lcd.preview_dsc.header.w != preview_w ||
s_lcd.preview_dsc.header.h != preview_h);
s_lcd.preview_w != preview_w ||
s_lcd.preview_h != preview_h);
s_lcd.preview_pixels = preview_pixels;
memset(&s_lcd.preview_dsc, 0, sizeof(s_lcd.preview_dsc));
s_lcd.preview_dsc.header.always_zero = 0;
s_lcd.preview_dsc.header.w = preview_w;
s_lcd.preview_dsc.header.h = preview_h;
s_lcd.preview_dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
s_lcd.preview_dsc.data_size = (uint32_t)((size_t)preview_w * preview_h * sizeof(uint16_t));
s_lcd.preview_dsc.data = (const uint8_t *)s_lcd.preview_pixels;
s_lcd.preview_w = preview_w;
s_lcd.preview_h = preview_h;
esp_err_t draw_err = lcd_apply_preview_locked(prev_pixels,
prev_w,
prev_h,
clear_before_draw,
lv_color_white(),
LCD_RGB565_WHITE,
err,
err_len);
if (prev_pixels != NULL) {
@@ -813,26 +688,20 @@ esp_err_t lcd_module_show_png(const uint8_t *png,
}
uint16_t *prev_pixels = s_lcd.preview_pixels;
uint16_t prev_w = s_lcd.preview_dsc.header.w;
uint16_t prev_h = s_lcd.preview_dsc.header.h;
uint16_t prev_w = s_lcd.preview_w;
uint16_t prev_h = s_lcd.preview_h;
bool clear_before_draw = (s_lcd.preview_pixels == NULL ||
s_lcd.preview_dsc.header.w != preview_w ||
s_lcd.preview_dsc.header.h != preview_h);
s_lcd.preview_w != preview_w ||
s_lcd.preview_h != preview_h);
s_lcd.preview_pixels = preview_pixels;
memset(&s_lcd.preview_dsc, 0, sizeof(s_lcd.preview_dsc));
s_lcd.preview_dsc.header.always_zero = 0;
s_lcd.preview_dsc.header.w = preview_w;
s_lcd.preview_dsc.header.h = preview_h;
s_lcd.preview_dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
s_lcd.preview_dsc.data_size = (uint32_t)((size_t)preview_w * preview_h * sizeof(uint16_t));
s_lcd.preview_dsc.data = (const uint8_t *)s_lcd.preview_pixels;
s_lcd.preview_w = preview_w;
s_lcd.preview_h = preview_h;
esp_err_t draw_err = lcd_apply_preview_locked(prev_pixels,
prev_w,
prev_h,
clear_before_draw,
lv_color_white(),
LCD_RGB565_WHITE,
err,
err_len);
if (prev_pixels != NULL) {
@@ -869,26 +738,20 @@ esp_err_t lcd_module_start_demo(void)
}
uint16_t *prev_pixels = s_lcd.preview_pixels;
uint16_t prev_w = s_lcd.preview_dsc.header.w;
uint16_t prev_h = s_lcd.preview_dsc.header.h;
uint16_t prev_w = s_lcd.preview_w;
uint16_t prev_h = s_lcd.preview_h;
bool clear_before_draw = (s_lcd.preview_pixels == NULL ||
s_lcd.preview_dsc.header.w != demo_w ||
s_lcd.preview_dsc.header.h != demo_h);
s_lcd.preview_w != demo_w ||
s_lcd.preview_h != demo_h);
s_lcd.preview_pixels = demo_pixels;
memset(&s_lcd.preview_dsc, 0, sizeof(s_lcd.preview_dsc));
s_lcd.preview_dsc.header.always_zero = 0;
s_lcd.preview_dsc.header.w = demo_w;
s_lcd.preview_dsc.header.h = demo_h;
s_lcd.preview_dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
s_lcd.preview_dsc.data_size = (uint32_t)((size_t)demo_w * demo_h * sizeof(uint16_t));
s_lcd.preview_dsc.data = (const uint8_t *)s_lcd.preview_pixels;
s_lcd.preview_w = demo_w;
s_lcd.preview_h = demo_h;
esp_err_t draw_err = lcd_apply_preview_locked(prev_pixels,
prev_w,
prev_h,
clear_before_draw,
lv_color_black(),
LCD_RGB565_BLACK,
decode_err,
sizeof(decode_err));
if (prev_pixels != NULL) {

View File

@@ -81,13 +81,6 @@ dependencies:
source:
type: idf
version: 5.5.2
lvgl/lvgl:
component_hash: d7c1ac037ae6e85d94897f807d6e7ba0946a83e720074fc95a4f6241da9f9f53
dependencies: []
source:
registry_url: https://components.espressif.com/
type: service
version: 8.4.0
direct_dependencies:
- espressif/button
- espressif/esp_audio_codec
@@ -95,7 +88,6 @@ direct_dependencies:
- espressif/esp_websocket_client
- espressif/libpng
- idf
- lvgl/lvgl
manifest_hash: 5b79c550c80a326ef9d785d7e8e10bbcc72576af958820e86c1740fad847ebab
manifest_hash: f2ca0e74532324c207c6e8a99582179a9b654e68175e1c46107837b09547e31a
target: esp32s3
version: 2.0.0

View File

@@ -18,5 +18,4 @@ dependencies:
espressif/esp_codec_dev: ^1.5.4
espressif/esp_audio_codec: ^2.4.1
espressif/libpng: ^1.6.55
lvgl/lvgl: ^8.3.11
espressif/button: ^4.1.5