285 lines
7.5 KiB
C
Executable File
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;
|
|
} |