449 lines
17 KiB
C
449 lines
17 KiB
C
#include "typedef.h"
|
||
#include "rect.h"
|
||
#include "res/resfile.h"
|
||
|
||
#include "dbi.h"
|
||
#include "jlgpu_math.h" // matrix
|
||
#include "jlgpu_driver.h" // gpu driver
|
||
#include "ui_resource.h" // JL UI resource
|
||
#include "ui_expand/ui_expand.h" // macro defined
|
||
|
||
#include "gpu_port.h" // module head file
|
||
#include "gpu_draw.h" // custom draw head file
|
||
|
||
#include "ui_core.h"
|
||
#include "ui_measure.h"
|
||
|
||
#include "ui/lcd/lcd_drive.h"
|
||
#include "res/mem_var.h"
|
||
#include "football.h"
|
||
|
||
#include "gpu_demo.h"
|
||
|
||
#if defined GPU_DEMO_FOOTBALL_ENABLE && GPU_DEMO_FOOTBALL_ENABLE
|
||
|
||
struct gpu_port_demo_priv {
|
||
struct lcd_interface *lcd;
|
||
struct lcd_info info;
|
||
|
||
pJLGPUTaskHead_t gpu_task_head;
|
||
uint8_t *buf1;
|
||
uint8_t *buf2;
|
||
/* uint8_t cur_buf; */
|
||
};
|
||
|
||
static struct gpu_port_demo_priv priv = {0};
|
||
|
||
#define __this (&priv)
|
||
|
||
struct football_info_user {
|
||
char *path; //资源文件的路径
|
||
u32 image_num; //足球表面图片的数量
|
||
u32 *image_id_tab; //图片的id
|
||
float x_diff;
|
||
float y_diff;
|
||
};
|
||
|
||
typedef enum {
|
||
IMAGE_FROM_RAM = 0,
|
||
IMAGE_FROM_FLASH,
|
||
} IMAGE_FROM;
|
||
|
||
#define PAGE0_c186_MENU_29SET 0x000001 // images\menu_29set.png
|
||
#define PAGE0_56cc_MENU_16SIRI 0x000002 // images\menu_16siri.png
|
||
#define PAGE0_e4e2_MENU_1CLOCK 0x000003 // images\menu_1clock.png
|
||
#define PAGE0_eb8d_MENU_4MUSIC 0x000004 // images\menu_4music.png
|
||
#define PAGE0_2e24_MENU_14SLEEP 0x000005 // images\menu_14sleep.png
|
||
#define PAGE0_1ee8_MENU_26TIMER 0x000006 // images\menu_26timer.png
|
||
#define PAGE0_f432_MENU_33PRUNE 0x000007 // images\menu_33Prune.png
|
||
#define PAGE0_a990_MENU_24ALIPAY 0x000008 // images\menu_24alipay.png
|
||
#define PAGE0_f02e_MENU_6WEATHER 0x000009 // images\menu_6weather.png
|
||
#define PAGE0_3efa_MENU_22COMPASS 0x00000a // images\menu_22compass.png
|
||
#define PAGE0_bffe_MENU_23FIND_MY 0x00000b // images\menu_23Find_my.png
|
||
#define PAGE0_66f5_MENU_30RESTART 0x00000c // images\menu_30restart.png
|
||
#define PAGE0_ca8e_MENU_18CALENDAR 0x00000d // images\menu_18calendar.png
|
||
#define PAGE0_e1ba_MENU_20PRESSURE 0x00000e // images\menu_20pressure.png
|
||
#define PAGE0_e9bf_MENU_2TELEPHONE 0x00000f // images\menu_2telephone.png
|
||
#define PAGE0_bdf6_MENU_34PASSWORD 0x000010 // images\menu_34password.png
|
||
#define PAGE0_16f7_MENU_80ACTIVITY 0x000011 // images\menu_80activity.png
|
||
#define PAGE0_d12b_MENU_13BREATHING 0x000012 // images\menu_13breathing.png
|
||
#define PAGE0_79bc_MENU_21ALTIMETER 0x000013 // images\menu_21altimeter.png
|
||
#define PAGE0_651f_MENU_27STOPWATCH 0x000014 // images\menu_27Stopwatch.png
|
||
#define PAGE0_b338_MENU_10HEART_RATE 0x000015 // images\menu_10heart_rate.png
|
||
#define PAGE0_cfa8_MENU_17CALCULATOR 0x000016 // images\menu_17calculator.png
|
||
#define PAGE0_dede_MENU_28PHOTOGRAPH 0x000017 // images\menu_28photograph.png
|
||
#define PAGE0_7f29_MENU_3INFORMATION 0x000018 // images\menu_3information.png
|
||
#define PAGE0_f695_MENU_5ALARM_CLOCK 0x000019 // images\menu_5alarm_clock.png
|
||
#define PAGE0_cf1d_MENU_7BEDSIDE_LAMP 0x00001a // images\menu_7bedside_lamp.png
|
||
#define PAGE0_f6d4_MENU_11BLOOD_OXYGEN 0x00001b // images\menu_11Blood_oxygen.png
|
||
#define PAGE0_c5ef_MENU_9INDOOR_SPORTS 0x00001c // images\menu_9indoor_sports.png
|
||
#define PAGE0_35c8_MENU_32AMBIENT_NOISE 0x00001d // images\menu_32ambient_noise.png
|
||
#define PAGE0_6a9f_MENU_8OUTDOOR_SPORTS 0x00001e // images\menu_8outdoor_sports.png
|
||
#define PAGE0_0aa3_MENU_12BLOOD_PRESSURE 0x00001f // images\menu_12blood_pressure.png
|
||
#define PAGE0_32d6_MENU_15HEALTH_REMINDER 0x000020 // images\menu_15Health_reminder.png
|
||
#define PAGE0_e103_MENU_25SOUND_RECORDING 0x000021 // images\menu_25sound_recording.png
|
||
#define PAGE0_e0fb_MENU_19FEMALE_ASSISTANT 0x000022 // images\menu_19Female_assistant.png
|
||
#define PAGE0_76b1_MENU_31FACTORY_RECOVERY 0x000023 // images\menu_31factory_recovery.png
|
||
#define PAGE0_9f4c_MENU_35POWER_SAVINGMODE 0x000024 // images\menu_35Power_savingmode.png
|
||
#define PAGE0_fbab_MENU_36NIGHT_RUNNINGLAMP 0x000025 // images\menu_36Night_runninglamp.png
|
||
|
||
#define FOOTBALL_IMAGE_NUM 37
|
||
u32 img_id_tab[FOOTBALL_IMAGE_NUM] = {
|
||
PAGE0_c186_MENU_29SET,
|
||
PAGE0_56cc_MENU_16SIRI,
|
||
PAGE0_e4e2_MENU_1CLOCK,
|
||
PAGE0_eb8d_MENU_4MUSIC,
|
||
PAGE0_2e24_MENU_14SLEEP,
|
||
PAGE0_1ee8_MENU_26TIMER,
|
||
PAGE0_f432_MENU_33PRUNE,
|
||
PAGE0_a990_MENU_24ALIPAY,
|
||
PAGE0_f02e_MENU_6WEATHER,
|
||
PAGE0_3efa_MENU_22COMPASS,
|
||
PAGE0_bffe_MENU_23FIND_MY,
|
||
PAGE0_66f5_MENU_30RESTART,
|
||
PAGE0_ca8e_MENU_18CALENDAR,
|
||
PAGE0_e1ba_MENU_20PRESSURE,
|
||
PAGE0_e9bf_MENU_2TELEPHONE,
|
||
PAGE0_bdf6_MENU_34PASSWORD,
|
||
PAGE0_16f7_MENU_80ACTIVITY,
|
||
PAGE0_d12b_MENU_13BREATHING,
|
||
PAGE0_79bc_MENU_21ALTIMETER,
|
||
PAGE0_651f_MENU_27STOPWATCH,
|
||
PAGE0_b338_MENU_10HEART_RATE,
|
||
PAGE0_cfa8_MENU_17CALCULATOR,
|
||
PAGE0_dede_MENU_28PHOTOGRAPH,
|
||
PAGE0_7f29_MENU_3INFORMATION,
|
||
PAGE0_f695_MENU_5ALARM_CLOCK,
|
||
PAGE0_cf1d_MENU_7BEDSIDE_LAMP,
|
||
PAGE0_f6d4_MENU_11BLOOD_OXYGEN,
|
||
PAGE0_c5ef_MENU_9INDOOR_SPORTS,
|
||
PAGE0_35c8_MENU_32AMBIENT_NOISE,
|
||
PAGE0_6a9f_MENU_8OUTDOOR_SPORTS,
|
||
PAGE0_0aa3_MENU_12BLOOD_PRESSURE,
|
||
PAGE0_32d6_MENU_15HEALTH_REMINDER,
|
||
PAGE0_e103_MENU_25SOUND_RECORDING,
|
||
PAGE0_e0fb_MENU_19FEMALE_ASSISTANT,
|
||
PAGE0_76b1_MENU_31FACTORY_RECOVERY,
|
||
PAGE0_9f4c_MENU_35POWER_SAVINGMODE,
|
||
PAGE0_fbab_MENU_36NIGHT_RUNNINGLAMP,
|
||
};
|
||
|
||
static void *gpu_port_demo_malloc(int size, u32 ram_type, u32 module_type)
|
||
{
|
||
void *buf = (void *)malloc(size);
|
||
|
||
return buf;
|
||
}
|
||
|
||
static void gpu_port_demo_free(void *buf, u32 ram_type, u32 module_type)
|
||
{
|
||
free(buf);
|
||
}
|
||
|
||
static void gpu_port_demo_lcd_init(void)
|
||
{
|
||
__this->lcd = lcd_get_hdl();
|
||
ASSERT(__this->lcd);
|
||
ASSERT(__this->lcd->init);
|
||
ASSERT(__this->lcd->get_screen_info);
|
||
ASSERT(__this->lcd->buffer_malloc);
|
||
ASSERT(__this->lcd->buffer_free);
|
||
ASSERT(__this->lcd->draw);
|
||
ASSERT(__this->lcd->set_draw_area);
|
||
ASSERT(__this->lcd->backlight_ctrl);
|
||
|
||
if (__this->lcd->init) {
|
||
extern const struct ui_devices_cfg ui_cfg_data;
|
||
__this->lcd->init((void *)&ui_cfg_data);
|
||
}
|
||
|
||
if (__this->lcd->get_screen_info) {
|
||
__this->lcd->get_screen_info(&__this->info);
|
||
}
|
||
|
||
if (__this->lcd->clear_screen) {
|
||
__this->lcd->clear_screen(0x000000, 0, __this->info.width - 1, 0, __this->info.height - 1);
|
||
}
|
||
|
||
|
||
if (__this->lcd->backlight_ctrl) {
|
||
__this->lcd->backlight_ctrl(100);
|
||
}
|
||
|
||
mem_var_init(3 * 1024, false);
|
||
ui_resfile_info_init(gpu_port_demo_malloc, gpu_port_demo_free); // UI 资源管理
|
||
}
|
||
|
||
//初始化gpu_port模块接口
|
||
static void gpu_port_demo_port_init(void)
|
||
{
|
||
jlgpu_module_init(gpu_port_demo_malloc, gpu_port_demo_free, __this->info.width, __this->info.height);
|
||
}
|
||
|
||
void gpu_port_demo_task_init(int gpu_out_format)
|
||
{
|
||
//创建任务链
|
||
__this->gpu_task_head = jlgpu_create_task_list_head();
|
||
if (!__this->gpu_task_head) {
|
||
printf("<gpu_port_demo> gpu create task list head fail!!! ");
|
||
return;
|
||
}
|
||
|
||
//设置任务链输出的格式
|
||
jlgpu_set_task_list_out_format(__this->gpu_task_head, gpu_out_format);
|
||
|
||
}
|
||
|
||
void gpu_port_demo_task_free(void)
|
||
{
|
||
if (__this->gpu_task_head) {
|
||
//删除任务链
|
||
jlgpu_delete_task_list_head(__this->gpu_task_head);
|
||
__this->gpu_task_head = NULL;
|
||
}
|
||
}
|
||
|
||
//创建绘制背景颜色任务
|
||
static void gpu_port_demo_create_bg_task(struct rect draw_rect, u32 color)
|
||
{
|
||
u8 a = (color >> 24) & 0xff;
|
||
u8 r = (color >> 16) & 0xff;
|
||
u8 g = (color >> 8) & 0xff;
|
||
u8 b = (color) & 0xff;
|
||
|
||
//创建gpu绘制任务
|
||
jlgpu_task_fill_param_init(0, 0, a, r, g, b);
|
||
memcpy(&task_param.draw, &draw_rect, sizeof(struct rect));
|
||
jlgpu_get_win_rect(&task_param.area); // 限制区域是整个GPU窗口区域
|
||
|
||
printf("<%s>----param->head:0x%p\n", __func__, __this->gpu_task_head);
|
||
|
||
jlgpu_create_task(__this->gpu_task_head, &task_param);
|
||
}
|
||
|
||
static void gpu_port_demo_football_init(struct football_param *football, struct football_info_user *football_user)
|
||
{
|
||
football->image = (struct ui_image_attrs *)malloc(football_user->image_num * sizeof(struct ui_image_attrs));
|
||
football->image_num = football_user->image_num;
|
||
|
||
char *img_path = football_user->path;
|
||
|
||
//打开资源文件
|
||
UI_RESFILE *fp = res_fopen(img_path, "r");
|
||
if (!fp) {
|
||
printf("%s fp is null", __func__);
|
||
ASSERT(0);
|
||
}
|
||
//获取文件的flash table
|
||
struct flash_file_info file_info;
|
||
ui_res_flash_info_get(&file_info, img_path, "res", true);
|
||
jlgpu_task_texture_param_init(0, 0);
|
||
//获取图片信息
|
||
for (int i = 0; i < football->image_num; i++) {
|
||
printf("id:%x\n", img_id_tab[i]);
|
||
jlui_res_get_image_info(0, (img_id_tab[i] & 0xffff), fp, &task_param.image, &task_param.info);
|
||
ui_res_get_image_flash_info(&task_param.info, &file_info, &task_param.image);
|
||
printf("<%s>--------format:%d, offset:0x%x, size:%d * %d\n", __func__, task_param.image.format, task_param.image.offset, task_param.image.width, task_param.image.height);
|
||
|
||
football->image[i].width = task_param.image.width;
|
||
football->image[i].height = task_param.image.height;
|
||
football->image[i].format = task_param.image.format;
|
||
football->image[i].clut_format = task_param.image.clut_format;
|
||
football->image[i].compress = task_param.image.compress;
|
||
football->image[i].has_clut = task_param.image.has_clut;
|
||
football->image[i].tab = (u8 *)task_param.info.tab;
|
||
football->image[i].data = (u8 *)task_param.info.offset;
|
||
football->image[i].len = task_param.image.len;
|
||
football->image[i].gpu_format = res_format_to_gpu(task_param.image.format);
|
||
printf("<%s>--------format:%d, offset:0x%x\n", __func__, task_param.image.format, task_param.info.offset);
|
||
}
|
||
|
||
struct rect win_rect;
|
||
jlgpu_get_win_rect(&win_rect);
|
||
|
||
football_init(football->image[0].width, football->image[0].height, 1.1f, 4.0f, win_rect.left, win_rect.top, win_rect.width, win_rect.height);
|
||
}
|
||
|
||
|
||
static void gpu_port_demo_create_football_task(struct football_info_user *football_user)
|
||
{
|
||
struct football_param football;
|
||
|
||
football.image = (struct ui_image_attrs *)malloc(football_user->image_num * sizeof(struct ui_image_attrs));
|
||
football.image_num = football_user->image_num;
|
||
|
||
char *img_path = football_user->path;
|
||
|
||
//打开资源文件
|
||
UI_RESFILE *fp = res_fopen(img_path, "r");
|
||
if (!fp) {
|
||
printf("%s fp is null", __func__);
|
||
ASSERT(0);
|
||
}
|
||
//获取文件的flash table
|
||
struct flash_file_info file_info;
|
||
ui_res_flash_info_get(&file_info, img_path, "res", true);
|
||
jlgpu_task_texture_param_init(0, 0);
|
||
//获取图片信息
|
||
for (int i = 0; i < football.image_num; i++) {
|
||
printf("id:%x\n", img_id_tab[i]);
|
||
jlui_res_get_image_info(0, (img_id_tab[i] & 0xffff), fp, &task_param.image, &task_param.info);
|
||
ui_res_get_image_flash_info(&task_param.info, &file_info, &task_param.image);
|
||
printf("<%s>--------format:%d, offset:0x%x, size:%d * %d\n", __func__, task_param.image.format, task_param.image.offset, task_param.image.width, task_param.image.height);
|
||
|
||
football.image[i].width = task_param.image.width;
|
||
football.image[i].height = task_param.image.height;
|
||
football.image[i].format = task_param.image.format;
|
||
football.image[i].clut_format = task_param.image.clut_format;
|
||
football.image[i].compress = task_param.image.compress;
|
||
football.image[i].has_clut = task_param.image.has_clut;
|
||
football.image[i].tab = (u8 *)task_param.info.tab;
|
||
football.image[i].data = (u8 *)task_param.info.offset;
|
||
football.image[i].len = task_param.image.len;
|
||
football.image[i].gpu_format = res_format_to_gpu(task_param.image.format);
|
||
printf("<%s>--------format:%d, offset:0x%x\n", __func__, task_param.image.format, task_param.info.offset);
|
||
}
|
||
|
||
struct rect win_rect;
|
||
jlgpu_get_win_rect(&win_rect);
|
||
|
||
football_init(football.image[0].width, football.image[0].height, 1.1f, 4.0f, win_rect.left, win_rect.top, win_rect.width, win_rect.height);
|
||
|
||
football.head = __this->gpu_task_head; //设置任务链表头
|
||
football.task_id = 1; //设置任务id,否则默认为零,会覆盖之前创建的任务
|
||
football_draw(&football, football_user->x_diff, football_user->y_diff);
|
||
|
||
if (fp) {
|
||
res_fclose(fp);
|
||
}
|
||
if (football.image) {
|
||
free(football.image);
|
||
}
|
||
}
|
||
|
||
void gpu_port_demo_draw_football(struct football_param *football, float x_diff, float y_diff, u32 background)
|
||
{
|
||
//输出配置
|
||
int width = __this->info.width;
|
||
int height = __this->info.height;
|
||
int out_format = GPU_FORMAT_RGB565;
|
||
int out_bpp = gpu_get_format_bpp(out_format) / 8;
|
||
int out_stride = width * out_bpp;
|
||
int block_height = 16; //分块输出到屏幕上,每块的大小(width * block_height)
|
||
|
||
//申请输出的缓存空间
|
||
__this->buf1 = (uint8_t *)zalloc(block_height * out_stride);
|
||
/* __this->buf2 = (uint8_t *)zalloc((height % block_height) * out_stride); */
|
||
|
||
struct rect draw_task_rect = {0};
|
||
//创建绘制背景颜色的任务
|
||
if (background) {
|
||
draw_task_rect.left = 0;
|
||
draw_task_rect.top = 0;
|
||
draw_task_rect.width = __this->info.width;
|
||
draw_task_rect.height = __this->info.height;
|
||
gpu_port_demo_create_bg_task(draw_task_rect, background);
|
||
}
|
||
|
||
//创建绘制图片的任务
|
||
football->head = __this->gpu_task_head; //设置任务链表头
|
||
football->task_id = 1; //设置任务id,否则默认为零,会覆盖之前创建的任务
|
||
football->mask_en = 0;
|
||
football_draw(football, x_diff, y_diff);
|
||
|
||
|
||
//设置输出buf并且显示到屏幕上
|
||
int block_num = 0;
|
||
block_num = (height % block_height) ? (height / block_height + 1) : (height / block_height);
|
||
//设置推屏区域
|
||
lcd_set_draw_area(0, width - 1, 0, height - 1);
|
||
|
||
struct rect draw_rect = {0};
|
||
int draw_height;
|
||
for (int i = 0; i < block_num; i++) {
|
||
if ((i + 1) * block_height < height) {
|
||
draw_height = block_height;
|
||
} else {
|
||
draw_height = height - (i * block_height);
|
||
}
|
||
|
||
draw_rect.left = 0;
|
||
draw_rect.top = i * block_height;
|
||
draw_rect.width = width;
|
||
draw_rect.height = draw_height;
|
||
|
||
memset(__this->buf1, 0, draw_rect.width * draw_rect.height * 2);
|
||
|
||
jlgpu_set_task_list_out_buf(__this->gpu_task_head, __this->buf1, &draw_rect, 0, 0);
|
||
jlgpu_task_list_run(__this->gpu_task_head);
|
||
/* jlgpu_dump_task_head(__this->gpu_task_head); */
|
||
|
||
|
||
if (!i) {
|
||
/* 开始推屏时使用 kistart */
|
||
lcd_draw_kistart(__this->buf1, draw_rect.left, draw_rect.left + draw_rect.width - 1, draw_rect.top, draw_rect.top + draw_rect.height - 1);
|
||
lcd_wait_busy();
|
||
} else {
|
||
/* 之后推屏时使用 continue 续传 */
|
||
lcd_draw_continue(__this->buf1, draw_rect.left, draw_rect.left + draw_rect.width - 1, draw_rect.top, draw_rect.top + draw_rect.height - 1);
|
||
lcd_wait_busy();
|
||
}
|
||
}
|
||
|
||
//将申请的内存进行释放
|
||
/* if(img->clut_tab){ */
|
||
/* free(img->clut_tab); */
|
||
/* img->clut_tab = NULL; */
|
||
/* } */
|
||
if (__this->buf1) {
|
||
free(__this->buf1);
|
||
__this->buf1 = NULL;
|
||
}
|
||
if (__this->buf2) {
|
||
free(__this->buf2);
|
||
__this->buf2 = NULL;
|
||
}
|
||
}
|
||
|
||
void gpu_demo_football(void *p)
|
||
{
|
||
gpu_port_demo_lcd_init(); //初始化lcd
|
||
gpu_port_demo_port_init(); //初始化gpu_port接口
|
||
struct football_info_user football_user = {0};
|
||
float x_diff = 0.0;
|
||
float y_diff = 0.0;
|
||
|
||
football_user.path = "storage/virfat_flash/C/ui/ui.res";
|
||
football_user.image_num = FOOTBALL_IMAGE_NUM;
|
||
football_user.image_id_tab = img_id_tab;
|
||
football_user.x_diff = 0;
|
||
football_user.y_diff = 0;
|
||
|
||
struct football_param football;
|
||
gpu_port_demo_football_init(&football, &football_user);
|
||
|
||
while (1) {
|
||
gpu_port_demo_task_init(GPU_FORMAT_RGB565);
|
||
gpu_port_demo_draw_football(&football, x_diff, y_diff, 0xff00ff00);
|
||
gpu_port_demo_task_free(); //任务链用完之后删除任务链,同时创建的任务也会清除
|
||
x_diff += 0.1;
|
||
y_diff += 0.1;
|
||
|
||
os_time_dly(50);
|
||
}
|
||
}
|
||
|
||
|
||
int gpu_demo_football_task(void)
|
||
{
|
||
printf(">>>>>>>>> %s()", __func__);
|
||
int err;
|
||
err = os_task_create(gpu_demo_football, NULL, 10, 1024 * 5, 512, "gpu_demo_football");
|
||
if (err != OS_NO_ERR) {
|
||
printf("gpu task creat fail %x\n", err);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
#endif
|