失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Mali GPU OpenGL ES 应用性能优化--基本方法

Mali GPU OpenGL ES 应用性能优化--基本方法

时间:2018-11-20 19:56:45

相关推荐

Mali GPU OpenGL ES 应用性能优化--基本方法

1. 常用优化工具

2. 常用优化方案

OpenGL ES优化的主要工作是在图形管道中找到影响性能的bottleneck,其bottleneck一般表现在以下几方面:

•在应用程序代码中,如冲突检测

•GPU与主内存间的数据传输

•在VP(Vertex Processor)中的顶点处理

•在FP(Fragment Processor)中的片断处理

可通过DS-5 Streamline来定位性能瓶颈(Locate bottleneck)。为了获取更好的性能,可从以下具体功能着手优化:

2.1 纹理(Texture)

高分辨率的纹理占用大量的内存,它是Mali GPU上的主要负荷,可从以下几方面进行优化:

•除非必要,尽量不要使用大纹理

•总是打开纹理映射(mipmapping),有时可能降低了渲染质量

•如果可能,排序三角形,当按render的次序render时,使其有相互覆盖的三角形放在一起

•压缩纹理,可减少内存占用、传输带宽,Mali-400 MP GPU支持ETC纹理压缩(每个像素占4bits,且不支持alpha通道),GPU硬件可解压ETC纹理,缺点是将降低图像质量

2.2抗锯齿(Anti-aliasing)

•GPU支持4x Full Scene Anti-Aliasing (FSAA),其性能损失微不足道;当创建context和rendering surface时,可通过选择EGL配置(EGL_SAMPLES=4)来激活4x FSAA

•Mali GPU还支持16x FSAA,其性能将下降到4x FSAA的1/4

2.3 画图模式(Draw Mode)

对于大的网格,一个顶点被包含在多个三角形中,这样的顶点被处理的次数依赖调用的画图函数:

•glDrawElements:每个顶点仅被处理一次,效率更高。

•glDrawArrays:每个顶点数据在每一个使用它的三角形中被传输和处理一次

按使用的次序存储顶点数据,可以改善顶点Cache效果,并且减少了从RAM到顶点Cache传输的数据量。

2.4顶点缓冲对象(Vertex Buffer Objects)

•使用顶点数组(Vertex Array)存储的顶点数据位于客户端内存(即主内存),当调用glDrawArrays或glDrawElements时,将把这些顶点数据从客户端内存copy到图形内存。

•Vertex Buffer Objects允许OpenGL ES2.0应用在高性能的图形内存中分配且Cahce顶点数据,然后从此内存中进行渲染。这样就避免了每当Draw一个原语时重发数据。

•Vertex Buffer Objects分类:

1) 数组缓冲对象(array buffer objects):由GL_ARRAY_BUFFER标识,用于存储顶点数据(Vertex Data)

2) 元素数组缓冲对象(element array buffer objects):由GL_ELEMENT_ARRAY_BUFFER标识,用于存原语索引(indices of primitive)

2.5 数据精度(Data Precision)

在可能的情况下,尽量使用低精度的数据,避免使用浮点和其它32位数据类型:

•定义顶点位置使用GL_SHORT

•定义Surface Normal使用GL_BYTE

•定义颜色使用GL_UNSIGNED_BYTE

2.6 处理的数据量(Volume of Data Processed)

要从以下几方面减少Mali GPU处理的数据量:

•只画当前帧看得见的原语:可在应用中通过clipping或frustum clulling来实现

•使用ETC压缩纹理

•根据深度排序几何体:按照从前到后的顺序排序几何体,根据深度排序draw调用。

2.7渲染目标(Render Targets)

以下因素与渲染目标有关:

•按照因素(cause-and-effect)顺序渲染所有的纹理

1)在纹理被使用之前render to textures

2)最后渲染后台缓冲区

•一次只绘制到一个渲染目标:确保绘制下一个目标之前,已经完成当前目标的所有调用

•不要在一帧中修改纹理:当调用API之前,设置好所有当前帧需要的纹理

2.8 处理管道(Processing Pipeline)

以下因素与图形处理管道有关:

• 使用eglSwapBuffers:

如果应用显示动画,确保通过调用eglSwapBuffers来结束一帧。应用接着产生下一帧,这样以确保在计算下一帧时,当前帧仍可稳定显示。

• 避免使用glReadPixels:

即使读取很少像素,对性能影响也比较大,因为它暂停了处理管理

• 限制glDrawElements中顶点个数:

在调用glDrawElements之后,在以前的操作(如:顶点着色、变换、光照)完成之后才开始创建多边形列表。为了使之并行,确保单次glDrawElements调用中包含的顶点数不要超过当前帧中所有顶点数的1/5。这在立即调用glDrawArrays之前或之后特别重要。

2.9着色器程序(Shader Programs)

•首先执行Shader编译:在应用程序启动时,且在开始向驱动发送顶点或纹理数据之前,完成Shading语言编译器所有相关的调用

•使用自定义着色器程序:把大的Shader程序采裁剪成每个Surface所需要的,而不使用大而全的Shader程序,小而精的Shader程序通常运行得更快

•考虑程序大小:可以使用Offline Shader Compiler检测程序大小。一个GPU指令可以包含一系列ESSL操作

•循环和条件分支:不要手动展开循环。相反,把数据放到数组中,然后在可能的地方使用for循环。当然,也可以使用if语句。

•避免使用过多的varyings:在shader编程时,在Fragment Shader程序中,尽量节约使用varings;因为在VP与内存或FP与内存间传递varings时需要消耗内存带宽

•避免使用过多的矩阵乘法:4x4的矩阵与4x1的向量相乘,需要执行16次乘法和12次加法,是非常昂贵的;如果需要一个向量与多个矩阵相乘,则向量依次与每个矩阵相乘,而不要先把所有的矩阵相乘,然后再与向量相乘

•评估程序的代价:常用的代价级别如下表所示,使用Offline Shader Compiler可以更精确地获取程序的代价。

2.10着色器运算(Shader Arithmetic)

•顶点处理器基于32位浮点值工作:Vertex Shader使用浮点表示整数。为了避免32位值,设置Vertex Shader程序的输出varing的精度为mediump或lowp。

•Fragment Shader使用16位浮点值工作:其构成为:sign;5位指数,以抵消15;10位尾数,用一个隐含的最显著1位

2.11 其它

• 使用点精灵:

而不是三角形或四边形来表示颗粒实体

• 使用适当尺寸的三角形:

避免使用长而细的三角形。FP(Fragment Processor 或Pixel Processor)总是处理4个邻近Fragment的组。因此处理1个像素宽度的Strip比处理2个像素宽度的Strip耗用更多的时间。

• 优化状态变化:

避免状态来回变化,可以把相同状态的调用组织在一起,以减少状态变化

• 清除整个Framebuffer:

总是调用glClear清除整个Framebuffer。如果可能,在清除framebuffer时,清除所有的buffer,如:color、depth, and stencil buffers。

void glClear(GLbitfield mask);

参数说明:

GLbitfield:可以使用 | 运算符组合不同的缓冲标志位,表明需要清除的缓冲,例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除颜色缓冲以及深度缓冲,可以使用以下标志位:

1)GL_COLOR_BUFFER_BIT: 当前可写的颜色缓冲

2)GL_DEPTH_BUFFER_BIT: 深度缓冲

3)GL_ACCUM_BUFFER_BIT: 累积缓冲

4)GL_STENCIL_BUFFER_BIT: 模板缓冲

• 最小化draw调用:

当调用glDrawArrays或glDrawElements时,GPU驱动需要收集所有当前OpenGL ES状态、纹理和顶点属性数据;然后驱动处理这些数据并产生可在GPU硬件上执行的命令,以执行真正的draw调用。此操作可以耗费大量的时间,所以如果执行多次调用,它将成为rendering的性能瓶颈。如果多个对象具有相同的rendering参数,但使用不同的纹理,则可以把纹理合并到一个大的纹理中,并调整其对应的纹理坐标即可。

• 避免使用glFlush和glFinish:

除非你无法避开,否则不要调用glFlush或glFinish,而使用eglSwapBuffers来触发一帧的结束。(注:glFlush只是把命令发送给Server,但并不等待执行完成。如果需要等到Server执行完成时才返回,则需要调用glFinish,但它严重影响性能。)

3. 发现和消除bottleneck

基本方法:

1) 使用专业工具(如DS-5 Streamline)

2) 在值得怀疑的图形管理阶段,增加或减少负荷,然后观察性能变化情况

发现和消除bottleneck可参考以下方案:

4. ESSL限定值

OpenGL ES Shading Language规范定义了各种着色器资源(shader resources)大小的最小值,在Mali GPU实现中,其中一些值大于规范中定义的最小值。常用的如下表所示:

如果觉得《Mali GPU OpenGL ES 应用性能优化--基本方法》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。