LVGL+HISI TDE充分发挥性能hisi3516dv300

/* 定义TDE绘图上下文结构体 */
typedef struct {
    lv_draw_ctx_t base;
    TDE_HANDLE tde_handle;
    TDE2_SURFACE_S dst_surface;
    TDE2_OPT_S tde_opt;
} lv_draw_tde_ctx_t;

/*-----------------------------
 *      清除屏幕(Clear)
 *---------------------------*/
static void lv_tde_clear(lv_draw_ctx_t *draw_ctx, const lv_area_t *area)
{
    lv_draw_tde_ctx_t *tde_ctx = (lv_draw_tde_ctx_t *)draw_ctx;
    TDE_HANDLE handle = HI_TDE2_BeginJob();
    if (handle == HI_ERR_TDE_INVALID_HANDLE) return;

    /* 将整个区域填充为背景色(通常为透明黑) */
    TDE2_RECT_S clear_rect = {
        .s32Xpos = area->x1,
        .s32Ypos = area->y1,
        .u32Width = lv_area_get_width(area),
        .u32Height = lv_area_get_height(area)
    };

    TDE2_FILLCOLOR_S clear_color = {
        .enColorFmt = TDE2_COLOR_FMT_ARGB8888,
        .u32FillColor = 0x00000000  // ARGB8888 格式的透明黑
    };

    HI_S32 ret = HI_TDE2_QuickFill(handle, &tde_ctx->dst_surface, &clear_rect, 
                                  &clear_color, &tde_ctx->tde_opt);
    if (ret == HI_SUCCESS) {
        HI_TDE2_EndJob(handle, HI_FALSE, HI_TRUE, 100); // 同步等待
    }
}

/*-----------------------------
 *      混合操作(Blend)
 *---------------------------*/
static void lv_tde_blend(lv_draw_ctx_t *draw_ctx, const lv_draw_sw_blend_dsc_t *dsc)
{
    lv_draw_tde_ctx_t *tde_ctx = (lv_draw_tde_ctx_t *)draw_ctx;
    TDE_HANDLE handle = HI_TDE2_BeginJob();
    if (handle == HI_ERR_TDE_INVALID_HANDLE) return;

    /* 配置源表面 */
    TDE2_SURFACE_S src_surface = {
        .enColorFmt = TDE2_COLOR_FMT_ARGB8888,
        .u32PhyAddr = (HI_U64)dsc->src_buf,
        .u32Width = dsc->src_w,
        .u32Height = dsc->src_h,
        .u32Stride = dsc->src_stride * lv_color_format_get_size(tde_ctx->cf)
    };

    /* 定义混合区域 */
    TDE2_RECT_S src_rect = {
        .s32Xpos = dsc->src_area->x1,
        .s32Ypos = dsc->src_area->y1,
        .u32Width = lv_area_get_width(dsc->src_area),
        .u32Height = lv_area_get_height(dsc->src_area)
    };

    TDE2_RECT_S dst_rect = {
        .s32Xpos = dsc->dest_area->x1,
        .s32Ypos = dsc->dest_area->y1,
        .u32Width = lv_area_get_width(dsc->dest_area),
        .u32Height = lv_area_get_height(dsc->dest_area)
    };

    /* 配置混合模式 */
    TDE2_OPT_S opt = tde_ctx->tde_opt;
    opt.enAluCmd = (dsc->blend_mode == LV_BLEND_MODE_ADDITIVE) ? 
                   TDE2_ALUCMD_ADD : TDE2_ALUCMD_SRCOVER;
    opt.u8GlobalAlpha = dsc->opa;

    /* 执行混合操作 */
    HI_S32 ret = HI_TDE2_Bitblit(handle, 
                                &src_surface, &src_rect,
                                &tde_ctx->dst_surface, &dst_rect,
                                &opt);
    if (ret == HI_SUCCESS) {
        HI_TDE2_EndJob(handle, HI_FALSE, HI_TRUE, 100);
    }
}

/*-----------------------------
 *      图像绘制(Draw Image)
 *---------------------------*/
static void lv_tde_draw_img(lv_draw_ctx_t *draw_ctx, const lv_draw_img_dsc_t *dsc,
                           const lv_area_t *coords, const uint8_t *src_buf)
{
    lv_draw_tde_ctx_t *tde_ctx = (lv_draw_tde_ctx_t *)draw_ctx;
    TDE_HANDLE handle = HI_TDE2_BeginJob();
    if (handle == HI_ERR_TDE_INVALID_HANDLE) return;

    /* 配置源图像表面 */
    TDE2_SURFACE_S src_surface = {
        .enColorFmt = TDE2_COLOR_FMT_ARGB8888, // 假设源为ARGB8888
        .u32PhyAddr = (HI_U64)src_buf,
        .u32Width = lv_area_get_width(coords),
        .u32Height = lv_area_get_height(coords),
        .u32Stride = lv_area_get_width(coords) * 4
    };

    /* 目标区域 */
    TDE2_RECT_S dst_rect = {
        .s32Xpos = coords->x1,
        .s32Ypos = coords->y1,
        .u32Width = lv_area_get_width(coords),
        .u32Height = lv_area_get_height(coords)
    };

    /* 处理旋转/缩放 */
    if (dsc->angle || dsc->zoom != LV_IMG_ZOOM_NONE) {
        TDE2_ROTATE_ANGLE_E rotate = TDE2_ROTATE_NONE;
        if (dsc->angle == 900) rotate = TDE2_ROTATE_90;
        else if (dsc->angle == 1800) rotate = TDE2_ROTATE_180;
        else if (dsc->angle == 2700) rotate = TDE2_ROTATE_270;

        HI_TDE2_Rotate(handle, &src_surface, NULL, 
                      &tde_ctx->dst_surface, &dst_rect, 
                      rotate, TDE2_MIRROR_NONE);
    }
    else {
        /* 直接拷贝图像 */
        HI_TDE2_QuickCopy(handle, 
                         &src_surface, NULL,
                         &tde_ctx->dst_surface, &dst_rect,
                         &tde_ctx->tde_opt);
    }

    HI_TDE2_EndJob(handle, HI_FALSE, HI_TRUE, 100);
}

/* 颜色格式转换函数(示例) */
static inline HI_U32 lv_color_to_tde_format(lv_color_t color, lv_opa_t opa)
{
    return (opa << 24) | (color.red << 16) | (color.green << 8) | color.blue;
}
/* 绘图上下文初始化 */
void lv_draw_tde_ctx_init(lv_disp_drv_t *drv, lv_draw_ctx_t *draw_ctx)
{
    lv_draw_tde_ctx_t *tde_ctx = (lv_draw_tde_ctx_t *)draw_ctx;
    
    /* 初始化基础上下文 */
    lv_draw_sw_init_ctx(drv, draw_ctx); 

    /* 配置TDE目标表面 */
    tde_ctx->dst_surface.PhyAddr = (HI_U64)drv->draw_buf->buf_act;
    tde_ctx->dst_surface.enColorFmt = TDE2_COLOR_FMT_ARGB8888; // 根据LVGL配置调整
    tde_ctx->dst_surface.u32Width = drv->hor_res;
    tde_ctx->dst_surface.u32Height = drv->ver_res;
    tde_ctx->dst_surface.u32Stride = drv->hor_res * 4; // ARGB8888 stride

    /* 初始化TDE默认选项 */
    memset(&tde_ctx->tde_opt, 0, sizeof(TDE2_OPT_S));
    tde_ctx->tde_opt.enClipMode = TDE2_CLIPMODE_NONE;
    tde_ctx->tde_opt.enAluCmd = TDE2_ALUCMD_SRCOVER;

    /* 重写绘图函数指针 */
    draw_ctx->clear = lv_tde_clear;
    draw_ctx->fill = lv_tde_fill;
    draw_ctx->blend = lv_tde_blend;
    draw_ctx->base_draw.draw_img = lv_tde_draw_img;
}

/* 绘图上下文反初始化 */
void lv_draw_tde_ctx_deinit(lv_disp_drv_t *drv, lv_draw_ctx_t *draw_ctx)
{
    lv_draw_tde_ctx_t *tde_ctx = (lv_draw_tde_ctx_t *)draw_ctx;
    
    /* 取消未完成的任务 */
    if (tde_ctx->tde_handle != HI_ERR_TDE_INVALID_HANDLE) {
        HI_TDE2_CancelJob(tde_ctx->tde_handle);
    }
    
    /* 释放资源 */
    lv_draw_sw_deinit_ctx(drv, draw_ctx);
}

/* 填充矩形示例实现 */
static void lv_tde_fill(lv_draw_ctx_t *draw_ctx, const lv_area_t *area, lv_color_t color, lv_opa_t opa)
{
    lv_draw_tde_ctx_t *tde_ctx = (lv_draw_tde_ctx_t *)draw_ctx;
    
    /* 创建TDE任务 */
    TDE_HANDLE handle = HI_TDE2_BeginJob();
    if (handle == HI_ERR_TDE_INVALID_HANDLE) return;

    /* 配置填充参数 */
    TDE2_RECT_S fill_area = {
        .s32Xpos = area->x1,
        .s32Ypos = area->y1,
        .u32Width = lv_area_get_width(area),
        .u32Height = lv_area_get_height(area)
    };

    TDE2_FILLCOLOR_S fill_color = {
        .enColorFmt = TDE2_COLOR_FMT_ARGB8888,
        .u32FillColor = lv_color_to32(color) | (opa << 24)
    };

    /* 执行快速填充 */
    HI_S32 ret = HI_TDE2_QuickFill(handle, &tde_ctx->dst_surface, &fill_area,
                                  &fill_color, &tde_ctx->tde_opt);
    
    if (ret == HI_SUCCESS) {
        HI_TDE2_EndJob(handle, HI_FALSE, HI_TRUE, 100); // 阻塞等待100ms
    }
}
static TDE2_ALUCMD_E blend_mode_map(lv_blend_mode_t mode) {
    switch(mode) {
        case LV_BLEND_MODE_ADDITIVE: return TDE2_ALUCMD_ADD;
        case LV_BLEND_MODE_SUBTRACTIVE: return TDE2_ALUCMD_SUB;
        default: return TDE2_ALUCMD_SRCOVER;
    }
}
/* 驱动初始化适配 */
void lv_disp_drv_init(lv_disp_drv_t *driver)
{
    lv_memset_00(driver, sizeof(lv_disp_drv_t));
    
    driver->hor_res = 720;
    driver->ver_res = 1280;
    
    /* 配置TDE绘图上下文 */
    driver->draw_ctx_init = lv_draw_tde_ctx_init;
    driver->draw_ctx_deinit = lv_draw_tde_ctx_deinit; 
    driver->draw_ctx_size = sizeof(lv_draw_tde_ctx_t);
    
    /* 其他驱动配置... */
}

/* 批量提交任务(示例) */
void flush_cb(lv_disp_drv_t *drv, const lv_area_t *area) {
    lv_draw_tde_ctx_t *ctx = (lv_draw_tde_ctx_t *)drv->draw_ctx;
    HI_TDE2_WaitAllDone(ctx->tde_handle); // 确保所有任务完成
    lv_disp_flush_ready(drv); // 通知 LVGL 刷新完成
}

进一步分析各函数的执行策略,采用硬件加速前后的数据
perf_monitor.h

/* perf_monitor.h */
#ifndef __PERF_MONITOR_H__
#define __PERF_MONITOR_H__

#include <stdint.h>
#include "lvgl/lvgl.h"

typedef struct {
    uint32_t call_count;     // 调用次数
    uint32_t total_time_us;  // 总耗时(微秒)
    uint32_t max_time_us;    // 单次最大耗时
} func_stats_t;

// 被监控的函数指针类型(适配 LVGL 绘图函数)
typedef void (*draw_func_t)(void *ctx, void *dsc, void *coords_or_points);

// 注册被监控的函数
void perf_monitor_register_func(draw_func_t func_ptr, const char *name);

// 打印统计结果
void perf_monitor_print_stats(void);

// 包装宏(简化函数替换)
#define WRAP_FUNC(orig_func, wrapper_func) \
    do { \
        perf_monitor_register_func((draw_func_t)orig_func, #orig_func); \
        orig_func = (typeof(orig_func))wrapper_func; \
    } while(0)

#endif // __PERF_MONITOR_H__

perf_monitor.c

/* 在绘图上下文初始化代码中替换原始函数 */
#include "perf_monitor.h"

/* perf_monitor.c */
#include "perf_monitor.h"
#include <stdio.h>

#define MAX_MONITORED_FUNCS 16

typedef struct {
    draw_func_t func_ptr;
    func_stats_t stats;
    const char *name;
} monitored_func_t;

static monitored_func_t monitored_funcs[MAX_MONITORED_FUNCS];
static uint8_t func_count = 0;

void perf_monitor_register_func(draw_func_t func_ptr, const char *name) {
    if (func_count >= MAX_MONITORED_FUNCS) return;
    monitored_funcs[func_count].func_ptr = func_ptr;
    monitored_funcs[func_count].name = name;
    lv_memset_00(&monitored_funcs[func_count].stats, sizeof(func_stats_t));
    func_count++;
}

static void update_stats(draw_func_t func_ptr, uint32_t time_us) {
    for (int i = 0; i < func_count; i++) {
        if (monitored_funcs[i].func_ptr == func_ptr) {
            monitored_funcs[i].stats.call_count++;
            monitored_funcs[i].stats.total_time_us += time_us;
            if (time_us > monitored_funcs[i].stats.max_time_us) {
                monitored_funcs[i].stats.max_time_us = time_us;
            }
            break;
        }
    }
}

void perf_monitor_print_stats(void) {
    printf("\n----- LVGL Draw Function Statistics -----\n");
    for (int i = 0; i < func_count; i++) {
        func_stats_t *s = &monitored_funcs[i].stats;
        if (s->call_count == 0) continue;

        printf("%-20s: Calls=%-5d | Avg=%-5dus | Max=%-5dus\n",
               monitored_funcs[i].name,
               s->call_count,
               s->total_time_us / s->call_count,
               s->max_time_us);
    }
    printf("-----------------------------------------\n");
}

/* 包装函数模板(通过宏生成) */
#define GENERATE_WRAPPER(orig_func) \
    static void orig_func##_wrapper(void *ctx, void *dsc, void *coords_or_points) { \
        uint32_t start = lv_tick_get(); \
        ((typeof(orig_func)*)orig_func)(ctx, dsc, coords_or_points); \
        uint32_t elapsed = lv_tick_elaps(start); \
        update_stats((draw_func_t)orig_func, elapsed); \
    }

// 为每个绘图函数生成包装器
GENERATE_WRAPPER(lv_draw_sw_arc)
GENERATE_WRAPPER(lv_draw_sw_rect)
GENERATE_WRAPPER(lv_draw_sw_bg)
GENERATE_WRAPPER(lv_draw_sw_letter)
GENERATE_WRAPPER(lv_draw_sw_img_decoded)
GENERATE_WRAPPER(lv_draw_sw_line)
GENERATE_WRAPPER(lv_draw_sw_polygon)
GENERATE_WRAPPER(lv_draw_sw_transform)
GENERATE_WRAPPER(lv_draw_sw_wait_for_finish)
GENERATE_WRAPPER(lv_draw_sw_buffer_copy)
GENERATE_WRAPPER(lv_draw_sw_layer_create)
GENERATE_WRAPPER(lv_draw_sw_layer_adjust)
GENERATE_WRAPPER(lv_draw_sw_layer_blend)
GENERATE_WRAPPER(lv_draw_sw_layer_destroy)

源代码中渲染集成

/* 在绘图上下文初始化代码中替换原始函数 */
#include "perf_monitor.h"

void lv_draw_sw_init_ctx(lv_disp_drv_t *drv, lv_draw_ctx_t *draw_ctx) {
    lv_draw_sw_ctx_t *draw_sw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
    lv_memset_00(draw_sw_ctx, sizeof(lv_draw_sw_ctx_t));

    // 使用宏替换所有绘图函数
    WRAP_FUNC(lv_draw_sw_arc, lv_draw_sw_arc_wrapper);
    WRAP_FUNC(lv_draw_sw_rect, lv_draw_sw_rect_wrapper);
    WRAP_FUNC(lv_draw_sw_bg, lv_draw_sw_bg_wrapper);
    WRAP_FUNC(lv_draw_sw_letter, lv_draw_sw_letter_wrapper);
    WRAP_FUNC(lv_draw_sw_img_decoded, lv_draw_sw_img_decoded_wrapper);
    WRAP_FUNC(lv_draw_sw_line, lv_draw_sw_line_wrapper);
    WRAP_FUNC(lv_draw_sw_polygon, lv_draw_sw_polygon_wrapper);
#if LV_DRAW_COMPLEX
    WRAP_FUNC(lv_draw_sw_transform, lv_draw_sw_transform_wrapper);
#endif
    WRAP_FUNC(lv_draw_sw_wait_for_finish, lv_draw_sw_wait_for_finish_wrapper);
    WRAP_FUNC(lv_draw_sw_buffer_copy, lv_draw_sw_buffer_copy_wrapper);
    WRAP_FUNC(lv_draw_sw_layer_create, lv_draw_sw_layer_create_wrapper);
    WRAP_FUNC(lv_draw_sw_layer_adjust, lv_draw_sw_layer_adjust_wrapper);
    WRAP_FUNC(lv_draw_sw_layer_blend, lv_draw_sw_layer_blend_wrapper);
    WRAP_FUNC(lv_draw_sw_layer_destroy, lv_draw_sw_layer_destroy_wrapper);

    draw_sw_ctx->base_draw.draw_arc = lv_draw_sw_arc;
    // ... 其他赋值保持不变
    draw_sw_ctx->blend = lv_draw_sw_blend_basic;
}

main中调用

/* 主循环中定期打印统计结果 */
while(1) {
    lv_task_handler();
    lv_tick_inc(5); // 假设系统时基为5ms
    
    static uint32_t last_print = 0;
    if (lv_tick_elaps(last_print) > 2000) { // 每2秒打印一次
        perf_monitor_print_stats();
        last_print = lv_tick_get();
    }
}

#include “draw_stats.h”
#include <stdio.h>

/*-----------------------------

  •    统计数据结构
    

---------------------------/
static draw_func_stats_t draw_stats[STATS_COUNT] = {
[STATS_DRAW_ARC] = {“draw_arc”, 0, 0, 0, UINT32_MAX},
[STATS_DRAW_RECT] = {“draw_rect”, 0, 0, 0, UINT32_MAX},
[STATS_DRAW_BG] = {“draw_bg”, 0, 0, 0, UINT32_MAX},
[STATS_DRAW_LETTER] = {“draw_letter”, 0, 0, 0, UINT32_MAX},
[STATS_DRAW_IMG_DECODED] = {“draw_img_decoded”, 0, 0, 0, UINT32_MAX},
[STATS_DRAW_LINE] = {“draw_line”, 0, 0, 0, UINT32_MAX},
[STATS_DRAW_POLYGON] = {“draw_polygon”, 0, 0, 0, UINT32_MAX},
#if LV_DRAW_COMPLEX
[STATS_DRAW_TRANSFORM] = {“draw_transform”, 0, 0, 0, UINT32_MAX},
#endif
[STATS_WAIT_FOR_FINISH] = {“wait_for_finish”, 0, 0, 0, UINT32_MAX},
[STATS_BUFFER_COPY] = {“buffer_copy”, 0, 0, 0, UINT32_MAX},
[STATS_LAYER_INIT] = {“layer_init”, 0, 0, 0, UINT32_MAX},
[STATS_LAYER_ADJUST] = {“layer_adjust”, 0, 0, 0, UINT32_MAX},
[STATS_LAYER_BLEND] = {“layer_blend”, 0, 0, 0, UINT32_MAX},
[STATS_LAYER_DESTROY] = {“layer_destroy”, 0, 0, 0, UINT32_MAX},
[STATS_BLEND] = {“blend”, 0, 0, 0, UINT32_MAX},
};

/*-----------------------------

  •    原始函数指针存储
    

---------------------------/
#define DEF_ORIG_FUNC(func) static typeof(func)* orig_##func = NULL

DEF_ORIG_FUNC(lv_draw_sw_arc);
DEF_ORIG_FUNC(lv_draw_sw_rect);
DEF_ORIG_FUNC(lv_draw_sw_bg);
DEF_ORIG_FUNC(lv_draw_sw_letter);
DEF_ORIG_FUNC(lv_draw_sw_img_decoded);
DEF_ORIG_FUNC(lv_draw_sw_line);
DEF_ORIG_FUNC(lv_draw_sw_polygon);
#if LV_DRAW_COMPLEX
DEF_ORIG_FUNC(lv_draw_sw_transform);
#endif
DEF_ORIG_FUNC(lv_draw_sw_wait_for_finish);
DEF_ORIG_FUNC(lv_draw_sw_buffer_copy);
DEF_ORIG_FUNC(lv_draw_sw_layer_create);
DEF_ORIG_FUNC(lv_draw_sw_layer_adjust);
DEF_ORIG_FUNC(lv_draw_sw_layer_blend);
DEF_ORIG_FUNC(lv_draw_sw_layer_destroy);
DEF_ORIG_FUNC(lv_draw_sw_blend_basic);

/*-----------------------------

  •    包装器宏定义
    

---------------------------/
#define WRAP_FUNC(func, stats_idx, …)
static void wrapped_##func(VA_ARGS) {
uint32_t start = lv_tick_get();
orig_##func(VA_ARGS);
uint32_t elapsed = lv_tick_elaps(start);
draw_func_stats_t* s = &draw_stats[stats_idx];
s->call_count++;
s->total_time_us += elapsed;
if (elapsed > s->max_time_us) s->max_time_us = elapsed;
if (elapsed < s->min_time_us) s->min_time_us = elapsed;
}

/*-----------------------------

  •    生成所有包装器
    

---------------------------/
WRAP_FUNC(lv_draw_sw_arc, STATS_DRAW_ARC,
lv_draw_ctx_t* ctx, const lv_draw_arc_dsc_t* dsc, const lv_area_t* coords)
WRAP_FUNC(lv_draw_sw_rect, STATS_DRAW_RECT,
lv_draw_ctx_t* ctx, const lv_draw_rect_dsc_t* dsc, const lv_area_t* coords)
WRAP_FUNC(lv_draw_sw_bg, STATS_DRAW_BG,
lv_draw_ctx_t* ctx, const lv_draw_rect_dsc_t* dsc, const lv_area_t* coords)
WRAP_FUNC(lv_draw_sw_letter, STATS_DRAW_LETTER,
lv_draw_ctx_t* ctx, const lv_draw_label_dsc_t* dsc, const lv_point_t* pos,
uint32_t letter, lv_draw_label_glyph_t* glyph_out)
WRAP_FUNC(lv_draw_sw_img_decoded, STATS_DRAW_IMG_DECODED,
lv_draw_ctx_t* ctx, const lv_draw_img_dsc_t* dsc, const lv_area_t* coords,
const uint8_t* map, const lv_draw_img_sup_t* sup, lv_color_format_t cf, void* color_out)
WRAP_FUNC(lv_draw_sw_line, STATS_DRAW_LINE,
lv_draw_ctx_t* ctx, const lv_draw_line_dsc_t* dsc)
WRAP_FUNC(lv_draw_sw_polygon, STATS_DRAW_POLYGON,
lv_draw_ctx_t* ctx, const lv_draw_rect_dsc_t* dsc, const lv_point_t* points,
uint16_t point_cnt)
#if LV_DRAW_COMPLEX
WRAP_FUNC(lv_draw_sw_transform, STATS_DRAW_TRANSFORM,
lv_draw_ctx_t* ctx, const lv_area_t* dest_area, const void* src_buf,
lv_coord_t src_w, lv_coord_t src_h, lv_coord_t src_stride,
const lv_draw_img_dsc_t* draw_dsc, lv_img_cf_t cf, lv_color_t* cbuf,
lv_opa_t* abuf)
#endif
WRAP_FUNC(lv_draw_sw_wait_for_finish, STATS_WAIT_FOR_FINISH,
lv_draw_ctx_t* ctx)
WRAP_FUNC(lv_draw_sw_buffer_copy, STATS_BUFFER_COPY,
lv_draw_ctx_t* ctx, void* dest_buf, const lv_area_t* dest_area,
lv_coord_t dest_stride, const void* src_buf, const lv_area_t* src_area,
lv_coord_t src_stride)
WRAP_FUNC(lv_draw_sw_layer_create, STATS_LAYER_INIT,
lv_draw_ctx_t* ctx, lv_draw_layer_ctx_t* layer_ctx, lv_draw_layer_flags_t flags)
WRAP_FUNC(lv_draw_sw_layer_adjust, STATS_LAYER_ADJUST,
lv_draw_ctx_t* ctx, lv_draw_layer_ctx_t* layer_ctx, lv_draw_layer_flags_t flags)
WRAP_FUNC(lv_draw_sw_layer_blend, STATS_LAYER_BLEND,
lv_draw_ctx_t* ctx, lv_draw_layer_ctx_t* layer_ctx, const lv_draw_img_dsc_t* draw_dsc)
WRAP_FUNC(lv_draw_sw_layer_destroy, STATS_LAYER_DESTROY,
lv_draw_ctx_t* ctx, lv_draw_layer_ctx_t* layer_ctx)
WRAP_FUNC(lv_draw_sw_blend_basic, STATS_BLEND,
lv_draw_ctx_t* ctx, const lv_draw_sw_blend_dsc_t* dsc)

/*-----------------------------

  •    核心接口实现
    

---------------------------/
void draw_stats_init(void) {
// 初始化所有统计项的最小时间
for (int i = 0; i < STATS_COUNT; i++) {
draw_stats[i].min_time_us = UINT32_MAX;
}
}

void draw_stats_print(void) {
LV_LOG_USER("\n========== LVGL Software Draw Statistics ==========");
for (int i = 0; i < STATS_COUNT; i++) {
draw_func_stats_t* s = &draw_stats[i];
if (s->call_count == 0) continue;

    LV_LOG_USER("%-20s | Calls: %-5d | Avg: %-5dus | Max: %-5dus | Min: %-5dus",
                s->func_name,
                s->call_count,
                s->call_count > 0 ? s->total_time_us / s->call_count : 0,
                s->max_time_us,
                s->min_time_us);
}
LV_LOG_USER("===================================================");

}

void lv_draw_sw_init_ctx_wrapped(lv_disp_t* disp, lv_draw_sw_ctx_t* draw_sw_ctx) {
lv_memset_00(draw_sw_ctx, sizeof(lv_draw_sw_ctx_t));

/* 替换所有绘图函数指针 */
#define REPLACE_FUNC(orig, wrapped, field) \
    orig_##orig = draw_sw_ctx->base_draw.field; \
    draw_sw_ctx->base_draw.field = (typeof(draw_sw_ctx->base_draw.field))wrapped_##wrapped;

REPLACE_FUNC(lv_draw_sw_arc, lv_draw_sw_arc, draw_arc);
REPLACE_FUNC(lv_draw_sw_rect, lv_draw_sw_rect, draw_rect);
REPLACE_FUNC(lv_draw_sw_bg, lv_draw_sw_bg, draw_bg);
REPLACE_FUNC(lv_draw_sw_letter, lv_draw_sw_letter, draw_letter);
REPLACE_FUNC(lv_draw_sw_img_decoded, lv_draw_sw_img_decoded, draw_img_decoded);
REPLACE_FUNC(lv_draw_sw_line, lv_draw_sw_line, draw_line);
REPLACE_FUNC(lv_draw_sw_polygon, lv_draw_sw_polygon, draw_polygon);

#if LV_DRAW_COMPLEX
REPLACE_FUNC(lv_draw_sw_transform, lv_draw_sw_transform, draw_transform);
#endif
REPLACE_FUNC(lv_draw_sw_wait_for_finish, lv_draw_sw_wait_for_finish, wait_for_finish);
REPLACE_FUNC(lv_draw_sw_buffer_copy, lv_draw_sw_buffer_copy, buffer_copy);
REPLACE_FUNC(lv_draw_sw_layer_create, lv_draw_sw_layer_create, layer_init);
REPLACE_FUNC(lv_draw_sw_layer_adjust, lv_draw_sw_layer_adjust, layer_adjust);
REPLACE_FUNC(lv_draw_sw_layer_blend, lv_draw_sw_layer_blend, layer_blend);
REPLACE_FUNC(lv_draw_sw_layer_destroy, lv_draw_sw_layer_destroy, layer_destroy);

/* 特别处理blend函数 */
orig_lv_draw_sw_blend_basic = draw_sw_ctx->blend;
draw_sw_ctx->blend = wrapped_lv_draw_sw_blend_basic;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值