7 #import <Metal/Metal.h>
8 #import <OCMock/OCMock.h>
9 #import <QuartzCore/QuartzCore.h>
10 #import <XCTest/XCTest.h>
12 #import "flutter/shell/platform/darwin/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
48 - (void)commitTransaction {
49 IOSurfaceRef surface = (__bridge IOSurfaceRef)
self->_layer.contents;
50 if (
self->_presentedSurface) {
51 IOSurfaceDecrementUseCount(
self->_presentedSurface);
53 IOSurfaceIncrementUseCount(surface);
54 self->_presentedSurface = surface;
58 if (
self->_presentedSurface) {
59 IOSurfaceDecrementUseCount(
self->_presentedSurface);
80 #define BAIL_IF_NO_DRAWABLE(drawable) \
81 if (drawable == nil) { \
82 [FlutterLogger logError:@"Could not allocate drawable"]; \
90 id<MTLTexture> t1, t2, t3;
94 t1 = drawable.texture;
96 [compositor commitTransaction];
100 t2 = drawable.texture;
102 [compositor commitTransaction];
106 t3 = drawable.texture;
108 [compositor commitTransaction];
114 XCTAssertEqual(drawable.texture, t1);
117 [compositor commitTransaction];
120 XCTAssertEqual(drawable.texture, t2);
122 [compositor commitTransaction];
125 XCTAssertEqual(drawable.texture, t3);
127 [compositor commitTransaction];
130 XCTAssertEqual(drawable.texture, t1);
133 [
self removeMetalLayer:layer];
136 - (void)testFlipWithDroppedFrame {
140 id<MTLTexture> t1, t2, t3;
144 t1 = drawable.texture;
146 [compositor commitTransaction];
147 XCTAssertTrue(IOSurfaceIsInUse(t1.iosurface));
151 t2 = drawable.texture;
153 [compositor commitTransaction];
157 t3 = drawable.texture;
159 [compositor commitTransaction];
162 IOSurfaceIncrementUseCount(t3.iosurface);
168 XCTAssertEqual(drawable.texture, t1);
169 XCTAssertFalse(IOSurfaceIsInUse(drawable.texture.iosurface));
173 XCTAssertEqual(drawable.texture, t2);
175 [compositor commitTransaction];
179 XCTAssertEqual(drawable.texture, t1);
181 IOSurfaceDecrementUseCount(t3.iosurface);
183 [
self removeMetalLayer:layer];
186 - (void)testDroppedDrawableReturnsTextureToPool {
190 for (
int i = 0; i < 3; ++i) {
195 id<MTLTexture> texture;
199 XCTAssertNotNil(drawable);
200 texture = drawable.texture;
207 XCTAssertEqual(texture, drawable.texture);
210 [
self removeMetalLayer:layer];
213 - (void)testLayerLimitsDrawableCount {
238 [
self removeMetalLayer:layer];
241 - (void)testTimeout {
248 __block MTLCommandBufferHandler handler;
250 id<MTLCommandBuffer> mockCommandBuffer = OCMProtocolMock(
@protocol(MTLCommandBuffer));
251 OCMStub([mockCommandBuffer addCompletedHandler:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
252 MTLCommandBufferHandler handlerOnStack;
253 [invocation getArgument:&handlerOnStack atIndex:2];
255 handler = handlerOnStack;
260 [compositor commitTransaction];
264 XCTAssertNil(drawable);
266 handler(mockCommandBuffer);
269 XCTAssertNotNil(drawable);
271 [
self removeMetalLayer:layer];
274 - (void)testDealloc {
284 [compositor commitTransaction];
286 [
self removeMetalLayer:layer];
288 CFTimeInterval start = CACurrentMediaTime();
289 while (weakLayer != nil && CACurrentMediaTime() - start < 1) {
291 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, YES);
294 XCTAssertNil(weakLayer);
FlutterMetalLayer * _layer
IOSurfaceRef _presentedSurface