From da82361dad97865d338697354ce89594a56dc845 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 25 Jun 2019 20:47:55 -0700 Subject: [PATCH] Purge caches on low memory on iOS (#9491) --- shell/common/rasterizer.cc | 13 +++++++++++++ shell/common/rasterizer.h | 5 +++++ shell/common/shell.cc | 11 +++++++++++ shell/common/shell.h | 7 +++++++ .../ios/framework/Source/FlutterEngine.mm | 19 +++++++++++++++++++ .../framework/Source/FlutterViewController.mm | 11 ----------- 6 files changed, 55 insertions(+), 11 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 60005a277e4..6d9e485447e 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -68,6 +68,19 @@ void Rasterizer::Teardown() { last_layer_tree_.reset(); } +void Rasterizer::NotifyLowMemoryWarning() const { + if (!surface_) { + FML_DLOG(INFO) << "Rasterizer::PurgeCaches called with no surface."; + return; + } + auto context = surface_->GetContext(); + if (!context) { + FML_DLOG(INFO) << "Rasterizer::PurgeCaches called with no GrContext."; + return; + } + context->freeGpuResources(); +} + flutter::TextureRegistry* Rasterizer::GetTextureRegistry() { return &compositor_context_->texture_registry(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index ad6d2da7a82..bc2df2d0d83 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -46,6 +46,11 @@ class Rasterizer final : public SnapshotDelegate { void Teardown(); + // Frees up Skia GPU resources. + // + // This method must be called from the GPU task runner. + void NotifyLowMemoryWarning() const; + fml::WeakPtr GetWeakPtr() const; fml::WeakPtr GetSnapshotDelegate() const; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 9e34a5b50de..ba38f792e12 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -369,6 +369,17 @@ Shell::~Shell() { platform_latch.Wait(); } +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. +} + bool Shell::IsSetup() const { return is_setup_; } diff --git a/shell/common/shell.h b/shell/common/shell.h index 16e5d544cd4..97cbe5ef8a9 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -78,6 +78,13 @@ class Shell final : public PlatformView::Delegate, DartVM* GetDartVM(); + // Embedders should call this under low memory conditions to free up + // internal caches used. + // + // This method posts a task to the GPU threads to signal the Rasterizer to + // free resources. + void NotifyLowMemoryWarning() const; + bool IsSetup() const; Rasterizer::Screenshot Screenshot(Rasterizer::ScreenshotType type, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 4ba2e83daa0..2d8ebc53e08 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -93,11 +93,21 @@ [self setupChannels]; + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(onMemoryWarning:) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; + return self; } - (void)dealloc { [_pluginPublications release]; + + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + [super dealloc]; } @@ -574,6 +584,15 @@ return _pluginPublications[pluginKey]; } +#pragma mark - Memory Notifications + +- (void)onMemoryWarning:(NSNotification*)notification { + if (_shell) { + _shell->NotifyLowMemoryWarning(); + } + [_systemChannel sendMessage:@{@"type" : @"memoryPressure"}]; +} + @end @implementation FlutterEngineRegistrar { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index fc08125a18a..89b6db71bc3 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -208,11 +208,6 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics name:UIAccessibilityBoldTextStatusDidChangeNotification object:nil]; - [center addObserver:self - selector:@selector(onMemoryWarning:) - name:UIApplicationDidReceiveMemoryWarningNotification - object:nil]; - [center addObserver:self selector:@selector(onUserSettingsChanged:) name:UIContentSizeCategoryDidChangeNotification @@ -794,12 +789,6 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch) #endif } -#pragma mark - Memory Notifications - -- (void)onMemoryWarning:(NSNotification*)notification { - [[_engine.get() systemChannel] sendMessage:@{@"type" : @"memoryPressure"}]; -} - #pragma mark - Locale updates - (void)onLocaleUpdated:(NSNotification*)notification {