Android图像处理系列:渲染性能优化——GL多线程的使用

本文探讨了Android相机应用中利用GL多线程进行性能优化的必要性和可行性,详细介绍了多线程的拆分原则,以及如何通过双Buffer解决数据不同步问题。测试结果显示,多线程能够显著提升帧率,改善用户体验。
摘要由CSDN通过智能技术生成

对于一个相机类应用来说,帧率或者流畅度是最关键的性能指标之一。一般来说,相机类应用因为要对图像数据做美颜、滤镜等处理,对每一帧数据的处理流程都比较长。天天P图的相机滤镜链处理过程也很长,中间包含了非常多步的计算和渲染,相机流处理流程中一帧要经过10~20个滤镜处理,即要调用OpenGL draw call10~20次,还包括了很多CPU阻塞操作,包括CPU计算(人脸检测、手势检测等)、纹理上传和下载等,而且滤镜处理数据还在随着产品需求增加而不断增加。如何在保证产品效果需求不断增加渲染和计算的情况下保证用户使用相机的流畅度是我们需要持续优化的工作。本文从多线程的角度出发,介绍OpenGL多线程的适用场景和拆分原则,以及多线程带来的数据不同步的问题和解决方案,最后用对比性能数据说明多线程的优化效果。

GL多线程的必要性和可行性

仔细分析我们的相机处理流程,GPU上的渲染操作并不是连续的,中间会被CPU阻塞操作多次打断,比如人脸检测是CPU操作,在人脸检测时GPU空闲,等待人脸检测结果出来后才能继续渲染,再比如纹理数据的上传或者下载操作,虽然调用的是OpenGL API,但是这些API调用并不能立即返回,而是需要阻塞等待前面的OpenGL指令执行完,且数据传输完成后才能继续渲染,在这段时间内,GPU资源都是空闲的。这就有必要使用多线程来分担这部分CPU计算或阻塞操作,以便更充分地使用GPU资源。

能调用OpenGL API的GL线程说白了其实就是一个包含了OpenGL上下文环境的普通线程。在默认情况下,一个GL线程是无法访问另一个GL线程的GL资源的,比如纹理、着色器和顶点缓冲区等。如果我们希望把纹理上传和下载等GPU阻塞操作放入另一个线程,就需要共享另一个线程的纹理等资源。OpenGL为了解决这个问题,提供了ShareContext的机制,在创建GL线程时可以引用另一个GL线程的上下文环境,以共享GL资源,这就为GL多线程提供了可行性。

GL多线程的拆分原则

这里我们用一个具体的场景为例介绍一下OpenGL多线程的拆分原则,如下图所示:
多线程0.jpg
假设一个渲染线程有5个渲染步骤,第一步渲染完后需要首先上传第二步渲染需要的纹理数据,然后渲染第二步;渲染第三步之前要首先上传需要的顶点Buffer,然后渲染第三步;渲染第四步之前需要首先编译渲染需要的shader,然后再渲染第四步;最后渲染第5步。<

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值