移动平台上的GPU优化

背景

这篇文章是内部一次分享会的PPT内容,起因是最近负责的一个AR剧本功能(类似抖音+FaceU),这篇文章也是OpenGL ES的采坑记录,是根据剧本文件,解析出时间和相关参数,使用GL绘制美颜,形变、脸妆、贴纸、特效、转场、分屏、截屏等等,同时对音频进行解码播放,最终生成视频。其中绘制分辨率为1280x720,贴纸、脸妆等贴纸使用到了第三方的人脸识别。

问题

反馈卡,对比FaceU,B612贴纸跟随卡,画面卡,总之就是卡。

过程

第一反应,是不是人脸识别导致线程阻塞引起的?

围绕线程

  1. 摄像头数据回调,人脸识别放到异步线程处理
  2. 纹理回调放到异步线程处理
  3. 开启多个渲染线程去进行加载纹理
  4. 开启多个渲染线程摄像头通知新纹理时进行缓存再绘制
  5. 提高摄像头帧数

==失败!!!==

两个结果

  1. 添加多个渲染线程不会影响速度,仅仅可能是逻辑需要。

  1. Camera是主线程,Texture是绘制线程

对症下药

1. 绘制引起的画面延迟大

  • 优化美颜和形变算法 寻找新美颜方案,优化POW函数

  • 多层贴纸绘制合并为一层
    客户端合将多个贴纸一次绘制。
    使用华为Mate 9测试,王者荣耀剧本绘制时间从18-20ms 降到13-15ms左右。

  • 客户端UI绘制过多
    歌词View存在BUG,绘制非常频繁,这里也有个坑,gfxinfo获取的帧数仅是View绘制的次数不包含GL绘制,因为该数据是SurfaceFlinger统计的。

2. 贴纸引起的画面卡顿

  • 贴纸预加载
    提前将贴纸加载到内存中,减少CPU从本地读取的延时。

  • 贴纸缓存
    将贴纸纹理缓存下来,循环使用,减少CPU到GPU纹理加载的延时。

  • 贴纸提前缓存第一帧
    渲染第一帧的时候,同时加载第二帧,依次类推,保证不会因为从CPU载入到GPU的间隔出现延时。

  • 四分屏卡顿
    缓存和减少四分屏FrameBuffer大小

3. 解决画面延时的关键方案

  • GLSurfaceView
    GLSurfaceView双缓冲机制,其中包含两个线程,一个进行临时绘制,一个进行最终绘制,最终将结果交给GL渲染线程进行绘制。

4. 人脸跟随延时

  • 合并线程
    摄像头数据和商汤的人脸识别都放到GL的渲染线程,同时进行人脸识别和绘制,保证人脸和点误差最小。

总结

技术实施
1. 合理设计使用GPU和CPU,保证两者的均衡

方案设计
1. 处理未知领域的技术,要尽可能的将相关技术和细节调研清楚
2. 参考行业成熟产品的技术选型

2 条评论

  1. 大神好,请教个问题,在不同的CPU线程中能否使用同一套Opengl es环境,这样会不会出现问题?

    1. @david 是两个CPU线程都可以提交GL指令吗?
      这种情况可以通过共享GLContext使用同一套GL环境。
      一般也没问题,但确实没必要开俩绘制线程。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

返回主页看更多
狠狠的抽打博主 支付宝 扫一扫