gpt4 book ai didi

ios - 调用 glDrawArrays 时随机崩溃

转载 作者:行者123 更新时间:2023-11-29 10:26:16 25 4
gpt4 key购买 nike

我正在制作一个 iOS 应用程序,它可以渲染大量我从磁盘动态流式传输的纹理。我将 NSCache 用于纹理的 LRU 缓存。一个屏幕显示 3D 模型,另一个屏幕显示纹理的全屏细节,可以通过滑动来更改该纹理。一种非常简单的旋转木马。该应用程序在 1GiB 设备上占用的 RAM 永远不会超过 250MiB,纹理的缓存运行良好。

对于全屏 View ,我有一个基于屏幕分辨率和纹理分辨率(不同纹理坐标)的 VBO 缓存。我从不删除这些 VBO,并始终检查 VBO 是否正常 (glIsBuffer())。屏幕是单独的 UIViewControllers,我在它们两个中使用相同的 EAGLContext,没有上下文共享。这没关系,因为它在同一个线程上。

所有这些都是 Open GL ES 2.0,一切正常。我可以在 3D/2D 屏幕之间切换,更改纹理。根据可用内存,根据需要即时创建/删除纹理。

但有时我在调用时渲染全屏四边形时会随机崩溃:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

当我连续收到大量内存警告时,就会发生这种情况。有时我会在几秒钟内收到数百条内存警告,应用程序运行正常,但有时它会在滑动到新的全屏纹理四边形时崩溃。即使对于已经全屏渲染的纹理,也会发生这种情况。它永远不会在使用相同纹理的 3D 模型上崩溃。

崩溃报告总是在 glDrawArrays 调用(在我的代码中),在 0x00000018 处有一个 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 异常。堆栈跟踪中的最后一次调用始终是 gleRunVertexSubmitARM。这种情况发生在各种 iPad 和 iPhone 上。

看起来系统内存压力损坏了一些 GL 内存,但我不知道何时、何地以及为什么。

我还尝试从 VBO 切换到在堆上保存顶点数据的旧方法,在调用 glDrawArrays 之前,我首先检查顶点数据是否不是 NULL .结果是一样的,在内存不足的情况下随机崩溃。

任何想法可能是错误的? EXC_BAD_ACCESS 中的地址0x00000018 确实很糟糕,但我不知道它应该是谁的地址。取消分配的纹理或着色器是否会在 glDrawArrays 中导致 EXC_BAD_ACCESS

最佳答案

经过几天的密集调试,我终于弄明白了。问题是 NSCache 存储 OpenGL 纹理。在内存压力下,NSCache 开始从中删除项目以释放​​内存。问题是,在那种情况下,它是在自己的后台线程 (com.apple.root.utility-qos) 上执行的,因此该线程没有 GL 上下文(也没有与主上下文的共享组),因此纹理名称是不是有效名称(无法删除)并且会泄漏 GL 内存。因此,在出现一些内存警告后,出现了大量泄漏的 GL 纹理、内存已满和应用程序最终崩溃。

TL DR:不要使用 NSCache 来缓存 OpenGL 对象,因为它会在内存警告后泄漏它们。

关于ios - 调用 glDrawArrays 时随机崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32123339/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com