在Android上上传纹理时避免失速

我们的游戏要求我们不断加载和创建新图像,然后将其放在纹理页面上然后用于渲染。 我们使用glTexSubImage2d上传来修改纹理页面的一部分。 我们不保留系统副本。 每当我们这样做时,我们在glTexSubImage2d调用中有一个六帧延迟。 我们在游戏开始之前将大部分图像加载到纹理上,但有些东西必然是动态的。

我假设整个渲染管道,无论是双重还是三重缓冲都被刷新,因为我想修改它正在使用的纹理,或者有一个引用。 即便如此,六帧加(0.1秒)似乎过度。 我们在IOS上完全一样,并且在修改纹理时几乎没有注意到任何延迟。 游戏通常在1或2帧上运行。

任何人都知道发生了什么事? 这是在三星Galaxy Note GTN7000上运行的。 我们正在使用SurfaceView类。 你能“关掉这个摊位”吗? 我理解这可能意味着一个框架左右的人工制品,其中渲染可能没有更新的纹理。

此外,任何想法如何知道或设置内部是否是双缓冲或三缓冲。

我还读到大多数桌面/ PC OpenGL驱动程序通过拥有两个或三个纹理副本并仅更新当前未使用的纹理,然后及时更新副本来解决这个问题。 我们根本就没有记忆!

谢谢

肖恩

Mali GPU(在N7000中使用)是这种纹理上传失速的最差GPU。 其他GPU处理得更好(或至少驱动程序更好地处理它)。

我遇到了你描述的完全相同的问题,对我来说唯一的解决方案是保留纹理数据的CPU副本,并对纹理进行三重缓冲。 每当我修改纹理时,我只修改CPU副本,并将纹理标记为脏。 在每个帧的开始,如果缓冲区已经更新,我循环三个纹理并在其中一个上执行glTexSubImage2D,然后成为活动纹理。

如果你使用少于三个纹理,或者你犯了任何错误并使用了纹理,你在最后两帧内做了glTexSubImage2D,它仍然会停滞。

我只在检测到Mali GPU时才这样做(检查驱动程序GL字符串)。 对于其他GPU和iOS,驱动程序足够好,不需要三重缓冲(因此我不必保留数据的CPU副本)。 我确实在Arm / Mali开发者论坛上检查了这个问题,他们推荐了三重缓冲。 你不应该需要超过三个。

另一个成功的方法是在Mali GPU上总是使用glTexImage2D而不是glTexSubImage2D。 这需要保留纹理数据的CPU端副本。 它在我的测试中表现得非常快,大概是因为在驱动程序中它正在制作纹理的新副本,因此如果之前的纹理仍在使用中则不必停顿。

我还实现了另一种可能的解决方案,但不再使用。 您可以使用Android GraphicBuffers。 请参阅此链接以获取一些基本信息: 在Android上使用直接纹理此方法可让您在没有停顿的情况下写入纹理,但是,它不是官方支持的API,我只能在马里工作并且只需付出很多努力。 它并不能完全解决问题,因为你仍然需要自己进行同步控制,否则你的应用程序可能会在使用时覆盖纹理数据,最终会在屏幕上出现一些损坏。