Files
AC707N/SDK/apps/watch/ui/jlgpu_demo/gpu_demo_football.c
T
2025-12-03 11:12:34 +08:00

449 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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