在Android上上传纹理时避免暂停

Avoiding stalls while uploading textures on Android

本文关键字:暂停 纹理 Android      更新时间:2023-10-16

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

我认为整个渲染管道,无论是双缓冲还是三缓冲,都会被刷新,因为我想修改它正在使用或引用的纹理。即使如此,六帧加(0.1秒)似乎也太多了。我们在IOS上也做了同样的操作,当纹理被修改时,你几乎不会注意到任何延迟。游戏通常在1或2帧上运行。

有人知道发生了什么事吗?这是在三星Galaxy Note GTN7000上运行的。我们正在使用SurfaceView类。你能"把这个摊位关掉"吗。我知道这可能意味着渲染可能没有更新纹理的帧左右的伪影。

此外,任何关于如何知道或设置其内部是双重缓冲还是三重缓冲的想法。

我还读到,大多数Desktop/PC OpenGL驱动程序都通过拥有两到三个纹理副本,只更新当前未使用的纹理副本,然后及时更新副本来绕过这一问题。我们根本没有记忆!

感谢

Shaun

马里GPU(用于N7000)是这种纹理上传停滞最糟糕的GPU。其他GPU处理得更好(或者至少驱动程序处理得更好)。

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

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

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

我成功的另一个解决方法是在马里GPU上始终使用glTexImage2D而不是glTexSubImage2D。这需要保留纹理数据的CPU侧副本。它在我的测试中表现得更快,大概是因为在驱动程序中,它正在制作纹理的新副本,因此如果以前的纹理仍在使用,就不必停滞。

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