Nexus 10/Android 4.2.2(三星Exynos 5 w/Mali-T604)上的glTexSubImage2D性能缓慢

Nexus 10/Android 4.2.2(三星Exynos 5 w/Mali-T604)上的glTexSubImage2D性能缓慢,android,opengl-es,textures,egl,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、三星Note 1和其他一些运行安卓4.0/4.1/4.2的廉价中国平板电脑(A31/RockChip 3

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

现在我不是说我的代码没有问题,而是考虑到同样的代码在iOS(iPad/iPhone)、Nexus 7、Kindle HD 8.9、三星Note 1和其他一些运行安卓4.0/4.1/4.2的廉价中国平板电脑(A31/RockChip 3188)上运行得非常好。我会说我的代码不太可能出错。在这些设备上,glTexSubImage2D()使用不到16ms的时间上载SD或720P HD纹理

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

我想知道

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

2) 如果有一项功能在所有其他SOC上处于“关闭”状态,但在Exynos 5上设置为“打开”。例如,自动MIPMAP生成选项。(顺便说一句,我已经脱掉了)

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

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

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

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 */

我正在尝试以每秒30帧或每秒60帧的速度以SD或720P高清分辨率渲染视频

这是我们向ARM报告的已知驱动程序问题。以后的更新应该会修复它。

编辑状态更新

我们现在已经成功地在公共固件上重现了一条路径的慢速上载条件,您可能会遇到这种情况,这将在下一个驱动程序版本中修复

如果为要上载到的纹理加倍缓冲纹理ID(例如帧N=ID X、N+1=ID Y、N+2=ID X、N+3=ID Y等),则有助于在当前固件上避免这种情况

谢谢,
Iso

我可以确认Android 4.3中已经解决了这一问题-我看到RGBA格式的性能比Android 4.2.2提高了2-3倍,其他纹理格式的性能比Android 4.2.2提高了10-50倍。这些结果适用于glTexImage2D和glTexSubImage2D。(无法添加评论,因此我必须将其放在此处)


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

考虑一下适用于Android的
SurfaceTexture
11:谢谢,但我仍然想知道为什么使用glTexSubImage2D()速度很慢,因为我不想维护多个代码路径-它适用于除ExynosWe之外的所有人。我们观察到相同(或非常相似)的问题并在上报告了它,但根据我们的测试,它确实似乎是4.2.1和4.2.2之间的回归。这是从4.2还是4.2.1的回归?如果是这样的话,我将回滚固件版本并继续开发…@romain guy-你知道这个更新何时发布吗?我的公司也有同样的问题。固定值是4.2.3还是5.0。为了确认你上传的是一个半平面的YUV曲面,它是两个8位亮度纹理,一个是8位Y,另一个是4位U/V值,打包到一个8位通道中。嗯,我没有足够的代表点来评论Romain的答案,所以我会在这里发布。不,这不是4.2到4.2.1之间的回归,因此回滚没有帮助。是的,我正在上载YUV420P(nv12)纹理。有解决办法吗?比如说,上传RGB纹理?交错Y平面和UV平面(因此您使用的是“YUVYUVYUV”而不是“YYY”、“UVUVUV”),并加载为亮度α纹理可能会起作用。。。。但是正如Romain所说,这是我们正在研究的东西,所以你可能只想等待驱动程序的下一个版本。显然,它仍然不够快。我的应用程序开始使用带有RGBA纹理的glTexSubImage2D,从那个版本开始,它就在Nexus10上崩溃了。它不会在任何其他Android上崩溃!