5 #import <Metal/Metal.h>
6 #import <OCMock/OCMock.h>
7 #import <QuartzCore/QuartzCore.h>
8 #import <XCTest/XCTest.h>
10 #include "flutter/fml/logging.h"
47 - (void)commitTransaction {
48 IOSurfaceRef surface = (__bridge IOSurfaceRef)
self->_layer.contents;
49 if (
self->_presentedSurface) {
50 IOSurfaceDecrementUseCount(
self->_presentedSurface);
52 IOSurfaceIncrementUseCount(surface);
53 self->_presentedSurface = surface;
57 if (
self->_presentedSurface) {
58 IOSurfaceDecrementUseCount(
self->_presentedSurface);
79 #define BAIL_IF_NO_DRAWABLE(drawable) \
80 if (drawable == nil) { \
81 FML_LOG(ERROR) << "Could not allocate drawable"; \
89 id<MTLTexture> t1, t2, t3;
93 t1 = drawable.texture;
95 [compositor commitTransaction];
99 t2 = drawable.texture;
101 [compositor commitTransaction];
105 t3 = drawable.texture;
107 [compositor commitTransaction];
113 XCTAssertEqual(drawable.texture, t1);
116 [compositor commitTransaction];
119 XCTAssertEqual(drawable.texture, t2);
121 [compositor commitTransaction];
124 XCTAssertEqual(drawable.texture, t3);
126 [compositor commitTransaction];
129 XCTAssertEqual(drawable.texture, t1);
132 [
self removeMetalLayer:layer];
135 - (void)testFlipWithDroppedFrame {
139 id<MTLTexture> t1, t2, t3;
143 t1 = drawable.texture;
145 [compositor commitTransaction];
146 XCTAssertTrue(IOSurfaceIsInUse(t1.iosurface));
150 t2 = drawable.texture;
152 [compositor commitTransaction];
156 t3 = drawable.texture;
158 [compositor commitTransaction];
161 IOSurfaceIncrementUseCount(t3.iosurface);
167 XCTAssertEqual(drawable.texture, t1);
168 XCTAssertFalse(IOSurfaceIsInUse(drawable.texture.iosurface));
172 XCTAssertEqual(drawable.texture, t2);
174 [compositor commitTransaction];
178 XCTAssertEqual(drawable.texture, t1);
180 IOSurfaceDecrementUseCount(t3.iosurface);
182 [
self removeMetalLayer:layer];
185 - (void)testDroppedDrawableReturnsTextureToPool {
189 for (
int i = 0; i < 3; ++i) {
194 id<MTLTexture> texture;
198 XCTAssertNotNil(drawable);
199 texture = (id<MTLTexture>)drawable.texture;
206 XCTAssertEqual(texture, drawable.texture);
209 [
self removeMetalLayer:layer];
212 - (void)testLayerLimitsDrawableCount {
237 [
self removeMetalLayer:layer];
240 - (void)testTimeout {
247 __block MTLCommandBufferHandler handler;
249 id<MTLCommandBuffer> mockCommandBuffer = OCMProtocolMock(
@protocol(MTLCommandBuffer));
250 OCMStub([mockCommandBuffer addCompletedHandler:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
251 MTLCommandBufferHandler handlerOnStack;
252 [invocation getArgument:&handlerOnStack atIndex:2];
254 handler = handlerOnStack;
259 [compositor commitTransaction];
263 XCTAssertNil(drawable);
265 handler(mockCommandBuffer);
268 XCTAssertNotNil(drawable);
270 [
self removeMetalLayer:layer];
273 - (void)testDealloc {
283 [compositor commitTransaction];
285 [
self removeMetalLayer:layer];
287 CFTimeInterval start = CACurrentMediaTime();
288 while (weakLayer != nil && CACurrentMediaTime() - start < 1) {
290 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, YES);
293 XCTAssertNil(weakLayer);