Skip to content

Commit d6627c6

Browse files
authored
Reland [ios] Refactor IOSSurface factory and unify surface creation (flutter#22016)
1 parent e4dffc1 commit d6627c6

24 files changed

+231
-53
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.h
10161016
FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.mm
10171017
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.h
10181018
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.mm
1019+
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_factory.h
1020+
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_factory.mm
10191021
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.h
10201022
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.mm
10211023
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal.h

shell/platform/darwin/ios/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ source_set("flutter_framework_source") {
9999
"ios_render_target_gl.mm",
100100
"ios_surface.h",
101101
"ios_surface.mm",
102+
"ios_surface_factory.h",
103+
"ios_surface_factory.mm",
102104
"ios_surface_gl.h",
103105
"ios_surface_gl.mm",
104106
"ios_surface_software.h",
@@ -219,6 +221,7 @@ shared_library("ios_test_flutter") {
219221
deps = [
220222
":flutter_framework_source",
221223
":ios_test_flutter_mrc",
224+
"//flutter/common:common",
222225
"//flutter/shell/platform/darwin/common:framework_shared",
223226
"//flutter/third_party/tonic",
224227
"//flutter/third_party/txt",

shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
static const char* kApplicationKernelSnapshotFileName = "kernel_blob.bin";
2929

30-
static flutter::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) {
30+
flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle) {
3131
auto command_line = flutter::CommandLineFromNSProcessInfo();
3232

3333
// Precedence:
@@ -181,7 +181,17 @@ - (instancetype)initWithPrecompiledDartBundle:(nullable NSBundle*)bundle {
181181
self = [super init];
182182

183183
if (self) {
184-
_settings = DefaultSettingsForProcess(bundle);
184+
_settings = FLTDefaultSettingsForBundle(bundle);
185+
}
186+
187+
return self;
188+
}
189+
190+
- (instancetype)initWithSettings:(const flutter::Settings&)settings {
191+
self = [self initWithPrecompiledDartBundle:nil];
192+
193+
if (self) {
194+
_settings = settings;
185195
}
186196

187197
return self;

shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212

1313
NS_ASSUME_NONNULL_BEGIN
1414

15+
flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle = nil);
16+
1517
@interface FlutterDartProject ()
1618

19+
/**
20+
* This is currently used for *only for tests* to override settings.
21+
*/
22+
- (instancetype)initWithSettings:(const flutter::Settings&)settings;
1723
- (const flutter::Settings&)settings;
1824
- (const flutter::PlatformData)defaultPlatformData;
1925

shell/platform/darwin/ios/framework/Source/FlutterEngine.mm

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
#import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h"
2929
#import "flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h"
3030
#import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
31+
#import "flutter/shell/platform/darwin/ios/ios_context.h"
3132
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
33+
#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h"
3234
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
3335
#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
3436
#include "flutter/shell/profiling/sampling_profiler.h"
@@ -64,6 +66,8 @@ @implementation FlutterEngine {
6466
fml::scoped_nsobject<FlutterObservatoryPublisher> _publisher;
6567

6668
std::shared_ptr<flutter::FlutterPlatformViewsController> _platformViewsController;
69+
flutter::IOSRenderingAPI _renderingApi;
70+
std::shared_ptr<flutter::IOSSurfaceFactory> _surfaceFactory;
6771
std::unique_ptr<flutter::ProfilerMetricsIOS> _profiler_metrics;
6872
std::unique_ptr<flutter::SamplingProfiler> _profiler;
6973

@@ -128,7 +132,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
128132

129133
_pluginPublications = [NSMutableDictionary new];
130134
_registrars = [[NSMutableDictionary alloc] init];
131-
_platformViewsController.reset(new flutter::FlutterPlatformViewsController());
135+
[self recreatePlatformViewController];
132136

133137
_binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self];
134138
_connections.reset(new flutter::ConnectionCollection());
@@ -162,6 +166,17 @@ - (instancetype)initWithName:(NSString*)labelPrefix
162166
return self;
163167
}
164168

169+
- (void)recreatePlatformViewController {
170+
_renderingApi = flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering);
171+
_surfaceFactory = flutter::IOSSurfaceFactory::Create(_renderingApi);
172+
_platformViewsController.reset(new flutter::FlutterPlatformViewsController(_surfaceFactory));
173+
_surfaceFactory->SetPlatformViewsController(_platformViewsController);
174+
}
175+
176+
- (flutter::IOSRenderingAPI)platformViewsRenderingAPI {
177+
return _renderingApi;
178+
}
179+
165180
- (void)dealloc {
166181
/// Notify plugins of dealloc. This should happen first in dealloc since the
167182
/// plugins may be talking to things like the binaryMessenger.
@@ -520,13 +535,12 @@ - (BOOL)createShell:(NSString*)entrypoint
520535
threadHostType};
521536

522537
// Lambda captures by pointers to ObjC objects are fine here because the
523-
// create call is
524-
// synchronous.
538+
// create call is synchronous.
525539
flutter::Shell::CreateCallback<flutter::PlatformView> on_create_platform_view =
526-
[](flutter::Shell& shell) {
540+
[self](flutter::Shell& shell) {
541+
[self recreatePlatformViewController];
527542
return std::make_unique<flutter::PlatformViewIOS>(
528-
shell, flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering),
529-
shell.GetTaskRunners());
543+
shell, self->_renderingApi, self->_surfaceFactory, shell.GetTaskRunners());
530544
};
531545

532546
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
@@ -554,9 +568,6 @@ - (BOOL)createShell:(NSString*)entrypoint
554568
[self setupChannels];
555569
[self onLocaleUpdated:nil];
556570
[self initializeDisplays];
557-
if (!_platformViewsController) {
558-
_platformViewsController.reset(new flutter::FlutterPlatformViewsController());
559-
}
560571
_publisher.reset([[FlutterObservatoryPublisher alloc]
561572
initWithEnableObservatoryPublication:settings.enable_observatory_publication]);
562573
[self maybeSetupPlatformViewChannels];

shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ - (void)testCallsNotifyLowMemory {
6767
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
6868
/*delegate=*/mock_delegate,
6969
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
70+
flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware),
7071
/*task_runners=*/runners);
7172

7273
id project = OCMClassMock([FlutterDartProject class]);

shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#import <OCMock/OCMock.h>
66
#import <XCTest/XCTest.h>
77

8+
#import "flutter/common/settings.h"
89
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
910
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h"
11+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
1012
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h"
1113

1214
FLUTTER_ASSERT_ARC
@@ -113,4 +115,23 @@ - (void)testWaitForFirstFrameTimeout {
113115
[self waitForExpectationsWithTimeout:1 handler:nil];
114116
}
115117

118+
- (void)testPlatformViewsControllerRenderingMetalBackend {
119+
FlutterEngine* engine = [[FlutterEngine alloc] init];
120+
[engine run];
121+
flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI];
122+
123+
XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kMetal);
124+
}
125+
126+
- (void)testPlatformViewsControllerRenderingSoftware {
127+
auto settings = FLTDefaultSettingsForBundle();
128+
settings.enable_software_rendering = true;
129+
FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings];
130+
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
131+
[engine run];
132+
flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI];
133+
134+
XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kSoftware);
135+
}
136+
116137
@end

shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
// found in the LICENSE file.
44

55
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
6+
#include "shell/platform/darwin/ios/rendering_api_selection.h"
67

78
@class FlutterBinaryMessengerRelay;
89

910
// Category to add test-only visibility.
1011
@interface FlutterEngine (Test) <FlutterBinaryMessenger>
1112
- (void)setBinaryMessenger:(FlutterBinaryMessengerRelay*)binaryMessenger;
1213
- (void)waitForFirstFrame:(NSTimeInterval)timeout callback:(void (^)(BOOL didTimeout))callback;
14+
- (flutter::IOSRenderingAPI)platformViewsRenderingAPI;
1315
@end

shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535

3636
- (instancetype)init NS_DESIGNATED_INITIALIZER;
3737
- (instancetype)initWithContentsScale:(CGFloat)contentsScale;
38-
- (std::unique_ptr<flutter::IOSSurface>)createSurface:
39-
(std::shared_ptr<flutter::IOSContext>)ios_context;
4038

4139
@end
4240

shell/platform/darwin/ios/framework/Source/FlutterOverlayView.mm

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,6 @@ + (Class)layerClass {
6262
return [FlutterView layerClass];
6363
}
6464

65-
- (std::unique_ptr<flutter::IOSSurface>)createSurface:
66-
(std::shared_ptr<flutter::IOSContext>)ios_context {
67-
return flutter::IOSSurface::Create(std::move(ios_context), // context
68-
fml::scoped_nsobject<CALayer>{[self.layer retain]}, // layer
69-
nullptr // platform views controller
70-
);
71-
}
72-
7365
// TODO(amirh): implement drawLayer to support snapshotting.
7466

7567
@end

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h"
1717
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
1818
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
19+
#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h"
1920
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
2021

2122
namespace flutter {
@@ -32,8 +33,8 @@
3233
overlay_view.reset([[FlutterOverlayView alloc] init]);
3334
overlay_view_wrapper.reset([[FlutterOverlayView alloc] init]);
3435

35-
std::unique_ptr<IOSSurface> ios_surface =
36-
[overlay_view.get() createSurface:std::move(ios_context)];
36+
auto ca_layer = fml::scoped_nsobject<CALayer>{[[overlay_view.get() layer] retain]};
37+
std::unique_ptr<IOSSurface> ios_surface = ios_surface_factory_->CreateSurface(ca_layer);
3738
std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface();
3839

3940
layer = std::make_shared<FlutterPlatformViewLayer>(
@@ -44,8 +45,8 @@
4445
overlay_view.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale]);
4546
overlay_view_wrapper.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale]);
4647

47-
std::unique_ptr<IOSSurface> ios_surface =
48-
[overlay_view.get() createSurface:std::move(ios_context)];
48+
auto ca_layer = fml::scoped_nsobject<CALayer>{[[overlay_view.get() layer] retain]};
49+
std::unique_ptr<IOSSurface> ios_surface = ios_surface_factory_->CreateSurface(ca_layer);
4950
std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface(gr_context);
5051

5152
layer = std::make_shared<FlutterPlatformViewLayer>(
@@ -436,6 +437,12 @@
436437
for (UIView* sub_view in [flutter_view subviews]) {
437438
[sub_view removeFromSuperview];
438439
}
440+
// See: https://github.com/flutter/flutter/issues/69305
441+
for (auto it = touch_interceptors_.begin(); it != touch_interceptors_.end(); it++) {
442+
FlutterTouchInterceptingView* view = it->second.get();
443+
[view removeFromSuperview];
444+
}
445+
touch_interceptors_.clear();
439446
views_.clear();
440447
composition_order_.clear();
441448
active_composition_order_.clear();

shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,16 @@ - (void)testCanCreatePlatformViewWithoutFlutterView {
121121
/*raster=*/thread_task_runner,
122122
/*ui=*/thread_task_runner,
123123
/*io=*/thread_task_runner);
124+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
124125
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
125126
/*delegate=*/mock_delegate,
126127
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
128+
/*ios_surface_factory=*/surface_factory,
127129
/*task_runners=*/runners);
128130

129-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
131+
auto flutterPlatformViewsController =
132+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
133+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
130134

131135
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
132136
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
@@ -175,12 +179,16 @@ - (void)testCompositePlatformView {
175179
/*raster=*/thread_task_runner,
176180
/*ui=*/thread_task_runner,
177181
/*io=*/thread_task_runner);
182+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
178183
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
179184
/*delegate=*/mock_delegate,
180185
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
186+
/*ios_surface_factory=*/surface_factory,
181187
/*task_runners=*/runners);
182188

183-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
189+
auto flutterPlatformViewsController =
190+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
191+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
184192

185193
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
186194
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
@@ -230,12 +238,16 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
230238
/*raster=*/thread_task_runner,
231239
/*ui=*/thread_task_runner,
232240
/*io=*/thread_task_runner);
241+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
233242
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
234243
/*delegate=*/mock_delegate,
235244
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
245+
/*ios_surface_factory=*/surface_factory,
236246
/*task_runners=*/runners);
237247

238-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
248+
auto flutterPlatformViewsController =
249+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
250+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
239251

240252
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
241253
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
@@ -301,12 +313,16 @@ - (void)testClipRect {
301313
/*raster=*/thread_task_runner,
302314
/*ui=*/thread_task_runner,
303315
/*io=*/thread_task_runner);
316+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
304317
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
305318
/*delegate=*/mock_delegate,
306319
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
320+
/*ios_surface_factory=*/surface_factory,
307321
/*task_runners=*/runners);
308322

309-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
323+
auto flutterPlatformViewsController =
324+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
325+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
310326

311327
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
312328
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
@@ -373,12 +389,16 @@ - (void)testClipRRect {
373389
/*raster=*/thread_task_runner,
374390
/*ui=*/thread_task_runner,
375391
/*io=*/thread_task_runner);
392+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
376393
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
377394
/*delegate=*/mock_delegate,
378395
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
396+
/*ios_surface_factory=*/surface_factory,
379397
/*task_runners=*/runners);
380398

381-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
399+
auto flutterPlatformViewsController =
400+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
401+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
382402

383403
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
384404
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
@@ -445,12 +465,16 @@ - (void)testClipPath {
445465
/*raster=*/thread_task_runner,
446466
/*ui=*/thread_task_runner,
447467
/*io=*/thread_task_runner);
468+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
448469
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
449470
/*delegate=*/mock_delegate,
450471
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
472+
/*ios_surface_factory=*/surface_factory,
451473
/*task_runners=*/runners);
452474

453-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
475+
auto flutterPlatformViewsController =
476+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
477+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
454478

455479
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
456480
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
@@ -518,12 +542,16 @@ - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
518542
/*raster=*/thread_task_runner,
519543
/*ui=*/thread_task_runner,
520544
/*io=*/thread_task_runner);
545+
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
521546
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
522547
/*delegate=*/mock_delegate,
523548
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
549+
/*ios_surface_factory=*/surface_factory,
524550
/*task_runners=*/runners);
525551

526-
auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
552+
auto flutterPlatformViewsController =
553+
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
554+
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);
527555

528556
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
529557
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];

0 commit comments

Comments
 (0)