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可参考以下方案:

问题点 解决方案
Application code Reduce the amount of processing that is unrelated to OpenGL ES calls, such as input processing, game logic, collision detection, and audio processing.
Driver overhead Group geometry with similar state together and eliminate unnecessary state changes.
Vertex attribute transfer Use smaller data types for the values. Also, use a more economical triangle scheme, and in general use glDrawElements rather than glDrawArrays.
Vertex shader processing, or Transform
and Lighting in OpenGL ES 1.1
Try the following options:
1) Use glDrawElements rather than glDrawArrays.
2) For OpenGL ES 1.1, reduce the number of lights.
2) Minimize the transformations of texture coordinates. You can avoid these transformations by setting the transformation matrix using OpenGL ES 1.1 function glLoadIdentity.
3) For OpenGL ES 2.0, simplify the vertex shader program.
Polygon list building  Use fewer graphics primitives. Also, avoid drawing significant amounts of the total geometry in any single call to glDrawElements.
Varying data transfer In OpenGL ES 1.1, use fewer texture coordinates. In OpenGL ES 2.0, use fewer varyings, and specify lower precision on varying variables out of the vertex shader.
Fragment shader processing, texture, color sum, and fog in OpenGL ES 1.1 Lower the resolution of the render target or reduce the size of the viewport.
For OpenGL ES 1.1, use fewer texture stages.
For OpenGL ES 2.0, simplify the fragment shader program.
Texture bandwidth Try the following options:
1)use fewer texture stages
2)lower the size of the textures, by using a smaller data format for each pixel, lower resolution, or texture compression
3)use a simpler texture filtering mode
4)collapse texture coordinates so that they always read from the same position in the texture.

Transfer to display framebuffer
Try the following options:
1) use a mode with lower pixel precision
2) lower the resolution of the render target.

4. ESSL限定值

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-28 15:32:36

Mali GPU OpenGL ES 应用性能优化--基本方法的相关文章

Mali GPU OpenGL ES 应用性能优化--测试+定位+优化流程

1. 使用DS-5 Streamline定位瓶颈 DS-5 Streamline要求GPU驱动启用性能测试,在Mali GPU驱动中激活性能测试对性能影响微不足道. 1.1 DS-5 Streamline简介 可使用DS-5 Streamline从CPU和Mali GPU中实时收集性能计数器,然后以图形方式显示这些计数器,其主要功能如下:     ? 收集计数器--从CPU和Mali GPU中     ? 保存收集到的计数器数据以供回放     ? 查看显示GPU活动.GPU活动和Framebu

WEB前端性能优化常见方法

web前端是应用服务器处理之前的部分,前端主要包括:HTML,CSS,javascript,image等各种资源,针对不同的资源有不同的优化方式. 1. 内容优化 (1)减少HTTP请求数:这条策略是最重要最有效的,因为一个完整的请求要经过DNS寻址,与服务器建立连接,发送数据,等待服务器响应,接收数据这样一个消耗时间成本和资源成本的复杂的过程. 常见方法:合并多个CSS文件和js文件,利用CSS Sprites整合图像,Inline Images(使用 data:URL scheme在实际的页

OpenCL入门:(三:GPU内存结构和性能优化)

如果我们需要优化kernel程序,我们必须知道一些GPU的底层知识,本文简单介绍一下GPU内存相关和线程调度知识,并且用一个小示例演示如何简单根据内存结构优化. 一.GPU总线寻址和合并内存访问 假设X指向一个32位整数数组的指针,数组首地址是0x00001232,那么一个线程需要访问第0个成员时是也许是如下访问的: int tmp = X[0] 假设内存总线宽度是256位,内存访问时必须和总线宽度对齐,所以内存只能访问0x00000020,0x00000040这种地址(0x20=256位),如

性能优化的方法

(1) 减少http请求次数:CSS Sprites, JS.CSS源码压缩.图片大小控制合适:网页Gzip,CDN托管,data缓存 ,图片服务器.(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能.(4) 当需要设置的样式很多时设置className而不是直接操作style.(5) 少用全局变量.缓存DOM节点查找

Nginx配置性能优化的方法

大多数的Nginx安装指南告诉你如下基础知识--通过apt-get安装,修改这里或那里的几行配置,好了,你已经有了一个Web服务器了.而且,在大多数情况下,一个常规安装的Nginx对你的网站来说已经能很好地工作了.然而,如果你真的想挤压出Nginx的性能,你必须更深入一些.在本指南中,我将解释Nginx的那些设置可以微调,以优化处理大量客户端时的性能.需要注意一点,这不是一个全面的微调指南.这是一个简单的预览--那些可以通过微调来提高性能设置的概述.你的情况可能不同. 基本的 (优化过的)配置

网站性能优化的方法--Yahoo

如何能让用户更快的打开我们的网页? 1.尽可能减少HTTP请求数 2.使用CDN(内容分发网络) 3.添加Expire/Cache-Control头 4.启用Gzip压缩 5.将CSS放在页面最上面 6.将Script放在页面最下面 7.避免在CSS中使用Expressions 8.将JavaScript和CSS都放在外部文件中 9.减少DNS查询 10.压缩JavaScript和Css 11.避免重定向 12.移除重复的脚本 13.配置实体标签(ETags) 14.使用AJAX缓存

服务器使用Windows Server 2008进行性能优化的方法

本文引用于:征途源码论坛(www.zhengtuwl.com)-----专注各类免费精品源码下载的平台 Windows效劳器大概是运用最多的体系,云效劳器中也不破例.运用中,契合用户操作习惯它有天然的优势,你能够快速装备所需求的功用但是,这并不能说明windows效劳器就没有缺点,恰恰相反,windows的安全性并没你想的那么高,运用不当会呈现各式各样的技术问答,这里,河南帝通科技就运用独立云效劳器上进步Windows Server 2008功能的一些最常见的主张.将页面文件放在独自的驱动器上

OpenGL ES Emulator比较

http://blog.csdn.net/nhsoft/article/details/6337434 http://www.klayge.org/2011/04/20/opengl-es-emulator横向比较/ http://blog.csdn.net/nhsoft/article/details/6337434 ============================================================================ 目前我手边可选的Emul

(转)OpenGL ES编程入门资源集合

出自:http://blog.csdn.net/u013467442/article/details/44498125 OpenGL ES 2.0中文手册:http://www.dreamingwish.com/articlelist/category/opengl-es-api 里边讲解了部分API的功能,作为基本的参考. OpenGL ES2.0 渲染管线:http://codingnow.cn/opengles/1504.html OpenGL ES2.0 绘制三角形:http://cod