5 #import <Cocoa/Cocoa.h>
6 #import <Metal/Metal.h>
7 #import <OCMock/OCMock.h>
12 #include "flutter/testing/testing.h"
13 #include "gtest/gtest.h"
18 - (nonnull instancetype)
init;
25 self = [
super initWithFrame:NSZeroRect];
27 [
self setWantsLayer:YES];
28 self.layer.contentsScale = 2.0;
33 - (void)onPresent:(CGSize)frameSize withBlock:(nonnull dispatch_block_t)block {
34 self.presentedFrameSize = frameSize;
43 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
44 id<MTLCommandQueue> commandQueue = [device newCommandQueue];
45 CALayer* layer =
reinterpret_cast<CALayer*
>(testView.layer);
47 commandQueue:commandQueue
54 CGPoint offset = CGPointZero,
56 const std::vector<FlutterRect>& paintRegion = {}) {
70 auto surface = [surfaceManager
surfaceForSize:CGSizeMake(100, 50)];
72 id<MTLTexture> metalTexture = (__bridge id)texture.texture;
73 EXPECT_EQ(metalTexture.width, 100ul);
74 EXPECT_EQ(metalTexture.height, 50ul);
75 texture.destruction_callback(texture.user_data);
83 auto surface = [surfaceManager
surfaceForSize:CGSizeMake(100, 50)];
87 texture.destruction_callback(texture.user_data);
89 FlutterMetalTexture dummyTexture{.texture_id = 1, .texture =
nullptr, .user_data =
nullptr};
91 EXPECT_EQ(surface1, nil);
94 EXPECT_EQ(surface2, surface);
102 auto surface1 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
103 [surfaceManager
present:@[ CreatePresentInfo(surface1) ]
notify:nil];
107 auto surface2 = [surfaceManager
surfaceForSize:CGSizeMake(110, 110)];
108 [surfaceManager
present:@[ CreatePresentInfo(surface2) ]
notify:nil];
112 auto surface3 = [surfaceManager
surfaceForSize:CGSizeMake(120, 120)];
113 [surfaceManager
present:@[ CreatePresentInfo(surface3) ]
notify:nil];
118 auto surfaceFromCache = [surfaceManager
surfaceForSize:CGSizeMake(110, 110)];
119 EXPECT_EQ(surfaceFromCache, surface2);
136 auto surface1 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
137 EXPECT_TRUE(CGSizeEqualToSize(surface1.size, CGSizeMake(100, 100)));
142 [surfaceManager
present:@[ CreatePresentInfo(surface1) ]
notify:nil];
146 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
150 auto surface2 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
151 EXPECT_TRUE(CGSizeEqualToSize(surface2.size, CGSizeMake(100, 100)));
155 [surfaceManager
present:@[ CreatePresentInfo(surface2) ]
notify:nil];
160 EXPECT_EQ(testView.layer.sublayers.count, 1ull);
163 auto surface3 = [surfaceManager
surfaceForSize:CGSizeMake(100, 100)];
164 EXPECT_EQ(surface3, surface1);
167 inline bool operator==(
const CGRect& lhs,
const CGRect& rhs) {
168 return CGRectEqualToRect(lhs, rhs);
175 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
177 auto surface1_1 = [surfaceManager
surfaceForSize:CGSizeMake(50, 30)];
178 [surfaceManager
present:@[ CreatePresentInfo(surface1_1, CGPointMake(20, 10)) ]
notify:nil];
180 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
183 auto surface2_1 = [surfaceManager
surfaceForSize:CGSizeMake(50, 30)];
184 auto surface2_2 = [surfaceManager
surfaceForSize:CGSizeMake(20, 20)];
186 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
187 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
189 FlutterRect{0, 0, 20, 20},
190 FlutterRect{40, 0, 60, 20},
195 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
196 EXPECT_EQ(testView.layer.sublayers[0].zPosition, 1.0);
197 EXPECT_EQ(testView.layer.sublayers[1].zPosition, 2.0);
198 CALayer* firstOverlaySublayer;
200 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
201 EXPECT_EQ(sublayers.count, 2ul);
202 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
203 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
204 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].contentsRect, CGRectMake(0, 0, 1, 1)));
205 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].contentsRect, CGRectMake(2, 0, 1, 1)));
206 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
207 firstOverlaySublayer = sublayers[0];
213 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
214 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
216 FlutterRect{0, 10, 20, 20},
220 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
222 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
223 EXPECT_EQ(sublayers.count, 1ul);
224 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
225 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 5, 10, 5)));
230 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
231 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
233 FlutterRect{0, 0, 20, 20},
234 FlutterRect{40, 0, 60, 20},
239 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
241 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
242 EXPECT_EQ(sublayers.count, 2ul);
243 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
244 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
245 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
246 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
249 auto surface3_1 = [surfaceManager
surfaceForSize:CGSizeMake(50, 30)];
250 [surfaceManager
present:@[ CreatePresentInfo(surface3_1, CGPointMake(20, 10)) ]
notify:nil];
252 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
257 EXPECT_EQ(testView.layer.sublayers.count, 0ul);