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

Commit d955a72

Browse files
authored
[macOS] Merge FlutterSurfaceManager and impls (#37701)
Previously, FlutterSurfaceManager was a protocol with two concrete implementations: FlutterGLSurfaceManager and FlutterMetalSurfaceManager. Most of the implementation was in a shared superclass, FlutterIOSurfaceManager, which called into the OpenGL or Metal-specific subclass when backend-specific operations (such as allocating textures) was required. It did so via a delegate pattern, wherein the subclasses both implemented the FlutterIOSurfaceManagerDelegate protocol that exposed the backend-specific functionality. Now that only the Metal implementation remains, the delegate code can be inlined into the calling functions, and the class hierarchy can be squashed into a single concrete implementation class, FlutterSurfaceManager, similar to how it was originally implemented in #21525 before we had two backends. Issue: flutter/flutter#108304 Issue: flutter/flutter#114445
1 parent 5b31f4f commit d955a72

File tree

6 files changed

+65
-134
lines changed

6 files changed

+65
-134
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2642,7 +2642,6 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuP
26422642
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin.mm
26432643
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm
26442644
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin_Internal.h
2645-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalSurfaceManagerTest.mm
26462645
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h
26472646
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.mm
26482647
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h
@@ -2660,6 +2659,7 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResiz
26602659
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.mm
26612660
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h
26622661
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm
2662+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm
26632663
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h
26642664
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.mm
26652665
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm

shell/platform/darwin/macos/BUILD.gn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,10 @@ executable("flutter_desktop_darwin_unittests") {
174174
"framework/Source/FlutterEngineTestUtils.mm",
175175
"framework/Source/FlutterKeyboardManagerUnittests.mm",
176176
"framework/Source/FlutterMenuPluginTest.mm",
177-
"framework/Source/FlutterMetalSurfaceManagerTest.mm",
178177
"framework/Source/FlutterPlatformNodeDelegateMacTest.mm",
179178
"framework/Source/FlutterPlatformViewControllerTest.mm",
180179
"framework/Source/FlutterRendererTest.mm",
180+
"framework/Source/FlutterSurfaceManagerTest.mm",
181181
"framework/Source/FlutterTextInputPluginTest.mm",
182182
"framework/Source/FlutterTextInputSemanticsObjectTest.mm",
183183
"framework/Source/FlutterViewControllerTest.mm",

shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@implementation FlutterMetalResizableBackingStoreProvider {
1212
id<MTLDevice> _device;
1313
id<MTLCommandQueue> _commandQueue;
14-
id<FlutterSurfaceManager> _surfaceManager;
14+
FlutterSurfaceManager* _surfaceManager;
1515
}
1616

1717
- (instancetype)initWithDevice:(id<MTLDevice>)device
@@ -21,9 +21,9 @@ - (instancetype)initWithDevice:(id<MTLDevice>)device
2121
if (self) {
2222
_device = device;
2323
_commandQueue = commandQueue;
24-
_surfaceManager = [[FlutterMetalSurfaceManager alloc] initWithDevice:device
25-
commandQueue:commandQueue
26-
layer:layer];
24+
_surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device
25+
commandQueue:commandQueue
26+
layer:layer];
2727
}
2828
return self;
2929
}

shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h

Lines changed: 16 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -9,88 +9,36 @@
99
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"
1010

1111
/**
12-
* Manages the render surfaces and their corresponding backing stores.
13-
*/
14-
@protocol FlutterSurfaceManager
15-
16-
/**
17-
* Updates the backing store size of the managed IOSurfaces to `size`. If the surfaces are already
18-
* of the same size, this is a no-op.
19-
*/
20-
- (void)ensureSurfaceSize:(CGSize)size;
21-
22-
/**
23-
* Swaps the front and the back buffer.
24-
*/
25-
- (void)swapBuffers;
26-
27-
/**
28-
* Returns the backing store for the back buffer.
29-
*/
30-
- (nonnull FlutterRenderBackingStore*)renderBuffer;
31-
32-
@end
33-
34-
/**
35-
* Methods for managing the IOSurfaces held by FlutterIOSurfaceManager.
36-
*/
37-
@protocol FlutterIOSurfaceManagerDelegate
38-
39-
/**
40-
* Tells the delegate that the front and back IOSurfaces are swapped.
41-
*/
42-
- (void)onSwapBuffers;
43-
44-
/**
45-
* Tells the delegate that the IOSurfaces have been resized. `bufferIndex` is to indicate the front
46-
* vs back buffer. `size` is the new size of the IOSurface.
47-
*/
48-
- (void)onUpdateSurface:(nonnull FlutterIOSurfaceHolder*)surface
49-
bufferIndex:(size_t)index
50-
size:(CGSize)size;
51-
52-
/**
53-
* Tells the delegate that IOSurface with given index has been released. Delegate should free
54-
* all resources associated with the surface
55-
*/
56-
- (void)onSurfaceReleased:(size_t)index;
57-
58-
@end
59-
60-
/**
61-
* Manages IOSurfaces for the FlutterEngine to render to.
12+
* Manages render surfaces and corresponding backing stores used by the engine.
6213
*
63-
* The backing store when rendering with on Metal its a Metal texture. There are two IOSurfaces
14+
* The backing store when rendering with on Metal is a Metal texture. There are two IOSurfaces
6415
* created during initialization, FlutterSurfaceManager manages the lifecycle of these.
6516
*/
66-
@interface FlutterIOSurfaceManager : NSObject <FlutterSurfaceManager>
67-
68-
/**
69-
* The object that acts as the delegate for the FlutterIOSurfaceManager. See:
70-
* FlutterIOSurfaceManagerDelegate.
71-
*/
72-
@property(nullable, nonatomic, weak) id<FlutterIOSurfaceManagerDelegate> delegate;
17+
@interface FlutterSurfaceManager : NSObject
7318

7419
/**
75-
* Initializes and returns an IOSurface manager that renders to a child layer (referred to as the
20+
* Initializes and returns a surface manager that renders to a child layer (referred to as the
7621
* content layer) of the containing layer and applies the transform to the contents of the content
7722
* layer.
7823
*/
79-
- (nullable instancetype)initWithLayer:(nonnull CALayer*)containingLayer
80-
contentTransform:(CATransform3D)transform;
24+
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
25+
commandQueue:(nonnull id<MTLCommandQueue>)commandQueue
26+
layer:(nonnull CALayer*)containingLayer;
8127

82-
@end
28+
/**
29+
* Updates the backing store size of the managed IOSurfaces the specified size. If the surfaces are
30+
* already of this size, this is a no-op.
31+
*/
32+
- (void)ensureSurfaceSize:(CGSize)size;
8333

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

8939
/**
90-
* Creates two IOSurfaces backed by Metal textures.
40+
* Returns the backing store for the back buffer.
9141
*/
92-
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
93-
commandQueue:(nonnull id<MTLCommandQueue>)commandQueue
94-
layer:(nonnull CALayer*)containingLayer;
42+
- (nonnull FlutterRenderBackingStore*)renderBuffer;
9543

9644
@end

shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,49 @@
1919
// BackBuffer will be released after kIdleDelay if there is no activity.
2020
static const double kIdleDelay = 1.0;
2121

22-
@implementation FlutterIOSurfaceManager {
22+
@interface FlutterSurfaceManager ()
23+
24+
/**
25+
* Cancels any previously-scheduled onIdle requests.
26+
*/
27+
- (void)cancelIdle;
28+
29+
/**
30+
* Creates a backing textures for the specified surface with the specified size.
31+
*/
32+
- (id<MTLTexture>)createTextureForSurface:(FlutterIOSurfaceHolder*)surface size:(CGSize)size;
33+
34+
@end
35+
36+
@implementation FlutterSurfaceManager {
2337
CALayer* _containingLayer; // provided (parent layer)
2438
CALayer* _contentLayer;
2539
CATransform3D _contentTransform;
2640

2741
CGSize _surfaceSize;
2842
FlutterIOSurfaceHolder* _ioSurfaces[kFlutterSurfaceManagerBufferCount];
2943
BOOL _frameInProgress;
44+
45+
id<MTLDevice> _device;
46+
id<MTLCommandQueue> _commandQueue;
47+
id<MTLTexture> _textures[kFlutterSurfaceManagerBufferCount];
3048
}
3149

32-
- (instancetype)initWithLayer:(CALayer*)containingLayer contentTransform:(CATransform3D)transform {
50+
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
51+
commandQueue:(nonnull id<MTLCommandQueue>)commandQueue
52+
layer:(nonnull CALayer*)containingLayer {
3353
self = [super init];
3454
if (self) {
3555
_containingLayer = containingLayer;
36-
_contentTransform = transform;
56+
_contentTransform = CATransform3DIdentity;
3757
_contentLayer = [[CALayer alloc] init];
3858
[_containingLayer addSublayer:_contentLayer];
3959

4060
_ioSurfaces[0] = [[FlutterIOSurfaceHolder alloc] init];
4161
_ioSurfaces[1] = [[FlutterIOSurfaceHolder alloc] init];
62+
63+
_device = device;
64+
_commandQueue = commandQueue;
4265
}
4366
return self;
4467
}
@@ -51,7 +74,7 @@ - (void)ensureSurfaceSize:(CGSize)size {
5174
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
5275
if (_ioSurfaces[i] != nil) {
5376
[_ioSurfaces[i] recreateIOSurfaceWithSize:size];
54-
[_delegate onUpdateSurface:_ioSurfaces[i] bufferIndex:i size:size];
77+
_textures[i] = [self createTextureForSurface:_ioSurfaces[i] size:size];
5578
}
5679
}
5780
}
@@ -71,7 +94,8 @@ - (void)swapBuffers {
7194

7295
std::swap(_ioSurfaces[kFlutterSurfaceManagerBackBuffer],
7396
_ioSurfaces[kFlutterSurfaceManagerFrontBuffer]);
74-
[_delegate onSwapBuffers];
97+
std::swap(_textures[kFlutterSurfaceManagerBackBuffer],
98+
_textures[kFlutterSurfaceManagerFrontBuffer]);
7599

76100
// performSelector:withObject:afterDelay needs to be performed on RunLoop thread
77101
[self performSelectorOnMainThread:@selector(reschedule) withObject:nil waitUntilDone:NO];
@@ -92,7 +116,7 @@ - (void)onIdle {
92116
// Release the back buffer and notify delegate. The buffer will be restored
93117
// on demand in ensureBackBuffer
94118
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = nil;
95-
[self.delegate onSurfaceReleased:kFlutterSurfaceManagerBackBuffer];
119+
_textures[kFlutterSurfaceManagerBackBuffer] = nil;
96120
}
97121
}
98122
}
@@ -104,9 +128,9 @@ - (void)ensureBackBuffer {
104128
// Restore previously released backbuffer
105129
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = [[FlutterIOSurfaceHolder alloc] init];
106130
[_ioSurfaces[kFlutterSurfaceManagerBackBuffer] recreateIOSurfaceWithSize:_surfaceSize];
107-
[_delegate onUpdateSurface:_ioSurfaces[kFlutterSurfaceManagerBackBuffer]
108-
bufferIndex:kFlutterSurfaceManagerBackBuffer
109-
size:_surfaceSize];
131+
_textures[kFlutterSurfaceManagerBackBuffer] =
132+
[self createTextureForSurface:_ioSurfaces[kFlutterSurfaceManagerBackBuffer]
133+
size:_surfaceSize];
110134
}
111135
};
112136
[self performSelectorOnMainThread:@selector(cancelIdle) withObject:nil waitUntilDone:NO];
@@ -117,47 +141,12 @@ - (void)cancelIdle {
117141
}
118142

119143
- (nonnull FlutterRenderBackingStore*)renderBuffer {
120-
@throw([NSException exceptionWithName:@"Sub-classes FlutterIOSurfaceManager of"
121-
" must override renderBuffer."
122-
reason:nil
123-
userInfo:nil]);
124-
}
125-
126-
@end
127-
128-
@implementation FlutterMetalSurfaceManager {
129-
id<MTLDevice> _device;
130-
id<MTLCommandQueue> _commandQueue;
131-
132-
id<MTLTexture> _textures[kFlutterSurfaceManagerBufferCount];
133-
}
134-
135-
- (nullable instancetype)initWithDevice:(nonnull id<MTLDevice>)device
136-
commandQueue:(nonnull id<MTLCommandQueue>)commandQueue
137-
layer:(nonnull CALayer*)containingLayer {
138-
self = [super initWithLayer:containingLayer contentTransform:CATransform3DIdentity];
139-
if (self) {
140-
super.delegate = self;
141-
_device = device;
142-
_commandQueue = commandQueue;
143-
}
144-
return self;
145-
}
146-
147-
- (FlutterRenderBackingStore*)renderBuffer {
148144
[self ensureBackBuffer];
149145
id<MTLTexture> texture = _textures[kFlutterSurfaceManagerBackBuffer];
150146
return [[FlutterMetalRenderBackingStore alloc] initWithTexture:texture];
151147
}
152148

153-
- (void)onSwapBuffers {
154-
std::swap(_textures[kFlutterSurfaceManagerBackBuffer],
155-
_textures[kFlutterSurfaceManagerFrontBuffer]);
156-
}
157-
158-
- (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface
159-
bufferIndex:(size_t)index
160-
size:(CGSize)size {
149+
- (id<MTLTexture>)createTextureForSurface:(FlutterIOSurfaceHolder*)surface size:(CGSize)size {
161150
MTLTextureDescriptor* textureDescriptor =
162151
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
163152
width:size.width
@@ -166,13 +155,7 @@ - (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface
166155
textureDescriptor.usage =
167156
MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite;
168157
// plane = 0 for BGRA.
169-
_textures[index] = [_device newTextureWithDescriptor:textureDescriptor
170-
iosurface:[surface ioSurface]
171-
plane:0];
172-
}
173-
174-
- (void)onSurfaceReleased:(size_t)index {
175-
_textures[index] = nil;
158+
return [_device newTextureWithDescriptor:textureDescriptor iosurface:[surface ioSurface] plane:0];
176159
}
177160

178161
@end

shell/platform/darwin/macos/framework/Source/FlutterMetalSurfaceManagerTest.mm renamed to shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@ - (instancetype)init {
2929

3030
namespace flutter::testing {
3131

32-
static FlutterMetalSurfaceManager* CreateSurfaceManager() {
32+
static FlutterSurfaceManager* CreateSurfaceManager() {
3333
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
3434
id<MTLCommandQueue> commandQueue = [device newCommandQueue];
3535
TestMetalView* metalView = [[TestMetalView alloc] init];
3636
CALayer* layer = reinterpret_cast<CALayer*>(metalView.layer);
37-
return [[FlutterMetalSurfaceManager alloc] initWithDevice:device
38-
commandQueue:commandQueue
39-
layer:layer];
37+
return [[FlutterSurfaceManager alloc] initWithDevice:device
38+
commandQueue:commandQueue
39+
layer:layer];
4040
}
4141

42-
TEST(FlutterMetalSurfaceManager, EnsureSizeUpdatesSize) {
43-
FlutterMetalSurfaceManager* surfaceManager = CreateSurfaceManager();
42+
TEST(FlutterSurfaceManager, EnsureSizeUpdatesSize) {
43+
FlutterSurfaceManager* surfaceManager = CreateSurfaceManager();
4444
CGSize size = CGSizeMake(100, 50);
4545
[surfaceManager ensureSurfaceSize:size];
4646
id<MTLTexture> texture =
@@ -49,8 +49,8 @@ - (instancetype)init {
4949
ASSERT_TRUE(CGSizeEqualToSize(size, textureSize));
5050
}
5151

52-
TEST(FlutterMetalSurfaceManager, EnsureSizeUpdatesSizeForBackBuffer) {
53-
FlutterMetalSurfaceManager* surfaceManager = CreateSurfaceManager();
52+
TEST(FlutterSurfaceManager, EnsureSizeUpdatesSizeForBackBuffer) {
53+
FlutterSurfaceManager* surfaceManager = CreateSurfaceManager();
5454
CGSize size = CGSizeMake(100, 50);
5555
[surfaceManager ensureSurfaceSize:size];
5656
[surfaceManager renderBuffer]; // make sure we have back buffer

0 commit comments

Comments
 (0)