初版
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,462 @@
|
||||
#include "typedef.h"
|
||||
#include "rect.h"
|
||||
#include "res/resfile.h"
|
||||
|
||||
#include "dbi.h"
|
||||
#include "jlgpu_math.h"
|
||||
#include "jlgpu_driver.h"
|
||||
#include "ui_resource.h" // RES格式与GPU格式互转接口
|
||||
#include "ui_expand/ui_expand.h" // 使用一些宏定义
|
||||
|
||||
#include "gpu_draw.h"
|
||||
#include "gpu_port.h"
|
||||
#include "ui_draw/ui_basic.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "jlui_app/ui_style.h"
|
||||
|
||||
#if (defined(CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE) || defined(CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE))
|
||||
|
||||
|
||||
/* debug 打印配置 */
|
||||
#define LOG_TAG_CONST JL_GPU
|
||||
#define LOG_TAG "[JL GPU]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
extern int ui_disp_out_stride_get();
|
||||
extern int lcd_get_screen_width();
|
||||
extern int lcd_get_screen_height();
|
||||
static void jlui_blend_by_gpu(u8 *mask_buf, struct rect *mask_r, u8 *disp_buf, struct rect *disp_r, int color);
|
||||
|
||||
|
||||
static const struct gpu_blend_interface gpu_draw_interface = {
|
||||
.gpu_blend = jlui_blend_by_gpu,
|
||||
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jlui_blend_by_gpu gpu绘图
|
||||
*
|
||||
* @param mask_buf 非压缩A8数据(前景)
|
||||
* @param mask_r A8数据绘制区域
|
||||
* @param disp_buf 底图,一般是屏驱buf(后景)
|
||||
* @param disp_r 底图区域
|
||||
* @param color A8颜色,这里传565
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
AT_UI_RAM
|
||||
void jlui_blend_mask(u8 *mask_buf, struct rect *mask_r, u8 *disp_buf, struct rect *disp_r, struct rect *draw_r, u32 color, float ratio_w, float ratio_h, int in_format)
|
||||
{
|
||||
|
||||
int r = ((color >> 11) & 0x1f) << 3;
|
||||
int g = ((color >> 5) & 0x3f) << 2;
|
||||
int b = ((color) & 0x1f) << 3;
|
||||
/* printf("%s (%d %d %d %d) (%d %d %d %d) %x %x (%d %d %d)", __func__, */
|
||||
/* mask_r->left, mask_r->top, mask_r->width, mask_r->height, */
|
||||
/* disp_r->left, disp_r->top, disp_r->width, disp_r->height, */
|
||||
/* (int)mask_buf, (int)disp_buf, r, g, b); */
|
||||
|
||||
gpu_out_params_t out_param = { 0 };
|
||||
gpu_basic_params_t basic_param = { 0 };
|
||||
gpu_transform_params_t transform_param = {0};
|
||||
|
||||
out_param.data = (uint8_t *)disp_buf;
|
||||
out_param.win_x_min = disp_r->left;
|
||||
out_param.win_x_max = disp_r->left + disp_r->width ;
|
||||
out_param.win_y_min = disp_r->top;
|
||||
out_param.win_y_max = disp_r->top + disp_r->height ;
|
||||
out_param.stride = lcd_get_screen_width() * 2; //disp_r->width * 2;
|
||||
out_param.format = GPU_FORMAT_RGB565;
|
||||
|
||||
/*********针对draw_r的区域超出屏幕区域的情况*****/
|
||||
struct rect lcd_rect;
|
||||
lcd_rect.left = 0;
|
||||
lcd_rect.top = 0;
|
||||
lcd_rect.width = lcd_get_screen_width();
|
||||
lcd_rect.height = lcd_get_screen_height();
|
||||
struct rect draw_rect;
|
||||
get_rect_cover(&lcd_rect, draw_r, &draw_rect);
|
||||
/************************************************/
|
||||
|
||||
/* basic_param.act_x_min = mask_r->left ; */
|
||||
/* basic_param.act_x_max = mask_r->left + mask_r->width; */
|
||||
/* basic_param.act_y_min = mask_r->top ; */
|
||||
/* basic_param.act_y_max = mask_r->top + mask_r->height; */
|
||||
basic_param.act_x_min = draw_rect.left ;
|
||||
basic_param.act_x_max = draw_rect.left + draw_rect.width ;
|
||||
basic_param.act_y_min = draw_rect.top ;
|
||||
basic_param.act_y_max = draw_rect.top + draw_rect.height;
|
||||
/* printf("basic:{%d %d %d %d}", basic_param.act_x_min, basic_param.act_x_max, basic_param.act_y_min, basic_param.act_y_max); */
|
||||
basic_param.alpha = 255;
|
||||
basic_param.red = r;
|
||||
basic_param.green = g;
|
||||
basic_param.blue = b;
|
||||
basic_param.layer_en = 1;
|
||||
basic_param.blend_mode = 1;
|
||||
basic_param.global_alpha = 128; //范围:0-128
|
||||
basic_param.premult = 0;
|
||||
|
||||
gpu_texture_params_t texture_param = { 0 };
|
||||
texture_param.adr_mode = 1;
|
||||
texture_param.data = mask_buf;
|
||||
texture_param.format = in_format;
|
||||
texture_param.compress_mode = 0;
|
||||
texture_param.stride = (mask_r->width * gpu_get_format_bpp(in_format) + 7) / 8 ;
|
||||
texture_param.compress_size = mask_r->width;
|
||||
texture_param.big_end = 1;
|
||||
|
||||
float zoom_w = (float)1 / ratio_w;
|
||||
float zoom_h = (float)1 / ratio_h;
|
||||
gpu_matrix_t matrix;
|
||||
gpu_matrix_set_identity(&matrix);
|
||||
float tran_x = (float)draw_r->left;
|
||||
float tran_y = (float)draw_r->top;
|
||||
|
||||
gpu_matrix_translate(&matrix, -tran_x, -tran_y);
|
||||
gpu_matrix_scale(&matrix, zoom_w, zoom_h);
|
||||
|
||||
/* printf("%s %f %f %f %f\n", __func__, zoom_w, zoom_h, tran_x, tran_y); */
|
||||
transform_param.M00 = matrix.m[0][0];
|
||||
transform_param.M01 = matrix.m[0][1];
|
||||
transform_param.M02 = matrix.m[0][2] - 0.5f * transform_param.M00 - 0.5f * transform_param.M01 + 0.5f;
|
||||
transform_param.M10 = matrix.m[1][0];
|
||||
transform_param.M11 = matrix.m[1][1];
|
||||
transform_param.M12 = matrix.m[1][2] - 0.5f * transform_param.M10 - 0.5f * transform_param.M11 + 0.5f;
|
||||
transform_param.fg_x_min = 0;
|
||||
transform_param.fg_x_max = mask_r->width;
|
||||
transform_param.fg_y_min = 0;
|
||||
transform_param.fg_y_max = mask_r->height;
|
||||
transform_param.sample_mode = 0;
|
||||
transform_param.shift_sel = 6;
|
||||
uint8_t mode = GPU_TEXTURE_AFFINE;
|
||||
gpu_reset_all_regs(mode);
|
||||
gpu_texture_affine(&basic_param, &texture_param, &transform_param);
|
||||
gpu_set_out_layer(&out_param);
|
||||
gpu_isr_sem_clr();
|
||||
gpu_run();
|
||||
gpu_wait_done();
|
||||
|
||||
/* printf("%s %d", __func__, __LINE__); */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jlui_blend_by_gpu gpu绘图
|
||||
*
|
||||
* @param mask_buf 非压缩A8数据(前景)
|
||||
* @param mask_r A8数据绘制区域
|
||||
* @param disp_buf 底图,一般是屏驱buf(后景)
|
||||
* @param disp_r 底图区域
|
||||
* @param color A8颜色,这里传565
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
extern const int JLUI_CUSTOM_DRAW_CACHE;
|
||||
AT_UI_RAM
|
||||
static void jlui_blend_by_gpu(u8 *mask_buf, struct rect *mask_r, u8 *disp_buf, struct rect *disp_r, int color)
|
||||
{
|
||||
if (JLUI_CUSTOM_DRAW_CACHE) {
|
||||
/* memcpy(disp_buf, mask_buf, disp_r->width * disp_r->height); // 一定是A8格式,直接copy */
|
||||
return;
|
||||
}
|
||||
|
||||
u8 r = ((color >> 11) & 0x1f) << 3;
|
||||
u8 g = ((color >> 5) & 0x3f) << 2;
|
||||
u8 b = ((color) & 0x1f) << 3;
|
||||
u8 alpha = ((u32)color) >> 24;
|
||||
/* printf("%s (%d %d %d %d) (%d %d %d %d) %x %x (%d %d %d)", __func__, */
|
||||
/* mask_r->left, mask_r->top, mask_r->width, mask_r->height, */
|
||||
/* disp_r->left, disp_r->top, disp_r->width, disp_r->height, */
|
||||
/* (int)mask_buf, (int)disp_buf, r, g, b); */
|
||||
/* put_buf(mask_buf,320*mask_r->height); */
|
||||
|
||||
gpu_out_params_t out_param = { 0 };
|
||||
gpu_basic_params_t basic_param = { 0 };
|
||||
|
||||
|
||||
out_param.data = (uint8_t *)disp_buf;
|
||||
out_param.win_x_min = 0;
|
||||
out_param.win_x_max = disp_r->width;
|
||||
out_param.win_y_min = 0;
|
||||
out_param.win_y_max = disp_r->height;
|
||||
out_param.stride = ui_disp_out_stride_get(); // disp_r->width*2;//lcd_get_screen_width() * 2;
|
||||
out_param.format = GPU_FORMAT_RGB565;
|
||||
|
||||
basic_param.act_x_min = mask_r->left;
|
||||
basic_param.act_x_max = mask_r->left + mask_r->width;
|
||||
basic_param.act_y_min = mask_r->top;
|
||||
basic_param.act_y_max = mask_r->top + mask_r->height;
|
||||
|
||||
basic_param.alpha = 255;
|
||||
basic_param.red = r;
|
||||
basic_param.green = g;
|
||||
basic_param.blue = b;
|
||||
basic_param.layer_en = 1;
|
||||
basic_param.blend_mode = 1;
|
||||
basic_param.global_alpha = alpha * 128 / 255; //范围:0-128
|
||||
#if 0
|
||||
uint8_t mode = GPU_TEXTURE;
|
||||
gpu_texture_params_t texture_param = { 0 };
|
||||
texture_param.adr_mode = 1;
|
||||
texture_param.data = mask_buf;
|
||||
texture_param.format = GPU_FORMAT_A8;
|
||||
texture_param.compress_mode = 0;
|
||||
texture_param.stride = (mask_r->width * gpu_get_format_bpp(GPU_FORMAT_A8) + 7) / 8 ;
|
||||
texture_param.compress_size = mask_r->width;
|
||||
texture_param.big_end = 1;
|
||||
|
||||
|
||||
gpu_reset_all_regs(mode);
|
||||
gpu_texture(&basic_param, &texture_param);
|
||||
gpu_set_out_layer(&out_param);
|
||||
gpu_isr_sem_clr();
|
||||
gpu_run();
|
||||
gpu_wait_done();
|
||||
#else
|
||||
uint8_t mode = GPU_FILL_MASK;
|
||||
gpu_mask_params_t mask_param = {0};
|
||||
mask_param.data = mask_buf;
|
||||
mask_param.mask_big_end = 0;
|
||||
mask_param.mask_format = GPU_MASK_FORMAT_A8;
|
||||
mask_param.mask_x_min = 0;
|
||||
mask_param.mask_x_max = mask_r->width;
|
||||
mask_param.mask_y_min = 0;
|
||||
mask_param.mask_y_max = mask_r->height;
|
||||
mask_param.stride = (mask_r->width * gpu_get_format_bpp(GPU_FORMAT_A8) + 7) / 8 ;
|
||||
|
||||
gpu_reset_all_regs(mode);
|
||||
gpu_fill_mask(&basic_param, &mask_param);
|
||||
gpu_set_out_layer(&out_param);
|
||||
gpu_isr_sem_clr();
|
||||
gpu_run();
|
||||
gpu_wait_done();
|
||||
#endif
|
||||
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jdec_to_jlgpu_texture_blend 硬件 GPU2D YUV422 格式 UYVY 转 RGB565
|
||||
*
|
||||
* @param dst_buf 输出buffer,一般为推屏buffer
|
||||
* @param dst_rect 输出buffer位置
|
||||
* @param src_buf jpeg图像数据
|
||||
* @param src_rect 图像数据位置(相对于jpeg)
|
||||
* @param draw_rect 绘制区域
|
||||
* @param stride 行步进
|
||||
* @param format 预留
|
||||
* @param p 私有句柄,预留给变换传参
|
||||
|
||||
* @return 0 linebuf已完全绘制 1linebuf未完全绘制
|
||||
* @return linebuf使用后剩余行数
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
#define GPU_OFFSET 800
|
||||
void dump_matrix(gpu_matrix_t *matrix);
|
||||
int jdec_to_jlgpu_texture_blend(u8 *dst_buf, struct rect *dst_rect, u8 *src_buf, struct rect *src_rect, struct rect *draw_rect, int src_stride, int format, void *p, int line_surpule, struct rect *cover_rect)
|
||||
{
|
||||
//缩放矩阵
|
||||
gpu_matrix_t tmp_matrix;
|
||||
gpu_matrix_t *matrix = NULL;
|
||||
if (p) {
|
||||
matrix = (gpu_matrix_t *)&tmp_matrix;
|
||||
memcpy(matrix, p, sizeof(gpu_matrix_t));
|
||||
} else {
|
||||
matrix = (gpu_matrix_t *)&tmp_matrix;
|
||||
gpu_matrix_set_identity(matrix);
|
||||
}
|
||||
//缩放系数
|
||||
float ratio_w = 1.0f, ratio_h = 1.0f; //倒数
|
||||
if (matrix) {
|
||||
ratio_w = matrix->m[0][0];
|
||||
ratio_h = matrix->m[1][1];
|
||||
}
|
||||
//区域计算
|
||||
/* DUMP_RECT(__func__, __LINE__, "dst_rect", dst_rect); //disp_buf区域 */
|
||||
/* DUMP_RECT(__func__, __LINE__, "src_rect", src_rect); //jpeg解码区域(缩放前,局部) */
|
||||
/* DUMP_RECT(__func__, __LINE__, "draw_rect", draw_rect); //jpeg显示区域(缩放后,局部) */
|
||||
/* DUMP_RECT(__func__, __LINE__, "cover_rect", cover_rect); //jpeg限制区域 (全局) */
|
||||
|
||||
//计算缩放后的尺寸
|
||||
struct rect jpeg_dec_scale_r;
|
||||
jpeg_dec_scale_r.left = src_rect->left / ratio_w;
|
||||
jpeg_dec_scale_r.top = ((float)src_rect->top / ratio_h);
|
||||
jpeg_dec_scale_r.width = src_rect->width / ratio_w;
|
||||
jpeg_dec_scale_r.height = (int)(src_rect->top + src_rect->height) / ratio_h - jpeg_dec_scale_r.top;
|
||||
/* DUMP_RECT(__func__, __LINE__, "jpeg_dec_scale_r", (struct rect *)(&jpeg_dec_scale_r)); //缩放后的区域 */
|
||||
|
||||
//偏移到显示位置
|
||||
struct rect jpeg_dec_draw;
|
||||
jpeg_dec_draw.left = draw_rect->left + jpeg_dec_scale_r.left;
|
||||
jpeg_dec_draw.top = draw_rect->top + jpeg_dec_scale_r.top;
|
||||
jpeg_dec_draw.width = jpeg_dec_scale_r.width;
|
||||
jpeg_dec_draw.height = jpeg_dec_scale_r.height;
|
||||
/* DUMP_RECT(__func__, __LINE__, "jpeg_dec_draw", (struct rect *)(&jpeg_dec_draw)); //缩放后在屏幕显示的区域 */
|
||||
|
||||
//与推屏区域取交集
|
||||
struct rect jpeg_dec_draw_cover_t;
|
||||
if (!get_rect_cover(dst_rect, &jpeg_dec_draw, &jpeg_dec_draw_cover_t)) {
|
||||
return 0 ;
|
||||
}
|
||||
//对显示区域取交集
|
||||
struct rect jpeg_dec_draw_cover;
|
||||
get_rect_cover(&jpeg_dec_draw_cover_t, cover_rect, &jpeg_dec_draw_cover);
|
||||
/* DUMP_RECT(__func__, (jpeg_dec_draw_cover.top + jpeg_dec_draw_cover.height), "jpeg_dec_draw_cover", (struct rect *)(&jpeg_dec_draw_cover)); //与推屏buf的交集 */
|
||||
|
||||
//输出配置
|
||||
int out_stride = ui_disp_out_stride_get(); //RGB565
|
||||
gpu_out_params_t out_param = {0};
|
||||
gpu_basic_params_t basic_param = {0};
|
||||
gpu_texture_params_t texture_param = {0};
|
||||
gpu_transform_params_t transform_param = {0};
|
||||
uint8_t adr_mode = 1;
|
||||
uint8_t blend_mode = GPU_BLEND_SRC;
|
||||
uint8_t mode = GPU_TEXTURE;
|
||||
if (matrix) {//缩放
|
||||
mode = GPU_TEXTURE_AFFINE;
|
||||
out_param.data = (uint8_t *)dst_buf;
|
||||
out_param.win_x_min = GPU_OFFSET + dst_rect->left;
|
||||
out_param.win_x_max = GPU_OFFSET + dst_rect->left + dst_rect->width;
|
||||
out_param.win_y_min = GPU_OFFSET + dst_rect->top;
|
||||
out_param.win_y_max = GPU_OFFSET + dst_rect->top + dst_rect->height;
|
||||
} else {
|
||||
out_param.data = (uint8_t *)dst_buf + (jpeg_dec_draw_cover.top - dst_rect->top) * out_stride;
|
||||
out_param.win_x_min = GPU_OFFSET + dst_rect->left;
|
||||
out_param.win_x_max = GPU_OFFSET + dst_rect->left + dst_rect->width;
|
||||
out_param.win_y_min = GPU_OFFSET + jpeg_dec_draw_cover.top;
|
||||
out_param.win_y_max = GPU_OFFSET + jpeg_dec_draw_cover.top + jpeg_dec_draw_cover.height;
|
||||
}
|
||||
|
||||
/* printf("@@@ win [%d, %d, %d, %d] h:%d \n", out_param.win_x_min, out_param.win_y_min, out_param.win_x_max - out_param.win_x_min, out_param.win_y_max - out_param.win_y_min, jpeg_dec_draw_cover.height); */
|
||||
out_param.stride = out_stride;
|
||||
out_param.format = GPU_FORMAT_RGB565;
|
||||
if (matrix) {
|
||||
basic_param.act_x_min = GPU_OFFSET + jpeg_dec_draw_cover.left;
|
||||
basic_param.act_x_max = GPU_OFFSET + jpeg_dec_draw_cover.left + jpeg_dec_draw_cover.width;
|
||||
basic_param.act_y_min = GPU_OFFSET + jpeg_dec_draw_cover.top;
|
||||
basic_param.act_y_max = GPU_OFFSET + jpeg_dec_draw_cover.top + jpeg_dec_draw_cover.height;
|
||||
} else {
|
||||
basic_param.act_x_min = GPU_OFFSET + draw_rect->left;
|
||||
basic_param.act_x_max = GPU_OFFSET + draw_rect->left + draw_rect->width;
|
||||
basic_param.act_y_min = GPU_OFFSET + jpeg_dec_draw.top;
|
||||
basic_param.act_y_max = GPU_OFFSET + jpeg_dec_draw.top + jpeg_dec_draw.height;
|
||||
}
|
||||
|
||||
/* printf("@@@ box [%d, %d, %d, %d]\n", basic_param.act_x_min, basic_param.act_y_min, basic_param.act_x_max - basic_param.act_x_min, basic_param.act_y_max - basic_param.act_y_min); */
|
||||
basic_param.global_alpha = 128;
|
||||
basic_param.blend_mode = blend_mode;
|
||||
basic_param.premult = 0;
|
||||
basic_param.layer_en = 1;
|
||||
basic_param.ext_mode = 1;
|
||||
|
||||
texture_param.adr_mode = adr_mode;
|
||||
texture_param.rbs = 0; // must 0; YUV422 => UYVY
|
||||
texture_param.data = (uint8_t *)src_buf ;
|
||||
texture_param.format = GPU_FORMAT_YUV422_BT601;
|
||||
texture_param.compress_mode = 0;
|
||||
texture_param.stride = src_stride;
|
||||
texture_param.compress_size = src_rect->width;
|
||||
gpu_reset_all_regs(mode);
|
||||
|
||||
if (matrix) {
|
||||
gpu_matrix_set_identity(matrix);
|
||||
gpu_matrix_translate(matrix, -GPU_OFFSET, -GPU_OFFSET);
|
||||
|
||||
struct rect real_scale_r;
|
||||
memcpy(&real_scale_r, &jpeg_dec_draw, sizeof(struct rect));
|
||||
real_scale_r.height = (int)(src_rect->height) / ratio_h;
|
||||
struct rect real_scale_cover_t;
|
||||
get_rect_cover(dst_rect, &real_scale_r, &real_scale_cover_t);
|
||||
struct rect real_scale_cover;
|
||||
get_rect_cover(&real_scale_cover_t, cover_rect, &real_scale_cover);
|
||||
if ((jpeg_dec_draw_cover.top + jpeg_dec_draw_cover.height) == (real_scale_cover.top + real_scale_cover.height)) {
|
||||
gpu_matrix_translate(matrix, -draw_rect->left, - jpeg_dec_draw.top);
|
||||
} else {
|
||||
//浮点补偿
|
||||
gpu_matrix_translate(matrix, -draw_rect->left, -(((float)src_rect->top / ratio_h) + draw_rect->top));
|
||||
}
|
||||
/* printf("%s matrix_offset:%f %f",__func__,matrix->m[0][2],matrix->m[1][2]); */
|
||||
gpu_matrix_scale(matrix, ratio_w, ratio_h);
|
||||
transform_param.M00 = matrix->m[0][0];
|
||||
transform_param.M01 = matrix->m[0][1];
|
||||
transform_param.M02 = matrix->m[0][2] - 0.5f * transform_param.M00 - 0.5f * transform_param.M01 + 0.5f;
|
||||
transform_param.M10 = matrix->m[1][0];
|
||||
transform_param.M11 = matrix->m[1][1];
|
||||
transform_param.M12 = matrix->m[1][2]/* - 0.5f * transform_param.M10 - 0.5f * transform_param.M11 + 0.5f*/;
|
||||
transform_param.fg_x_min = 0;
|
||||
transform_param.fg_x_max = src_rect->width;
|
||||
transform_param.fg_y_min = 0;
|
||||
transform_param.fg_y_max = src_rect->height;
|
||||
transform_param.sample_mode = 0;
|
||||
transform_param.shift_sel = 6;
|
||||
gpu_texture_affine(&basic_param, &texture_param, &transform_param);
|
||||
} else {
|
||||
gpu_texture(&basic_param, &texture_param);
|
||||
}
|
||||
gpu_set_out_layer(&out_param);
|
||||
gpu_isr_sem_clr();
|
||||
gpu_run();
|
||||
gpu_wait_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jlui_argb8565_to_rgb565(u8 *out_buf, struct rect *out_r, u8 *in_buf, struct rect *in_r)
|
||||
{
|
||||
gpu_out_params_t out_param = { 0 };
|
||||
gpu_basic_params_t basic_param = { 0 };
|
||||
gpu_transform_params_t transform_param = {0};
|
||||
//out info
|
||||
out_param.data = (uint8_t *)out_buf;
|
||||
out_param.win_x_min = 0;
|
||||
out_param.win_x_max = out_r->width ;
|
||||
out_param.win_y_min = 0;
|
||||
out_param.win_y_max = out_r->height ;
|
||||
out_param.format = GPU_FORMAT_RGB565;
|
||||
out_param.stride = (out_r->width * gpu_get_format_bpp(out_param.format) + 7) / 8;
|
||||
//in info
|
||||
basic_param.act_x_min = 0;
|
||||
basic_param.act_x_max = in_r->width;
|
||||
basic_param.act_y_min = 0;
|
||||
basic_param.act_y_max = in_r->height;
|
||||
basic_param.alpha = 0xff;
|
||||
basic_param.layer_en = 1;
|
||||
basic_param.blend_mode = 1;
|
||||
basic_param.global_alpha = 128; //范围:0-128
|
||||
basic_param.premult = 1;
|
||||
//in texture
|
||||
gpu_texture_params_t texture_param = { 0 };
|
||||
texture_param.adr_mode = 1;
|
||||
texture_param.data = in_buf;
|
||||
texture_param.format = GPU_FORMAT_ARGB8565;
|
||||
texture_param.compress_mode = 0;
|
||||
texture_param.stride = (in_r->width * gpu_get_format_bpp(texture_param.format) + 7) / 8 ;
|
||||
texture_param.compress_size = in_r->width;
|
||||
|
||||
uint8_t mode = GPU_TEXTURE;
|
||||
gpu_reset_all_regs(mode);
|
||||
gpu_texture(&basic_param, &texture_param);
|
||||
gpu_set_out_layer(&out_param);
|
||||
gpu_isr_sem_clr();
|
||||
gpu_run();
|
||||
gpu_wait_done();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void jlui_gpu_blend_init()
|
||||
{
|
||||
gpu_blend_init((struct gpu_blend_interface *)&gpu_draw_interface);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
#ifndef __PUBLIC_GPU_DRAW_H__
|
||||
#define __PUBLIC_GPU_DRAW_H__
|
||||
|
||||
|
||||
void jlui_gpu_blend_init();
|
||||
int jdec_to_jlgpu_texture_blend(u8 *dst_buf, struct rect *dst_rect, u8 *src_buf, struct rect *src_rect, struct rect *draw_rect, int src_stride, int format, void *p, int line_surpule, struct rect *cover);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
#ifndef __PUBLIC_GPU_TASK_H__
|
||||
#define __PUBLIC_GPU_TASK_H__
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief GPU 任务名
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
#define GPU_TASK_NAME "gpu"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief GPU任务消息类型
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
GPU_MSG_OTHER,
|
||||
GPU_MSG_DRAW,
|
||||
GPU_MSG_DUMP,
|
||||
GPU_MSG_DRAW_LIST,
|
||||
} gpu_task_msg_t;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief GPU刷新方式标志
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
GPU_SYNC_REDRAW, // 同步/串行刷新
|
||||
GPU_ASYN_REDRAW, // 异步/并行刷新
|
||||
} gpu_redraw_mode_t;
|
||||
|
||||
int jlgpu_scheduler_async_free_buf(void *p);
|
||||
void jlgpu_scheduler_set_redraw_mode(struct draw_context *dc, gpu_redraw_mode_t mode);
|
||||
void *jlgpu_scheduler_create_mult_task_list(struct draw_context *dc);
|
||||
void jlgpu_scheduler_delete_mult_task_list(struct draw_context *dc);
|
||||
void *jlgpu_scheduler_draw_mult_task_list(struct draw_context *dc);
|
||||
void jlgpu_scheduler_init(void *(*malloc)(int, u32, u32), void (*free)(void *, u32, u32), u16 lcd_width, u16 lcd_height);
|
||||
void jlgpu_scheduler_free();
|
||||
int jlgpu_scheduler_wait_sync();
|
||||
int jlgpu_scheduler_async_free_jpeg_res(void *p);
|
||||
int jlgpu_scheduler_get_redraw_mode();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,989 @@
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "jljpeg_decode.h"
|
||||
#include "res/resfile.h"
|
||||
#include "ui_core.h"
|
||||
#include "jlgpu_math.h" // matrix
|
||||
#include "jlgpu_driver.h" // gpu 驱动
|
||||
#include "gpu_port.h" // GPU 接口,依赖于 jlgpu_driver.h
|
||||
#include "gpu_task.h"
|
||||
#include <math.h>
|
||||
#include "ui/lcd/lcd_drive.h" // lcd 驱动
|
||||
|
||||
#define LOG_TAG_CONST JPEG
|
||||
#define LOG_TAG "[JPEG]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_DUMP_ENABLE
|
||||
#define LOG_WARN_ENABLE
|
||||
#define LOG_CHAR_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
struct jpeg_hd_manager {
|
||||
struct list_head entry;
|
||||
jdec_opj *opj;
|
||||
u32 check;
|
||||
u32 vaild;
|
||||
u32 task_id;
|
||||
u32 elm_id;
|
||||
u8 file_flag;
|
||||
};
|
||||
struct jpeg_priv {
|
||||
u32 task_id;
|
||||
u32 elm_id;
|
||||
};
|
||||
struct jpeg_hd_manager jpg_hd_manager_info;
|
||||
#define __this (&jpg_hd_manager_info)
|
||||
|
||||
|
||||
spinlock_t lock;
|
||||
#define ENTER_CRITICAL() spin_lock(&lock)
|
||||
#define EXIT_CRITICAL() spin_unlock(&lock)
|
||||
|
||||
#define UI_IO_DEBUG_0(i,x) //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);}
|
||||
#define UI_IO_DEBUG_1(i,x) //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);}
|
||||
int jpeg_module_opj_free_file_hd(FILE *fp);
|
||||
int jlgpu_scheduler_async_free_jpeg_res(void *p);
|
||||
int jpeg_module_opj_release_async(void *jpg);
|
||||
void *psram_cache_2_nocache(void *p);
|
||||
u32 jlui_jpeg_infunc_bits_stream(struct _jdec_opj *opj, u8 *buf, u32 len);
|
||||
extern void psram_flush_cache(void *begin, u32 len);
|
||||
extern const u8 norflash_ext_sfc_en;//给gpu判断互斥
|
||||
extern void norflash_espi_mutex_enter();
|
||||
extern void norflash_espi_mutex_exit();
|
||||
extern u32 ps_ram_size[];
|
||||
static volatile const u32 psram_size = (u32)ps_ram_size;
|
||||
|
||||
#define IS_SFC1_ADDR(addr) (!psram_size && (memory_in_flash(addr)))
|
||||
#define DUMP_RECT(func, line, name, rect) \
|
||||
printf("[RECT] %s() %d, %s [%d, %d, %d, %d]\n", func, line, name, (rect)->left, (rect)->top, (rect)->width, (rect)->height)
|
||||
//======================================================================//
|
||||
// jpeg链表管理
|
||||
// 支持多jpeg显示,注意
|
||||
// 1. 多jpeg水平方向无交叉时,效率不影响(即垂直排列)
|
||||
// 2. 需要全屏刷新
|
||||
// 3. 不带psram时不支持变换
|
||||
// 4. 注意ram消耗
|
||||
//======================================================================//
|
||||
void *jpeg_hd_create_priv(u32 task_id, u32 elm_id)
|
||||
{
|
||||
struct jpeg_priv *priv = (struct jpeg_priv *)jpeg_malloc(sizeof(struct jpeg_priv));
|
||||
priv->task_id = task_id;
|
||||
priv->elm_id = elm_id;
|
||||
return (void *)priv;
|
||||
}
|
||||
int jpeg_hd_get_priv_len()
|
||||
{
|
||||
return sizeof(struct jpeg_priv);
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_check 查询是否存在jpeg句柄
|
||||
*
|
||||
* @param check
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static void *jpeg_hd_manager_check(u32 check)
|
||||
{
|
||||
struct jpeg_hd_manager *p;
|
||||
struct jpeg_hd_manager *rp = NULL;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry(p, &__this->entry, entry) {
|
||||
if (p->check == check) {
|
||||
rp = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
if (rp) {
|
||||
log_debug("%s hd:0x%x opj:0x%x check:0x%x", __func__, (u32)rp, (u32)rp->opj, check);
|
||||
} else {
|
||||
|
||||
log_debug("%s check:0x%x", __func__, check);
|
||||
}
|
||||
return (void *)rp;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_find_by_opj 判断句柄是否存在
|
||||
*
|
||||
* @param opj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static void *jpeg_hd_manager_find_by_opj(void *opj)
|
||||
{
|
||||
struct jpeg_hd_manager *p;
|
||||
struct jpeg_hd_manager *rp = NULL;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry(p, &__this->entry, entry) {
|
||||
if (p->opj == opj) {
|
||||
rp = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
if (rp) {
|
||||
log_debug("%s hd:0x%x opj:0x%x check:0x%x", __func__, (u32)rp, (u32)rp->opj, (u32)opj);
|
||||
} else {
|
||||
|
||||
log_debug("%s check:0x%x", __func__, (u32)opj);
|
||||
}
|
||||
return (void *)rp;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_find_by_id 通过id查找句柄
|
||||
*
|
||||
* @param task_id
|
||||
* @param elm_id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static void *jpeg_hd_manager_find_by_id(u32 task_id, u32 elm_id)
|
||||
{
|
||||
struct jpeg_hd_manager *p;
|
||||
struct jpeg_hd_manager *rp = NULL;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry(p, &__this->entry, entry) {
|
||||
if ((p->task_id == task_id)
|
||||
&& (p->elm_id == elm_id)) {
|
||||
rp = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
if (rp) {
|
||||
log_debug("%s hd:0x%x opj:0x%x task_id:0x%x elm_id:0x%x \n", __func__, (u32)rp, (u32)rp->opj, task_id, elm_id);
|
||||
} else {
|
||||
|
||||
log_debug("%s task_id:0x%x elm_id:0x%x \n", __func__, task_id, elm_id);
|
||||
}
|
||||
return (void *)rp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_add 添加jpeg句柄记录
|
||||
*
|
||||
* @param opj
|
||||
* @param check
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static struct jpeg_hd_manager *jpeg_hd_manager_add(void *opj, u32 check)
|
||||
{
|
||||
struct jpeg_hd_manager *p = jpeg_malloc(sizeof(struct jpeg_hd_manager));
|
||||
memset(p, 0, sizeof(struct jpeg_hd_manager));
|
||||
p->opj = (jdec_opj *)opj;
|
||||
p->check = check;
|
||||
p->vaild = 0;
|
||||
log_debug("%s hd:0x%x opj:0x%x check:0x%x", __func__, (u32)p, (u32)p->opj, check);
|
||||
ENTER_CRITICAL();
|
||||
list_add_tail(&p->entry, &__this->entry);
|
||||
EXIT_CRITICAL();
|
||||
return p;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_del 删除jpeg句柄记录
|
||||
*
|
||||
* @param opj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static int jpeg_hd_manager_del(void *opj)
|
||||
{
|
||||
log_debug("%s opj:0x%x ", __func__, (u32)opj);
|
||||
struct jpeg_hd_manager *p, *n;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry_safe(p, n, &__this->entry, entry) {
|
||||
if (p->opj == opj) {
|
||||
list_del(&(p->entry));
|
||||
if (p->file_flag) {
|
||||
FILE *fp = (FILE *)(((int *)p->opj->device)[0]);
|
||||
jpeg_module_opj_free_file_hd(fp);
|
||||
}
|
||||
jpeg_module_opj_release_async((void *)p->opj);
|
||||
jpeg_free(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_clr 清空所有jpeg句柄记录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static int jpeg_hd_manager_clr()
|
||||
{
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
struct jpeg_hd_manager *p, *n;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry_safe(p, n, &__this->entry, entry) {
|
||||
list_del(&(p->entry));
|
||||
if (p->file_flag) {
|
||||
|
||||
FILE *fp = (FILE *)(((int *)p->opj->device)[0]);
|
||||
jpeg_module_opj_free_file_hd(fp);
|
||||
}
|
||||
jpeg_module_opj_release_async((void *)p->opj);
|
||||
|
||||
jpeg_free(p);
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_vaild_set 有效性设置
|
||||
*
|
||||
* @param opj
|
||||
* @param vaild
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static int jpeg_hd_manager_vaild_set(void *opj, int vaild)
|
||||
{
|
||||
log_debug("%s opj:0x%x", __func__, (u32)opj);
|
||||
struct jpeg_hd_manager *p, *n;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry_safe(p, n, &__this->entry, entry) {
|
||||
if (p->opj == opj) {
|
||||
p->vaild = vaild;
|
||||
log_debug("%s hd:0x%x opj:0x%x svaild:%d pvaild:0x%x", __func__, (u32)p, (u32)opj, vaild, p->vaild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_hd_manager_vaild_sub 有效性--
|
||||
*
|
||||
* @param opj
|
||||
* @param vaild
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static int jpeg_hd_manager_vaild_sub(void *opj)
|
||||
{
|
||||
log_debug("%s opj:0x%x", __func__, (u32)opj);
|
||||
struct jpeg_hd_manager *p, *n;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry_safe(p, n, &__this->entry, entry) {
|
||||
if (p->opj == opj) {
|
||||
if (p->vaild) {
|
||||
p->vaild --;
|
||||
}
|
||||
log_debug("%s hd:0x%x opj:0x%x pvaild:0x%x", __func__, (u32)p, (u32)opj, p->vaild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//======================================================================//
|
||||
// jpeg句柄管理
|
||||
//======================================================================//
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_free_res_cb jpeg资源释放接口,gpu_task调用
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void jpeg_module_free_res_cb(void *p)
|
||||
{
|
||||
jdec_opj *opj = (jdec_opj *)p;
|
||||
if (opj) {
|
||||
/*释放图片资源*/
|
||||
jpeg_free(opj->device);
|
||||
/*释放底层*/
|
||||
jljpeg_decode_release(opj, 0);
|
||||
jpeg_hd_manager_del(p);
|
||||
/*释放句柄*/
|
||||
jpeg_free(opj);
|
||||
/*如果全局句柄与当前一致,释放,如果不一致说明已经切换为新的句柄,就不需再清*/
|
||||
if (jljpeg_get_decode_hd() == opj) {
|
||||
jljpeg_get_decode_hd_clr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int jpeg_module_opj_free_file_hd(FILE *fp)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
|
||||
printf("%s 0x%x [FILE]fp:0x%x", __func__, rets, (u32)fp);
|
||||
|
||||
int argv[3] = {0};
|
||||
int retry = 3;
|
||||
argv[0] = (int)fclose;
|
||||
argv[1] = 1;
|
||||
argv[2] = (int)fp;
|
||||
|
||||
__try_again:
|
||||
int ret = os_taskq_post_type(GPU_TASK_NAME, Q_CALLBACK, 3, argv);
|
||||
if (ret) {
|
||||
if (retry) {
|
||||
os_time_dly(1);
|
||||
retry--;
|
||||
goto __try_again;
|
||||
}
|
||||
printf("%s post ret:%d retry:%d\n", __func__, ret, retry);
|
||||
}
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_release_async 异步释放接口,post到gpu_task执行
|
||||
*
|
||||
* @param opj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_opj_release_async(void *opj)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_debug("%s 0x%x opj:%x", __func__, rets, opj);
|
||||
|
||||
if (opj) {
|
||||
/*同步到gpu线程释放,避免gpu在使用jpeg资源*/
|
||||
jlgpu_scheduler_async_free_jpeg_res(opj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_init jpeg句柄初始化(初始化硬件、解析文件头)
|
||||
*
|
||||
* @param priv
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_opj_init(void *priv)
|
||||
{
|
||||
jdec_opj *opj = (jdec_opj *)priv;
|
||||
void *dev = opj->device;
|
||||
int ret = jljpeg_decode_init(opj);
|
||||
if (!ret) {
|
||||
ret = jljpeg_img_info_get(opj, jlui_jpeg_infunc_bits_stream, dev);
|
||||
#if 0
|
||||
wdt_clear();
|
||||
FILE *fp = fopen("storage/sd0/C/debug/test****.jpg", "w+");
|
||||
if (fp) {
|
||||
struct flash_file_info *image_info = (struct flash_file_info *)opj->device;
|
||||
printf("buf:0x%x len:%d", image_info->offset, image_info->last_tab_data_len);
|
||||
fwrite((u8 *)image_info->offset, 1, image_info->last_tab_data_len, fp);
|
||||
fclose(fp);
|
||||
os_time_dly(1);
|
||||
}
|
||||
ASSERT(!ret, "jpeg file notsupport err:%x", ret);
|
||||
#endif
|
||||
if (ret) {
|
||||
log_warn("%s err:%d", __func__, ret);
|
||||
}
|
||||
}
|
||||
log_debug("%s %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_create 创建jpeg句柄
|
||||
*
|
||||
* @param dev
|
||||
* @param dev_len
|
||||
* @param check
|
||||
* @param index
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *jpeg_module_opj_create(void *dev, int dev_len, u32 check, u32 index, u32 task_id, u32 elm_id)
|
||||
{
|
||||
int ret;
|
||||
struct jpeg_hd_manager *hd = jpeg_hd_manager_check(check);
|
||||
jdec_opj *opj = NULL;
|
||||
if (!hd) {
|
||||
opj = jpeg_malloc(sizeof(jdec_opj));
|
||||
hd = jpeg_hd_manager_add(opj, check);
|
||||
opj->device = jpeg_malloc(dev_len);
|
||||
memcpy(opj->device, dev, dev_len);
|
||||
ret = jpeg_module_opj_init((void *)opj);
|
||||
if (ret) {
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
jpeg_module_opj_release_async((void *)opj);
|
||||
opj = NULL;
|
||||
}
|
||||
hd->task_id = task_id;
|
||||
hd->elm_id = elm_id;
|
||||
} else {
|
||||
opj = hd->opj;
|
||||
}
|
||||
if (opj) {
|
||||
jpeg_hd_manager_vaild_set(opj, 1);
|
||||
}
|
||||
return (void *)opj;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_set_invaild_by_index 将某个jpeg句柄设为无效
|
||||
*
|
||||
* @param index
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_opj_set_invaild_by_index(int index)
|
||||
{
|
||||
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
struct jpeg_hd_manager *p, *n;
|
||||
ENTER_CRITICAL();
|
||||
list_for_each_entry_safe(p, n, &__this->entry, entry) {
|
||||
jpeg_hd_manager_vaild_sub(p->opj);
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_invaild_clr 将无效的句柄清除
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_opj_invaild_clr()
|
||||
{
|
||||
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
struct jpeg_hd_manager *p, *n;
|
||||
ENTER_CRITICAL();
|
||||
|
||||
list_for_each_entry_safe(p, n, &__this->entry, entry) {
|
||||
if (p->vaild) {
|
||||
continue;
|
||||
}
|
||||
list_del(&(p->entry));
|
||||
if (p->file_flag) {
|
||||
|
||||
FILE *fp = (FILE *)(((int *)p->opj->device)[0]);
|
||||
jpeg_module_opj_free_file_hd(fp);
|
||||
}
|
||||
jpeg_module_opj_release_async(p->opj);
|
||||
|
||||
jpeg_free(p);
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_clr_all 清除所有句柄
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_opj_clr_all()
|
||||
{
|
||||
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
return jpeg_hd_manager_clr();
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_init 模块初始化
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_init()
|
||||
{
|
||||
INIT_LIST_HEAD(&__this->entry);
|
||||
return 0;
|
||||
}
|
||||
//======================================================================//
|
||||
// jpeg数据输出输出
|
||||
//======================================================================//
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jlui_jpeg_infunc_bits_stream jpeg数据流
|
||||
*
|
||||
* @param opj jpeg句柄
|
||||
* @param buf jpeg buf
|
||||
* @param len jpeg读取长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
u32 jlui_jpeg_infunc_bits_stream(struct _jdec_opj *opj, u8 *buf, u32 len)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
/* log_debug("%s jpeg_info:%x %x buf:%x rets:0x%x\n", __func__, (int)opj, (int)opj->device, (int)buf, rets); */
|
||||
//dev句柄,可以是flash_info、ram地址、文件系统句柄等,只需要将
|
||||
//偏移为opj->curr_offset长度为len数据,copy到buf,并返回实际的copy长度即可
|
||||
struct flash_file_info *image_info = (struct flash_file_info *)opj->device;
|
||||
int start_addr, end_addr, curr_addr, read_len;
|
||||
if (image_info->tab) { //使用mmu_table
|
||||
int need_len = len;
|
||||
int poffset = opj->curr_offset;
|
||||
int curr_offset = 0;
|
||||
int mmu_idx = (poffset + image_info->offset) / 4096; //计算起始mmu_tab
|
||||
/* printf("%s offset %d end:%d tbsize:%d", __func__, image_info->offset, image_info->last_tab_data_len, image_info->tab_size / 4); */
|
||||
do {
|
||||
//当前mmu块的最大长度
|
||||
int block_end = (mmu_idx == ((image_info->tab_size / 4) - 1)) ? image_info->last_tab_data_len : 4096;
|
||||
//当前mmu块的起始偏移
|
||||
int block_offset = (image_info->offset + poffset) % 4096;
|
||||
//当前mmu块的可读长度
|
||||
int block_len = block_end - block_offset;
|
||||
//拷贝长度
|
||||
read_len = (block_len < need_len) ? block_len : need_len;
|
||||
//拷贝地址
|
||||
curr_addr = image_info->tab[mmu_idx] + block_offset;
|
||||
/* printf("%s mmu_idx:%d block_end:%d block_offset:%d block_len:%d read_len:%d need_len:%d,poffset:%d curr_offset%d\n", */
|
||||
/* __func__, mmu_idx, block_end, block_offset, block_len, read_len, need_len, poffset, curr_offset); */
|
||||
//分块拷贝
|
||||
if (buf) {
|
||||
if (norflash_ext_sfc_en && IS_SFC1_ADDR(curr_addr)) {
|
||||
norflash_espi_mutex_enter();
|
||||
}
|
||||
memcpy(buf + curr_offset, (const u8 *)curr_addr, read_len);
|
||||
if (norflash_ext_sfc_en && IS_SFC1_ADDR(curr_addr)) {
|
||||
norflash_espi_mutex_exit();
|
||||
}
|
||||
}
|
||||
//计算下一块mmu
|
||||
poffset += read_len;
|
||||
curr_offset += read_len;
|
||||
need_len -= read_len;
|
||||
if (mmu_idx >= ((image_info->tab_size / 4) - 1)) {//读取完所有mmu
|
||||
break;
|
||||
} else {
|
||||
mmu_idx ++;
|
||||
}
|
||||
if (need_len <= 0) {//读取完数据
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
//返回实际读取总长度
|
||||
read_len = curr_offset;
|
||||
} else {
|
||||
//资源起始地址
|
||||
start_addr = image_info->offset;
|
||||
//结束地址
|
||||
end_addr = image_info->offset + image_info->last_tab_data_len;
|
||||
//拷贝地址
|
||||
curr_addr = start_addr + opj->curr_offset;
|
||||
//拷贝长度
|
||||
read_len = (curr_addr + len > end_addr) ? end_addr - curr_addr : len;
|
||||
//拷贝
|
||||
if (buf) {
|
||||
if (norflash_ext_sfc_en && IS_SFC1_ADDR(curr_addr)) {
|
||||
norflash_espi_mutex_enter();
|
||||
}
|
||||
memcpy(buf, (const u8 *)curr_addr, read_len);
|
||||
if (norflash_ext_sfc_en && IS_SFC1_ADDR(curr_addr)) {
|
||||
norflash_espi_mutex_exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* log_debug("%s start_addr:0x%x end_addr:0x%x file_len:%d curr_addr:0x%x len:%d read_len:%d", */
|
||||
/* __func__, start_addr, end_addr, end_addr - start_addr, curr_addr, len, read_len); */
|
||||
return read_len;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg绘图回调
|
||||
*
|
||||
* @param id 0
|
||||
* @param dst_buf 屏显buffer
|
||||
* @param dst_r 屏显buffer rect
|
||||
* @param src_r 图片/控件尺寸
|
||||
* @param bytes_per_pixel 格式
|
||||
* @param priv jpeg句柄
|
||||
* @param matrix 变换矩阵
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
static void jpeg_draw_cb(int id, u8 *dst_buf, struct rect *dst_r, struct rect *src_r, u8 bytes_per_pixel, void *priv, void *matrix)
|
||||
{
|
||||
jdec_opj *opj = (jdec_opj *)priv; //jpeg解码句柄
|
||||
|
||||
opj->matrix = matrix; //获取变换矩阵
|
||||
//计算缩放系数
|
||||
float ratio_w = 1.0;
|
||||
float ratio_h = 1.0;
|
||||
if (opj->matrix) {
|
||||
gpu_matrix_t *m = matrix;
|
||||
ratio_w = m->m[0][0];//
|
||||
ratio_h = m->m[1][1];//
|
||||
/* log_debug("ratio_w: %f, ratio_h: %f\n", ratio_w, ratio_h); */
|
||||
}
|
||||
|
||||
/* 计算变换后图片的输出区域 */
|
||||
struct rect jpeg_draw_src;
|
||||
memcpy(&jpeg_draw_src, src_r, sizeof(struct rect));
|
||||
//放大时为中心放大
|
||||
int center_y = src_r->top + src_r->height / 2;
|
||||
jpeg_draw_src.height = opj->height / ratio_h;
|
||||
jpeg_draw_src.top = center_y - jpeg_draw_src.height / 2;
|
||||
int center_x = src_r->left + src_r->width / 2;
|
||||
jpeg_draw_src.width = opj->width / ratio_w;
|
||||
jpeg_draw_src.left = center_x - jpeg_draw_src.width / 2;
|
||||
/* DUMP_RECT(__func__, __LINE__, "dst_r", dst_r); //推屏buf */
|
||||
/* DUMP_RECT(__func__, __LINE__, "src_r", src_r); //jpeg显示区域 */
|
||||
/* DUMP_RECT(__func__, __LINE__, "jpeg_draw_src", &jpeg_draw_src); //jpeg缩放后区域 */
|
||||
|
||||
/* 计算图片输出和推屏Buf的重叠区域 */
|
||||
struct rect cover_r_t;
|
||||
if (!get_rect_cover(dst_r, src_r, &cover_r_t)) {
|
||||
return;
|
||||
}
|
||||
if (jljpeg_get_decode_hd() && (opj != jljpeg_get_decode_hd())) {
|
||||
jljpeg_decode_hdl_reset(opj);
|
||||
/* jljpeg_decode_reset_curr(); */
|
||||
}
|
||||
//计算缩放后的区域*以推屏区域、jpeg缩放区域、控件显示区域的交集作为最终输出,放大时受控件尺寸限制会变成中心放大
|
||||
struct rect cover_r;
|
||||
get_rect_cover(&cover_r_t, &jpeg_draw_src, &cover_r);
|
||||
/* DUMP_RECT(__func__, __LINE__, "cover_r", &cover_r); //重叠区域 */
|
||||
//计算jpeg解码的区域
|
||||
int draw_top = cover_r.top - jpeg_draw_src.top; //绘制的top
|
||||
int draw_btm = cover_r.height + draw_top; //绘制的bottom
|
||||
int draw_h = cover_r.height; //绘制高度
|
||||
/* int dec_top = draw_top * ratio_h; //需要解码的top */
|
||||
/* int dec_btm = ceilf((float)draw_btm * ratio_h); //需要解码的高度,这里需要向上取 */
|
||||
/* int dec_h = dec_btm - dec_top; //解码高度 */
|
||||
int max_dec_height = (opj->msy << 3) / ratio_h; //一个mcu分块缩放后可以有效绘制的行数
|
||||
int sub_top = 0;
|
||||
int sub_height = (draw_h > max_dec_height) ? max_dec_height : draw_h;
|
||||
//按mcu快缩放后的有效高度进行分行处理
|
||||
while (sub_top + draw_top < draw_btm) {
|
||||
int dec_sub_top = (draw_top + sub_top) * ratio_h;
|
||||
int dec_sub_btm = ceilf((float)(draw_top + sub_top + sub_height) * ratio_h);
|
||||
int dec_sub_h = dec_sub_btm - dec_sub_top;
|
||||
/* log_debug("%s draw(%d %d) dec(%d %d)%d maxdec%d sub(%d %d) dec_sub(%d %d)", */
|
||||
/* __func__, draw_top, draw_btm, dec_top, dec_btm, dec_h, max_dec_height, sub_top, sub_height, dec_sub_top, dec_sub_btm); */
|
||||
struct rect jpeg_dec_r; /*jpeg解码区域*/
|
||||
/* jpeg_dec_r.left = (cover_r.left - src_r->left) * ratio_w; */
|
||||
jpeg_dec_r.left = (cover_r.left - jpeg_draw_src.left) * ratio_w;
|
||||
jpeg_dec_r.top = dec_sub_top;
|
||||
jpeg_dec_r.width = cover_r.width * ratio_w;
|
||||
jpeg_dec_r.height = dec_sub_h;
|
||||
struct rect block_r; /*缩放后显示的区域*/
|
||||
block_r.top = cover_r.top + sub_top;
|
||||
block_r.height = sub_height;
|
||||
block_r.left = dst_r->left;
|
||||
block_r.width = dst_r->width;
|
||||
/* DUMP_RECT(__func__, __LINE__, "block_r", &block_r); */
|
||||
/* DUMP_RECT(__func__, __LINE__, "jpeg_dec_r", &jpeg_dec_r); */
|
||||
u8 *disp_buf = dst_buf + (block_r.top - dst_r->top) * 2 * dst_r->width;
|
||||
/*启动解码*/
|
||||
jljpeg_decode_start(opj, &jpeg_draw_src, &jpeg_dec_r, &cover_r, &block_r, disp_buf);
|
||||
sub_top += sub_height;
|
||||
sub_height = (sub_top + sub_height + draw_top < draw_btm) ? max_dec_height : draw_btm - draw_top - sub_top;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_draw_cb_gpu gpu绘图回调
|
||||
*
|
||||
* @param id
|
||||
* @param dst_buf
|
||||
* @param dst_r
|
||||
* @param src_r
|
||||
* @param bytes_per_pixel
|
||||
* @param priv
|
||||
* @param matrix
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void jpeg_draw_cb_gpu(int id, u8 *dst_buf, struct rect *dst_r, struct rect *src_r, u8 bytes_per_pixel, void *priv, void *matrix)
|
||||
{
|
||||
//先用过id获取句柄,如果获取不到就return
|
||||
struct jpeg_priv *__jpeg_priv = (struct jpeg_priv *) priv;
|
||||
struct jpeg_hd_manager *hd = jpeg_hd_manager_find_by_id(__jpeg_priv->task_id, __jpeg_priv->elm_id);
|
||||
if (!hd) {
|
||||
log_warn("%s elmid:%d task_id:%d", __func__, __jpeg_priv->elm_id, __jpeg_priv->task_id);
|
||||
return;
|
||||
}
|
||||
jpeg_draw_cb(id, dst_buf, dst_r, src_r, bytes_per_pixel, hd->opj, matrix);
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jlui_draw_jpeg_cb_exit 任务销毁时调用,释放jpeg资源
|
||||
*
|
||||
* @param priv jpeg句柄
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_draw_cb_exit(void *draw_info, void *priv)
|
||||
{
|
||||
pJLGPUTaskDraw_t __draw_info = (pJLGPUTaskDraw_t)draw_info;
|
||||
/*使用双任务链推屏时,在息屏前或更新资源句柄前释放jpeg句柄,避免双链表冲突*/
|
||||
void *opj = __draw_info->priv;
|
||||
__draw_info->priv = NULL;//由应用层释放
|
||||
__draw_info->priv_len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief cache_gpu_input_jpeg_data_cb 将数据拷贝到psram
|
||||
*
|
||||
* @param priv jpeg句柄
|
||||
* @param dst 解码后的输出buf
|
||||
* @param src NULL
|
||||
* @param len 0
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void cache_gpu_input_jpeg_data_cb(void *priv, void *dst, void *src, int len)
|
||||
{
|
||||
jdec_opj *jpg_hd = (jdec_opj *)priv;
|
||||
//解码
|
||||
struct rect jpeg_dec = {
|
||||
.left = 0,
|
||||
.top = 0,
|
||||
.width = jpg_hd->width,
|
||||
.height = jpg_hd->height,
|
||||
};
|
||||
int bytes_per_pixel = 2;
|
||||
u32 jpeg_width_align = (jpeg_dec.width + 15) / 16 * 16;
|
||||
u32 jpeg_height_align = (jpg_hd->height + 15) / 16 * 16;
|
||||
u32 jpeg_stride = bytes_per_pixel * jpeg_width_align ;
|
||||
u8 *tmp_buf = malloc_psram(jpeg_stride * jpeg_height_align);
|
||||
jlgpu_scheduler_wait_sync();
|
||||
extern int ui_disp_out_stride_set(u16 stride);
|
||||
ui_disp_out_stride_set(jpeg_stride);
|
||||
struct rect dst_r = {
|
||||
.left = 0,
|
||||
.top = 0,
|
||||
.width = jpeg_width_align,
|
||||
.height = jpeg_height_align,
|
||||
};
|
||||
jpeg_draw_cb(0, tmp_buf, &dst_r, &jpeg_dec, bytes_per_pixel, jpg_hd, NULL);
|
||||
UI_IO_DEBUG_1(B, 6)
|
||||
texture_line_to_tile_base(dst, tmp_buf, jpeg_width_align, jpeg_height_align, GPU_FORMAT_RGB565);
|
||||
UI_IO_DEBUG_0(B, 6)
|
||||
free_psram(tmp_buf);
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief cache_gpu_input_jpeg_data 解码jpeg图片到psram
|
||||
*
|
||||
* @param head 预留
|
||||
* @param task_param gpu任务参数
|
||||
* @param fp jpeg文件指针
|
||||
* @param index 任务链索引,一般为0、1
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *cache_gpu_input_jpeg_data(void *head, pJLGPUTaskParam_t task_param, void *fp, int index)
|
||||
{
|
||||
/* 检查是否已经有缓存,如果需要缓存jpg没在cache里,释放原来的,缓存新的 */
|
||||
void *cache_addr = gpu_input_stream_cache_check(task_param->image.data_crc);
|
||||
//jpeg原始数据,nand使用
|
||||
u8 *jpeg_src_data = NULL;
|
||||
int vaild_index = index;
|
||||
/* printf("@@@@@ cache_addr: 0x%x\n crc:%d", (u32)cache_addr,task_param->image.data_crc); */
|
||||
if (!cache_addr) {//解码jpeg到psram
|
||||
jdec_opj *jpg_hd = jpeg_malloc(sizeof(jdec_opj)); //在任务销毁时释放
|
||||
jpg_hd->device = jpeg_malloc(sizeof(struct flash_file_info));//设备句柄,这里可以是文件句柄等,搭配input_steam使用
|
||||
#if TCFG_NANDFLASH_DEV_ENABLE
|
||||
if (fp) {
|
||||
//文件头解析的时候比较零散,这里直接将文件拷贝到psram,解完后free
|
||||
UI_IO_DEBUG_1(B, 2);
|
||||
jpeg_src_data = jpeg_malloc(task_param->image.len);
|
||||
res_fseek(fp, (u32)task_param->image.offset, SEEK_SET);
|
||||
res_fread(fp, jpeg_src_data, task_param->image.len);
|
||||
struct flash_file_info *p_info = (struct flash_file_info *)jpg_hd->device;
|
||||
p_info->offset = (u32)jpeg_src_data;
|
||||
p_info->tab = NULL;
|
||||
p_info->tab_size = 0;
|
||||
p_info->last_tab_data_len = task_param->image.len;
|
||||
UI_IO_DEBUG_0(B, 2);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
#else
|
||||
memcpy(jpg_hd->device, &task_param->info, sizeof(struct flash_file_info));
|
||||
#endif
|
||||
UI_IO_DEBUG_1(B, 4);
|
||||
if (jpeg_module_opj_init(jpg_hd)) {//初始化jpeg头
|
||||
//异常释放资源
|
||||
jpeg_free(jpg_hd->device);
|
||||
jljpeg_decode_release(jpg_hd, 0);
|
||||
jpeg_free(jpg_hd);
|
||||
if (jpeg_src_data) {
|
||||
jpeg_free(jpeg_src_data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//cache
|
||||
/* u32 jpeg_stride = 2 * (jpg_hd->width + 7) / 8 * 8; */
|
||||
/* u32 jpeg_height_align = (jpg_hd->height + 7) / 8 * 8; */
|
||||
u32 jpeg_width_align = (jpg_hd->width + 15) / 16 * 16;
|
||||
u32 jpeg_stride = 2 * jpeg_width_align;
|
||||
u32 jpeg_height_align = (jpg_hd->height + 15) / 16 * 16;
|
||||
u32 jpeg_img_len = jpeg_stride * jpeg_height_align ;
|
||||
cache_addr = gpu_input_stream_cache_add_with_callback(jpg_hd, jpg_hd, jpeg_img_len,
|
||||
task_param->image.data_crc, NULL, 0, cache_gpu_input_jpeg_data_cb);
|
||||
//从cache同步到物理介质,后续用nocache直接访问
|
||||
psram_flush_cache(cache_addr, jpeg_img_len);
|
||||
jpeg_free(jpg_hd->device);
|
||||
jljpeg_decode_release(jpg_hd, 1);
|
||||
jpeg_free(jpg_hd);
|
||||
if (jpeg_src_data) {
|
||||
jpeg_free(jpeg_src_data);
|
||||
}
|
||||
UI_IO_DEBUG_0(B, 4);
|
||||
}
|
||||
//使用nocache地址访问,提高读效率
|
||||
task_param->texture.data = psram_cache_2_nocache(cache_addr);
|
||||
/* task_param->texture.data =(cache_addr); */
|
||||
//更新任务配置
|
||||
task_param->texture.mmu_tab_base = NULL;
|
||||
task_param->format = GPU_FORMAT_RGB565;
|
||||
task_param->texture.not_compress = 1;
|
||||
task_param->texture.adr_mode = 0;
|
||||
int width = task_param->image.width;
|
||||
int height = task_param->image.height;
|
||||
|
||||
task_param->image.width = (width + 15) / 16 * 16;
|
||||
task_param->image.height = (height + 15) / 16 * 16;
|
||||
|
||||
if (cache_addr) {
|
||||
gpu_input_stream_cache_vaild_value_set_by_index((u32)cache_addr, 3);
|
||||
gpu_input_stream_cache_set_index((u32)cache_addr, index);
|
||||
}
|
||||
return task_param->texture.data;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jlui_jpeg_infunc jpeg位流输入
|
||||
*
|
||||
* @param opj 句柄
|
||||
* @param buf 位流buf
|
||||
* @param len 预获取长度
|
||||
*
|
||||
* @return 实际数据长度
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
|
||||
static u32 jlui_jpeg_infunc(struct _jdec_opj *opj, u8 *buf, u32 len)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
if (buf) {
|
||||
FILE *fp = (FILE *)(((int *)opj->device)[0]);
|
||||
/* printf("%s fp:0x%x",__func__,(u32)fp); */
|
||||
/* printf("%s offset:%d len:%d end:%d\n", __func__, opj->curr_offset,len,flen(fp)); */
|
||||
fseek(fp, opj->curr_offset, SEEK_SET);
|
||||
return fread(buf, len, 1, fp);
|
||||
} else {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_init jpeg句柄初始化(初始化硬件、解析文件头)
|
||||
*
|
||||
* @param priv
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_module_opj_init_file(void *priv)
|
||||
{
|
||||
jdec_opj *opj = (jdec_opj *)priv;
|
||||
void *dev = opj->device;
|
||||
int ret = jljpeg_decode_init(opj);
|
||||
if (!ret) {
|
||||
ret = jljpeg_img_info_get(opj, jlui_jpeg_infunc, dev);
|
||||
ASSERT(!ret, "jpeg file notsupport err:%x", ret);
|
||||
}
|
||||
log_debug("%s %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_module_opj_create 创建jpeg句柄
|
||||
*
|
||||
* @param dev
|
||||
* @param dev_len
|
||||
* @param check
|
||||
* @param index
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *jpeg_module_opj_create_file(void *path, int path_len, u32 check, u32 index, u32 task_id, u32 elm_id)
|
||||
{
|
||||
int ret;
|
||||
struct jpeg_hd_manager *hd = jpeg_hd_manager_check(check);
|
||||
jdec_opj *opj = NULL;
|
||||
if (!hd) {
|
||||
opj = jpeg_malloc(sizeof(jdec_opj));
|
||||
hd = jpeg_hd_manager_add(opj, check);
|
||||
void *dev = (void *)fopen(path, "r");
|
||||
printf("%s [FILE] fp:0x%x ", __func__, (u32)dev);
|
||||
int dev_len = sizeof(FILE *);
|
||||
hd->file_flag = 1;
|
||||
opj->device = jpeg_malloc(dev_len);
|
||||
memcpy(opj->device, &dev, dev_len);
|
||||
ret = jpeg_module_opj_init_file((void *)opj);
|
||||
if (ret) {
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
jpeg_module_opj_release_async((void *)opj);
|
||||
opj = NULL;
|
||||
}
|
||||
hd->task_id = task_id;
|
||||
hd->elm_id = elm_id;
|
||||
} else {
|
||||
opj = hd->opj;
|
||||
}
|
||||
if (opj) {
|
||||
jpeg_hd_manager_vaild_set(opj, 1);
|
||||
}
|
||||
return (void *)opj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,616 @@
|
||||
/* #include "app_task.h" */
|
||||
#include "system/timer.h"
|
||||
#include "device/device.h"
|
||||
#include "key_event_deal.h"
|
||||
|
||||
#include "res/resfile.h"
|
||||
#include "jlui/ui.h"
|
||||
#include "jlui_app/ui_style.h"
|
||||
#include "jlui_app/ui_api.h"
|
||||
#include "jlui_app/res_config.h"
|
||||
#include "jlui_app/ui_resource.h"
|
||||
#include "jlui_app/ui_sys_param.h"
|
||||
#include "ui_draw/ui_type.h"
|
||||
|
||||
#include "jlgpu_math.h" // matrix
|
||||
#include "jlgpu_driver.h" // gpu 驱动
|
||||
|
||||
#include "gpu_port.h" // GPU 接口,依赖于 jlgpu_driver.h
|
||||
#include "gpu_task.h"
|
||||
|
||||
#include "jljpeg_decode.h"
|
||||
#include "jpeg_stream.h"
|
||||
#include "video/avi/avilib.h"
|
||||
|
||||
#define LOG_TAG_CONST JPEG
|
||||
#define LOG_TAG "[JPEG_STREAM]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define JPEG_STREAM_ALLOC malloc_psram
|
||||
#define JPEG_STREAM_FREE free_psram
|
||||
|
||||
#define JPEG_STREAM_SPIN_LOCK_EN 1
|
||||
|
||||
struct jpeg_stream_info {
|
||||
// jpeg原图
|
||||
u8 *src_buf;
|
||||
int src_len;
|
||||
volatile u8 data_lock;
|
||||
u16 idx;
|
||||
#if JPEG_STREAM_SPIN_LOCK_EN
|
||||
spinlock_t lock;
|
||||
#else
|
||||
OS_MUTEX lock;
|
||||
#endif
|
||||
} __jpeg_stream_info;
|
||||
#define __this (&__jpeg_stream_info)
|
||||
|
||||
#if JPEG_STREAM_SPIN_LOCK_EN
|
||||
#define JPEG_STREAM_LOCK_INIT spin_lock_init(&__this->lock);
|
||||
#define JPEG_STREAM_LOCK spin_lock(&__this->lock);
|
||||
#define JPEG_STREAM_UNLOCK spin_unlock(&__this->lock);
|
||||
#else
|
||||
#define JPEG_STREAM_LOCK_INIT os_mutex_create(&__this->lock);
|
||||
#define JPEG_STREAM_LOCK os_mutex_pend(&__this->lock);
|
||||
#define JPEG_STREAM_UNLOCK os_mutex_post(&__this->lock);
|
||||
#endif
|
||||
|
||||
#define GPU_TASK_ID(page, id, index) ((page << 26) | (0 << 24) | (id << 8) | index)
|
||||
|
||||
|
||||
extern u32 usr_mmu_hash(u32 hash, u8 *data, int len);
|
||||
extern void *jpeg_module_opj_create_file(void *path, int path_len, u32 check, u32 index, u32 task_id, u32 elm_id);
|
||||
extern void *jpeg_module_opj_create(void *dev, int dev_len, u32 check, u32 index, u32 task_id, u32 elm_id);
|
||||
extern int jpeg_module_opj_clr_all();
|
||||
extern void *jpeg_hd_create_priv(u32 task_id, u32 elm_id);
|
||||
extern int jpeg_hd_get_priv_len();
|
||||
extern void jpeg_draw_cb_gpu(int id, u8 *dst_buf, struct rect *dst_r, struct rect *src_r, u8 bytes_per_pixel, void *priv, void *matrix);
|
||||
extern void jlui_free(void *buf, u32 ram_type, u32 module_type);
|
||||
extern int jpeg_module_opj_init(void *priv);
|
||||
extern int jljpeg_decode_release(jdec_opj *opj, int global_hd_clr);
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_init jpeg数据流初始化
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jljpeg_stream_init()
|
||||
{
|
||||
JPEG_STREAM_LOCK_INIT;
|
||||
__this->data_lock = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_deinit
|
||||
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jljpeg_stream_deinit()
|
||||
{
|
||||
JPEG_STREAM_LOCK;
|
||||
__this->data_lock = 1;
|
||||
__this->src_len = 0;
|
||||
JPEG_STREAM_FREE(__this->src_buf);
|
||||
__this->src_buf = NULL;
|
||||
JPEG_STREAM_UNLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_lock 数据锁保护
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void jljpeg_stream_src_data_lock()
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_debug("<%s> rets:%x\n", __func__, rets);
|
||||
JPEG_STREAM_LOCK;
|
||||
__this->data_lock = 1;
|
||||
JPEG_STREAM_UNLOCK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_unlock 数据解锁保护
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void jljpeg_stream_src_data_unlock()
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_debug("<%s> rets:%x\n", __func__, rets);
|
||||
JPEG_STREAM_LOCK;
|
||||
__this->data_lock = 0;
|
||||
JPEG_STREAM_UNLOCK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_lock_check 查询锁状态
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jljpeg_stream_src_data_lock_check()
|
||||
{
|
||||
return __this->data_lock;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_copy 输入数据并拷贝到psram缓存
|
||||
*
|
||||
* @param buf
|
||||
* @param size
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jljpeg_stream_src_data_copy(u8 *buf, int size)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_debug("<%s> rets:%x size:%d\n", __func__, rets, size);
|
||||
if (jljpeg_stream_src_data_lock_check()) {
|
||||
return -1;
|
||||
}
|
||||
JPEG_STREAM_LOCK;
|
||||
if (__this->src_buf) {
|
||||
JPEG_STREAM_FREE(__this->src_buf);
|
||||
}
|
||||
log_debug("%s line:%d buf:%x", __func__, __LINE__, (u32)__this->src_buf);
|
||||
__this->src_len = size;
|
||||
__this->src_buf = JPEG_STREAM_ALLOC(size);
|
||||
memcpy(__this->src_buf, buf, size);
|
||||
__this->idx++;
|
||||
log_debug("%s line:%d buf:%x", __func__, __LINE__, (u32)__this->src_buf);
|
||||
JPEG_STREAM_UNLOCK;
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_len_get 获取缓存数据长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jljpeg_stream_src_data_len_get()
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_debug("<%s> rets:%x len:%d\n", __func__, rets, __this->src_len);
|
||||
return __this->src_len;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_get 获取缓存数据地址
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
u8 *jljpeg_stream_src_data_get()
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
log_debug("<%s> rets:%x buf:0x%x\n", __func__, rets, (u32)__this->src_buf);
|
||||
return __this->src_buf;
|
||||
}
|
||||
|
||||
void camera_manager_resume(void);
|
||||
void camera_manager_suspend(void);
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jljpeg_stream_src_data_save_to_file 将缓存数据写入到文件
|
||||
*
|
||||
* @param filename 路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jljpeg_stream_src_data_save_to_file(s8 *filename)
|
||||
{
|
||||
int has_photo = 0;
|
||||
//100ms 足够编完一帧
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (jljpeg_stream_src_data_len_get()) {
|
||||
log_debug("%s %d", __func__, __LINE__);
|
||||
has_photo = 1;
|
||||
break;
|
||||
}
|
||||
os_time_dly(1);
|
||||
}
|
||||
|
||||
if (!has_photo) {
|
||||
return -1;
|
||||
}
|
||||
/* camera_manager_suspend(); */
|
||||
/* wdt_clear(); */
|
||||
FILE *fp = fopen(filename, "w+");
|
||||
log_debug("%s file_name:%s save ", __func__, filename);
|
||||
if (fp) {
|
||||
fwrite(jljpeg_stream_src_data_get(), 1, jljpeg_stream_src_data_len_get(), fp);
|
||||
u8 name[17] = {0};
|
||||
fget_name(fp, name, 16);
|
||||
log_info("%s file_name:%s real_name:%s save succ!!!", __func__, filename, name);
|
||||
fclose(fp);
|
||||
}
|
||||
/* camera_manager_resume(); */
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void jpeg_task_cb_exit(void *draw_info, void *priv)
|
||||
{
|
||||
/* jpeg_data_lock_unlock(); */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_image_ram 从ram中加载jpeg显示
|
||||
*
|
||||
* @param dc
|
||||
* @param left
|
||||
* @param top
|
||||
* @param width
|
||||
* @param height
|
||||
* @param addr jpeg地址
|
||||
* @param len
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void jpeg_image_ram(struct draw_context *dc, int left, int top, int width, int height, u8 *addr, int len)
|
||||
{
|
||||
jljpeg_stream_src_data_lock();
|
||||
int elm_id = dc->elm->id;
|
||||
u8 elm_index = 1;
|
||||
u16 idx = __this->idx;
|
||||
elm_index = dc->elm_index++;
|
||||
|
||||
int task_id = GPU_TASK_ID(dc->page, idx, elm_index);
|
||||
jlgpu_task_basic_param_init(GPU_TASK_IMAGE, task_id, elm_id);
|
||||
task_param.priority = dc->elm->prior;
|
||||
task_param.image.width = width;
|
||||
task_param.image.height = height;
|
||||
struct rect image_rect;
|
||||
image_rect.left = left;
|
||||
image_rect.top = top;
|
||||
image_rect.width = task_param.image.width;
|
||||
image_rect.height = task_param.image.height;
|
||||
// if (!get_rect_align(&dc->rect, &image_rect, dc->hori_align, dc->vert_align)) {
|
||||
// return ;
|
||||
// }
|
||||
|
||||
jlgpu_get_win_rect(&task_param.area);
|
||||
|
||||
task_param.info.offset = (u32)addr;
|
||||
task_param.info.last_tab_data_len = len;
|
||||
/* printf("%s %d %d", __func__, task_param.info.offset, task_param.info.last_tab_data_len); */
|
||||
get_rect_cover(&dc->rect, &image_rect, &task_param.draw);
|
||||
/* memcpy(&task_param.draw, &image_rect, sizeof(struct rect)); */
|
||||
task_param.task_type = GPU_TASK_DRAW;
|
||||
task_param.cb_func = jpeg_draw_cb_gpu;
|
||||
/* task_param.cb_exit = jpeg_task_cb_exit; */
|
||||
u32 res_hash = 5383;
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.image, sizeof(struct image_file));
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.task_id, 4);
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.element_id, 4);
|
||||
void *opj = jpeg_module_opj_create(&task_param.info, sizeof(struct flash_file_info), res_hash, dc->index, task_param.task_id, task_param.element_id);
|
||||
if (opj) {
|
||||
pJLGPUTaskUnit_t taskp = jlgpu_get_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id);
|
||||
if (taskp && taskp->info.draw_info) {
|
||||
jlui_free(taskp->info.draw_info->priv, UI_RAM_SRAM, UI_MODULE_FRAME);
|
||||
}
|
||||
task_param.priv = jpeg_hd_create_priv(task_param.task_id, task_param.element_id);
|
||||
task_param.priv_len = jpeg_hd_get_priv_len();
|
||||
task_param.draw_en = 1;
|
||||
}
|
||||
task_param.clut_format = task_param.image.clut_format;
|
||||
task_param.has_clut = task_param.image.has_clut;
|
||||
task_param.texture.data = (u8 *)task_param.info.offset;
|
||||
task_param.texture.mmu_tab_base = (u8 *)task_param.info.tab;
|
||||
|
||||
jlgpu_update_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id, &task_param);
|
||||
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_image_file 从文件加载图片,不缓存
|
||||
*
|
||||
* @param dc
|
||||
* @param left
|
||||
* @param top
|
||||
* @param width
|
||||
* @param height
|
||||
* @param path 路径
|
||||
* @param path_len
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void jpeg_image_file(struct draw_context *dc, int left, int top, int width, int height, u8 *path, int path_len)
|
||||
{
|
||||
int elm_id = dc->elm->id;
|
||||
u8 elm_index = 1;
|
||||
u16 idx = __this->idx;
|
||||
elm_index = dc->elm_index++;
|
||||
|
||||
int task_id = GPU_TASK_ID(dc->page, idx, elm_index);
|
||||
jlgpu_task_basic_param_init(GPU_TASK_IMAGE, task_id, elm_id);
|
||||
task_param.priority = dc->elm->prior;
|
||||
task_param.image.width = width;
|
||||
task_param.image.height = height;
|
||||
struct rect image_rect;
|
||||
image_rect.left = left;
|
||||
image_rect.top = top;
|
||||
image_rect.width = task_param.image.width;
|
||||
image_rect.height = task_param.image.height;
|
||||
// if (!get_rect_align(&dc->rect, &image_rect, dc->hori_align, dc->vert_align)) {
|
||||
// return ;
|
||||
// }
|
||||
|
||||
jlgpu_get_win_rect(&task_param.area);
|
||||
|
||||
/* task_param.info.offset = (u32)addr; */
|
||||
/* task_param.info.last_tab_data_len = len; */
|
||||
/* printf("%s %d %d", __func__, task_param.info.offset, task_param.info.last_tab_data_len); */
|
||||
get_rect_cover(&dc->rect, &image_rect, &task_param.draw);
|
||||
/* memcpy(&task_param.draw, &image_rect, sizeof(struct rect)); */
|
||||
task_param.task_type = GPU_TASK_DRAW;
|
||||
task_param.cb_func = jpeg_draw_cb_gpu;
|
||||
/* task_param.cb_exit = jpeg_task_cb_exit; */
|
||||
u32 res_hash = 5383;
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)path, path_len);
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.task_id, 4);
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.element_id, 4);
|
||||
void *opj = jpeg_module_opj_create_file((void *)path, path_len, res_hash, dc->index, task_param.task_id, task_param.element_id);
|
||||
if (opj) {
|
||||
pJLGPUTaskUnit_t taskp = jlgpu_get_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id);
|
||||
if (taskp && taskp->info.draw_info) {
|
||||
jlui_free(taskp->info.draw_info->priv, UI_RAM_SRAM, UI_MODULE_FRAME);
|
||||
}
|
||||
task_param.priv = jpeg_hd_create_priv(task_param.task_id, task_param.element_id);
|
||||
task_param.priv_len = jpeg_hd_get_priv_len();
|
||||
task_param.draw_en = 1;
|
||||
}
|
||||
task_param.clut_format = task_param.image.clut_format;
|
||||
task_param.has_clut = task_param.image.has_clut;
|
||||
task_param.texture.data = (u8 *)task_param.info.offset;
|
||||
task_param.texture.mmu_tab_base = (u8 *)task_param.info.tab;
|
||||
|
||||
jlgpu_update_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id, &task_param);
|
||||
|
||||
}
|
||||
extern void cache_gpu_input_jpeg_data_cb(void *priv, void *dst, void *src, int len);
|
||||
void *cache_gpu_input_jpeg_data_file(void *head, pJLGPUTaskParam_t task_param, u32 check, char *path)
|
||||
{
|
||||
/* 检查是否已经有缓存,如果需要缓存jpg没在cache里,释放原来的,缓存新的 */
|
||||
void *cache_addr = gpu_input_stream_cache_check(check);
|
||||
//jpeg原始数据,nand使用
|
||||
u8 *jpeg_src_data = NULL;
|
||||
int jpeg_src_data_len = 0;
|
||||
log_debug("@@@@@ cache_addr: 0x%x\n crc:0x%x path:%s", (u32)cache_addr, check, path);
|
||||
if (!cache_addr) {//解码jpeg到psram
|
||||
log_debug("%s path%s", __func__, path);
|
||||
|
||||
if (strstr(path, "avi") || strstr(path, "AVI")) {
|
||||
log_debug("AVI");
|
||||
wdt_clear();
|
||||
#if 0//限制文件大小
|
||||
FILE *avi_fp = fopen(path, "r");
|
||||
int avi_len = flen(avi_fp);
|
||||
fclose(avi_fp);
|
||||
if (avi_len > 80 * 1024 * 1024) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1//只解第一帧数据,内存开销小。code by ds
|
||||
int get_first_video_frame_info(const char *filename, int *offset, int *size);
|
||||
int frame_pos = 0, frame_len = 0;
|
||||
get_first_video_frame_info(path, &frame_pos, &frame_len);
|
||||
log_debug("%s %d pos:%d len:%d", __func__, __LINE__, frame_pos, frame_len);
|
||||
if (frame_len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
jpeg_src_data_len = frame_len;
|
||||
if (jpeg_src_data_len <= 0) {
|
||||
log_warn("%s %d", __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
jpeg_src_data = jpeg_malloc(jpeg_src_data_len);
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (fp) {
|
||||
fseek(fp, frame_pos, SEEK_SET);
|
||||
fread(jpeg_src_data, jpeg_src_data_len, 1, fp);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
#else//按avilib流程打开文件,内存开销都大
|
||||
avi_t *in_fd = AVI_open_input_file(path, 1);
|
||||
if (in_fd) {
|
||||
int frame_idx = 0;
|
||||
#if 1//先拿到pos和len,再申请内存
|
||||
int AVI_get_video_frame_info(avi_t * AVI, int frame, int *pos, int *len);
|
||||
int pos, len = 0;
|
||||
|
||||
AVI_get_video_frame_info(in_fd, frame_idx, &pos, &len);
|
||||
AVI_close(in_fd);
|
||||
log_debug("%s %d pos:%d len:%d", __func__, __LINE__, pos, len);
|
||||
jpeg_src_data_len = len;
|
||||
if (jpeg_src_data_len <= 0) {
|
||||
log_warn("%s %d", __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
jpeg_src_data = jpeg_malloc(jpeg_src_data_len);
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (fp) {
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
fread(jpeg_src_data, jpeg_src_data_len, 1, fp);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
#else//先申请内存,再释放文件
|
||||
jpeg_src_data_len = AVI_frame_size(in_fd, frame_idx);
|
||||
if (jpeg_src_data_len <= 0) {
|
||||
/* AVI_close(in_fd); */
|
||||
log_warn("%s %d", __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
jpeg_src_data = jpeg_malloc(jpeg_src_data_len);
|
||||
AVI_set_video_position(in_fd, frame_idx);
|
||||
int key_frame;
|
||||
AVI_read_frame(in_fd, (char *)jpeg_src_data, &key_frame);
|
||||
AVI_close(in_fd);
|
||||
#endif
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
} else {
|
||||
log_debug("JPEG");
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (fp) {
|
||||
//文件头解析的时候比较零散,这里直接将文件拷贝到psram,解完后free
|
||||
jpeg_src_data_len = flen(fp);
|
||||
jpeg_src_data = jpeg_malloc(jpeg_src_data_len);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(jpeg_src_data, jpeg_src_data_len, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
log_debug("%s dat:%x len%d\n", __func__, (u32)jpeg_src_data, jpeg_src_data_len);
|
||||
if (jpeg_src_data == NULL) {
|
||||
log_error("path:%s not find\n", path);
|
||||
return 0;
|
||||
}
|
||||
jdec_opj *jpg_hd = jpeg_malloc(sizeof(jdec_opj)); //在任务销毁时释放
|
||||
jpg_hd->device = jpeg_malloc(sizeof(struct flash_file_info));//设备句柄,这里可以是文件句柄等,搭配input_steam使用
|
||||
|
||||
struct flash_file_info *p_info = (struct flash_file_info *)jpg_hd->device;
|
||||
p_info->offset = (u32)jpeg_src_data;
|
||||
p_info->tab = NULL;
|
||||
p_info->tab_size = 0;
|
||||
p_info->last_tab_data_len = jpeg_src_data_len;
|
||||
if (jpeg_module_opj_init(jpg_hd)) {//初始化jpeg头
|
||||
//异常释放资源
|
||||
jpeg_free(jpg_hd->device);
|
||||
jljpeg_decode_release(jpg_hd, 0);
|
||||
jpeg_free(jpg_hd);
|
||||
if (jpeg_src_data) {
|
||||
jpeg_free(jpeg_src_data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//cache
|
||||
/* u32 jpeg_stride = 2 * (jpg_hd->width + 7) / 8 * 8; */
|
||||
/* u32 jpeg_height_align = (jpg_hd->height + 7) / 8 * 8; */
|
||||
u32 jpeg_width_align = (jpg_hd->width + 15) / 16 * 16;
|
||||
u32 jpeg_stride = 2 * jpeg_width_align;
|
||||
u32 jpeg_height_align = (jpg_hd->height + 15) / 16 * 16;
|
||||
u32 jpeg_img_len = jpeg_stride * jpeg_height_align ;
|
||||
cache_addr = gpu_input_stream_cache_add_with_callback(jpg_hd, jpg_hd, jpeg_img_len,
|
||||
check, NULL, 0, cache_gpu_input_jpeg_data_cb);
|
||||
//从cache同步到物理介质,后续用nocache直接访问
|
||||
/* psram_flush_cache(cache_addr, jpeg_img_len); */
|
||||
jpeg_free(jpg_hd->device);
|
||||
jljpeg_decode_release(jpg_hd, 1);
|
||||
jpeg_free(jpg_hd);
|
||||
if (jpeg_src_data) {
|
||||
jpeg_free(jpeg_src_data);
|
||||
}
|
||||
|
||||
}
|
||||
//使用nocache地址访问,提高读效率
|
||||
/* task_param->texture.data = psram_cache_2_nocache(cache_addr); */
|
||||
task_param->texture.data = (cache_addr);
|
||||
//更新任务配置
|
||||
task_param->texture.mmu_tab_base = NULL;
|
||||
task_param->format = GPU_FORMAT_RGB565;
|
||||
task_param->texture.not_compress = 1;
|
||||
task_param->texture.adr_mode = 0;
|
||||
int width = task_param->image.width;
|
||||
int height = task_param->image.height;
|
||||
|
||||
task_param->image.width = (width + 15) / 16 * 16;
|
||||
task_param->image.height = (height + 15) / 16 * 16;
|
||||
|
||||
if (cache_addr) {
|
||||
gpu_input_stream_cache_vaild_value_set_by_index((u32)cache_addr, 3);
|
||||
}
|
||||
return task_param->texture.data;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jpeg_image_file_psram 从文件加载jpeg解码到psram
|
||||
*
|
||||
* @param dc
|
||||
* @param left
|
||||
* @param top
|
||||
* @param width
|
||||
* @param height
|
||||
* @param path 路径
|
||||
* @param path_len
|
||||
* @param scale_en 缩放
|
||||
* @param scale_f
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int jpeg_image_file_psram(struct draw_context *dc, int left, int top, int width, int height, char *path, int path_len, int scale_en, float scale_f)
|
||||
{
|
||||
int elm_id = dc->elm->id;
|
||||
u8 elm_index = 1;
|
||||
u16 idx = __this->idx;
|
||||
elm_index = dc->elm_index++;
|
||||
|
||||
int task_id = GPU_TASK_ID(dc->page, idx, elm_index);
|
||||
jlgpu_task_basic_param_init(GPU_TASK_IMAGE, task_id, elm_id);
|
||||
task_param.priority = dc->elm->prior;
|
||||
task_param.image.width = width;
|
||||
task_param.image.height = height;
|
||||
struct rect image_rect;
|
||||
image_rect.left = left;
|
||||
image_rect.top = top;
|
||||
image_rect.width = task_param.image.width;
|
||||
image_rect.height = task_param.image.height;
|
||||
|
||||
jlgpu_get_win_rect(&task_param.area);
|
||||
|
||||
get_rect_cover(&dc->rect, &image_rect, &task_param.draw);
|
||||
|
||||
task_param.task_type = GPU_TASK_IMAGE;
|
||||
u32 res_hash = 5383;
|
||||
res_hash = usr_mmu_hash(res_hash, (u8 *)path, path_len);
|
||||
/* res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.task_id, 4); */
|
||||
/* res_hash = usr_mmu_hash(res_hash, (u8 *)&task_param.element_id, 4); */
|
||||
|
||||
task_param.clut_format = task_param.image.clut_format;
|
||||
task_param.has_clut = task_param.image.has_clut;
|
||||
task_param.texture.data = (u8 *)task_param.info.offset;
|
||||
task_param.texture.mmu_tab_base = (u8 *)task_param.info.tab;
|
||||
|
||||
task_param.texture.data = cache_gpu_input_jpeg_data_file(dc->gpu_task_head, &task_param, res_hash, path);
|
||||
if (!task_param.texture.data) {
|
||||
log_warn("%s %d", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
//加个缩放
|
||||
task_param.scale_en = scale_en;
|
||||
task_param.texture.tran.ratio_w = scale_f;
|
||||
task_param.texture.tran.ratio_h = scale_f;
|
||||
if (task_param.texture.data) {
|
||||
jlgpu_update_task_by_id(dc->gpu_task_head, task_param.task_id, task_param.element_id, &task_param);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef __jpeg_stream__
|
||||
#define __jpeg_stream__
|
||||
|
||||
#include "app_config.h"
|
||||
int jljpeg_stream_init();
|
||||
int jljpeg_stream_deinit();
|
||||
|
||||
void jljpeg_stream_src_data_lock();
|
||||
void jljpeg_stream_src_data_unlock();
|
||||
int jljpeg_stream_src_data_lock_check();
|
||||
|
||||
int jljpeg_stream_src_data_copy(u8 *buf, int size);
|
||||
int jljpeg_stream_src_data_len_get();
|
||||
u8 *jljpeg_stream_src_data_get();
|
||||
|
||||
int jljpeg_stream_src_data_save_to_file(s8 *filename);
|
||||
|
||||
void jpeg_image_ram(struct draw_context *dc, int left, int top, int width, int height, u8 *addr, int len);
|
||||
void jpeg_image_file(struct draw_context *dc, int left, int top, int width, int height, u8 *path, int path_len);
|
||||
int jpeg_image_file_psram(struct draw_context *dc, int left, int top, int width, int height, char *path, int path_len, int scale_en, float scale_f);
|
||||
#endif// __jpeg_stream__
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
#include "app_config.h"
|
||||
#include "includes.h"
|
||||
|
||||
#include "dbi.h"
|
||||
|
||||
#include "lcd_task.h"
|
||||
|
||||
struct lcd_task_private_def {
|
||||
u8 has_init;
|
||||
};
|
||||
|
||||
static struct lcd_task_private_def lcd_task_priv ALIGNED(4) = {0};
|
||||
#define __this (&lcd_task_priv)
|
||||
|
||||
|
||||
|
||||
|
||||
void jllcd_task(void *p)
|
||||
{
|
||||
int ret;
|
||||
int msg[32] = {0};
|
||||
|
||||
while (1) {
|
||||
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
|
||||
if (ret != OS_TASKQ) {
|
||||
continue;
|
||||
}
|
||||
/* put_buf((u8 *)msg, 32); */
|
||||
/* printf("%s(), msg: %d, flush: %d, area[%d, %d, %d, %d], addr: 0x%x, hdl: 0x%x\n", \ */
|
||||
/* __func__, msg[0], msg[1], msg[2], msg[3], msg[4], msg[5], msg[6], msg[7]); */
|
||||
|
||||
switch (msg[0]) {
|
||||
case LCD_MSG_FLUSH:
|
||||
// 消息格式:刷屏动作,刷屏标志,刷屏区域,刷屏buf,buf句柄
|
||||
switch (msg[1]) {
|
||||
case LCD_FLUSH_SET_AREA:
|
||||
lcd_set_draw_area(msg[2], msg[3], msg[4], msg[5]);
|
||||
break;
|
||||
case LCD_FLUSH_KISTART:
|
||||
extern void lcd_wait_te_sync();
|
||||
lcd_wait_te_sync(); // 等待TE同步
|
||||
lcd_set_draw_area(msg[2], msg[3], msg[4], msg[5]); // 设置绘制区域
|
||||
lcd_draw_kistart((u8 *)msg[6], msg[2], msg[3], msg[4], msg[5]); // 开始绘制
|
||||
break;
|
||||
case LCD_FLUSH_CONTINUE:
|
||||
lcd_draw_continue((u8 *)msg[6], msg[2], msg[3], msg[4], msg[5]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LCD_MSG_OTHER:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef __PUBLIC_LCD_TASK_H__
|
||||
#define __PUBLIC_LCD_TASK_H__
|
||||
|
||||
|
||||
// LCD 任务名称
|
||||
#define LCD_TASK_NAME "lcd"
|
||||
|
||||
|
||||
// LCD 消息类型
|
||||
typedef enum {
|
||||
LCD_MSG_OTHER, // 默认消息
|
||||
LCD_MSG_FLUSH, // 刷屏消息
|
||||
} lcd_task_msg_t;
|
||||
|
||||
|
||||
// 刷屏动作标志
|
||||
typedef enum {
|
||||
LCD_FLUSH_SET_AREA, // 设置刷屏区域
|
||||
LCD_FLUSH_KISTART, // 启动刷屏
|
||||
LCD_FLUSH_CONTINUE, // 续传
|
||||
} lcd_flush_flag_t;
|
||||
|
||||
|
||||
void jllcd_task(void *p);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,668 @@
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "ui_core.h"
|
||||
#include "control.h"
|
||||
|
||||
//UI框架RAM统计使能
|
||||
/* #define UI_BUF_DEBUG //内存debug */
|
||||
/* #define UI_BUF_CALC_LITE //轻量级统计 */
|
||||
/* #define UI_BUF_CALC //分模块统计 */
|
||||
#define LOG_TAG_CONST UI_BUF
|
||||
#define LOG_TAG "[ui_buf]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#if TCFG_UI_ENABLE
|
||||
|
||||
|
||||
extern size_t xPortGetPhysiceMemorySize(void);
|
||||
extern const u32 config_ui_alloc_psram_mod_sel;
|
||||
|
||||
/***************************************************************/
|
||||
// UI_BUF_CALC
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
#ifdef UI_BUF_CALC
|
||||
struct buffer_calc {
|
||||
struct list_head list;
|
||||
u8 *buf;
|
||||
int size;
|
||||
u32 ram_type;
|
||||
u32 module_type;
|
||||
};
|
||||
static struct buffer_calc buffer_used = {
|
||||
.list = {
|
||||
.next = &buffer_used.list,
|
||||
.prev = &buffer_used.list,
|
||||
},
|
||||
};
|
||||
static int jlui_malloc_cnt = 0;
|
||||
|
||||
/* RAM 类型名 */
|
||||
const static char *ui_ram_type_name[] = {
|
||||
"sram",
|
||||
"param",
|
||||
"cache",
|
||||
};
|
||||
|
||||
/* 统计各模块内存占用数量 */
|
||||
struct ui_module_name_def {
|
||||
char name[24]; // 模块名称
|
||||
int module; // 模块ID
|
||||
int sram; // 模块申请sram数量
|
||||
int other_ram; // psram or cache
|
||||
int count; // 模块申请内存次数
|
||||
};
|
||||
#define WIDGET(type) ((type << 16) | UI_MODULE_WIDGET)
|
||||
|
||||
static struct ui_module_name_def ui_module_name[] = {
|
||||
{"ui_core", UI_MODULE_CORE, 0, 0, 0},
|
||||
{"ui_frame", UI_MODULE_FRAME, 0, 0, 0},
|
||||
{"ui_resource", UI_MODULE_RESOURCE, 0, 0, 0},
|
||||
{"ui_gpu", UI_MODULE_GPU, 0, 0, 0},
|
||||
{"ui_dbi", UI_MODULE_DBI, 0, 0, 0},
|
||||
{"ui_font", UI_MODULE_FONT, 0, 0, 0},
|
||||
{"buf_manager", UI_MODULE_BUFFER, 0, 0, 0},
|
||||
{"gpu_cache", UI_MODULE_CACHE, 0, 0, 0},
|
||||
{"jpeg ", UI_MODULE_JPEG, 0, 0, 0},
|
||||
{"window", WIDGET(CTRL_TYPE_WINDOW), 0, 0, 0},
|
||||
{"layout", WIDGET(CTRL_TYPE_LAYOUT), 0, 0, 0},
|
||||
{"layer", WIDGET(CTRL_TYPE_LAYER), 0, 0, 0},
|
||||
{"grid ", WIDGET(CTRL_TYPE_GRID), 0, 0, 0},
|
||||
{"list ", WIDGET(CTRL_TYPE_LIST), 0, 0, 0},
|
||||
{"button", WIDGET(CTRL_TYPE_BUTTON), 0, 0, 0},
|
||||
{"pic ", WIDGET(CTRL_TYPE_PIC), 0, 0, 0},
|
||||
{"battery", WIDGET(CTRL_TYPE_BATTERY), 0, 0, 0},
|
||||
{"time ", WIDGET(CTRL_TYPE_TIME), 0, 0, 0},
|
||||
{"camera", WIDGET(CTRL_TYPE_CAMERA_VIEW), 0, 0, 0},
|
||||
{"text ", WIDGET(CTRL_TYPE_TEXT), 0, 0, 0},
|
||||
{"animation", WIDGET(CTRL_TYPE_ANIMATION), 0, 0, 0},
|
||||
{"player", WIDGET(CTRL_TYPE_PLAYER), 0, 0, 0},
|
||||
{"number", WIDGET(CTRL_TYPE_NUMBER), 0, 0, 0},
|
||||
{"progress", WIDGET(CTRL_TYPE_PROGRESS), 0, 0, 0},
|
||||
{"multiprogress", WIDGET(CTRL_TYPE_MULTIPROGRESS), 0, 0, 0},
|
||||
{"watch", WIDGET(CTRL_TYPE_WATCH), 0, 0, 0},
|
||||
{"slider", WIDGET(CTRL_TYPE_SLIDER), 0, 0, 0},
|
||||
{"vslider", WIDGET(CTRL_TYPE_VSLIDER), 0, 0, 0},
|
||||
{"compass", WIDGET(CTRL_TYPE_COMPASS), 0, 0, 0},
|
||||
};
|
||||
|
||||
static void ui_module_ram_change(int ram_type, int module_type, int size, int add) // add 表示size符号,+1/-1
|
||||
{
|
||||
int i;
|
||||
int operator = ((add > 0) ? (1) : (-1));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ui_module_name); i++) {
|
||||
if (ui_module_name[i].module == module_type) {
|
||||
if (ram_type == UI_RAM_SRAM) {
|
||||
ui_module_name[i].sram += (operator * size);
|
||||
} else {
|
||||
ui_module_name[i].other_ram += (operator * size);
|
||||
}
|
||||
ui_module_name[i].count += (operator);
|
||||
printf("[BUF_CALC]=====>>> %s %s sram %d,other_ram:%d total: %d, count: %d\n",
|
||||
ui_module_name[i].name, ((operator > 0) ? "malloc" : "free"), size, ui_module_name[i].sram, ui_module_name[i].other_ram, ui_module_name[i].count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("[BUF_CALC]=====>>> unknow module type: %d, size: %d, add: %d\n", module_type, size, add);
|
||||
}
|
||||
|
||||
void ui_module_ram_dump()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(ui_module_name); i++) {
|
||||
printf("[BUF_CALC]=====>>> module: %s \t sram_size: %d \t other_ram:%d \t count: %d\n",
|
||||
ui_module_name[i].name, ui_module_name[i].sram, ui_module_name[i].other_ram, ui_module_name[i].count);
|
||||
}
|
||||
}
|
||||
|
||||
void ui_buf_calc_add(void *buf, int size, u32 ram_type, u32 module_type)
|
||||
{
|
||||
jlui_malloc_cnt += 1;
|
||||
struct buffer_calc *new = (struct buffer_calc *)malloc(sizeof(struct buffer_calc));
|
||||
new->buf = buf;
|
||||
new->size = size;
|
||||
new->ram_type = ram_type;
|
||||
new->module_type = module_type;
|
||||
|
||||
list_add_tail((struct list_head *)new, (struct list_head *)&buffer_used);
|
||||
/* 打印申请的buf地址,buf大小,buf类型,申请模块 */
|
||||
printf("platform_malloc : 0x%x, size: %d, ram: %s\n", (int)buf, size, ui_ram_type_name[ram_type]);
|
||||
int real_type = -1;
|
||||
if (memory_in_vtl(buf)) {
|
||||
real_type = UI_RAM_SRAM;
|
||||
}
|
||||
/* 如果是UI控件申请,打印该UI控件申请的buf总大小 */
|
||||
ui_module_ram_change(real_type, module_type, size, 1);
|
||||
/* ui_module_ram_dump(); */
|
||||
|
||||
/* 统计整个UI框架申请的buf大小 */
|
||||
struct buffer_calc *p;
|
||||
int buffer_used_total = 0;
|
||||
list_for_each_entry(p, &buffer_used.list, list) {
|
||||
buffer_used_total += p->size;
|
||||
}
|
||||
printf("%s() =====>>> used buffer size:%d, malloc count: %d\n\n", __func__, buffer_used_total, jlui_malloc_cnt);
|
||||
}
|
||||
void ui_buf_calc_sub(void *buf, u32 ram_type, u32 module_type)
|
||||
{
|
||||
jlui_malloc_cnt -= 1;
|
||||
struct buffer_calc *p, *n;
|
||||
int size = 0;
|
||||
list_for_each_entry_safe(p, n, &buffer_used.list, list) {
|
||||
if (p->buf == buf) {
|
||||
/* 如果释放的ram类型和记录的不一样,打印警报 */
|
||||
if (p->ram_type != ram_type) {
|
||||
printf("[Warning]: platform_free ram type, excepted: %s, actual: %s\n",
|
||||
ui_ram_type_name[p->ram_type], ui_ram_type_name[ram_type]);
|
||||
}
|
||||
/* 如果释放的模块和记录的不一样,打印警报 */
|
||||
if (p->module_type != module_type) {
|
||||
printf("[Warning]: platform_free module type, excepted: %d, actual: %d\n", p->module_type, module_type);
|
||||
module_type = p->module_type;//使用记录的module
|
||||
}
|
||||
size = p->size;
|
||||
/* 打印释放的buf地址,buf大小,buf类型,释放模块 */
|
||||
printf("platform_free : 0x%x, size: %d, ram: %s, module: %d\n",
|
||||
(int)p->buf, p->size, ui_ram_type_name[ram_type], module_type);
|
||||
__list_del_entry((struct list_head *)p);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
int real_type = -1;
|
||||
if (memory_in_vtl(buf)) {
|
||||
real_type = UI_RAM_SRAM;
|
||||
}
|
||||
/* 如果是UI控件释放,打印该UI控件剩余的buf总大小 */
|
||||
if (size) {
|
||||
ui_module_ram_change(real_type, module_type, size, -1);
|
||||
}
|
||||
/* ui_module_ram_dump(); */
|
||||
|
||||
int buffer_used_total = 0;
|
||||
list_for_each_entry(p, &buffer_used.list, list) {
|
||||
buffer_used_total += p->size;
|
||||
}
|
||||
printf("%s() =====>>> used buffer size:%d, malloc count: %d\n\n", __func__, buffer_used_total, jlui_malloc_cnt);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
// UI_BUF_CALC_LITE
|
||||
/***************************************************************/
|
||||
#ifdef UI_BUF_CALC_LITE
|
||||
static u32 jlui_malloc_total_ram_count = 0; //heap ram size
|
||||
static u32 jlui_malloc_total_ram_max = 0; //heap ram峰值
|
||||
static u32 jlui_malloc_total_ram_unuse = 0; //未使用最大数量
|
||||
static u32 jlui_malloc_total_ram_cnt_max = 0; //ram申请数量统计峰值
|
||||
static u32 jlui_malloc_total_ram_cnt = 0; //ram申请数量统计
|
||||
|
||||
static u32 jlui_malloc_sram_count = 0;
|
||||
static u32 jlui_malloc_sram_max = 0;
|
||||
static u32 jlui_malloc_sram_unuse = 0;
|
||||
static u32 jlui_malloc_sram_cnt_max = 0;
|
||||
static u32 jlui_malloc_sram_cnt = 0;
|
||||
#endif
|
||||
void jlui_malloc_ram_info_dump()
|
||||
{
|
||||
#ifdef UI_BUF_CALC_LITE
|
||||
printf("%s [totalram] curr_size:%d max_size%d curr_block:%d max_block:%d\n", __func__, \
|
||||
jlui_malloc_total_ram_count, jlui_malloc_total_ram_max, jlui_malloc_total_ram_cnt_max, jlui_malloc_total_ram_cnt);
|
||||
printf("%s [sram] curr_size:%d max_size%d curr_block:%d max_block:%d unuse_in_max:%d\n", __func__, \
|
||||
jlui_malloc_sram_count, jlui_malloc_sram_max, jlui_malloc_sram_cnt_max, jlui_malloc_sram_cnt, jlui_malloc_sram_unuse);
|
||||
#endif
|
||||
}
|
||||
|
||||
void jlui_malloc_ram_info_clr(u8 clr)
|
||||
{
|
||||
#ifdef UI_BUF_CALC_LITE
|
||||
if (clr & BIT(0)) {
|
||||
jlui_malloc_total_ram_count = 0;
|
||||
jlui_malloc_sram_count = 0;
|
||||
}
|
||||
if (clr & BIT(1)) {
|
||||
jlui_malloc_total_ram_max = 0;
|
||||
jlui_malloc_total_ram_cnt_max = 0;
|
||||
jlui_malloc_sram_max = 0;
|
||||
jlui_malloc_sram_cnt_max = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
// CACHE_BUF
|
||||
/***************************************************************/
|
||||
|
||||
#if TCFG_DCACHE_RUN_GPU_BUF || TCFG_ICACHE_RUN_GPU_BUF||TCFG_ICACHE_RUN_FTL_BUF
|
||||
#include "lbuf.h"
|
||||
|
||||
extern u32 dcache_ram_bss_remain_begin;
|
||||
extern u32 dcache_ram_bss_remain_end;
|
||||
#define DCACHE_GPU_START (int)(&dcache_ram_bss_remain_begin)
|
||||
#define DCACHE_GPU_END (int)(&dcache_ram_bss_remain_end)
|
||||
#define DCACHE_GPU_ADDR (void *)(DCACHE_GPU_START)
|
||||
#define DCACHE_GPU_SIZE (int)(DCACHE_GPU_END - DCACHE_GPU_START)
|
||||
|
||||
extern u32 icache_ram_bss_remain_begin;
|
||||
extern u32 icache_ram_bss_remain_end;
|
||||
#define ICACHE_GPU_START (int)(&icache_ram_bss_remain_begin)
|
||||
#define ICACHE_GPU_END (int)(&icache_ram_bss_remain_end)
|
||||
#define ICACHE_GPU_ADDR (void *)(ICACHE_GPU_START)
|
||||
#define ICACHE_GPU_SIZE (int)(ICACHE_GPU_END - ICACHE_GPU_START)
|
||||
|
||||
static struct lbuff_head *dcache_gpu_lbuf = NULL;
|
||||
static struct lbuff_head *icache_gpu_lbuf = NULL;
|
||||
|
||||
#if TCFG_ICACHE_DYNAMIC_SWITCH
|
||||
extern void icache_way_switch(u8 num);
|
||||
static void jlgpu_icache_ram_check(void)
|
||||
{
|
||||
if (icache_gpu_lbuf == NULL) {
|
||||
icache_way_switch(4 - TCFG_FREE_ICACHE_WAY);
|
||||
icache_gpu_lbuf = lbuf_init(ICACHE_GPU_ADDR, ICACHE_GPU_SIZE, 4, 0);
|
||||
}
|
||||
}
|
||||
static u8 jlgpu_icache_ram_enter(u32 timeout)
|
||||
{
|
||||
if (icache_gpu_lbuf) {
|
||||
struct lbuff_state state = {0};
|
||||
lbuf_state(icache_gpu_lbuf, &state);
|
||||
if (((int)state.avaliable + (int)sizeof(struct lbuff_head)) == ICACHE_GPU_SIZE) {
|
||||
icache_gpu_lbuf = NULL;
|
||||
icache_way_switch(4);
|
||||
return 1;
|
||||
} else {
|
||||
putchar('C');
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
REGISTER_LP_REQUEST(power_jlui_icache) = {
|
||||
.name = "ich_ram",
|
||||
.request_enter = jlgpu_icache_ram_enter,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int jlgpu_cache_init(void)
|
||||
{
|
||||
#if TCFG_DCACHE_RUN_GPU_BUF
|
||||
dcache_gpu_lbuf = lbuf_init(DCACHE_GPU_ADDR, DCACHE_GPU_SIZE, 4, 0);
|
||||
/* lbuf_dump(dcache_gpu_lbuf); */
|
||||
#endif
|
||||
#if TCFG_ICACHE_RUN_GPU_BUF||TCFG_ICACHE_RUN_FTL_BUF
|
||||
icache_gpu_lbuf = lbuf_init(ICACHE_GPU_ADDR, ICACHE_GPU_SIZE, 4, 0);
|
||||
/* lbuf_dump(icache_gpu_lbuf); */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
early_initcall(jlgpu_cache_init);
|
||||
|
||||
static int jlgpu_buf_is_cache(void *buf)
|
||||
{
|
||||
#if TCFG_DCACHE_RUN_GPU_BUF
|
||||
if (((int)buf >= DCACHE_GPU_START) && ((int)buf < DCACHE_GPU_END)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if TCFG_ICACHE_RUN_GPU_BUF||TCFG_ICACHE_RUN_FTL_BUF
|
||||
if (((int)buf >= ICACHE_GPU_START) && ((int)buf < ICACHE_GPU_END)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *jlgpu_cache_malloc(int size)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
#if TCFG_ICACHE_DYNAMIC_SWITCH
|
||||
jlgpu_icache_ram_check();
|
||||
#endif
|
||||
|
||||
#if TCFG_DCACHE_RUN_GPU_BUF
|
||||
if (ptr == NULL) {
|
||||
ptr = lbuf_alloc(dcache_gpu_lbuf, size);
|
||||
/* if (ptr == NULL) { */
|
||||
/* printf("dcache gpu over \n"); */
|
||||
/* lbuf_dump(dcache_gpu_lbuf); */
|
||||
/* } */
|
||||
}
|
||||
#endif
|
||||
#if TCFG_ICACHE_RUN_GPU_BUF||TCFG_ICACHE_RUN_FTL_BUF
|
||||
if (ptr == NULL) {
|
||||
ptr = lbuf_alloc(icache_gpu_lbuf, size);
|
||||
/* if (ptr == NULL) { */
|
||||
/* printf("icache gpu over \n"); */
|
||||
/* lbuf_dump(icache_gpu_lbuf); */
|
||||
/* } */
|
||||
}
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void jlgpu_cache_free(void *buf)
|
||||
{
|
||||
lbuf_free(buf);
|
||||
}
|
||||
void *cache_malloc(int size)
|
||||
{
|
||||
void *ptr = jlgpu_cache_malloc(size);
|
||||
if (ptr == NULL) {
|
||||
ptr = malloc(size);
|
||||
}
|
||||
printf("%s ptr:0x%x\n", __func__, (u32)ptr);
|
||||
return ptr;
|
||||
}
|
||||
void cache_free(void *buf)
|
||||
{
|
||||
if (jlgpu_buf_is_cache(buf)) {
|
||||
jlgpu_cache_free(buf);
|
||||
return;
|
||||
}
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
// PSRAM
|
||||
/***************************************************************/
|
||||
#define NO_CACHE_ADDR_BEGIN ((void*)0x04000000)
|
||||
#define NO_CACHE_ADDR_END ((void*)0x08000000)//不含
|
||||
#define CACHE_ADDR_BEGIN ((void*)0x08000000)
|
||||
#define CACHE_ADDR_END ((void*)0x0C000000)//不含
|
||||
#define CACHE_NO_CACHE_TRANS (0x04000000)
|
||||
#define PSRAM_ADDR_BEGIN NO_CACHE_ADDR_BEGIN
|
||||
#define PSRAM_ADDR_END CACHE_ADDR_END
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief psram_cache_2_nocache
|
||||
*
|
||||
* @param p
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *psram_cache_2_nocache(void *p)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
if ((p >= CACHE_ADDR_BEGIN) && (p < CACHE_ADDR_END)) {
|
||||
u32 addr = (u32)p;
|
||||
return (void *)(addr - CACHE_NO_CACHE_TRANS);
|
||||
}
|
||||
if ((p >= NO_CACHE_ADDR_BEGIN) && (p < NO_CACHE_ADDR_END)) {
|
||||
return p;
|
||||
}
|
||||
ASSERT(0, "ADDR:0x%x rets:0x%x", (u32)p, rets);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief psram_nocache_2_cache
|
||||
*
|
||||
* @param p
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *psram_nocache_2_cache(void *p)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
if ((p >= CACHE_ADDR_BEGIN) && (p < CACHE_ADDR_END)) {
|
||||
return (p);
|
||||
}
|
||||
if ((p >= NO_CACHE_ADDR_BEGIN) && (p < NO_CACHE_ADDR_END)) {
|
||||
u32 addr = (u32)p;
|
||||
return (void *)(addr + CACHE_NO_CACHE_TRANS);
|
||||
}
|
||||
ASSERT(0, "ADDR:0x%x rets:0x%x", (u32)p, rets);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ui_buf_is_psram_nocache(void *buf)
|
||||
{
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
if ((buf >= NO_CACHE_ADDR_BEGIN) && (buf < NO_CACHE_ADDR_END)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int ui_buf_is_psram(void *buf)
|
||||
{
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
if ((buf >= PSRAM_ADDR_BEGIN) && (buf < PSRAM_ADDR_END)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#ifdef UI_BUF_CALC_LITE
|
||||
static void *jlui_malloc_calc_lite(int size, u32 ram_type, u32 module_type)
|
||||
{
|
||||
u8 *buf = NULL;
|
||||
u8 sram_flag = 0;
|
||||
size += 8;
|
||||
do {
|
||||
#if (TCFG_DCACHE_RUN_GPU_BUF || TCFG_ICACHE_RUN_GPU_BUF)&&(!TCFG_PSRAM_DEV_ENABLE)
|
||||
if (module_type == UI_MODULE_GPU) {
|
||||
buf = jlgpu_cache_malloc(size);
|
||||
if (buf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if TCFG_PSRAM_DEV_ENABLE //psram buf
|
||||
if (config_ui_alloc_psram_mod_sel & BIT((module_type & 0xffff))) {
|
||||
buf = malloc_psram(size);
|
||||
if (buf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
buf = malloc(size); //sram buf
|
||||
sram_flag = 1;
|
||||
} while (0);
|
||||
|
||||
size -= 8;
|
||||
int magic = 0xaabbccdd;
|
||||
memcpy(buf, &magic, 4); //free时识别
|
||||
memcpy(buf + 4, &size, 4); //free时统计
|
||||
|
||||
jlui_malloc_total_ram_count += size;
|
||||
jlui_malloc_total_ram_cnt++;
|
||||
if (jlui_malloc_total_ram_count > jlui_malloc_total_ram_max) {
|
||||
jlui_malloc_total_ram_max = jlui_malloc_total_ram_count;
|
||||
jlui_malloc_total_ram_cnt_max = jlui_malloc_total_ram_cnt;
|
||||
}
|
||||
if (sram_flag) {
|
||||
jlui_malloc_sram_count += size;
|
||||
jlui_malloc_sram_cnt++;
|
||||
if (jlui_malloc_sram_count > jlui_malloc_sram_max) {
|
||||
jlui_malloc_sram_max = jlui_malloc_sram_count;
|
||||
jlui_malloc_sram_cnt_max = jlui_malloc_sram_cnt;
|
||||
jlui_malloc_sram_unuse = xPortGetPhysiceMemorySize();
|
||||
}
|
||||
}
|
||||
buf += 8;
|
||||
return (void *)buf;
|
||||
}
|
||||
static void jlui_free_calc_lite(void *buf)
|
||||
{
|
||||
int size = 0;
|
||||
u8 *tmp_buf = (u8 *)buf;
|
||||
tmp_buf -= 8;
|
||||
u32 magic = 0;
|
||||
memcpy(&magic, tmp_buf, 4);
|
||||
if (magic == 0xaabbccdd) {
|
||||
memcpy(&size, tmp_buf + 4, 4);
|
||||
jlui_malloc_total_ram_cnt--;
|
||||
jlui_malloc_total_ram_count -= size;
|
||||
buf = tmp_buf;
|
||||
}
|
||||
#if (TCFG_DCACHE_RUN_GPU_BUF || TCFG_ICACHE_RUN_GPU_BUF)&&(!TCFG_PSRAM_DEV_ENABLE)
|
||||
if (jlgpu_buf_is_cache(buf)) {
|
||||
jlgpu_cache_free(buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
if (ui_buf_is_psram(buf)) {
|
||||
buf = psram_nocache_2_cache(buf);
|
||||
free_psram(buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (size) {
|
||||
jlui_malloc_sram_cnt--;
|
||||
jlui_malloc_sram_count -= size;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
#endif
|
||||
static void *jlui_malloc_normal(int size, u32 ram_type, u32 module_type)
|
||||
{
|
||||
void *buf = NULL;
|
||||
do {
|
||||
#if (TCFG_DCACHE_RUN_GPU_BUF || TCFG_ICACHE_RUN_GPU_BUF)&&(!TCFG_PSRAM_DEV_ENABLE)
|
||||
if (module_type == UI_MODULE_GPU) {
|
||||
buf = jlgpu_cache_malloc(size);
|
||||
if (buf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if TCFG_PSRAM_DEV_ENABLE //psram buf
|
||||
if ((config_ui_alloc_psram_mod_sel & BIT(module_type)) || (ram_type == UI_RAM_PSRAM)) {
|
||||
buf = malloc_psram(size);
|
||||
if (buf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
buf = malloc(size); //sram buf
|
||||
} while (0);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void jlui_free_normal(void *buf)
|
||||
{
|
||||
#if TCFG_DCACHE_RUN_GPU_BUF || TCFG_ICACHE_RUN_GPU_BUF
|
||||
if (jlgpu_buf_is_cache(buf)) {
|
||||
jlgpu_cache_free(buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
if (ui_buf_is_psram(buf)) {
|
||||
if (ui_buf_is_psram_nocache(buf)) {
|
||||
buf = psram_nocache_2_cache(buf);
|
||||
}
|
||||
free_psram(buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (buf) {
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void async_buffer_free(void *buf)
|
||||
{
|
||||
jlui_free_normal(buf);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief jlui_malloc 杰理UI框架内存申请接口
|
||||
*
|
||||
* @Params size 申请内存大小
|
||||
* @Params ram_type 申请的ram类型
|
||||
* @Params module_type 发起申请的模块
|
||||
*
|
||||
* @return 内存指针
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *jlui_malloc(int size, u32 ram_type, u32 module_type)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
#ifdef UI_BUF_CALC_LITE
|
||||
void *buf = jlui_malloc_calc_lite(size, ram_type, module_type);
|
||||
#else
|
||||
void *buf = jlui_malloc_normal(size, ram_type, module_type);
|
||||
#endif//UI_BUF_CALC_LITE
|
||||
#ifdef UI_BUF_CALC
|
||||
ui_buf_calc_add(buf, size, ram_type, module_type);
|
||||
#endif//UI_BUF_CALC
|
||||
#ifdef UI_BUF_DEBUG
|
||||
printf("[%s]buf:0x%x rets:0x%x size:0x%x ram_type:0x%x module_type:0x%x", __func__, (u32)buf, rets, size, ram_type, module_type);
|
||||
#endif
|
||||
return (void *)buf;
|
||||
}
|
||||
|
||||
void *jlui_zalloc(int size)
|
||||
{
|
||||
void *p = jlui_malloc(size, UI_RAM_SRAM, UI_MODULE_FRAME);
|
||||
if (p) {
|
||||
memset(p, 0x00, size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void jlui_free(void *buf, u32 ram_type, u32 module_type)
|
||||
{
|
||||
u32 rets;
|
||||
__asm__ volatile("%0 = rets":"=r"(rets));
|
||||
#ifdef UI_BUF_DEBUG
|
||||
printf("[%s]buf:0x%x rets:0x%x ram_type:0x%x module_type:0x%x", __func__, (u32)buf, rets, ram_type, module_type);
|
||||
#endif
|
||||
#ifdef UI_BUF_CALC_LITE
|
||||
jlui_free_calc_lite(buf);
|
||||
#else
|
||||
jlui_free_normal(buf);
|
||||
#endif//UI_BUF_CALC_LITE
|
||||
#ifdef UI_BUF_CALC
|
||||
ui_buf_calc_sub(buf, ram_type, module_type);
|
||||
#endif//UI_BUF_CALC
|
||||
}
|
||||
|
||||
u8 buf_is_heap_addr(void *p)
|
||||
{
|
||||
if (memory_in_vtl(p)) {
|
||||
return true;
|
||||
}
|
||||
#if TCFG_DCACHE_RUN_GPU_BUF || TCFG_ICACHE_RUN_GPU_BUF
|
||||
if (jlgpu_buf_is_cache(p)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
if (ui_buf_is_psram(p)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,508 @@
|
||||
#include "app_config.h"
|
||||
#include "jlgpu_driver.h"
|
||||
#include "res/resfile.h"
|
||||
#include "res_config.h"
|
||||
#include "ui_resource.h"
|
||||
#include "control.h"
|
||||
#include "font/font_all.h"
|
||||
#include "font/language_list.h"
|
||||
#include "res/mem_var.h"
|
||||
#include "jlui_app/ui_style.h"
|
||||
|
||||
|
||||
#if (defined(CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE) || defined(CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE))
|
||||
|
||||
|
||||
//只读文件系统配置
|
||||
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
|
||||
#define UI_MODE_PHY_BASE TCFG_SDFILE_FLASH_DEV_PATY_BASE //分区地址
|
||||
#define UI_MODE_PHY_FLASH PHY_JL_INSERT_FLASH //分区物理区间
|
||||
#elif TCFG_SDFILE_EXTERN_FLASH_ENABLE
|
||||
#define UI_MODE_PHY_BASE TCFG_SDFILE_FLASH_DEV_PATY_BASE //分区地址
|
||||
#define UI_MODE_PHY_FLASH PHY_JL_EXTERN_FLASH //分区物理区间
|
||||
#else
|
||||
#define UI_MODE_PHY_BASE 0
|
||||
#define UI_MODE_PHY_FLASH PHY_JL_NAND_FLASH
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//vir fat 文件系统
|
||||
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
|
||||
//内置flash
|
||||
#define UI_FAT_PHY_FLASH PHY_JL_INSERT_FLASH
|
||||
#define UI_FAT_PHY_WATCH_BASE TCFG_VIRFAT_FLASH_DEV_PATY_BASE
|
||||
#else
|
||||
//外挂flash
|
||||
#define UI_FAT_PHY_FLASH PHY_JL_EXTERN_FLASH
|
||||
#define UI_FAT_PHY_WATCH_BASE 0
|
||||
#endif
|
||||
|
||||
#if TCFG_NANDFLASH_DEV_ENABLE
|
||||
#define UI_FAT_PHY_BASE TCFG_UI_FAT_FLASH_DEV_PATY_SIZE
|
||||
#endif
|
||||
extern u32 sfc1_flash_addr2cpu_addr(u32 offset);
|
||||
|
||||
int ui_res_get_image_flash_info(struct flash_file_info *image_info, struct flash_file_info *prj_info, struct image_file *img_file);
|
||||
int ui_prj_info_table_release();
|
||||
int ui_watch_resfile_check(void);
|
||||
|
||||
//字库设计放内置
|
||||
struct ui_load_info ui_load_info_table[] = {
|
||||
#if TCFG_NANDFLASH_DEV_ENABLE&&(!TCFG_SDFILE_INSERT_FLASH_ENABLE)
|
||||
{0, 0, UI_MODE_PHY_FLASH, UI_MODE_PHY_BASE, JL_PATH"JL.sty", NULL},
|
||||
#else
|
||||
{0, 0, UI_MODE_PHY_FLASH, UI_MODE_PHY_BASE, JL_PATH"JL.sty", NULL},
|
||||
#endif
|
||||
#if TCFG_NANDFLASH_DEV_ENABLE&&(!TCFG_VIRFAT_INSERT_FLASH_ENABLE)
|
||||
{1, 0, PHY_JL_NAND_FLASH, UI_FAT_PHY_BASE, RES_PATH"watch/watch.sty", NULL},
|
||||
#else
|
||||
{1, 1, UI_FAT_PHY_FLASH, UI_FAT_PHY_WATCH_BASE, RES_PATH"watch/watch.sty", NULL},
|
||||
#endif
|
||||
{2, 0, UI_MODE_PHY_FLASH, UI_MODE_PHY_BASE, SIDEBAR_PATH"sidebar.sty", NULL},
|
||||
{3, 0, UI_MODE_PHY_FLASH, UI_MODE_PHY_BASE, NULL, NULL},
|
||||
{4, 0, PHY_JL_INSERT_FLASH, 0, UPGRADE_PATH"upgrade.sty", NULL},
|
||||
{-1, 0, PHY_JL_EXTERN_FLASH, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
#define UI_PRJ_RES_JL BIT(0)
|
||||
#define UI_PRJ_RES_WATCH BIT(1)
|
||||
#define UI_PRJ_RES_SIDEBAR BIT(2)
|
||||
#define UI_PRJ_RES_UPDATE BIT(3)
|
||||
|
||||
#define UI_PRJ_RES_CHECK (UI_PRJ_RES_JL|UI_PRJ_RES_WATCH)
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ui_res_flash_info_get 获取文件信息
|
||||
*
|
||||
* @param file_info 输出,文件信息
|
||||
* @param path 文件路径
|
||||
* @param str 不重要,给"res"
|
||||
* @param mmu_tab 1,返回mmu_tab
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int ui_res_flash_info_get(struct flash_file_info *file_info, char *path, char *str, int mmu_tab)
|
||||
{
|
||||
/* #if TCFG_NANDFLASH_DEV_ENABLE */
|
||||
/* return 0; */
|
||||
/* #else */
|
||||
return __ui_res_flash_info_get(file_info, path, str, ui_load_info_table[1].phy_dev, ui_load_info_table[1].phy_addr, mmu_tab);
|
||||
/* #endif */
|
||||
}
|
||||
int jlui_res_get_image_info(u32 prj_id, u32 img_id, UI_RESFILE *specfile, struct image_file *image, struct flash_file_info *info)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 image_id = img_id;
|
||||
u32 page_num = img_id >> 16;
|
||||
|
||||
/* ret = open_image_by_id(prj_id, specfile, image, (image_id & 0xffff), (image_id >> 16)); */
|
||||
if (specfile) {
|
||||
if (open_image_by_id(prj_id, specfile, image, (image_id & 0xffff), (image_id >> 16))) {
|
||||
printf("open image by id err!\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
} else {
|
||||
struct mem_var *list;
|
||||
if ((list = mem_var_search(0, 0, (image_id & 0xffff), page_num, prj_id)) != NULL) {
|
||||
mem_var_get(list, (u8 *)image, sizeof(struct image_file));
|
||||
} else {
|
||||
if (open_image_by_id(prj_id, specfile, image, (image_id & 0xffff), (image_id >> 16))) {
|
||||
printf("open image by id err!\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
mem_var_add(0, 0, (image_id & 0xffff), page_num, prj_id, (u8 *)image, sizeof(struct image_file));
|
||||
}
|
||||
}
|
||||
|
||||
/* if (ret) { */
|
||||
/* printf("open image by id err!\n"); */
|
||||
/* return ret; */
|
||||
/* } */
|
||||
/* printf("open image by id succ!\n"); */
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
int jlui_res_get_strpic_info(u32 prj_id, u8 mode, u16 id, struct image_file *image, struct flash_file_info *info)
|
||||
{
|
||||
int ret;
|
||||
u32 str_id = id;
|
||||
if (mode == 0) {
|
||||
ret = open_string_pic(prj_id, image, str_id);
|
||||
} else if (mode == 1) {
|
||||
ret = open_string_pic2(prj_id, image, str_id);
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
printf("open string err!\n");
|
||||
return ret;
|
||||
}
|
||||
/* printf("open string succ!\n"); */
|
||||
|
||||
ui_res_get_image_flash_info(info, &ui_load_info_table[prj_id].str_file_info, image);
|
||||
|
||||
return ret;
|
||||
}
|
||||
char *ui_get_res_path_by_pj_id(int prj)
|
||||
{
|
||||
return (char *)ui_load_info_table[prj].path;
|
||||
}
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ui_resfile_check 资源校验
|
||||
*
|
||||
* @return 0 成功 other 失败
|
||||
*
|
||||
* @note UI_PRJ_RES_CHECK 中配置需要检查的项
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int ui_resfile_check()
|
||||
{
|
||||
#if (UI_PRJ_RES_CHECK & UI_PRJ_RES_JL)
|
||||
UI_RESFILE *fp_jl = res_fopen(ui_load_info_table[0].path, "r");
|
||||
if (!fp_jl) {
|
||||
printf("[%s] ui prj[jl] check fail", __func__);
|
||||
return -1;
|
||||
}
|
||||
res_fclose(fp_jl);
|
||||
#endif
|
||||
#if (UI_PRJ_RES_CHECK & UI_PRJ_RES_WATCH)
|
||||
int ret = ui_watch_resfile_check();
|
||||
if (ret == false) {
|
||||
printf("[%s] ui prj[watch] check fail", __func__);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#if (UI_PRJ_RES_CHECK & UI_PRJ_RES_SIDEBAR)
|
||||
UI_RESFILE *fp_sidebar = res_fopen(ui_load_info_table[2].path, "r");
|
||||
if (!fp_sidebar) {
|
||||
printf("[%s] ui prj[sidebar] check fail", __func__);
|
||||
return -1;
|
||||
}
|
||||
res_fclose(fp_sidebar);
|
||||
#endif
|
||||
#if (UI_PRJ_RES_CHECK & UI_PRJ_RES_UPDATE)
|
||||
UI_RESFILE *fp_update = res_fopen(ui_load_info_table[4].path, "r");
|
||||
if (!fp_update) {
|
||||
printf("[%s] ui prj[update] check fail", __func__);
|
||||
return -1;
|
||||
}
|
||||
res_fclose(fp_update);
|
||||
#endif
|
||||
void rcsp_update_flag_clear();
|
||||
#if TCFG_UPDATE_ENABLE
|
||||
rcsp_update_flag_clear();
|
||||
#endif
|
||||
printf("[%s] ui prj check succ ", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ui_resfile_info_init ui资源信息初始化
|
||||
*
|
||||
* @return 0 succ other fail
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int ui_resfile_info_init(
|
||||
void *(*malloc)(int size, u32 ram_type, u32 module_type),
|
||||
void (*free)(void *p, u32 ram_type, u32 module_type))
|
||||
{
|
||||
//资源校验
|
||||
if (ui_resfile_check()) {
|
||||
#if (RCSP_MODE && JL_RCSP_EXTRA_FLASH_OPT)
|
||||
extern void rcsp_eflash_flag_set(u8 eflash_state_type);
|
||||
rcsp_eflash_flag_set(1);//校验失败,进文件传输
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
//注册tab到库
|
||||
ui_prj_info_table_init(ui_load_info_table, malloc, free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ui_resfile_info_release 注销ui资源
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int ui_resfile_info_release()
|
||||
{
|
||||
extern int ui_prj_info_table_release();
|
||||
ui_prj_info_table_release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//**************************************************************************************//
|
||||
#if 0
|
||||
void ui_resfile_test_code()
|
||||
{
|
||||
struct flash_file_info file_info = {0};
|
||||
struct flash_file_info image_info = {0};
|
||||
struct image_file image_f = {0};
|
||||
ui_resfile_info_init();
|
||||
int ret = open_image_by_id(0, NULL, &image_f, 1, 1);
|
||||
if (ret) {
|
||||
printf("open image file");
|
||||
return ;
|
||||
}
|
||||
ui_res_get_image_flash_info(&image_info, &ui_load_info_table[0].image_file_info, &image_f);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
char *font_get_file_addr(char *file_name)
|
||||
{
|
||||
struct vfs_attr attr;
|
||||
FILE *fp = fopen(file_name, "r");
|
||||
if (!fp) {
|
||||
printf("Failed to get font file addr!\n");
|
||||
return NULL;
|
||||
}
|
||||
fget_attrs(fp, &attr);
|
||||
fclose(fp);
|
||||
#if TCFG_SDFILE_EXTERN_FLASH_ENABLE
|
||||
return (char *) sfc1_flash_addr2cpu_addr(attr.sclust + UI_MODE_PHY_BASE);
|
||||
#else
|
||||
return (char *)sdfile_flash_addr2cpu_addr(attr.sclust + UI_MODE_PHY_BASE);
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
void __font_pix_copy(struct font_info *info, u8 *pix, s16 x, s16 y, u16 height, u16 width)
|
||||
{
|
||||
int i, j, h;
|
||||
u16 xpos;
|
||||
u16 ypos;
|
||||
if (info->flags & FONT_SHOW_SCROLL) {
|
||||
int font_lang_id = font_lang_get();
|
||||
if (font_lang_id == Arabic || font_lang_id == Hebrew || font_lang_id == UnicodeMixLeftword) { //显示方向从右到左
|
||||
if (x > info->text_width - info->xpos_offset) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (x + width < info->xpos_offset) { //x + width防止字符被中断
|
||||
return; //当解析字符串累计buf宽度未到指定位置时不填充字库buf
|
||||
} else {
|
||||
x -= info->xpos_offset; //偏移x的值,使其对应到字库buf起始位置
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < (height + 7) / 8; j++) { /* 纵向8像素为1字节 */
|
||||
for (i = 0; i < width; i++) {
|
||||
u8 pixel = pix[j * width + i];
|
||||
int hh = height - (j * 8);
|
||||
if (hh > 8) {
|
||||
hh = 8;
|
||||
}
|
||||
|
||||
if (x + i < 0) {
|
||||
continue; //x的值在文本框边界的时候可能为负,将负的部分舍弃
|
||||
}
|
||||
xpos = x + i;
|
||||
for (h = 0; h < hh; h++) {
|
||||
u16 clr = (pixel & BIT(h)) ? 1 : 0;
|
||||
if (clr) {
|
||||
if (info->text_image_buf) {
|
||||
u8 *pdisp = info->text_image_buf;
|
||||
if (y + j * 8 + h < 0) {
|
||||
continue;
|
||||
}
|
||||
ypos = y + j * 8 + h;
|
||||
if ((ypos < info->text_image_height) && (xpos < info->text_image_width)) {
|
||||
pdisp[ypos * info->text_image_stride + xpos / 8] |= BIT(7 - xpos % 8);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* endof for h */
|
||||
}/* endof for i */
|
||||
}/* endof for j */
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) //new font tool, for 1 2 4 8 bit
|
||||
void __new_cb_font_pix_copy(struct font_info *info, u8 *pix, s16 x, s16 y, u16 height, u16 width)
|
||||
{
|
||||
if (info->flags & FONT_SHOW_SCROLL) {
|
||||
int font_lang_id = font_lang_get();
|
||||
if (font_lang_id == Arabic || font_lang_id == Hebrew || \
|
||||
font_lang_id == UnicodeMixLeftword) {
|
||||
if (x > info->text_width - info->xpos_offset) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (x + width < info->xpos_offset) { //x + width防止字符被中断
|
||||
return; //当解析字符串累计buf宽度未到指定位置时不填充字库buf
|
||||
} else {
|
||||
x -= info->xpos_offset; //偏移x的值,使其对应到字库buf起始位置
|
||||
}
|
||||
}
|
||||
}
|
||||
u8 *pdisp = (u8 *)info->text_image_buf;
|
||||
u8 *pixbuf = (u8 *)pix;
|
||||
int i, j;
|
||||
|
||||
struct rect font_r;
|
||||
struct rect image_r;
|
||||
struct rect r;
|
||||
font_r.left = x;
|
||||
font_r.top = y;
|
||||
font_r.width = width;
|
||||
font_r.height = height;
|
||||
image_r.left = 0;
|
||||
image_r.top = 0;
|
||||
image_r.width = info->text_image_width;
|
||||
image_r.height = info->text_image_height;
|
||||
|
||||
u8 pixel, bpp, bpp_mode;
|
||||
u32 font_bit, image_bit;
|
||||
u16 font_byte_idx, font_bit_idx;
|
||||
u16 image_byte_idx, image_bit_idx;
|
||||
if (get_rect_cover(&font_r, &image_r, &r)) {
|
||||
bpp_mode = Font_GetBitDepth();
|
||||
u16 line_pixel = 0;
|
||||
if (bpp_mode == BIT_DEPTH_1BPP) {
|
||||
bpp = 1;
|
||||
line_pixel = info->text_image_stride * 8;
|
||||
} else if (bpp_mode == BIT_DEPTH_2BPP) {
|
||||
line_pixel = info->text_image_stride * 4;
|
||||
bpp = 2;
|
||||
} else if (bpp_mode == BIT_DEPTH_4BPP) {
|
||||
line_pixel = info->text_image_stride * 2;
|
||||
bpp = 4;
|
||||
} else {
|
||||
line_pixel = info->text_image_stride;
|
||||
bpp = 8;
|
||||
}
|
||||
u8 pix_num_in_byte = 8 / bpp;
|
||||
u8 reserved_bit = 0xff >> (8 - bpp);
|
||||
int font_bit_row_start, img_bit_row_start;
|
||||
|
||||
if (bpp == 1) {
|
||||
for (j = 0; j < r.height; j++) {
|
||||
font_bit_row_start = (r.top - font_r.top + j) * width + r.left - font_r.left;
|
||||
img_bit_row_start = (r.top - image_r.top + j) * line_pixel + r.left - image_r.left;
|
||||
for (i = 0; i < r.width; i++) {
|
||||
font_bit = font_bit_row_start + i;
|
||||
font_byte_idx = font_bit >> 3;
|
||||
font_bit_idx = font_bit & 7;
|
||||
image_bit = img_bit_row_start + i;
|
||||
image_byte_idx = image_bit >> 3;
|
||||
image_bit_idx = image_bit & 7;
|
||||
pixel = (pixbuf[font_byte_idx] >> ((7 - font_bit_idx))) & reserved_bit;
|
||||
pdisp[image_byte_idx] |= (pixel << ((7 - image_bit_idx)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < r.height; j++) {
|
||||
font_bit_row_start = (r.top - font_r.top + j) * width + r.left - font_r.left;
|
||||
img_bit_row_start = (r.top - image_r.top + j) * line_pixel + r.left - image_r.left;
|
||||
for (i = 0; i < r.width; i++) {
|
||||
font_bit = font_bit_row_start + i;
|
||||
font_byte_idx = font_bit / pix_num_in_byte;
|
||||
font_bit_idx = font_bit % pix_num_in_byte;
|
||||
image_bit = img_bit_row_start + i;
|
||||
image_byte_idx = image_bit / pix_num_in_byte;
|
||||
image_bit_idx = image_bit % pix_num_in_byte;
|
||||
pixel = (pixbuf[font_byte_idx] >> ((pix_num_in_byte - 1 - font_bit_idx) * bpp)) & reserved_bit;
|
||||
pdisp[image_byte_idx] |= (pixel << ((pix_num_in_byte - 1 - image_bit_idx) * bpp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void platform_putchar(struct font_info *info, u8 *pixel, u16 width, u16 height, u16 x, u16 y)
|
||||
{
|
||||
if (info->each_line_width_info) {
|
||||
u8 total_line = (u8)(info->each_line_width_info[0]);
|
||||
u8 curr_line = (u8)((info->each_line_width_info[0] >> 8) + 1);
|
||||
u16 curr_line_width = info->each_line_width_info[curr_line];
|
||||
if (total_line > 1 || ((info->flags & FONT_VERTICAL_SCROLL) && info->top_extra_fill < 0)) {
|
||||
u16 x_offset = (info->text_width - curr_line_width) / 2;
|
||||
int font_lang_id = font_lang_get();
|
||||
if (font_lang_id == Arabic || font_lang_id == Hebrew || font_lang_id == UnicodeMixLeftword) {
|
||||
x -= x_offset;
|
||||
} else {
|
||||
x += x_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((info->tool_version == 0) || (info->tool_version == 0x0100)) {
|
||||
__font_pix_copy(info,
|
||||
pixel,
|
||||
(s16)x,
|
||||
(s16)y,
|
||||
height,
|
||||
width);
|
||||
} else {
|
||||
__new_cb_font_pix_copy(info,
|
||||
pixel,
|
||||
(s16)x,
|
||||
(s16)y,
|
||||
height,
|
||||
width);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct font_info font_info_table[] = {
|
||||
//gb2312
|
||||
{
|
||||
.language_id = Chinese_Simplified, //简体中文
|
||||
.flags = FONT_SHOW_PIXEL | FONT_SHOW_MULTI_LINE,
|
||||
.pixel.file.name = (char *)FONT_PATH"F_GB2312.PIX",
|
||||
.ascpixel.file.name = (char *)FONT_PATH"F_ASCII.PIX",
|
||||
.tabfile.name = (char *)FONT_PATH"F_GB2312.TAB",
|
||||
.isgb2312 = true,
|
||||
.bigendian = false,
|
||||
.putchar = platform_putchar,
|
||||
},
|
||||
|
||||
{
|
||||
.language_id = Unicode,
|
||||
.flags = FONT_SHOW_PIXEL | FONT_SHOW_MULTI_LINE,
|
||||
.pixel.file.name = (char *)FONT_PATH"F_UNIC.PIX",
|
||||
.bigendian = false,
|
||||
.putchar = platform_putchar,
|
||||
},
|
||||
{
|
||||
.language_id = UnicodeMixRightword,
|
||||
.flags = FONT_SHOW_PIXEL | FONT_SHOW_MULTI_LINE,
|
||||
.pixel.file.name = (char *)FONT_PATH"F_UNIC.PIX",
|
||||
.bigendian = false,
|
||||
.putchar = platform_putchar,
|
||||
},
|
||||
{
|
||||
.language_id = UnicodeMixLeftword,
|
||||
.flags = FONT_SHOW_PIXEL | FONT_SHOW_MULTI_LINE,
|
||||
.pixel.file.name = (char *)FONT_PATH"F_UNIC.PIX",
|
||||
.bigendian = false,
|
||||
.putchar = platform_putchar,
|
||||
},
|
||||
|
||||
{
|
||||
.language_id = 0,//不能删
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef __PUBLIC_JLUI_RESOURCE_H__
|
||||
#define __PUBLIC_JLUI_RESOURCE_H__
|
||||
|
||||
#include "gpu_format.h"
|
||||
|
||||
int jlui_res_get_image_info(u32 prj_id, u32 img_id, UI_RESFILE *specfile, struct image_file *image, struct flash_file_info *info);
|
||||
int jlui_res_get_strpic_info(u32 prj_id, u8 mode, u16 id, struct image_file *image, struct flash_file_info *info);
|
||||
|
||||
int ui_resfile_check();
|
||||
|
||||
int ui_resfile_info_init(
|
||||
void *(*malloc)(int size, u32 ram_type, u32 module_type),
|
||||
void (*free)(void *p, u32 ram_type, u32 module_type));
|
||||
int ui_resfile_info_release();
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user