5 #import <Cocoa/Cocoa.h>
6 #import <Metal/Metal.h>
11 #include "flutter/testing/testing.h"
12 #include "gtest/gtest.h"
17 - (nonnull instancetype)
init;
23 - (instancetype)
init {
24 self = [
super initWithFrame:NSZeroRect];
26 [
self setWantsLayer:YES];
27 self.layer.contentsScale = 2.0;
32 - (void)onPresent:(CGSize)frameSize
33 withBlock:(nonnull dispatch_block_t)block
34 delay:(NSTimeInterval)delay {
35 self.presentedFrameSize = frameSize;
44 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
45 id<MTLCommandQueue> commandQueue = [device newCommandQueue];
46 CALayer* layer =
reinterpret_cast<CALayer*
>(testView.layer);
48 commandQueue:commandQueue
55 CGPoint offset = CGPointZero,
57 const std::vector<FlutterRect>& paintRegion = {}) {
71 auto surface = [surfaceManager
surfaceForSize:CGSizeMake(100, 50)];
73 id<MTLTexture> metalTexture = (__bridge id)texture.texture;
74 EXPECT_EQ(metalTexture.width, 100ul);
75 EXPECT_EQ(metalTexture.height, 50ul);
76 texture.destruction_callback(texture.user_data);
84 auto surface = [surfaceManager
surfaceForSize:CGSizeMake(100, 50)];
88 texture.destruction_callback(texture.user_data);
90 FlutterMetalTexture dummyTexture{.texture_id = 1, .texture =
nullptr, .user_data =
nullptr};
92 EXPECT_EQ(surface1, nil);
95 EXPECT_EQ(surface2, surface);
103 auto surface1 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
108 auto surface2 = [surfaceManager
surfaceForSize:CGSizeMake(110, 110)];
113 auto surface3 = [surfaceManager
surfaceForSize:CGSizeMake(120, 120)];
119 auto surfaceFromCache = [surfaceManager
surfaceForSize:CGSizeMake(110, 110)];
120 EXPECT_EQ(surfaceFromCache, surface2);
125 for (
int i = 0; i < 30 ; ++i) {
142 auto surface1 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
143 EXPECT_TRUE(CGSizeEqualToSize(surface1.size, CGSizeMake(100, 100)));
152 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
156 auto surface2 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
157 EXPECT_TRUE(CGSizeEqualToSize(surface2.size, CGSizeMake(100, 100)));
166 EXPECT_EQ(testView.layer.sublayers.count, 1ull);
169 auto surface3 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
170 EXPECT_EQ(surface3, surface1);
177 auto surface1 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
182 surface1.isInUseOverride = YES;
184 auto surface2 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
188 for (
int i = 0; i < 30 - 1; ++i) {
189 auto surface3 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
194 auto surface4 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
200 inline bool operator==(
const CGRect& lhs,
const CGRect& rhs) {
201 return CGRectEqualToRect(lhs, rhs);
208 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
210 auto surface1_1 = [surfaceManager
surfaceForSize:CGSizeMake(50, 30)];
211 [surfaceManager
presentSurfaces:@[ CreatePresentInfo(surface1_1, CGPointMake(20, 10)) ]
215 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
218 auto surface2_1 = [surfaceManager
surfaceForSize:CGSizeMake(50, 30)];
219 auto surface2_2 = [surfaceManager
surfaceForSize:CGSizeMake(20, 20)];
221 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
222 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
224 FlutterRect{0, 0, 20, 20},
225 FlutterRect{40, 0, 60, 20},
231 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
232 EXPECT_EQ(testView.layer.sublayers[0].zPosition, 1.0);
233 EXPECT_EQ(testView.layer.sublayers[1].zPosition, 2.0);
234 CALayer* firstOverlaySublayer;
236 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
237 EXPECT_EQ(sublayers.count, 2ul);
238 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
239 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
240 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].contentsRect, CGRectMake(0, 0, 1, 1)));
241 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].contentsRect, CGRectMake(2, 0, 1, 1)));
242 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
243 firstOverlaySublayer = sublayers[0];
249 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
250 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
252 FlutterRect{0, 10, 20, 20},
257 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
259 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
260 EXPECT_EQ(sublayers.count, 1ul);
261 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
262 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 5, 10, 5)));
267 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
268 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
270 FlutterRect{0, 0, 20, 20},
271 FlutterRect{40, 0, 60, 20},
277 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
279 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
280 EXPECT_EQ(sublayers.count, 2ul);
281 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
282 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
283 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
284 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
287 auto surface3_1 = [surfaceManager
surfaceForSize:CGSizeMake(50, 30)];
288 [surfaceManager
presentSurfaces:@[ CreatePresentInfo(surface3_1, CGPointMake(20, 10)) ]
292 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
297 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
FlutterMetalTexture asFlutterMetalTexture()
nullable FlutterSurface * fromFlutterMetalTexture:(nonnull const FlutterMetalTexture *texture)
nonnull FlutterSurface * surfaceForSize:(CGSize size)
FlutterBackBufferCache * backBufferCache
void presentSurfaces:atTime:notify:(nonnull NSArray< FlutterSurfacePresentInfo * > *surfaces,[atTime] CFTimeInterval presentationTime,[notify] nullable dispatch_block_t notify)
NSArray< FlutterSurface * > * frontSurfaces
std::vector< FlutterRect > paintRegion
CGSize presentedFrameSize
nonnull instancetype init()
TEST(FlutterSurfaceManager, LayerManagement)
bool operator==(const CGRect &lhs, const CGRect &rhs)
static FlutterSurfacePresentInfo * CreatePresentInfo(FlutterSurface *surface, CGPoint offset=CGPointZero, size_t index=0, const std::vector< FlutterRect > &paintRegion={})
static FlutterSurfaceManager * CreateSurfaceManager(TestView *testView)