diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index fdd6d53ccd..00174c6fc1 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -2642,7 +2642,6 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuP FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin_Internal.h -FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalSurfaceManagerTest.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h @@ -2660,6 +2659,7 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResiz FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm diff --git a/engine/src/flutter/shell/platform/darwin/macos/BUILD.gn b/engine/src/flutter/shell/platform/darwin/macos/BUILD.gn index e51c50cf1c..059b2bc4e5 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/BUILD.gn +++ b/engine/src/flutter/shell/platform/darwin/macos/BUILD.gn @@ -174,10 +174,10 @@ executable("flutter_desktop_darwin_unittests") { "framework/Source/FlutterEngineTestUtils.mm", "framework/Source/FlutterKeyboardManagerUnittests.mm", "framework/Source/FlutterMenuPluginTest.mm", - "framework/Source/FlutterMetalSurfaceManagerTest.mm", "framework/Source/FlutterPlatformNodeDelegateMacTest.mm", "framework/Source/FlutterPlatformViewControllerTest.mm", "framework/Source/FlutterRendererTest.mm", + "framework/Source/FlutterSurfaceManagerTest.mm", "framework/Source/FlutterTextInputPluginTest.mm", "framework/Source/FlutterTextInputSemanticsObjectTest.mm", "framework/Source/FlutterViewControllerTest.mm", diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm index 620c8dbf8c..fc07530c37 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm @@ -11,7 +11,7 @@ @implementation FlutterMetalResizableBackingStoreProvider { id _device; id _commandQueue; - id _surfaceManager; + FlutterSurfaceManager* _surfaceManager; } - (instancetype)initWithDevice:(id)device @@ -21,9 +21,9 @@ if (self) { _device = device; _commandQueue = commandQueue; - _surfaceManager = [[FlutterMetalSurfaceManager alloc] initWithDevice:device - commandQueue:commandQueue - layer:layer]; + _surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device + commandQueue:commandQueue + layer:layer]; } return self; } diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h index cc5ab32782..2f6a0974e4 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h @@ -9,13 +9,25 @@ #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h" /** - * Manages the render surfaces and their corresponding backing stores. + * Manages render surfaces and corresponding backing stores used by the engine. + * + * The backing store when rendering with on Metal is a Metal texture. There are two IOSurfaces + * created during initialization, FlutterSurfaceManager manages the lifecycle of these. */ -@protocol FlutterSurfaceManager +@interface FlutterSurfaceManager : NSObject /** - * Updates the backing store size of the managed IOSurfaces to `size`. If the surfaces are already - * of the same size, this is a no-op. + * Initializes and returns a surface manager that renders to a child layer (referred to as the + * content layer) of the containing layer and applies the transform to the contents of the content + * layer. + */ +- (nullable instancetype)initWithDevice:(nonnull id)device + commandQueue:(nonnull id)commandQueue + layer:(nonnull CALayer*)containingLayer; + +/** + * Updates the backing store size of the managed IOSurfaces the specified size. If the surfaces are + * already of this size, this is a no-op. */ - (void)ensureSurfaceSize:(CGSize)size; @@ -30,67 +42,3 @@ - (nonnull FlutterRenderBackingStore*)renderBuffer; @end - -/** - * Methods for managing the IOSurfaces held by FlutterIOSurfaceManager. - */ -@protocol FlutterIOSurfaceManagerDelegate - -/** - * Tells the delegate that the front and back IOSurfaces are swapped. - */ -- (void)onSwapBuffers; - -/** - * Tells the delegate that the IOSurfaces have been resized. `bufferIndex` is to indicate the front - * vs back buffer. `size` is the new size of the IOSurface. - */ -- (void)onUpdateSurface:(nonnull FlutterIOSurfaceHolder*)surface - bufferIndex:(size_t)index - size:(CGSize)size; - -/** - * Tells the delegate that IOSurface with given index has been released. Delegate should free - * all resources associated with the surface - */ -- (void)onSurfaceReleased:(size_t)index; - -@end - -/** - * Manages IOSurfaces for the FlutterEngine to render to. - * - * The backing store when rendering with on Metal its a Metal texture. There are two IOSurfaces - * created during initialization, FlutterSurfaceManager manages the lifecycle of these. - */ -@interface FlutterIOSurfaceManager : NSObject - -/** - * The object that acts as the delegate for the FlutterIOSurfaceManager. See: - * FlutterIOSurfaceManagerDelegate. - */ -@property(nullable, nonatomic, weak) id delegate; - -/** - * Initializes and returns an IOSurface manager that renders to a child layer (referred to as the - * content layer) of the containing layer and applies the transform to the contents of the content - * layer. - */ -- (nullable instancetype)initWithLayer:(nonnull CALayer*)containingLayer - contentTransform:(CATransform3D)transform; - -@end - -/** - * FlutterSurfaceManager implementation where the IOSurfaces managed are backed by a Metal textures. - */ -@interface FlutterMetalSurfaceManager : FlutterIOSurfaceManager - -/** - * Creates two IOSurfaces backed by Metal textures. - */ -- (nullable instancetype)initWithDevice:(nonnull id)device - commandQueue:(nonnull id)commandQueue - layer:(nonnull CALayer*)containingLayer; - -@end diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm index 938c9cf08a..06d0e5f234 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm @@ -19,7 +19,21 @@ enum { // BackBuffer will be released after kIdleDelay if there is no activity. static const double kIdleDelay = 1.0; -@implementation FlutterIOSurfaceManager { +@interface FlutterSurfaceManager () + +/** + * Cancels any previously-scheduled onIdle requests. + */ +- (void)cancelIdle; + +/** + * Creates a backing textures for the specified surface with the specified size. + */ +- (id)createTextureForSurface:(FlutterIOSurfaceHolder*)surface size:(CGSize)size; + +@end + +@implementation FlutterSurfaceManager { CALayer* _containingLayer; // provided (parent layer) CALayer* _contentLayer; CATransform3D _contentTransform; @@ -27,18 +41,27 @@ static const double kIdleDelay = 1.0; CGSize _surfaceSize; FlutterIOSurfaceHolder* _ioSurfaces[kFlutterSurfaceManagerBufferCount]; BOOL _frameInProgress; + + id _device; + id _commandQueue; + id _textures[kFlutterSurfaceManagerBufferCount]; } -- (instancetype)initWithLayer:(CALayer*)containingLayer contentTransform:(CATransform3D)transform { +- (nullable instancetype)initWithDevice:(nonnull id)device + commandQueue:(nonnull id)commandQueue + layer:(nonnull CALayer*)containingLayer { self = [super init]; if (self) { _containingLayer = containingLayer; - _contentTransform = transform; + _contentTransform = CATransform3DIdentity; _contentLayer = [[CALayer alloc] init]; [_containingLayer addSublayer:_contentLayer]; _ioSurfaces[0] = [[FlutterIOSurfaceHolder alloc] init]; _ioSurfaces[1] = [[FlutterIOSurfaceHolder alloc] init]; + + _device = device; + _commandQueue = commandQueue; } return self; } @@ -51,7 +74,7 @@ static const double kIdleDelay = 1.0; for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) { if (_ioSurfaces[i] != nil) { [_ioSurfaces[i] recreateIOSurfaceWithSize:size]; - [_delegate onUpdateSurface:_ioSurfaces[i] bufferIndex:i size:size]; + _textures[i] = [self createTextureForSurface:_ioSurfaces[i] size:size]; } } } @@ -71,7 +94,8 @@ static const double kIdleDelay = 1.0; std::swap(_ioSurfaces[kFlutterSurfaceManagerBackBuffer], _ioSurfaces[kFlutterSurfaceManagerFrontBuffer]); - [_delegate onSwapBuffers]; + std::swap(_textures[kFlutterSurfaceManagerBackBuffer], + _textures[kFlutterSurfaceManagerFrontBuffer]); // performSelector:withObject:afterDelay needs to be performed on RunLoop thread [self performSelectorOnMainThread:@selector(reschedule) withObject:nil waitUntilDone:NO]; @@ -92,7 +116,7 @@ static const double kIdleDelay = 1.0; // Release the back buffer and notify delegate. The buffer will be restored // on demand in ensureBackBuffer _ioSurfaces[kFlutterSurfaceManagerBackBuffer] = nil; - [self.delegate onSurfaceReleased:kFlutterSurfaceManagerBackBuffer]; + _textures[kFlutterSurfaceManagerBackBuffer] = nil; } } } @@ -104,9 +128,9 @@ static const double kIdleDelay = 1.0; // Restore previously released backbuffer _ioSurfaces[kFlutterSurfaceManagerBackBuffer] = [[FlutterIOSurfaceHolder alloc] init]; [_ioSurfaces[kFlutterSurfaceManagerBackBuffer] recreateIOSurfaceWithSize:_surfaceSize]; - [_delegate onUpdateSurface:_ioSurfaces[kFlutterSurfaceManagerBackBuffer] - bufferIndex:kFlutterSurfaceManagerBackBuffer - size:_surfaceSize]; + _textures[kFlutterSurfaceManagerBackBuffer] = + [self createTextureForSurface:_ioSurfaces[kFlutterSurfaceManagerBackBuffer] + size:_surfaceSize]; } }; [self performSelectorOnMainThread:@selector(cancelIdle) withObject:nil waitUntilDone:NO]; @@ -117,47 +141,12 @@ static const double kIdleDelay = 1.0; } - (nonnull FlutterRenderBackingStore*)renderBuffer { - @throw([NSException exceptionWithName:@"Sub-classes FlutterIOSurfaceManager of" - " must override renderBuffer." - reason:nil - userInfo:nil]); -} - -@end - -@implementation FlutterMetalSurfaceManager { - id _device; - id _commandQueue; - - id _textures[kFlutterSurfaceManagerBufferCount]; -} - -- (nullable instancetype)initWithDevice:(nonnull id)device - commandQueue:(nonnull id)commandQueue - layer:(nonnull CALayer*)containingLayer { - self = [super initWithLayer:containingLayer contentTransform:CATransform3DIdentity]; - if (self) { - super.delegate = self; - _device = device; - _commandQueue = commandQueue; - } - return self; -} - -- (FlutterRenderBackingStore*)renderBuffer { [self ensureBackBuffer]; id texture = _textures[kFlutterSurfaceManagerBackBuffer]; return [[FlutterMetalRenderBackingStore alloc] initWithTexture:texture]; } -- (void)onSwapBuffers { - std::swap(_textures[kFlutterSurfaceManagerBackBuffer], - _textures[kFlutterSurfaceManagerFrontBuffer]); -} - -- (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface - bufferIndex:(size_t)index - size:(CGSize)size { +- (id)createTextureForSurface:(FlutterIOSurfaceHolder*)surface size:(CGSize)size { MTLTextureDescriptor* textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm width:size.width @@ -166,13 +155,7 @@ static const double kIdleDelay = 1.0; textureDescriptor.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite; // plane = 0 for BGRA. - _textures[index] = [_device newTextureWithDescriptor:textureDescriptor - iosurface:[surface ioSurface] - plane:0]; -} - -- (void)onSurfaceReleased:(size_t)index { - _textures[index] = nil; + return [_device newTextureWithDescriptor:textureDescriptor iosurface:[surface ioSurface] plane:0]; } @end diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalSurfaceManagerTest.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm similarity index 75% rename from engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalSurfaceManagerTest.mm rename to engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm index 7776077638..fdcd62f9d7 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalSurfaceManagerTest.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm @@ -29,18 +29,18 @@ namespace flutter::testing { -static FlutterMetalSurfaceManager* CreateSurfaceManager() { +static FlutterSurfaceManager* CreateSurfaceManager() { id device = MTLCreateSystemDefaultDevice(); id commandQueue = [device newCommandQueue]; TestMetalView* metalView = [[TestMetalView alloc] init]; CALayer* layer = reinterpret_cast(metalView.layer); - return [[FlutterMetalSurfaceManager alloc] initWithDevice:device - commandQueue:commandQueue - layer:layer]; + return [[FlutterSurfaceManager alloc] initWithDevice:device + commandQueue:commandQueue + layer:layer]; } -TEST(FlutterMetalSurfaceManager, EnsureSizeUpdatesSize) { - FlutterMetalSurfaceManager* surfaceManager = CreateSurfaceManager(); +TEST(FlutterSurfaceManager, EnsureSizeUpdatesSize) { + FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(); CGSize size = CGSizeMake(100, 50); [surfaceManager ensureSurfaceSize:size]; id texture = @@ -49,8 +49,8 @@ TEST(FlutterMetalSurfaceManager, EnsureSizeUpdatesSize) { ASSERT_TRUE(CGSizeEqualToSize(size, textureSize)); } -TEST(FlutterMetalSurfaceManager, EnsureSizeUpdatesSizeForBackBuffer) { - FlutterMetalSurfaceManager* surfaceManager = CreateSurfaceManager(); +TEST(FlutterSurfaceManager, EnsureSizeUpdatesSizeForBackBuffer) { + FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(); CGSize size = CGSizeMake(100, 50); [surfaceManager ensureSurfaceSize:size]; [surfaceManager renderBuffer]; // make sure we have back buffer