refactor(platform): remove lvgl dependency from screen preview
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user