文档管理中心
最佳实践行业场景解决方案拍摄美化XComponent图形渲染常见问题定位指导

XComponent图形渲染常见问题定位指导

概述

XComponent组件作为一种渲染组件,可用于满足开发者实现高级自定义渲染的需求,例如相机预览流的显示和游戏画面的渲染。XComponent渲染时可能出现黑屏、卡顿等问题,本文从XComponent渲染原理图形渲染定位工具链典型案例分析思路三个方面提供定位排查指导。

XComponent渲染原理

XComponent组件负责创建Surface,并通过回调将Surface的相关信息告知应用。应用可以通过一系列接口设定Surface的属性。该组件本身不对所绘制的内容进行感知,亦不提供渲染绘制的接口。XComponent渲染的架构图如下图所示:

XComponent持有一个Surface,开发者能通过调用NativeWindow模块的接口,申请并提交Buffer至图形队列,以此方式将自绘制内容传送至该Surface,其主体流程如下图所示:

数据流向图如下图所示:

经过上述流程,应用自绘制的内容就可以显示在XComponent持有的Surface区域,而XComponent则负责将此Surface整合进UI界面,其中展示的内容正是开发者发送的自绘制内容。Surface的默认位置与大小与XComponent组件一致,开发者可利用setXComponentSurfaceRect()接口自定义调整Surface的位置和大小。

图形渲染定位工具链

HiLog关键日志信息及常见错误码

  • 图形渲染异常信息及错误码

    在日志中搜索C01401或Bufferqueue,可以获取图形渲染异常信息和对应的错误码。错误码可参考OHNativeErrorCode,异常信息如下图所示:

Hidumper查询图形渲染信息

  • 查询UI组件树

    参考获取期望应用组件树获取组件树信息,然后搜索XComponent,可获取XComponent组件信息,如下图所示:

  • 查询Render Service常见信息

    使用hdc shell "hidumper -s RenderService -a allInfo"命令可同时获取surface、RS树等信息。

    1. 获取RS树信息

    RS树是Render Service根据UI组件树转换成的渲染树信息。使用hdc shell "hidumper -s RenderService -a RSTree" > RSTree.dump命令获取RS树信息,然后搜索SURFACE_NODE,可获取XComponent组件对应的节点信息,如下图所示:

    2. 获取surface信息

    使用hdc shell "hidumper -s RenderService -a surface" > surface.dump命令获取surface信息,然后根据XComponent id或者XComponent的Surface id搜索,可获取XComponent组件对应的surface信息和图形队列信息,如下图所示:

Frame分析图形渲染帧异常信息

典型案例分析思路

XComponent生命周期异常问题分析思路

问题描述

使用OH_NativeXComponentOnSurfaceCreated()接口从XComponent组件获取NativeWindow后,传递给渲染子线程使用,当页面退出,XComponent组件销毁时,出现崩溃。

可能根因

  1. XComponent组件销毁时会将NativeWindow引用计数减一,若减为0析构后,子线程仍在使用会导致崩溃。
  2. OH_NativeXComponent实例生命周期与XComponent组件强相关,如果在XComponent组件销毁后仍然操作该对象,将可能出现稳定性问题,造成应用的崩溃。

解决方案

  1. 在将NativeWindow传递给子线程前,使用OH_NativeWindow_NativeObjectReference()将其引用计数加一;当子线程使用完成后,使用OH_NativeWindow_NativeObjectUnreference()将其引用计数减一。
  2. 参考OH_NativeXComponent向OH_ArkUI_SurfaceHolder的迁移,使用OH_ArkUI_SurfaceHolder相关接口代替OH_NativeXComponent相关接口。

XComponent与其它组件图层叠加异常问题分析思路

问题描述

使用XComponent组件绘制内容的背景是透明的,但是层叠布局只能看到第一层绘制的内容。

可能根因

当开发者传输的绘制内容包含透明元素时,Surface区域的显示效果会与下方内容进行合成展示。如果传输内容完全透明,将XComponent的背景色设置成黑色,最终显示为一片黑色区域,层叠布局下方的内容将不可见。

解决方案

将XComponent组件的backgroundColor设置为透明。

画面黑屏问题分析思路

问题描述

使用XComponent组件渲染,画面黑屏。

可能根因

  1. XComponent生命周期异常,例如组件没有创建、Surface id异常。
  2. XComponent渲染异常,例如RS树上没有XComponent节点、XComponent的宽或高为0。
  3. 应用发送的Buffer数据异常,例如未发送Buffer、发送了全黑的Buffer。

解决方案

  1. 参考XComponent组件关键日志信息,排查onSurfaceCreated()/onLoad()是否触发成功、Surface id是否正常。参考创建XComponent和管理Surface生命周期,选择合适的方式创建XComponent并管理XComponent持有Surface的生命周期。
  2. 参考Hidumper查询图形渲染信息,排查UI树和RS树是否存在XComponent节点,节点的宽高是否正常,visibility等属性是否正常。
  3. 排查上层链路的功能是否正常,例如相机预览、解码器出帧、OpenGL处理等是否正常。

画面闪烁问题分析思路

问题描述

页面切换时,XComponent渲染画面出现闪烁。

可能根因

XComponent组件销毁重建或XComponent属性发生变化。

解决方案

参考Hidumper查询图形渲染信息,排查UI树和RS树上的XComponent节点信息是否有变化,例如id、宽高、背景色、透明度等属性是否有变化。

画面撕裂问题分析思路

问题描述

从XComponent对应的NativeWindow中获取Buffer并进行绘制,送显后画面出现花屏、裂屏。

可能根因

使用OH_NativeWindow_NativeWindowRequestBuffer()获取Buffer时,会返回一个fenceFd,这个fenceFd是消费者进程创建的一个文件句柄,表示消费者是否已完成Buffer消费。只有消费端完成消费后,生产者才可以开始填充Buffer,否则会造成花屏、裂屏等问题。

解决方案

调用OH_NativeWindow_NativeWindowRequestBuffer()后,等待fenceFd等于-1(-1表示消费者已完成Buffer消费)后,再将生产的内容写入Buffer。详细使用方法可参考NativeWindow开发指导 (C/C++)

画面卡顿问题分析思路

问题描述

从XComponent对应的NativeWindow中获取Buffer并进行绘制,连续渲染时画面出现卡顿。

可能根因

  1. 生产端填充Buffer的时间过长,即生产端速度<消费端速度,导致卡顿。
  2. 为了确保不同来源的复杂绘制效果能在同一时间节点完成绘制、合成与显示,Render Service依赖VSync实现全局统一的信号收发机制。如果在使用OH_NativeWindow_NativeWindowFlushBuffer()提交Buffer时,没有申请NativeVsync,会导致应用的绘制帧率与系统帧率不同步,出现卡顿。

解决方案

  1. 提高生产端的生产速度,例如使用硬件解码、优化后处理算法等。
  2. 参考NativeVSync开发指导 (C/C++),在提交Buffer时,申请VSync。

渲染内存泄漏问题分析思路

问题描述

使用OH_NativeImage_AcquireNativeWindowBuffer()获取Buffer,消费后已使用OH_NativeImage_ReleaseNativeWindowBuffer()归还Buffer,仍然出现内存泄漏。

可能根因

  1. OH_NativeImage_ReleaseNativeWindowBuffer()只在成功时减少引用计数,未对返回值做处理会导致内存泄漏。
  2. 使用OH_NativeWindow_NativeObjectReference()对Buffer增加一次引用计数后,未配套减少引用计数,导致该Buffer无法释放。

解决方案

  1. OH_NativeImage_ReleaseNativeWindowBuffer()返回不为NATIVE_ERROR_OK时,额外调用OH_NativeWindow_NativeObjectUnreference()减少一次引用计数。
  2. 确保所有分支返回时都有配套调用OH_NativeWindow_NativeObjectUnreference()减少一次引用计数。
在 最佳实践 中进行搜索
请输入您想要搜索的关键词