Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[macOS] Merge FlutterSurfaceManager classes #37701

Merged
merged 1 commit into from
Nov 17, 2022
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: 1 addition & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2643,7 +2643,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
Expand All @@ -2661,6 +2660,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
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/darwin/macos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@implementation FlutterMetalResizableBackingStoreProvider {
id<MTLDevice> _device;
id<MTLCommandQueue> _commandQueue;
id<FlutterSurfaceManager> _surfaceManager;
FlutterSurfaceManager* _surfaceManager;
}

- (instancetype)initWithDevice:(id<MTLDevice>)device
Expand All @@ -21,9 +21,9 @@ - (instancetype)initWithDevice:(id<MTLDevice>)device
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,88 +9,36 @@
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"

/**
* Manages the render surfaces and their corresponding backing stores.
*/
@protocol FlutterSurfaceManager

/**
* 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.
*/
- (void)ensureSurfaceSize:(CGSize)size;

/**
* Swaps the front and the back buffer.
*/
- (void)swapBuffers;

/**
* Returns the backing store for the back buffer.
*/
- (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.
* Manages render surfaces and corresponding backing stores used by the engine.
*
* The backing store when rendering with on Metal its a Metal texture. There are two IOSurfaces
* 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.
*/
@interface FlutterIOSurfaceManager : NSObject <FlutterSurfaceManager>

/**
* The object that acts as the delegate for the FlutterIOSurfaceManager. See:
* FlutterIOSurfaceManagerDelegate.
*/
@property(nullable, nonatomic, weak) id<FlutterIOSurfaceManagerDelegate> delegate;
@interface FlutterSurfaceManager : NSObject

/**
* Initializes and returns an IOSurface manager that renders to a child layer (referred to as the
* 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)initWithLayer:(nonnull CALayer*)containingLayer
contentTransform:(CATransform3D)transform;
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
commandQueue:(nonnull id<MTLCommandQueue>)commandQueue
layer:(nonnull CALayer*)containingLayer;

@end
/**
* 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;

/**
* FlutterSurfaceManager implementation where the IOSurfaces managed are backed by a Metal textures.
* Swaps the front and the back buffer.
*/
@interface FlutterMetalSurfaceManager : FlutterIOSurfaceManager <FlutterIOSurfaceManagerDelegate>
- (void)swapBuffers;

/**
* Creates two IOSurfaces backed by Metal textures.
* Returns the backing store for the back buffer.
*/
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
commandQueue:(nonnull id<MTLCommandQueue>)commandQueue
layer:(nonnull CALayer*)containingLayer;
- (nonnull FlutterRenderBackingStore*)renderBuffer;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,49 @@
// 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<MTLTexture>)createTextureForSurface:(FlutterIOSurfaceHolder*)surface size:(CGSize)size;

@end

@implementation FlutterSurfaceManager {
CALayer* _containingLayer; // provided (parent layer)
CALayer* _contentLayer;
CATransform3D _contentTransform;

CGSize _surfaceSize;
FlutterIOSurfaceHolder* _ioSurfaces[kFlutterSurfaceManagerBufferCount];
BOOL _frameInProgress;

id<MTLDevice> _device;
id<MTLCommandQueue> _commandQueue;
id<MTLTexture> _textures[kFlutterSurfaceManagerBufferCount];
}

- (instancetype)initWithLayer:(CALayer*)containingLayer contentTransform:(CATransform3D)transform {
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
commandQueue:(nonnull id<MTLCommandQueue>)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;
}
Expand All @@ -51,7 +74,7 @@ - (void)ensureSurfaceSize:(CGSize)size {
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];
}
}
}
Expand All @@ -71,7 +94,8 @@ - (void)swapBuffers {

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];
Expand All @@ -92,7 +116,7 @@ - (void)onIdle {
// 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;
}
}
}
Expand All @@ -104,9 +128,9 @@ - (void)ensureBackBuffer {
// 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];
Expand All @@ -117,47 +141,12 @@ - (void)cancelIdle {
}

- (nonnull FlutterRenderBackingStore*)renderBuffer {
@throw([NSException exceptionWithName:@"Sub-classes FlutterIOSurfaceManager of"
" must override renderBuffer."
reason:nil
userInfo:nil]);
}

@end

@implementation FlutterMetalSurfaceManager {
id<MTLDevice> _device;
id<MTLCommandQueue> _commandQueue;

id<MTLTexture> _textures[kFlutterSurfaceManagerBufferCount];
}

- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
commandQueue:(nonnull id<MTLCommandQueue>)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<MTLTexture> 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<MTLTexture>)createTextureForSurface:(FlutterIOSurfaceHolder*)surface size:(CGSize)size {
MTLTextureDescriptor* textureDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
width:size.width
Expand All @@ -166,13 +155,7 @@ - (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ - (instancetype)init {

namespace flutter::testing {

static FlutterMetalSurfaceManager* CreateSurfaceManager() {
static FlutterSurfaceManager* CreateSurfaceManager() {
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
id<MTLCommandQueue> commandQueue = [device newCommandQueue];
TestMetalView* metalView = [[TestMetalView alloc] init];
CALayer* layer = reinterpret_cast<CALayer*>(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<MTLTexture> texture =
Expand All @@ -49,8 +49,8 @@ - (instancetype)init {
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
Expand Down