Edit online

场景选择

Read time: 4 minute(s)
ArtInChip 平台在进行屏幕旋转时,兼容单 buffer 和双 buffer 的应用程序,可以提供多种屏幕旋转场景供用户选择。各种场景的详细对比说明如下表所示:
1. 屏幕旋转场景对比
场景 优势 劣势
双绘制 buffer 和双显示 buffer 对应用友好,仅需修改 dts 配置即可达成竖屏横用,不需要修改上层应用。 占用的内存资源多,需要 4 块 buf,有一块绘制 buf 是可以节省下来的。720x1280 的屏幕显示 32 位 RGB 数据时,需要约 14M 的物理连续内存。
单绘制 buffer 和双显示 buffer 能避免显示撕裂现象,能节省下一块绘制 buf。 需要修改应用程序。
单绘制 buffer 和单显示 buffer 占用的内存资源最小 需要手动触发更新,必须修改应用。 只有一块显示 buf,撕裂现象不可避免,只能在一些特定的场景中使用。

本节以一块 720x1280 的屏幕竖屏横用为例进行详细说明。

双绘制 buffer 和双显示 buffer

  1. menuconfig 配置
    Board options  --->
        Graphics Support  --->
            Graphics support
                [*] Display Support
                    [*] Support double framebuffer
                    framebuffer rotation degree (90)  --->
  2. disp_conf.h 头文件配置
    /**
     * FB ROTATION options
     */
    
    /* drawing buf for GUI, range [1, 2] */
    #define AIC_FB_DRAW_BUF_NUM 2
    内存使用情况如下所示:
    +-------------------------+
    |      绘制 buf 0         |
    +-------------------------+
    |      绘制 buf 1         |
    +-----+-------------------+
    |     |
    | 显  |
    | 示  |
    | buf |
    | 0   |
    |     |
    +-----+
    |     |
    | 显  |
    | 示  |
    | buf |
    | 1   |
    |     |
    +-----+

    GUI 在绘制 buf0 绘制完界面后,底层驱动会把数据旋转到显示 buf0 进行显示,绘制 buf1 同理。

注:

显示 buffer 的双 buf 由 menuconfig 中的 Support double framebuffer 选项使能。

单绘制 buffer 和双显示 buffer

disp_conf.h 头文件,将绘制 buf 修改为 1 个,并通过 menuconfig 中的 Support double framebuffer 选项使能显示双 buf。
  1. menuconfig 配置
    Board options  --->
        Graphics Support  --->
            Graphics support
                [*] Display Support
                    [*] Support double framebuffer
                    framebuffer rotation degree (90)  --->
  2. disp_conf.h 头文件配置
    /**
     * FB ROTATION options
     */
    
    /* drawing buf for GUI, range [1, 2] */
    #define AIC_FB_DRAW_BUF_NUM 1
内存使用情况如下所示:
+-------------------------+
|      绘制 buf 0         |
+-----+-------------------+
|     |
| 显  |
| 示  |
| buf |
| 0   |
|     |
+-----+
|     |
| 显  |
| 示  |
| buf |
| 1   |
|     |
+-----+
GUI 在绘制 buf0 绘制完界面后,在调用 ioctl pan_display 时,底层驱动会自动切换显示 buf,避免撕裂现象的发生,GUI 应用程序不需要关注显示 buf 的切换。
int buf_id = 0;
int zero = 0;

if (mpp_fb_ioctl(fbfd, FBIOPAN_DISPLAY, buf_id) == 0) {
    if (mpp_fb_ioctl(fbfd, FBIO_WAITFORVSYNC, &zero) < 0) {
        printf("ioctl FBIO_WAITFORVSYNC fail\n");
        return;
    }
} else {
    printf("pan display err\n");
}

单绘制 buffer 和单显示 buffer

disp_conf.h 头文件中,将绘制 buf 修改为 1 个,并取消 menuconfig 中的 Support doubleframe buffer 选项:
  1. menuconfig 配置
    Board options  --->
        Graphics Support  --->
            Graphics support
                [*] Display Support
                    framebuffer rotation degree (90)  --->
  2. disp_conf.h 头文件配置
    /**
     * FB ROTATION options
     */
    
    /* drawing buf for GUI, range [1, 2] */
    #define AIC_FB_DRAW_BUF_NUM 1
其底层的内存使用情况如下所示:
+-------------------------+
|      绘制 buf 0         |
+-----+-------------------+
|     |
| 显  |
| 示  |
| buf |
| 0   |
|     |
+-----+
注:

因为 Display Engine 无法确定 CPU 绘制完成的时机,所以需要应用使用 ioctl pan_display 去手动触发更新。

GUI 在绘制 buf0 绘制完界面后,需要手工调用 ioctl pan_display 才可以触发显示驱动把数据旋转到显示 buf0。
int buf_id = 0;
int zero = 0;

if (mpp_fb_ioctl(fbfd, FBIOPAN_DISPLAY, buf_id) == 0) {
    if (mpp_fb_ioctl(fbfd, FBIO_WAITFORVSYNC, &zero) < 0) {
        printf("ioctl FBIO_WAITFORVSYNC fail\n");
        return;
    }
} else {
    printf("pan display err\n");
}