blob: bd6bf4d57b58b345ded11185108d60422217f59f [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Foundation/Foundation.h>
#import <Metal/Metal.h>
#import <OCMock/OCMock.h>
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
#import "flutter/testing/testing.h"
@interface FlutterViewMockProvider : NSObject <FlutterViewProvider> {
FlutterView* _defaultView;
}
/**
* Create a FlutterViewMockProvider with the provided view as the default view.
*/
- (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view;
@end
@implementation FlutterViewMockProvider
- (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view {
self = [super init];
if (self != nil) {
_defaultView = view;
}
return self;
}
- (nullable FlutterView*)getView:(uint64_t)viewId {
if (viewId == kFlutterDefaultViewId) {
return _defaultView;
}
return nil;
}
@end
namespace flutter::testing {
namespace {
typedef void (^PresentBlock)(NSArray<FlutterSurfacePresentInfo*>*);
id<FlutterViewProvider> MockViewProvider(PresentBlock onPresent = nil) {
FlutterView* viewMock = OCMClassMock([FlutterView class]);
FlutterSurfaceManager* surfaceManagerMock = OCMClassMock([FlutterSurfaceManager class]);
FlutterSurface* surfaceMock = OCMClassMock([FlutterSurface class]);
__block id<MTLTexture> textureMock = OCMProtocolMock(@protocol(MTLTexture));
OCMStub([viewMock surfaceManager]).andReturn(surfaceManagerMock);
OCMStub([surfaceManagerMock surfaceForSize:CGSize{}])
.ignoringNonObjectArgs()
.andDo(^(NSInvocation* invocation) {
CGSize size;
[invocation getArgument:&size atIndex:2];
OCMStub([textureMock width]).andReturn(size.width);
OCMStub([textureMock height]).andReturn(size.height);
})
.andReturn(surfaceMock);
FlutterMetalTexture texture = {
.struct_size = sizeof(FlutterMetalTexture),
.texture_id = 1,
.texture = (__bridge void*)textureMock,
.user_data = (__bridge void*)surfaceMock,
.destruction_callback = nullptr,
};
OCMStub([surfaceManagerMock present:[OCMArg any] notify:[OCMArg any]])
.andDo(^(NSInvocation* invocation) {
NSArray<FlutterSurfacePresentInfo*>* info;
[invocation getArgument:&info atIndex:2];
if (onPresent != nil) {
onPresent(info);
}
});
OCMStub([surfaceMock asFlutterMetalTexture]).andReturn(texture);
return [[FlutterViewMockProvider alloc] initWithDefaultView:viewMock];
}
} // namespace
TEST(FlutterCompositorTest, TestCreate) {
std::unique_ptr<flutter::FlutterCompositor> macos_compositor =
std::make_unique<FlutterCompositor>(MockViewProvider(),
/*platform_view_controller*/ nullptr);
FlutterBackingStore backing_store;
FlutterBackingStoreConfig config;
config.struct_size = sizeof(FlutterBackingStoreConfig);
config.size.width = 800;
config.size.height = 600;
macos_compositor->CreateBackingStore(&config, &backing_store);
ASSERT_EQ(backing_store.type, kFlutterBackingStoreTypeMetal);
ASSERT_NE(backing_store.metal.texture.texture, nil);
id<MTLTexture> texture = (__bridge id<MTLTexture>)backing_store.metal.texture.texture;
ASSERT_EQ(texture.width, 800ul);
ASSERT_EQ(texture.height, 600ul);
}
TEST(FlutterCompositorTest, TestPresent) {
__block NSArray<FlutterSurfacePresentInfo*>* presentedSurfaces = nil;
auto onPresent = ^(NSArray<FlutterSurfacePresentInfo*>* info) {
presentedSurfaces = info;
};
std::unique_ptr<flutter::FlutterCompositor> macos_compositor =
std::make_unique<FlutterCompositor>(MockViewProvider(onPresent),
/*platform_view_controller*/ nullptr);
FlutterBackingStore backing_store;
FlutterBackingStoreConfig config;
config.struct_size = sizeof(FlutterBackingStoreConfig);
config.size.width = 800;
config.size.height = 600;
macos_compositor->CreateBackingStore(&config, &backing_store);
FlutterLayer layers[] = {{
.struct_size = sizeof(FlutterLayer),
.type = kFlutterLayerContentTypeBackingStore,
.backing_store = &backing_store,
.offset = {0, 0},
.size = {800, 600},
}};
const FlutterLayer* layers_ptr = layers;
macos_compositor->Present(kFlutterDefaultViewId, &layers_ptr, 1);
ASSERT_EQ(presentedSurfaces.count, 1ul);
}
} // namespace flutter::testing