如何避免崩溃“在应用程序处于后台状态时进行OpenGL渲染”

时间:2019-09-14 07:42:17

标签: ios objective-c opengl-es google-fabric

最近我收到了很多关于Fabric的崩溃报告。它说,基于此处显示的堆栈跟踪,它看起来像是在应用转移到背景状态或从背景状态转换时触发了OpenGL渲染的新调用。如果您在应用程序委托的方法中设置OpenGL绘图,请确保仅在applicationDidBecomeActive:中进行此操作,而不要在application:willFinishLaunchingWithOptions:或application:didFinishLaunchingWithOptions:中进行此操作。

0   libGPUSupportMercury.dylib  gpus_ReturnNotPermittedKillClient
1   AGXGLDriver (Missing)
2   libGPUSupportMercury.dylib  gpusSubmitDataBuffers
3   AGXGLDriver (Missing)
4   WebCore WebCore::GraphicsContext3D::reshape(int, int) + 580
5   WebCore WebCore::WebGLRenderingContextBase::initializeNewContext() + 936
6   WebCore WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase(WebCore::CanvasBase&, WTF::Ref<WebCore::GraphicsContext3D, WTF::DumbPtrTraits<WebCore::GraphicsContext3D> >&&, WebCore::GraphicsContext3DAttributes) + 660
7   WebCore WebCore::WebGLRenderingContext::create(WebCore::CanvasBase&, WTF::Ref<WebCore::GraphicsContext3D, WTF::DumbPtrTraits<WebCore::GraphicsContext3D> >&&, WebCore::GraphicsContext3DAttributes) + 84
8   WebCore WebCore::WebGLRenderingContextBase::create(WebCore::CanvasBase&, WebCore::GraphicsContext3DAttributes&, WTF::String const&) + 1416
9   WebCore WebCore::HTMLCanvasElement::getContext(JSC::ExecState&, WTF::String const&, WTF::Vector<JSC::Strong<JSC::Unknown>, 0ul, WTF::CrashOnOverflow, 16ul>&&) + 904
10  WebCore  WebCore::jsHTMLCanvasElementPrototypeFunctionGetContext(JSC::ExecState*) + 424
11  JavaScriptCore  llint_entry + 89612
12  JavaScriptCore  llint_entry + 82980
13  JavaScriptCore  llint_entry + 82980
14  JavaScriptCore  llint_entry + 82980
15  JavaScriptCore  llint_entry + 82980
16  JavaScriptCore  llint_entry + 82980
17  JavaScriptCore  vmEntryToJavaScript + 268
18  JavaScriptCore  JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 424
19  JavaScriptCore  JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) + 200
20  WebCore  WebCore::JSExecState::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) + 140
21  WebCore  WebCore::ScheduledAction::executeFunctionInContext(JSC::JSGlobalObject*, JSC::JSValue, WebCore::ScriptExecutionContext&) + 424
22  WebCore  WebCore::ScheduledAction::execute(WebCore::Document&) + 144
23  WebCore  WebCore::DOMTimer::fired() + 816
24  WebCore  WebCore::ThreadTimers::sharedTimerFiredInternal() + 216
25  WebCore  WebCore::timerFired(__CFRunLoopTimer*, void*) + 28
26  CoreFoundation  __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28
27  CoreFoundation  __CFRunLoopDoTimer + 864
28  CoreFoundation  __CFRunLoopDoTimers + 248
29  CoreFoundation  __CFRunLoopRun + 1844
30  CoreFoundation  CFRunLoopRunSpecific + 436
31  WebCore RunWebThread(void*) + 600
32  libsystem_pthread.dylib _pthread_body + 128
33  libsystem_pthread.dylib _pthread_start + 44
34  libsystem_pthread.dylib thread_start + 4

如何查找代码崩溃的地方?

2 个答案:

答案 0 :(得分:1)

据我所知,苹果不支持iOS 13或10.15的openGL,请尝试将其转换为金属

“重要:在macOS 10.14中不推荐使用OpenGL。要在GPU上创建高性能代码,请改用Metal框架。请参见Metal。”

https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_intro/opengl_intro.html

答案 1 :(得分:0)

GLKViewController在ios 13中运行正常。关于您的问题,我是通过以下方式完成的。

在您的应用程序委托中。

- (void)applicationWillResignActive:(UIApplication *)application
{
        [[NSNotificationCenter defaultCenter] postNotificationName:@".applicationWillResignActive" object:nil];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
        [[NSNotificationCenter defaultCenter] postNotificationName:@".applicationDidBecomeActive" object:nil];
}

然后在渲染视图控制器中。

- (void)viewWillAppear:(BOOL)animated
{
        [super viewWillAppear:animated];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationWillResignActive:)
                                                     name:@".applicationWillResignActive"
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidBecomeActive:)
                                                     name:@".applicationDidBecomeActive"
                                                   object:nil];
         self.preferredFramesPerSecond = 30;
         self.pauseOnWillResignActive = NO;
         self.resumeOnDidBecomeActive = NO;
}

GLKit拥有自己的机制来处理去往后台的操作(该pauseOnWillResignActive属性),但对我来说效果不佳。我怀疑是因为它仅停止渲染计时器,而不会使用glFinish()或glFlush()刷新gl操作队列。所以我自己处理。

- (void) viewDidDisappear:(BOOL)animated
{
        [super viewDidDisappear:animated];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@".applicationDidBecomeActive" object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@".applicationWillResignActive" object:nil];
}

- (void)applicationWillResignActive:(NSNotification *)note
{
        [self suspend];
}

- (void)applicationDidBecomeActive:(NSNotification *)note
{
        [self resume];
}

现在您的suspend和resume方法可能如下所示。

-(void) suspend
{
        self.suspended = YES;
        glFinish();
}

-(void) resume
{
        if (self.suspended) {
                self.suspended = NO;
                [(GLKView *)self.view display];
        }
}

PS。尽管效果很好,但这是一个很旧的API(GLKit)。我真的建议您弄清楚如何使用金属。