LVGL界面卡顿优化总结

前言

前面移植了lvgl到全志r528平台(Linux),但是运行起来界面有些卡顿,当遇到页面切换时帧率能下降到个位数。为此,我查阅了大量资料,咨询了方案厂商,总结出一些优化方案。注意这是针对Linux平台下的优化。

优化点

1. 开启硬件G2D加速

根据厂商提供的资料和Demo,我们可以使用全志提供的驱动文件代替lvgl自带的fb驱动。实际效果并不理想,厂商还在优化探索当中。

2. 使用双缓存

根据lvgl的资料,我们可以初始化两个缓冲区,采用双缓存来刷新。双缓存也可以增加刷新速度。对于缓存区的大小也有讲究,网络上也有人分析对比过,当采用两个缓冲区,每个缓冲区相当于屏幕的一半大小时效果最佳,但是我们在实践过程中,遇到了一些问题,最终采用了两个和屏幕一样大的缓冲区。

/*Create a display buffer*/
static lv_disp_draw_buf_t disp_buf1;
static lv_color_t buf1_1[HAIER_HOR_RES * HAIER_VER_RES];
static lv_color_t buf1_2[HAIER_HOR_RES * HAIER_VER_RES];

lv_disp_draw_buf_init(&disp_buf1, buf1_1, buf1_2, HAIER_HOR_RES * HAIER_VER_RES);

3. 局部刷新

在显示驱动中有一个参数是是否开启全局刷新,我们把它设置为0即可。以下贴了lv_disp_drv_t的几个配置项,可以根据自己情况进行修改和测试效果,选择适合自己配置参数。

typedef struct _lv_disp_drv_t {

    lv_coord_t hor_res;         /**< Horizontal resolution.*/
    lv_coord_t ver_res;         /**< Vertical resolution.*/

    lv_coord_t
    physical_hor_res;     /**< Horizontal resolution of the full / physical display. Set to -1 for fullscreen mode.*/
    lv_coord_t
    physical_ver_res;     /**< Vertical resolution of the full / physical display. Set to -1 for fullscreen mode.*/
    lv_coord_t
    offset_x;             /**< Horizontal offset from the full / physical display. Set to 0 for fullscreen mode.*/
    lv_coord_t offset_y;             /**< Vertical offset from the full / physical display. Set to 0 for fullscreen mode.*/

    /** Pointer to a buffer initialized with `lv_disp_draw_buf_init()`.
     * LVGL will use this buffer(s) to draw the screens contents*/
    lv_disp_draw_buf_t * draw_buf;

    uint32_t direct_mode : 1;        /**< 1: Use screen-sized buffers and draw to absolute coordinates*/
    uint32_t full_refresh : 1;       /**< 1: Always make the whole screen redrawn*/
    uint32_t sw_rotate : 1;          /**< 1: use software rotation (slower)*/
    uint32_t antialiasing : 1;       /**< 1: anti-aliasing is enabled on this display.*/
    uint32_t rotated : 2;            /**< 1: turn the display by 90 degree. @warning Does not update coordinates for you!*/
    uint32_t screen_transp : 1;      /**Handle if the screen doesn't have a solid (opa == LV_OPA_COVER) background.
                                       * Use only if required because it's slower.*/

    uint32_t dpi : 10;              /** DPI (dot per inch) of the display. Default value is `LV_DPI_DEF`.*/
    ........other code ............
} lv_disp_drv_t;

4. 图层处理

尽量减少图层的叠加,以电台首页为例:

static lv_obj_t *create_obj_radio_home(lv_fragment_t *self, lv_obj_t *container)
{    
    // 修改前,叠加一个背景图层,实际没有必要,可以优化掉
    // lv_obj_t *lv_parent = lv_obj_create_full(container, COLOR_PAGE_BG);
    // lv_obj_add_event_cb(lv_parent, event_handler, LV_EVENT_CLICKED, NULL);

    // lv_list = lv_obj_create_transp(lv_parent, COLOR_TRANSP);
    // 修改后:
    lv_list = lv_obj_create_full(container, COLOR_PAGE_BG);
    lv_obj_set_style_bg_color(container, lv_color_hex(0x161616), LV_STATE_DEFAULT);
    // lv_obj_set_style_bg_opa(lv_list, LV_OPA_TRANSP, LV_STATE_DEFAULT);
    lv_obj_set_user_data(lv_list, 9999);
    lv_obj_set_size(lv_list, LV_PCT(100), HAIER_SIZE(1048));
    lv_obj_set_pos(lv_list, 0, HAIER_SIZE(102));
    lv_obj_set_style_bg_color(lv_list, lv_color_hex(0x161616), LV_STATE_DEFAULT);
    
    lv_obj_set_scrollbar_mode(lv_list, LV_SCROLLBAR_MODE_OFF); 
    
    ......

5. 图文处理

当文字叠加到图片上方时会引发卡顿。以首页应用列表Tab为例,我们将文案内容固定的文字切为图片,可以大大减少卡顿情况:

  • 优化前:
    组件+背景+图标+文字=四层 大概在10FPS
static void creat_app_card(lv_obj_t *tab, app_data data)
{
    lv_obj_t *app_card = lv_obj_create_transp(tab, COLOR_TRANSP);
    lv_obj_set_size(app_card, HAIER_SIZE(140), HAIER_SIZE(185));
    lv_obj_add_event_cb(app_card, app_click_handler, LV_EVENT_CLICKED, data.pos);

    lv_obj_t *img_bg = lv_img_create_transp(app_card, &icon_app_bg);
    lv_obj_set_size(img_bg, HAIER_SIZE(120), HAIER_SIZE(120));
    lv_obj_align(img_bg, LV_ALIGN_TOP_MID, 0, HAIER_SIZE(10));
    lv_obj_add_event_cb(img_bg, app_click_handler, LV_EVENT_CLICKED, data.pos);
    lv_obj_t *img_icon = lv_img_create_transp(img_bg, data.icon);
    lv_obj_center(img_icon);
    lv_obj_add_event_cb(img_icon, app_click_handler, LV_EVENT_CLICKED, data.pos);

    lv_obj_t *name = lv_label_create_transp(app_card, data.name, COLOR_WHITE);
    lv_obj_add_style(name, &common_font_style_24_bold, LV_STATE_DEFAULT);
    lv_obj_align_to(name, img_bg, LV_ALIGN_OUT_BOTTOM_MID, 0, HAIER_SIZE(23));
    lv_obj_add_event_cb(name, app_click_handler, LV_EVENT_CLICKED, data.pos);
}
  • 优化后:
    一张图=一层 稳定66FPS
static void create_app_card_new(lv_obj_t *tab, app_data data){
    lv_obj_t *app_card = lv_img_create_transp(tab, app_img_new[data.pos]);
    lv_obj_set_size(app_card, HAIER_SIZE(120), HAIER_SIZE(170));
    lv_obj_add_event_cb(app_card, app_click_handler, LV_EVENT_CLICKED, data.pos);
}

6. 字体配置

前面讲过,字体和图片叠加会引起帧数降低,于是分别测试图片和文字,发现引起卡顿的主要是文字。以低置恒温页面和电台首页为例:

页面 优化前 探索实验
电台首页 10fps 图文叠加,图片居多 66fps 去掉文字
恒温首页 10fps 图文交替,文字较多 15fps 去掉图片

由以上现象我们可以得出结论,文字会影响帧率,于是找到lv_conf.h文件中关于freetypoe的相关的配置:
加大缓存,更换缓存类型:最终低置恒温,菜谱等这类“图文交替”的页面在全屏滑动时能够稳定在30FPS+,达到了良好的显示效果。

  • 修改前:
/*FreeType library*/
#define LV_USE_FREETYPE 1
#if LV_USE_FREETYPE
    /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
    #define LV_FREETYPE_CACHE_SIZE (16 * 1024)
    #if LV_FREETYPE_CACHE_SIZE >= 0
        /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
        /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
        /* if font size >= 256, must be configured as image cache */
        #define LV_FREETYPE_SBIT_CACHE 1
        /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
        /* (0:use system defaults) */
        #define LV_FREETYPE_CACHE_FT_FACES 1
        #define LV_FREETYPE_CACHE_FT_SIZES 20
    #endif
#endif
  • 修改后
/*FreeType library*/
#define LV_USE_FREETYPE 1
#if LV_USE_FREETYPE
    /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
    #define LV_FREETYPE_CACHE_SIZE (4 * 1024*1024)
    #if LV_FREETYPE_CACHE_SIZE >= 0
        /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
        /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
        /* if font size >= 256, must be configured as image cache */
        #define LV_FREETYPE_SBIT_CACHE 0
        /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
        /* (0:use system defaults) */
        #define LV_FREETYPE_CACHE_FT_FACES 20
        #define LV_FREETYPE_CACHE_FT_SIZES 30
    #endif
#endif

你可能感兴趣的:(c语言,lvgl,LVGL)