Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Reland [ios] Refactor IOSSurface factory and unify surface creation #22016

Merged
merged 3 commits into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_factory.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_factory.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal.h
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ source_set("flutter_framework_source") {
"ios_render_target_gl.mm",
"ios_surface.h",
"ios_surface.mm",
"ios_surface_factory.h",
"ios_surface_factory.mm",
"ios_surface_gl.h",
"ios_surface_gl.mm",
"ios_surface_software.h",
Expand Down Expand Up @@ -219,6 +221,7 @@ shared_library("ios_test_flutter") {
deps = [
":flutter_framework_source",
":ios_test_flutter_mrc",
"//flutter/common:common",
"//flutter/shell/platform/darwin/common:framework_shared",
"//flutter/third_party/tonic",
"//flutter/third_party/txt",
Expand Down
14 changes: 12 additions & 2 deletions shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

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

static flutter::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) {
flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle) {
auto command_line = flutter::CommandLineFromNSProcessInfo();

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

if (self) {
_settings = DefaultSettingsForProcess(bundle);
_settings = FLTDefaultSettingsForBundle(bundle);
}

return self;
}

- (instancetype)initWithSettings:(const flutter::Settings&)settings {
self = [self initWithPrecompiledDartBundle:nil];

if (self) {
_settings = settings;
}

return self;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@

NS_ASSUME_NONNULL_BEGIN

flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle = nil);

@interface FlutterDartProject ()

/**
* This is currently used for *only for tests* to override settings.
*/
- (instancetype)initWithSettings:(const flutter::Settings&)settings;
- (const flutter::Settings&)settings;
- (const flutter::PlatformData)defaultPlatformData;

Expand Down
29 changes: 20 additions & 9 deletions shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
#import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
#import "flutter/shell/platform/darwin/ios/ios_context.h"
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h"
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
#include "flutter/shell/profiling/sampling_profiler.h"
Expand Down Expand Up @@ -64,6 +66,8 @@ @implementation FlutterEngine {
fml::scoped_nsobject<FlutterObservatoryPublisher> _publisher;

std::shared_ptr<flutter::FlutterPlatformViewsController> _platformViewsController;
flutter::IOSRenderingAPI _renderingApi;
std::shared_ptr<flutter::IOSSurfaceFactory> _surfaceFactory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaaclarke might relate to the work you're doing now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, it's probably going to create merge conflicts for me. I don't think it necessarily helps or hurts what I was doing.

std::unique_ptr<flutter::ProfilerMetricsIOS> _profiler_metrics;
std::unique_ptr<flutter::SamplingProfiler> _profiler;

Expand Down Expand Up @@ -128,7 +132,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix

_pluginPublications = [NSMutableDictionary new];
_registrars = [[NSMutableDictionary alloc] init];
_platformViewsController.reset(new flutter::FlutterPlatformViewsController());
[self recreatePlatformViewController];

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

- (void)recreatePlatformViewController {
_renderingApi = flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering);
_surfaceFactory = flutter::IOSSurfaceFactory::Create(_renderingApi);
_platformViewsController.reset(new flutter::FlutterPlatformViewsController(_surfaceFactory));
_surfaceFactory->SetPlatformViewsController(_platformViewsController);
}

- (flutter::IOSRenderingAPI)platformViewsRenderingAPI {
return _renderingApi;
}

- (void)dealloc {
/// Notify plugins of dealloc. This should happen first in dealloc since the
/// plugins may be talking to things like the binaryMessenger.
Expand Down Expand Up @@ -520,13 +535,12 @@ - (BOOL)createShell:(NSString*)entrypoint
threadHostType};

// Lambda captures by pointers to ObjC objects are fine here because the
// create call is
// synchronous.
// create call is synchronous.
flutter::Shell::CreateCallback<flutter::PlatformView> on_create_platform_view =
[](flutter::Shell& shell) {
[self](flutter::Shell& shell) {
[self recreatePlatformViewController];
return std::make_unique<flutter::PlatformViewIOS>(
shell, flutter::GetRenderingAPIForProcess(FlutterView.forceSoftwareRendering),
shell.GetTaskRunners());
shell, self->_renderingApi, self->_surfaceFactory, shell.GetTaskRunners());
};

flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
Expand Down Expand Up @@ -554,9 +568,6 @@ - (BOOL)createShell:(NSString*)entrypoint
[self setupChannels];
[self onLocaleUpdated:nil];
[self initializeDisplays];
if (!_platformViewsController) {
_platformViewsController.reset(new flutter::FlutterPlatformViewsController());
}
_publisher.reset([[FlutterObservatoryPublisher alloc]
initWithEnableObservatoryPublication:settings.enable_observatory_publication]);
[self maybeSetupPlatformViewChannels];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ - (void)testCallsNotifyLowMemory {
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware),
/*task_runners=*/runners);

id project = OCMClassMock([FlutterDartProject class]);
Expand Down
21 changes: 21 additions & 0 deletions shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>

#import "flutter/common/settings.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h"

FLUTTER_ASSERT_ARC
Expand Down Expand Up @@ -113,4 +115,23 @@ - (void)testWaitForFirstFrameTimeout {
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testPlatformViewsControllerRenderingMetalBackend {
FlutterEngine* engine = [[FlutterEngine alloc] init];
[engine run];
flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI];

XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kMetal);
}

- (void)testPlatformViewsControllerRenderingSoftware {
auto settings = FLTDefaultSettingsForBundle();
settings.enable_software_rendering = true;
FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings];
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
[engine run];
flutter::IOSRenderingAPI renderingApi = [engine platformViewsRenderingAPI];

XCTAssertEqual(renderingApi, flutter::IOSRenderingAPI::kSoftware);
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
// found in the LICENSE file.

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

@class FlutterBinaryMessengerRelay;

// Category to add test-only visibility.
@interface FlutterEngine (Test) <FlutterBinaryMessenger>
- (void)setBinaryMessenger:(FlutterBinaryMessengerRelay*)binaryMessenger;
- (void)waitForFirstFrame:(NSTimeInterval)timeout callback:(void (^)(BOOL didTimeout))callback;
- (flutter::IOSRenderingAPI)platformViewsRenderingAPI;
@end
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@

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

@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ + (Class)layerClass {
return [FlutterView layerClass];
}

- (std::unique_ptr<flutter::IOSSurface>)createSurface:
(std::shared_ptr<flutter::IOSContext>)ios_context {
return flutter::IOSSurface::Create(std::move(ios_context), // context
fml::scoped_nsobject<CALayer>{[self.layer retain]}, // layer
nullptr // platform views controller
);
}

// TODO(amirh): implement drawLayer to support snapshotting.

@end
15 changes: 11 additions & 4 deletions shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
#import "flutter/shell/platform/darwin/ios/ios_surface_factory.h"
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"

namespace flutter {
Expand All @@ -32,8 +33,8 @@
overlay_view.reset([[FlutterOverlayView alloc] init]);
overlay_view_wrapper.reset([[FlutterOverlayView alloc] init]);

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

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

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

layer = std::make_shared<FlutterPlatformViewLayer>(
Expand Down Expand Up @@ -436,6 +437,12 @@
for (UIView* sub_view in [flutter_view subviews]) {
[sub_view removeFromSuperview];
}
// See: https://github.com/flutter/flutter/issues/69305
for (auto it = touch_interceptors_.begin(); it != touch_interceptors_.end(); it++) {
FlutterTouchInterceptingView* view = it->second.get();
[view removeFromSuperview];
}
touch_interceptors_.clear();
views_.clear();
composition_order_.clear();
active_composition_order_.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,16 @@ - (void)testCanCreatePlatformViewWithoutFlutterView {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down Expand Up @@ -175,12 +179,16 @@ - (void)testCompositePlatformView {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down Expand Up @@ -230,12 +238,16 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down Expand Up @@ -301,12 +313,16 @@ - (void)testClipRect {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down Expand Up @@ -373,12 +389,16 @@ - (void)testClipRRect {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down Expand Up @@ -445,12 +465,16 @@ - (void)testClipPath {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down Expand Up @@ -518,12 +542,16 @@ - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto surface_factory = flutter::IOSSurfaceFactory::Create(flutter::IOSRenderingAPI::kSoftware);
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*ios_surface_factory=*/surface_factory,
/*task_runners=*/runners);

auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
auto flutterPlatformViewsController =
std::make_shared<flutter::FlutterPlatformViewsController>(surface_factory);
surface_factory->SetPlatformViewsController(flutterPlatformViewsController);

FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
Expand Down
Loading