OpenGL ES应用在锁屏或进入后台时崩溃

5

我的应用程序是一个广泛使用OpenGL的应用程序,它被用于处理图像、渲染场景、显示预览等。然而,在我按照苹果官方文档《iOS OpenGL ES编程指南》实现多任务后,奇怪的崩溃仍然会不时出现。调试导航栏堆栈跟踪显示类似于“sgxPatchDeferredFramebufferOffsets”、“presentRenderbuffer EXC_BAD_ACCESS”、“gpus_ReturnNotPermittedKillClient”等信息。

因此,我想知道到底应该如何实现OpenGL ES多任务。

=============更新:问题已解决============

感谢您的回答,CStreel和其他试图帮助我的人。

在重新阅读了《iOS OpenGL ES编程指南》中的“后台应用程序可能无法在图形硬件上执行命令”部分之后,我对这个问题有了新的理解。我的应用程序存在一个大问题,即不应在通知方法中实现OpenGL ES多任务。由于与委托方法不同,通知方法将异步调用,当应用程序已经进入后台时,这些停止动画操作和glFinish()调用可能就不会生效了。当我在执行一系列与OpenGL ES相关的操作时,如果立即按下锁屏按钮,这种情况可能更加频繁发生。

如果您发现了其他问题,请随时与我联系。


如果你在后台从串行队列调用OpenGL ES,问题仍然存在。即使告诉计时器停止触发,一个块仍然会完成,这可能会导致崩溃。http://stackoverflow.com/questions/19215554/how-to-stop-opengl-drawing-when-calling-opengl-from-background - openfrog
2个回答

4
当您的应用程序即将进入后台时,如果您的应用程序调用任何OGLES函数,则操作系统将立即终止您的应用程序。
阅读应用程序状态和多任务处理以获取更多信息。 阅读成为负责任的后台应用程序
以下是该文档的一些摘录:
(Required) When moving to the background, make sure your app adjusts its behavior appropriately.

关于OGLES。
 ...the app should stop calling OpenGL ES functions.

我已经实现了这些代理以及通知。当应用程序退出活动状态时,我停止了捕获会话和动画。我尝试在接收到退出活动通知后在处理调度队列中调用glfinish(),但没有帮助。 - cocoatoast

0

通知可以同步或异步。如果您在注册通知时指定了NSOperationQueue,则回调将是异步的,否则我认为它将始终是同步的。

我遇到了一些崩溃,并在我的代码中发现了一些错误:

  1. 共享的EAGLContext,尽管被“多线程”使用,但并不总是在所有使用它的线程上设置。似乎每次离开RunLoop进入您的应用程序代码并发出任何openGL命令时,都必须在主线程上设置上下文。
  2. iOS 6在更改缓冲区时需要额外的“glFlush()”,可能是由于iOS 6中的一个错误。 iOS 5和7没有受到影响。
  3. “DidEnterBackground”通知和其他代码/线程之间缺乏同步,这意味着主线程通知应用程序状态更改时会提前返回,而其他线程仍在使用openGL。 等待通知线程完成调用openGL后再进行返回,只有在允许其返回后,iOS才开始对openGL进行“看门狗”。

我使用DidEnterBackground/WillEnterForeground通知(而不是回调)来停止/重新开始OpenGL操作。 我仍然会偶尔遇到崩溃(必须使用自动化并锁定/解锁/旋转20-30分钟才能发生),但是使用WillResignActive/DidBecomeActive没有任何区别; 它们仍然会发生。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接