我正在创建一个iOS应用程序,它可以渲染大量纹理,我可以动态地从磁盘流式传输。我使用NSCache进行纹理的LRU缓存。有一个带有3D模型的屏幕和一个带有纹理全屏细节的屏幕,可以通过滑动更改此纹理。一种非常简单的旋转木马。该应用程序永远不会在1GiB设备上占用超过250MiB的RAM,纹理缓存效果很好。
对于全屏视图,我有一个基于屏幕分辨率和纹理分辨率(不同纹理坐标)的VBO缓存。我从不删除这些VBO并始终检查VBO是否正常(glIsBuffer()
)。屏幕是单独的UIViewControllers,我在它们中使用相同的EAGLContext,没有上下文共享。这是可以的,因为它在同一个线程上。
这一切都是Open GL ES 2.0,一切都很好。我可以在3D / 2D屏幕之间切换,更改纹理。根据可用内存,根据需要动态创建/删除纹理。
但有时候在调用时会渲染全屏四边形时会出现随机崩溃:
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
当我连续收到大量内存警告时,可能会发生这种情况。有时我可以在几秒钟内获得数百个内存警告,并且应用程序正常工作但有时它会在刷到新的全屏纹理四边形时崩溃。即使对于已经全屏渲染的纹理,也会发生这种情况。它永远不会在使用相同纹理的3D模型上崩溃。
崩溃报告始终位于glDrawArrays
调用(在我的代码中),但EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000018
例外。堆栈跟踪中的最后一次调用始终为gleRunVertexSubmitARM
。这种情况发生在各种iPad和iPhone上。
看起来系统内存压力会破坏一些GL内存,但我不知道何时,何地以及为何。
我也试过从VBO切换到在堆上有顶点数据的旧方法,在调用NULL
之前我首先检查顶点数据是否不是glDrawArrays
。在低内存情况下,结果是相同的随机崩溃。
任何想法都可能出错? 0x00000018
中的地址EXC_BAD_ACCESS
非常糟糕,但我不知道它应该是哪个地址。取消分配的纹理或着色器是否会导致EXC_BAD_ACCESS
中的glDrawArrays
?