积分582 / 贡献0

提问0答案被采纳0文章52

[经验分享] 应用界面出现闪屏问题分析报告 原创

Laval社区小助手 显示全部楼层 发表于 2024-9-4 10:37:37

1 关键字

OpenHarmony;闪屏;透视

2 问题描述

开发板型号:dayu200-RK3568

芯片:RK3568

内核版本: Linux5.10

OH版本:OpenHarmony3.1-Release

问题现象:OpenHarmony3.1-Release版本适配RK3568,当打开应用时出现闪屏现象。设置显示屏横屏,插入鼠标,当鼠标在显示屏右边移动时,大概率出现闪屏现象。

测试步骤:

  1. OpenHarmony3.1Release版本按照RK3568的适配文档操作,烧录系统到单板。
  2. 设置显示屏横屏显示。
  3. 打开应用时出现闪屏现象。
  4. 接入鼠标,当鼠标在显示屏左边移动时,大概率出现闪屏现象。

3 问题原因

3.1 正常机制

当鼠标移动后的渲染合成正常,无闪频现象。

3.2 异常机制

当鼠标移动到屏幕边缘后,渲染合成机制出现问题,概率性出现闪频现象。

4 解决方案

  • 根据日志信息,对比版本,修复以下代码: device/hihope/hardware/display/src/display_gfx/display_gfx.c b/hardware/display/src/display_gfx/display_gfx.c

    --- a/hardware/display/src/display_gfx/display_gfx.c
    +++ b/hardware/display/src/display_gfx/display_gfx.c
    @@ -354,12 +354,15 @@ int32_t doFlit(ISurface *srcSurface, IRect *srcRect, ISurface *dstSurface, IRect
             ALIGN_UP(dstSurface->height, 16), dstRgaBuffer.vir_addr);
    
         srect.x = srcRect->x;
    +    srect.x = (srect.x == 1) ? 0 : srect.x;^M
         srect.y = srcRect->y;
    +    srect.y = (srect.y == 1) ? 0 : srect.y;^M
         srect.height = srcRect->h;
         srect.width = srcRect->w;
         drect.x = dstRect->x;
         drect.x = (drect.x == 1) ? 0 : drect.x;
         drect.y = dstRect->y;
    +    drect.y = (drect.y == 1) ? 0 : drect.y;^M
         drect.height = dstRect->h;
         dre
  • 编译烧录后,验证显示正常。

5 定位过程

5.1 初步分析

初步分析,多图层闪屏问题应该不是渲染过程引起的,应该是合成过程引起。

5.2 分析日志

  • 日志打印错误
    08-05 09:18:39.928   374   374 E 02500/DISP: [doFlit@display_gfx.c:461] gfx improcess Invalid parameters: Hardware limitation src rect, unsupported operation of images smaller than 2 pixels, rect[x,y,w,h] = [0, 1, 64, 63]
    08-05 09:19:05.866   374   374 E 02500/DISP: [doFlit@display_gfx.c:461] gfx improcess Invalid parameters: Hardware limitation dst rect, unsupported operation of images smaller than 2 pixels, rect[x,y,w,h] = [65, 1, 64, 64]
    08-05 09:19:05.878   374   374 E 02500/DISP: [doFlit@display_gfx.c:461] gfx improcess Invalid parameters: Hardware limitation dst rect, unsupported operation of images smaller than 2 pixels, rect[x,y,w,h] = [65, 1, 64, 64]
  • 根据错误定位到代码
    int32_t doFlit(ISurface *srcSurface, IRect *srcRect, ISurface *dstSurface, IRect *dstRect, GfxOpt *opt)
    {
        ...
        srect.x = srcRect->x;
        srect.y = srcRect->y;
        srect.height = srcRect->h;
        srect.width = srcRect->w;
        drect.x = dstRect->x;
        drect.y = dstRect->y;
        drect.height = dstRect->h;
        drect.width = dstRect->w;    
        ...
        ret = improcess(srcRgaBuffer, dstRgaBuffer, bRgbBuffer, srect, drect, prect, usage);
        if (ret != IM_STATUS_SUCCESS) {
            DISPLAY_LOGE("gfx improcess %{public}s", imStrError(ret));
        }    
        ...
    }

根据日志报错信息,发现参数小于2引起函数错误。

5.2 对比版本

对比版本,发现3.2Beta版本确实引入对参数的修改来规避此问题。烧录验证后,此问题修复。

--- a/hardware/display/src/display_gfx/display_gfx.c
+++ b/hardware/display/src/display_gfx/display_gfx.c
@@ -354,12 +354,15 @@ int32_t doFlit(ISurface *srcSurface, IRect *srcRect, ISurface *dstSurface, IRect
         ALIGN_UP(dstSurface->height, 16), dstRgaBuffer.vir_addr);

     srect.x = srcRect->x;
+    srect.x = (srect.x == 1) ? 0 : srect.x;^M
     srect.y = srcRect->y;
+    srect.y = (srect.y == 1) ? 0 : srect.y;^M
     srect.height = srcRect->h;
     srect.width = srcRect->w;
     drect.x = dstRect->x;
     drect.x = (drect.x == 1) ? 0 : drect.x;
     drect.y = dstRect->y;
+    drect.y = (drect.y == 1) ? 0 : drect.y;^M
     drect.height = dstRect->h;

6 知识分享

根据现象初步断定,这种多图层透视问题不是渲染过程中引起的,而是在合成过程中产生的。分析日志得出合成过程提前退出造成闪屏,根因是rockchip硬件有限制,对一些特殊的参数判定为错误参数,造成合成失败。

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部