diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index c3c76ec82d..6290299ca6 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -152,14 +152,19 @@ void FlutterPlatformViewLayerPool::RecycleLayers() { } std::vector> -FlutterPlatformViewLayerPool::GetUnusedLayers() { +FlutterPlatformViewLayerPool::RemoveUnusedLayers() { std::vector> results; for (size_t i = available_layer_index_; i < layers_.size(); i++) { results.push_back(layers_[i]); } + layers_.erase(layers_.begin() + available_layer_index_, layers_.end()); return results; } +size_t FlutterPlatformViewLayerPool::size() const { + return layers_.size(); +} + void FlutterPlatformViewsController::SetFlutterView(UIView* flutter_view) { flutter_view_.reset(flutter_view); } @@ -402,6 +407,10 @@ size_t FlutterPlatformViewsController::EmbeddedViewCount() const { return composition_order_.size(); } +size_t FlutterPlatformViewsController::LayerPoolSize() const { + return layer_pool_->size(); +} + UIView* FlutterPlatformViewsController::GetPlatformViewByID(int64_t view_id) { return [GetFlutterTouchInterceptingViewByID(view_id) embeddedView]; } @@ -873,8 +882,7 @@ std::shared_ptr FlutterPlatformViewsController::GetLay } void FlutterPlatformViewsController::RemoveUnusedLayers() { - std::vector> layers = layer_pool_->GetUnusedLayers(); - for (const std::shared_ptr& layer : layers) { + for (const auto& layer : layer_pool_->RemoveUnusedLayers()) { [layer->overlay_view_wrapper removeFromSuperview]; } @@ -915,7 +923,6 @@ void FlutterPlatformViewsController::DisposeViews() { clip_count_.erase(viewId); views_to_recomposite_.erase(viewId); } - views_to_dispose_ = std::move(views_to_delay_dispose); } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 8a65d7c1cf..a14dcf8007 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -10,6 +10,7 @@ #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTouchInterceptingView_Test.h" #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" @@ -3314,4 +3315,30 @@ fml::RefPtr CreateNewThread(const std::string& name) { XCTAssertEqualObjects([touchInteceptorView accessibilityContainer], container); } +- (void)testLayerPool { + // Create an IOSContext and GrDirectContext. + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar"]; + [engine run]; + XCTAssertTrue([engine iosPlatformView] != nullptr); + auto ios_context = [engine iosPlatformView]->GetIosContext(); + auto gr_context = ios_context->GetMainContext(); + + auto pool = flutter::FlutterPlatformViewLayerPool{}; + + // Add layers to the pool. + auto layer1 = pool.GetLayer(gr_context.get(), ios_context, MTLPixelFormatBGRA8Unorm); + XCTAssertEqual(pool.size(), 1u); + auto layer2 = pool.GetLayer(gr_context.get(), ios_context, MTLPixelFormatBGRA8Unorm); + XCTAssertEqual(pool.size(), 2u); + + // Mark all layers as unused. + pool.RecycleLayers(); + XCTAssertEqual(pool.size(), 2u); + + // Free the unused layers. + auto unused_layers = pool.RemoveUnusedLayers(); + XCTAssertEqual(unused_layers.size(), 2u); + XCTAssertEqual(pool.size(), 0u); +} + @end diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index afda710e7f..e1f8f3e071 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -176,13 +176,15 @@ class FlutterPlatformViewLayerPool { const std::shared_ptr& ios_context, MTLPixelFormat pixel_format); - // Gets the layers in the pool that aren't currently used. - // This method doesn't mark the layers as unused. - std::vector> GetUnusedLayers(); + // Removes unused layers from the pool. Returns the unused layers. + std::vector> RemoveUnusedLayers(); // Marks the layers in the pool as available for reuse. void RecycleLayers(); + // Returns the count of layers currently in the pool. + size_t size() const; + private: // The index of the entry in the layers_ vector that determines the beginning of the unused // layers. For example, consider the following vector: @@ -236,6 +238,8 @@ class FlutterPlatformViewsController { size_t EmbeddedViewCount() const; + size_t LayerPoolSize() const; + // Returns the `FlutterPlatformView`'s `view` object associated with the view_id. // // If the `FlutterPlatformViewsController` does not contain any `FlutterPlatformView` object or