硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1958|回复: 0
收起左侧

[ThreadX全家桶] GUIX学习笔记4 - 横竖屏切换方案(基于RT1052)

[复制链接]

24

主题

131

回帖

203

积分

高级会员

积分
203
发表于 2022-1-12 14:14:27 | 显示全部楼层 |阅读模式
理想情况下,GUI设计分辨率应等于LCD显示分辨率,在高清屏出现之前,这个条件很容易满足,有些小尺寸TFT驱动器也支持通过配置寄存器来自动旋转屏幕。
但现在很多高清屏已经不支持横屏了,只能是用户通过软件自行旋转。

GUIX Studio内置了旋转配置项,但在RT1052平台下没有测试成功。此处介绍一种用代码实现的屏幕旋转操作步骤,结合RT1052的PXP功能,将涉及的数据块搬运,
屏幕旋转操作均通过PXP硬件来实现。OS为Threadx。

1-GUIX Studio的屏幕尺寸按实际需要设置,比如800480的分辨率,想竖屏显示,则设置为宽=480,高=800.

2-GUIX Studio不开通旋转。

3-LCD驱动涉及到的屏幕尺寸按LCD规格书设置,不然显示会不正常。

4-修改GUIX的LCD驱动函数,即那个显示切换函数,_gx_display_driver_imxrt_buffer_toggle(). 这个函数主要涉及脏矩阵的实时刷新,涉及到的操作主要是数据块搬运。
   旋转代码如下:
    visible_frame ^= 1;
    int working_frame = visible_frame ^ 0x01;
        canvas->gx_canvas_memory = (ULONG *)frame_buffer[working_frame];

        /* 强制dcache更新 */
        DCACHE_CleanInvalidateByRange((uint32_t)frame_buffer[visible_frame], FRAME_BUFFER_PIXELS*2);
       
#if defined(LCD_ROTATE)       
        /* 图像旋转90度 */
        PXP_StartRoteate(PXP, (uint32_t)frame_buffer[visible_frame],(uint32_t)rotate_buffer[visible_frame], kPXP_Rotate90);
       
        /* 强制dcache更新 */
        DCACHE_CleanInvalidateByRange((uint32_t)rotate_buffer[visible_frame], FRAME_BUFFER_PIXELS*2);
       
        /* 显存地址(旋转) */
        ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)rotate_buffer[visible_frame]);
#else
       
        /* 显存地址(不旋转) */
        ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)frame_buffer[visible_frame]);       
#endif       


5-对于脏矩阵的数据块拷贝,官方采用的是memcopy,现调整为PXP图像搬运,虽然实测并不能提高速度,但可以解放CPU做别的事。
        /* 脏矩阵尺寸 */
        copy_width  = Copy.gx_rectangle_right - Copy.gx_rectangle_left + 1;
        copy_height = Copy.gx_rectangle_bottom - Copy.gx_rectangle_top + 1;
               
                pxp_pic_copy_config_t pxp_pic_copy_config = {
               
                        /* 源矩阵 */       
                        .srcPicBaseAddr = (uint32_t)frame_buffer[visible_frame],               
                        .srcPitchBytes  = canvas->gx_canvas_x_resolution * 2,               
                        .srcOffsetX          = Copy.gx_rectangle_left,
                        .srcOffsetY          = Copy.gx_rectangle_top,
                       
                        /* 目的矩阵 */
                        .destPicBaseAddr= (uint32_t)frame_buffer[working_frame],               
                        .destPitchBytes = canvas->gx_canvas_x_resolution * 2,       
                };
                /* 开始拷贝 */       
                PXP_StartPictureCopy(PXP, &pxp_pic_copy_config);
               
                /* 等待拷贝完成 */       
                tx_event_flags_get(&event_flags_lcd, 0x02, TX_OR_CLEAR, &actual_flags, TX_WAIT_FOREVER);


6-通过以上调整可以看出,屏幕旋转,局部或全局图片刷新工作均是通过PXP硬件实现的。但这并不能提高刷新率,只是解放了CPU罢了。

7-实测结果:以800*480横屏为例,从开始更新脏矩阵,直至LCD显示完整,测试其时间开销。这个时间开销已包含PXP阻塞时间。
. 横屏全屏显示:15ms
. 横屏竖显全屏:33ms
也就是说:不需要旋转的话,全屏刷新率可做到60帧,需要旋转的话,做到30帧。另外旋转代码只针对全屏旋转,局部旋转没测出来。也就是说,即便GUIX
为窗口局部刷新,但实际上还是全屏旋转,只不过因为有PXP,不会给CPU增添麻烦。

8-横屏,横显示
1.jpg 2.jpg

9-横屏,竖显示
3.jpg 4.jpg

10-LCD旋转资源分析:PXP是RT1052自带的外设,旋转不会增加CPU负担,但会减小刷新率。旋转也需要独立增加1或2个全屏缓冲区。
     实测1个缓冲区很稳,但滑屏过程中似乎见过局部波纹(也可能是心理作用),两个最好,完全杜绝在当前显存直接更新数据。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-22 04:38 , Processed in 0.248265 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表