10.1_demo/src/e_port_disp.c
2026-05-12 10:05:01 +08:00

285 lines
7.5 KiB
C
Executable File

/*********************
* INCLUDES
*********************/
#include "e_port_disp.h"
#include <stdbool.h>
#include "../lvgl/lvgl.h"
#include <stdlib.h>
#include <fcntl.h> /* open, O_RDWR */
#include <unistd.h> /* close, lseek */
#include <sys/ioctl.h> /* ioctl */
#include <sys/mman.h> /* mmap, munmap, PROT_* MAP_* */
#include <linux/fb.h> /* fb_var_screeninfo, fb_fix_screeninfo */
#include <stdint.h> /* intptr_t */
#include <stdio.h>
#include <string.h>
#include "e_conf.h"
#include "common/qua_sys_platform.h"
#include "filter/qua_mm_filter.h"
#include "system/qua_mm_system.h"
#include "utils/qua_display_parser.h"
#include "bootanimation/qua_bootanimation.h"
#include "display/fbdev.h"
/**********************
* STATIC VARIABLES
**********************/
static disp_handle_t front_disp;
static disp_handle_t back_disp;
// 屏幕旋转
int g_screen_rotation = 0;
qua_mm_system_ops_t *g_sys_ops = NULL;
qua_mm_tde_device_t *g_tde_device_for_hole = NULL;
// ======================== 内部函数声明 ========================
static QUA_S32 init_common_sys();
static QUA_S32 init_tde_device();
static void init_display(const char *fb_name);
static void cleanup_resources(void)
{
if (g_tde_device_for_hole != NULL)
{
g_tde_device_for_hole = NULL;
}
if (g_sys_ops != NULL)
{
g_sys_ops = NULL;
}
}
int init_dev(void)
{
if (init_common_sys() != QUA_SUCCESS)
{
printf("init_common_sys failed\n");
return -1;
}
QUA_BOOL gl_ret = qua_gl_init(g_sys_ops);
if (!gl_ret)
{
printf("qua_gl_init error!\n");
goto cleanup;
}
if (init_tde_device() != QUA_SUCCESS)
{
printf("init_tde_device failed\n");
goto cleanup;
}
#if DISP_COUNT == 2
init_display(FB_DEV_BACK);
#endif
printf("%s 1\n", __func__);
lv_group_set_default(lv_group_create());
char ID_0[DEVICE_ID_LENGTH] = "700000000000";
front_disp.fb_width = LV_USE_HOR_SIZE;
front_disp.fb_height = LV_USE_VER_SIZE;
front_disp.device_index = 0; // 前屏索引为0
strcpy(front_disp.device_id, ID_0);
printf("fbdev1 id: %s\n", ID_0);
front_disp.display_handle = qua_vppo_init("id:display0");
if (front_disp.display_handle == NULL)
{
printf("Failed to init display0\n");
goto cleanup;
}
// printf("开始初始化fb设备\n");
init_display(FB_DEV_FRONT);
int fb_actual_h = fbdev_get_actual_height();
if (fb_actual_h <= 0) fb_actual_h = LV_USE_VER_SIZE;
lv_display_t *disp = lv_display_create(LV_USE_HOR_SIZE, fb_actual_h);
if (disp == NULL)
{
printf("Failed to create display\n");
goto cleanup;
}
printf("create display w=%d h=%d (fb_h=%d) rotation=%d\n", LV_USE_HOR_SIZE, fb_actual_h, fb_actual_h, g_screen_rotation);
if (g_screen_rotation == 1)
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_90);
else if (g_screen_rotation == 2)
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_180);
else if (g_screen_rotation == 3)
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
uint8_t *fb_buf = fbdev_req_mem(DISP_BUF_SIZE);
if (fb_buf == NULL)
{
printf("Failed to allocate framebuffer\n");
goto cleanup;
}
printf("fbdev1 FB pointer: %p\n", fb_buf);
lv_display_set_buffers(disp, fb_buf, NULL, DISP_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_flush_cb(disp, fbdev_flush);
lv_obj_t *parent = lv_display_get_screen_active(disp);
lv_obj_set_style_bg_color(parent, lv_color_hex(0x1989FA), LV_PART_MAIN); // 设置背景颜色
front_disp.root_obj = parent;
#if DISP_COUNT == 2
char ID_1[DEVICE_ID_LENGTH] = "700000000001";
printf("fbdev2 id: %s\n", ID_1);
back_disp.fb_width = LV_USE_HOR_SIZE;
back_disp.fb_height = LV_USE_VER_SIZE;
back_disp.device_index = 1; //
strcpy(back_disp.device_id, ID_1);
back_disp.display_handle = qua_vppo_init("id:display1");
if (back_disp.display_handle == NULL)
{
printf("Failed to init display1\n");
goto cleanup;
}
lv_display_t *disp2 = lv_display_create(LV_USE_HOR_SIZE, LV_USE_VER_SIZE);
if (disp2 == NULL)
{
printf("Failed to create back display\n");
goto cleanup;
}
if (g_screen_rotation == 1)
lv_display_set_rotation(disp2, LV_DISPLAY_ROTATION_90);
else if (g_screen_rotation == 2)
lv_display_set_rotation(disp2, LV_DISPLAY_ROTATION_180);
else if (g_screen_rotation == 3)
lv_display_set_rotation(disp2, LV_DISPLAY_ROTATION_270);
uint8_t *fb_buf2 = fbdev_req_mem(DISP_BUF_SIZE);
if (fb_buf2 == NULL)
{
printf("Failed to allocate back framebuffer\n");
goto cleanup;
}
printf("fbdev2 FB pointer: %p\n", fb_buf2);
lv_display_set_buffers(disp2, fb_buf2, NULL, DISP_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_flush_cb(disp2, fbdev2_flush);
lv_obj_t *parent2 = lv_display_get_screen_active(disp2);
lv_obj_set_style_bg_color(parent2, lv_color_hex(0x1989FA), LV_PART_MAIN); // 设置背景颜色
back_disp.root_obj = parent2;
#endif
return 0;
cleanup:
cleanup_resources();
return -1;
}
disp_handle_t get_front_display(void)
{
return front_disp;
}
disp_handle_t get_back_display(void)
{
return back_disp;
}
void disp_exit(void)
{
fbdev_exit();
#if DISP_COUNT == 2
fbdev2_exit();
#endif
cleanup_resources();
}
static void init_display(const char *fb_name)
{
int retry_count = 0;
int delay_ms = 100; // 初始延迟100ms
while (retry_count < 5)
{
if (access(fb_name, F_OK) == 0)
{
if (strcmp(fb_name, FB_DEV_FRONT) == 0)
{
fbdev_init();
}
else
{
fbdev2_init();
}
break;
}
// 使用指数退避算法
usleep(delay_ms * 1000);
delay_ms *= 2; // 每次重试延迟时间翻倍
retry_count++;
printf("fbdev not ready, retry count %d\n", retry_count);
}
}
static QUA_S32 init_common_sys()
{
QUA_S32 ret = QUA_SUCCESS;
char platform[16];
qua_mm_system_t *system = NULL;
qua_init_display_parser();
qua_make_platform("qm10xd", qua_sys_os(), platform, sizeof(platform));
ret = qua_mm_init(QUA_TRUE, platform, &system);
if (ret != QUA_SUCCESS || system == NULL)
{
printf("Error: qua mm init failed 0x%x\n", ret);
return ret;
}
qua_mm_system_ops_t *sys_ops = (qua_mm_system_ops_t *)system;
g_sys_ops = sys_ops;
qua_vb_config_t vb_cfg;
memset(&vb_cfg, 0, sizeof(qua_vb_config_t));
vb_cfg.max_pool_cnt = 128;
vb_cfg.common_pools[0].block_size = 32768;
vb_cfg.common_pools[0].block_cnt = 2;
return sys_ops->sys_init(&vb_cfg);
}
static QUA_S32 init_tde_device()
{
QUA_S32 ret;
const qua_mm_module_t *filter_module = NULL;
ret = qua_mm_load_module(QUA_MM_MODULE_FILTER, &filter_module);
if (ret != QUA_SUCCESS || filter_module == NULL)
{
printf("load filter module failed\n");
return QUA_FAILURE;
}
printf("Module %s, API version %d\n", filter_module->id, filter_module->api_version);
qua_mm_device_t *mm_device = NULL;
ret = filter_module->open_device(filter_module, QUA_MM_FILTER_DEV_TDE, 0, &mm_device);
if (ret != QUA_SUCCESS || mm_device == NULL)
{
printf(" open tde dev failed\n");
return QUA_FAILURE;
}
g_tde_device_for_hole = (qua_mm_tde_device_t *)mm_device;
printf("Device %s\n", g_tde_device_for_hole->parent.id);
return QUA_SUCCESS;
}