GR5526(8)-图形化常见问题及解决参考

[TOC]

1. Lvgl 显示类问题

1.1 Lvgl旋转图片时, 图片在某些旋转角度出现叠影现象.

  • 问题描述:

    • 在 基于GR5526 版本Lvgl 实现图片旋转功能时候, 旋转到某些角度, 图片会出现叠影异常

  • 问题源码:

    • 测试图片:

      ../../_images/gpu_rotate.jpg

    • 绘制到屏幕中心并旋转后的问题现象:

      ../../_images/gpu_rotate_issue.png

    • 图片素材

      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),
          };
      
    • 测试源码:

      #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
      
  • 原因:

    • 图片源数据放置在 数据Flash上, 在渲染时通过映射空间直接寻址, GPU在进行旋转渲染时, 根据需要会发生不同总线宽度的访问, 而外部Flash 需要根据总线宽度的改变而显性改变端序配置, 这在代码中不便实现.

  • 解决方法:

    • 将需要旋转的图片, 放置到支持任意总线宽度随机访问的 PSRAM空间供GPU访问即可.

    • 修改后参考源码:

      #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