From 433b2507dbeb2a98fbcb2448ec06d59fcd383c39 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Tue, 22 Aug 2017 19:57:52 -0700 Subject: [PATCH] Disable all rasterizer work while backgrounded on iOS (flutter/engine#4002) On iOS, backgrounded applications are not permitted to execute GPU work. See [1]. When backgrounding the application, we now tear down the underlying iOS render surface, and re-create when the app returns to foreground. See [2] for a Technica Q&A on GL-related crashes when rendering is attempted by a backgrounded application. [1]: https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/ImplementingaMultitasking-awareOpenGLESApplication/ImplementingaMultitasking-awareOpenGLESApplication.html#//apple_ref/doc/uid/TP40008793-CH5-SW1 [2]: https://developer.apple.com/library/content/qa/qa1766/_index.html --- .../darwin/ios/framework/Source/FlutterViewController.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index d858b3262d..449cb9aed8 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -313,6 +313,7 @@ class PlatformMessageResponseDarwin : public blink::PlatformMessageResponse { - (void)surfaceUpdated:(BOOL)appeared { FTL_CHECK(_platformView != nullptr); + // NotifyCreated/NotifyDestroyed are synchronous and require hops between the UI and GPU thread. if (appeared) { _platformView->NotifyCreated(); } else { @@ -377,11 +378,14 @@ class PlatformMessageResponseDarwin : public blink::PlatformMessageResponse { - (void)applicationDidEnterBackground:(NSNotification*)notification { TRACE_EVENT0("flutter", "applicationDidEnterBackground"); + [self surfaceUpdated:NO]; [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.paused"]; } - (void)applicationWillEnterForeground:(NSNotification*)notification { TRACE_EVENT0("flutter", "applicationWillEnterForeground"); + if (_viewportMetrics.physical_width) + [self surfaceUpdated:YES]; [_lifecycleChannel.get() sendMessage:@"AppLifecycleState.inactive"]; }