Skip to content

Purge caches on iOS can happen when unexpected GL context is active #48182

@shorben07

Description

@shorben07

This issue is a specific case of a more general issue described in #41620. With the exception that the engine's fix flutter/engine#13812 does not fix this case, so it should be reported and fixed separately.

In the summer, 2019 in pr flutter/engine#9491 @dnfield added purge caches on low memory events. On such events, the flutter engine frees gpu resources.

The problem is that flutter engine does not make sure that the correct context is set before freeGpuResources is called.

From Apple's docs:

When you call any OpenGL ES API function, OpenGL ES evaluates it with respect to the calling thread’s current context. Because OpenGL ES functions require a current context, you must use this method to select a context for the current thread before calling any OpenGL ES function

In other words before making something with the context you should make it current for the thread.

Example

Here is an example when flutter and mapbox with MGLOpenGLStyleLayer crashes under low memory conditions:

Flutter engine starts up. <EAGLContext: 0x280d67c20> is flutter's GL context
Screen Shot 2020-01-04 at 6 38 06 PM
Screen Shot 2020-01-04 at 6 38 22 PM
<EAGLContext: 0x280d5c3e0> is mapbox's GL context
Screen Shot 2020-01-04 at 6 38 40 PM
Flutter Engine receives memory warning first. Task is added to GPU task runner to clear cache

  if (_shell) {
    _shell->NotifyLowMemoryWarning();
  }
...
void Shell::NotifyLowMemoryWarning() const {
  task_runners_.GetGPUTaskRunner()->PostTask(
      [rasterizer = rasterizer_->GetWeakPtr()]() {
        if (rasterizer) {
          rasterizer->NotifyLowMemoryWarning();
        }
      });
  // The IO Manager uses resource cache limits of 0, so it is not necessary
  // to purge them.
}

Screen Shot 2020-01-04 at 6 39 55 PM

Mapbox receives memory warning second. It set context to free resources

Screen Shot 2020-01-04 at 6 40 14 PM

Mapbox set context to nil after it is done with freening resources

Screen Shot 2020-01-04 at 6 40 24 PM

Drawing cycle happens in map view. Mapbox set current context

Screen Shot 2020-01-04 at 6 40 33 PM

After mapbox drawing phase GrLegacyDirectContext::freeGpuResources() is called and current gl context is still mapbox's

Screen Shot 2020-01-04 at 6 40 46 PM

Screen Shot 2020-01-04 at 6 40 58 PM

Very soon after that app crashes because mapbox's gl context is corrupted

Screen Shot 2020-01-04 at 6 41 18 PM

Example's source code: https://github.com/shorben07/flutter-mapbox-crash

Target Platform: iOS
Target OS version/browser: Any
Devices: any physical device

Logs

flutter doctor -v
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.14.5 18F132, locale en-UA)
    • Flutter version 1.12.13+hotfix.5 at /Users/shorben/Documents/Projects/flutter
    • Framework revision 27321ebbad (4 weeks ago), 2019-12-10 18:15:01 -0800
    • Engine revision 2994f7e1e6
    • Dart version 2.7.0

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/shorben/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • ANDROID_HOME = /Users/shorben/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.3, Build version 11C29
    • CocoaPods version 1.8.4

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 42.1.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.39.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.4.1

[✓] Connected device (2 available)
    • Serhii’s iPhone • 1e6f141526c2c87ea4965c2979a2fa4515f52e2c • ios • iOS 13.3
    • iPhone 5s       • 688BC58B-AEAD-422C-91A7-FAF40E0F08B6     • ios • com.apple.CoreSimulator.SimRuntime.iOS-12-2 (simulator)

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineflutter/engine related. See also e: labels.platform-iosiOS applications specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions