在Nexus 10 / Android 4.2.2上降低glTexSubImage2D性能(三星Exynos 5 w / Mali-T604)

时间:2013-03-22 22:07:35

标签: android opengl-es textures egl

我有一个Android应用程序,可将视频解码为yuv420p格式,然后使用OpenGLES呈现视频帧。 我使用glTexSubImage2D()将y / u / v缓冲区上传到GPU,然后使用着色器进行YUV2RGB转换。所有EGL / OpenGL设置/呈现代码都是本机代码。

现在我并不是说我的代码没有问题,但考虑到相同的代码在iOS(iPad / iPhone),Nexus 7,Kindle HD 8.9,Samsung Note 1和其他一些便宜的中国平板电脑上运行完美(A31 / RockChip 3188)运行Android 4.0 / 4.1 / 4.2。我会说我的代码不太可能出错。在这些设备上,glTexSubImage2D()使用不到16ms的时间来上传SD或720P高清纹理。

然而,在Nexus 10上,glTexSubImage2D()对于SD或720P高清纹理大约需要50~90ms,这对于30fps或60fps视频来说太慢了。

我想知道

1)如果我应该选择不同的纹理格式(RGBA或BGRA)。有没有办法检测哪个是GPU使用的最佳纹理格式?

2)如果在所有其他SOC上有一个“OFF”功能,但在Exynos 5上设置为“ON”。例如,自动MIPMAP生成选项。 (顺便说一句,顺便说一下)

3)如果这是三星Exynos SOC的已知问题 - 我找不到Exynos CPU的支持论坛

4)配置EGL表面时是否需要设置任何选项?喜欢,透明度,表面格式等? (我不知道我在说什么)

5)这可能意味着GPU正在进行隐式格式转换,但我检查了GL_LUMINANCE始终使用。它再次适用于所有其他平台。

6)其他什么?

我的EGL配置:

const EGLint attribs[] = {
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_NONE
};

初始设置:

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, ctx->frameW, ctx->frameH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); /* also for U/V  */

随后的部分替换:

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ctx->frameW, ctx->frameH, GL_LUMINANCE, GL_UNSIGNED_BYTE, yBuffer); /*also for U/V */

我试图在SD或720P HD分辨率下以~30FPS或~60FPS渲染视频。

3 个答案:

答案 0 :(得分:6)

这是我们向ARM报告的已知驱动程序问题。未来的更新应该解决它。

答案 1 :(得分:1)

编辑状态更新

我们现在设法为公共固件上的一个路径重现缓慢的上传条件,这可能会在下一个驱动程序版本中修复。

如果您为上传到它的纹理双重缓冲纹理ID(例如,帧N = ID X,N + 1 = ID Y,N + 2 = ID X,N + 3 = ID Y等)帮助避免在当前固件上使用此功能。

谢谢, Iso

答案 2 :(得分:1)

我可以确认这已在Android 4.3中得到修复 - 我发现RGBA格式的性能提升了2-3倍,其他纹理格式比Android 4.2.2提高了10-50倍。这些结果适用于glTexImage2D和glTexSubImage2D。 (无法添加评论,所以我不得不把它放在这里)

编辑:如果你坚持使用4.2.2,你可以尝试使用RGBA纹理,它应该具有更好的性能(3-10x左右,具有更大的两种纹理尺寸)。