GR5526 (8)-Graphical FAQ and Solution Reference

[TOC]

1. Lvgl display class problem

1.1 Lvgl When rotating an image, the image appears to be foldover at some rotation angles.

  • Description of the problem:

    • When the image rotation function is implemented based on GR5526 version Lvgl, the image will appear abnormal folding when it is rotated to certain angles.

  • Problem source code:

    • Test picture:

      ../../_images/gpu_rotate.jpg

    • Problems after drawing to the center of the screen and rotating:

      ../../_images/gpu_rotate_issue.png

    • Picture material

      const lv_img_dsc_t  wd_img_image_8888 = {
          .header.always_zero = 0,
          .header.w = 120,
          .header.h = 120,
          .data_size = 57600, 
          .header.cf = LV_IMG_CF_TRUE_COLOR,
          .data = (uint8_t*)(QSPI0_XIP_BASE + ADDR_IMAGE_8888),
          };
      
  • Test source code:

    #include "lvgl.h"
    #include "lv_img_dsc_list.h"
    #include "app_graphics_mem.h"

    #define DELTA_ANGLE     (60)
    
    static lv_obj_t*        img = NULL;
    static lv_timer_t*      waitting_timer = NULL;
    
    static void inner_on_timer_cb(lv_timer_t* timer);
    
    void lvgl_test(void)
    {
        lv_obj_t * scr  = lv_scr_act();
        img = lv_img_create(scr);
    
        lv_img_set_src(img, &wd_img_image_8888);
        lv_img_set_pivot(img, wd_img_image_8888.header.w / 2, wd_img_image_8888.header.h / 2);
        lv_obj_center(img);
        if (!waitting_timer)
        {
            waitting_timer = lv_timer_create(inner_on_timer_cb, 100, NULL);
            lv_timer_set_repeat_count(waitting_timer, -1);
        }
        lv_timer_reset(waitting_timer);
    }
    
    static void inner_on_timer_cb(lv_timer_t* timer)
    {
        if (timer && img)
        {
            int16_t angle = lv_img_get_angle(img);
            lv_img_set_angle(img, angle + DELTA_ANGLE); //转动图片
        }
    }z

  • Reason

    • The image source data is placed on the data Flash, and is directly addressed through the mapping space during rendering. When the GPU performs rotation rendering, different bus widths will be accessed as required, and the external Flash needs to explicitly change the endian configuration according to the change of the bus width, which is inconvenient to implement in the code.

  • Solution:

    • Place the image that needs to be rotated in the PSRAM space that supports random access of any bus width for GPU access.

    • Reference source code after modification:

        #include "lvgl.h"
        #include "lv_img_dsc_list.h"
        #include "app_graphics_mem.h"

        #define DELTA_ANGLE     (60)
        
        static lv_obj_t*        img = NULL;
        static lv_img_dsc_t     img_cache;
        static lv_timer_t*      waitting_timer = NULL;
        
        static void inner_on_timer_cb(lv_timer_t* timer);
        
        void lvgl_test(void)
        {
            lv_obj_t * scr  = lv_scr_act();
            img = lv_img_create(scr);
        
            uint8_t * p_buf = app_graphics_mem_malloc(wd_img_image_8888.data_size);
            memcpy(p_buf, wd_img_image_8888.data, wd_img_image_8888.data_size);
        
            memcpy(&img_cache, &wd_img_image_8888, sizeof(wd_img_image_8888));
            img_cache.data = p_buf;
        
            lv_img_set_src(img, &img_cache);
            lv_img_set_pivot(img, img_cache.header.w / 2, img_cache.header.h / 2);
            lv_obj_center(img);
            if (!waitting_timer)
            {
                waitting_timer = lv_timer_create(inner_on_timer_cb, 100, NULL);
                lv_timer_set_repeat_count(waitting_timer, -1);
            }
            lv_timer_reset(waitting_timer);
        }
        
        static void inner_on_timer_cb(lv_timer_t* timer)
        {
            if (timer && img)
            {
                int16_t angle = lv_img_get_angle(img);
                lv_img_set_angle(img, angle + DELTA_ANGLE); //转动图片
            }
        }z