7 #import <Metal/Metal.h>
27 return reinterpret_cast<int64_t
>(
_texture);
30 - (instancetype)initWithSize:(CGSize)size device:(
id<MTLDevice>)device {
31 if (
self = [super init]) {
34 self->_texture = [
FlutterSurface createTextureForIOSurface:_ioSurface size:size device:device];
39 static void ReleaseSurface(
void* surface) {
40 if (surface !=
nullptr) {
41 CFBridgingRelease(surface);
46 FlutterMetalTexture res;
47 memset(&res, 0,
sizeof(FlutterMetalTexture));
48 res.struct_size =
sizeof(FlutterMetalTexture);
49 res.texture = (__bridge
void*)
_texture;
50 res.texture_id =
self.textureId;
51 res.user_data = (
void*)CFBridgingRetain(
self);
52 res.destruction_callback = ReleaseSurface;
56 + (
FlutterSurface*)fromFlutterMetalTexture:(const FlutterMetalTexture*)texture {
61 CFRelease(_ioSurface);
64 + (IOSurfaceRef)createIOSurfaceWithSize:(CGSize)size {
65 unsigned pixelFormat =
'BGRA';
66 unsigned bytesPerElement = 4;
68 size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow,
size.width * bytesPerElement);
69 size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize,
size.height * bytesPerRow);
70 NSDictionary* options = @{
71 (id)kIOSurfaceWidth : @(
size.width),
72 (id)kIOSurfaceHeight : @(
size.height),
73 (id)kIOSurfacePixelFormat : @(pixelFormat),
74 (id)kIOSurfaceBytesPerElement : @(bytesPerElement),
75 (id)kIOSurfaceBytesPerRow : @(bytesPerRow),
76 (id)kIOSurfaceAllocSize : @(totalBytes),
79 IOSurfaceRef res = IOSurfaceCreate((CFDictionaryRef)options);
80 IOSurfaceSetValue(res, CFSTR(
"IOSurfaceColorSpace"), kCGColorSpaceSRGB);
84 + (id<MTLTexture>)createTextureForIOSurface:(IOSurfaceRef)surface
86 device:(
id<MTLDevice>)device {
87 MTLTextureDescriptor* textureDescriptor =
88 [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
92 textureDescriptor.usage =
93 MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite;
95 return [device newTextureWithDescriptor:textureDescriptor iosurface:surface plane:0];