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);
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) {
199 XCTAssertNotNil(drawable);
207 XCTAssertEqual(
texture, drawable.texture);
210 [
self removeMetalLayer:layer];
213- (void)testLayerLimitsDrawableCount {
238 [
self removeMetalLayer:layer];
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];
258 [(id<FlutterMetalDrawable>)drawable flutterPrepareForPresent:mockCommandBuffer];
260 [compositor commitTransaction];
264 XCTAssertNil(drawable);
269 XCTAssertNotNil(drawable);
271 [
self removeMetalLayer:layer];
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);
297- (void)testResizeAndPresent {
301 id<CAMetalDrawable> oldSizeDrawable1 = [layer
nextDrawable];
303 id<CAMetalDrawable> oldSizeDrawable2 = [layer
nextDrawable];
306 const CGFloat newSize = 200;
310 [oldSizeDrawable1 present];
311 [compositor commitTransaction];
312 [oldSizeDrawable2 present];
313 [compositor commitTransaction];
316 for (
int i = 0;
i < 4;
i++) {
319 [compositor commitTransaction];
320 XCTAssertEqual(drawable.texture.width, newSize);
323 [
self removeMetalLayer:layer];
const gchar FlBinaryMessengerMessageHandler handler
FlutterMetalLayer * _layer
IOSurfaceRef _presentedSurface