• 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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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); 
        
        ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 优化后:
      一张图=一层 稳定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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 修改后
    /*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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    java面向对象-----再谈方法
    【neovim 技巧系列】quickfix 与文本处理
    Python编写Word文档
    vue3 - Ts版本
    Ambire 第一次治理投票:WALLET 质押者选择新的燃烧率和锁定期
    【调度算法】关于轮盘赌和锦标赛两种选择算子的选用思考
    mybatis-plus
    基于微信小程序的音乐播放平台
    数据迁移的高招!两台笔记本电脑怎么互传文件
    摩托罗拉手机在中国以外的市场复兴,在欧洲和美国大幅增长
  • 原文地址:https://blog.csdn.net/qq_18454025/article/details/134536768