Files
AC707N/SDK/cpu/br35/ui_driver/interface/ui_buf_manager.c
T
2025-12-03 11:12:34 +08:00

669 lines
20 KiB
C

#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