7 #import <CoreMedia/CoreMedia.h>
8 #import <Metal/Metal.h>
10 #import "flutter/fml/platform/darwin/cf_utils.h"
32 return reinterpret_cast<int64_t
>(
_texture);
36 return _isInUseOverride || IOSurfaceIsInUse(_ioSurface);
40 return _isInUseOverride;
43 - (void)setIsInUseOverride:(BOOL)isInUseOverride {
47 - (instancetype)initWithSize:(CGSize)size device:(
id<MTLDevice>)device {
48 if (
self = [super init]) {
51 self->_texture = [
FlutterSurface createTextureForIOSurface:_ioSurface size:size device:device];
57 return FlutterMetalTexture{
58 .struct_size =
sizeof(FlutterMetalTexture),
63 .user_data = (__bridge_retained
void*)
self,
64 .destruction_callback =
73 + (
FlutterSurface*)fromFlutterMetalTexture:(const FlutterMetalTexture*)texture {
77 + (IOSurfaceRef)createIOSurfaceWithSize:(CGSize)size {
78 unsigned pixelFormat = kCVPixelFormatType_32BGRA;
79 unsigned bytesPerElement = 4;
81 size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow,
size.width * bytesPerElement);
82 size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize,
size.height * bytesPerRow);
83 NSDictionary* options = @{
84 (id)kIOSurfaceWidth : @(
size.width),
85 (id)kIOSurfaceHeight : @(
size.height),
86 (id)kIOSurfacePixelFormat : @(pixelFormat),
87 (id)kIOSurfaceBytesPerElement : @(bytesPerElement),
88 (id)kIOSurfaceBytesPerRow : @(bytesPerRow),
89 (id)kIOSurfaceAllocSize : @(totalBytes),
92 IOSurfaceRef res = IOSurfaceCreate((CFDictionaryRef)options);
93 IOSurfaceSetValue(res, kIOSurfaceColorSpace, kCGColorSpaceSRGB);
97 + (id<MTLTexture>)createTextureForIOSurface:(IOSurfaceRef)surface
99 device:(
id<MTLDevice>)device {
100 MTLTextureDescriptor* textureDescriptor =
101 [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
105 textureDescriptor.usage =
106 MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite;
108 return [device newTextureWithDescriptor:textureDescriptor iosurface:surface plane:0];