我有一个opengl app,使用vbo渲染较多的GL_TRIANGLES,一个批次的顶点数在2~3万左右,大概7~8个批次。在大部分手机上运行良好,如gpu为adreno、powervr等,但是在android设备mali400 gpu上,出现花屏甚至卡死并提示gpu out of memory
为此,我们特地对出现问题的机型进行深入测试并做了以下尝试:
1、改变三角形顶点顺序:顺时针或逆时针
2、顶点坐标除以10倍或100倍,防止溢出,(其实顶点数据都在1万以内的浮点数,并不大)
3、单个批次渲染顶点个数控制在一定的点数内,如9000个点
4、不使用vbo
5、使用vbo,空间额外开辟得更大些
以上尝试中,方法4正常,但是出于性能问题不考虑采用。 方法3某种意义上能解决,不足之处在于不同的设备,这个顶点上限值并不同,无法确定
Google了一番,发现有许多网友遇到类似问题
https://community.arm.com/graphics/f/discussions/3523/mali-400-mp-driver-bug
https://forums.khronos.org/showthread.php/8975-Max-number-of-polygon
https://community.arm.com/graphics/f/discussions/6804/mali-400-strange-gldrawelements-behavior-question
问题均集中在vbo顶点数遇到麻烦,似乎新的驱动可以解决
我在meizu m030手机上运行我的app,不做任何修改(开vbo,单个批次顶点数上限不控制),完全正常,该设备也是mali400的gpu,区别在于驱动是较新的
运行时logcat可以看到 mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Mon May 14 20:33:23 KST 2012
求大神指教:新的驱动是否解决了这个问题,并且告知下其根本原因,不胜感激
yanteng你好,原因其实比较清楚了,就是out of memory,我可以尝试解释下。
> 一个批次的顶点数在2~3万左右,大概7~8个批次
我是不是可以理解为一个FBO有大概8个draw,每个draw的vertex数目是2-3万?
Mali GPU是tile-based GPU,所以在运行过程中会为shader中出现的varying分配memory,假设一个shader的vertex shader用到了4个vec4 varying输出,那么一个FBO所需要的memory大概是30000 * 8(8个draw) * 4(4个vec4) * 4(1个vec4是4个float) * sizeof(float) = 15360000 bytes = 14.65M bytes.
因为GPU是按照pipeline执行的,假设同时有3个FBO可以同时运行,那么运行你这个app所需要的memory就是14.65M * 3 ~ 44M。
这是一个不小的数字,在老的手机上很可能会导致out of memory。
新的驱动肯定解决了这个问题,具体解决思路属于内部资料就不说了。
如果你想在app层解决这个问题,可以尝试下要么限制每个FBO所需要的memory,可以从减少draw的个数,varying的个数等方面考虑,要么尝试牺牲一些性能,在FBO画完后稍微等待下再画下一个FBO。
顺便说下,我不能解释“4、不使用vbo”为什么可以解决这个问题。