// // TGRTCMetalContextHolder.m // TgVoipWebrtc // // Created by Mikhail Filimonov on 28.06.2021. // Copyright © 2021 Mikhail Filimonov. All rights reserved. // #import "TGRTCMetalContextHolder.h" static NSString *const vertexFunctionName = @"vertexPassthrough"; static NSString *const fragmentFunctionName = @"fragmentColorConversion"; static NSString *const fragmentDoTransformFilter = @"doTransformFilter"; static NSString *const twoInputVertexName = @"twoInputVertex"; static NSString *const transformAndBlendName = @"transformAndBlend"; static NSString *const scaleAndBlurName = @"scaleAndBlur"; static NSString *const fragmentPlainName = @"fragmentPlain"; @implementation TGRTCMetalContextHolder { id _device; id _pipelineYuvRgb; id _pipelineTransformAndBlend; id _pipelineScaleAndBlur; id _pipelineThrough; id _sampler; id _defaultLibrary; CGDirectDisplayID _displayId; } -(id __nullable)init { if(self = [super init]) { _displayId = CGMainDisplayID(); _device = CGDirectDisplayCopyCurrentMetalDevice(_displayId); _defaultLibrary = [_device newDefaultLibrary]; } if (!_device) { return nil; } _sampler = [self defaultSamplerState:_device]; [self loadPipelines]; return self; } - (id)defaultSamplerState:(id)device { MTLSamplerDescriptor *samplerDescriptor = [[MTLSamplerDescriptor alloc] init]; samplerDescriptor.minFilter = MTLSamplerMinMagFilterLinear; samplerDescriptor.magFilter = MTLSamplerMinMagFilterLinear; samplerDescriptor.sAddressMode = MTLSamplerAddressModeClampToZero; samplerDescriptor.tAddressMode = MTLSamplerAddressModeClampToZero; return [device newSamplerStateWithDescriptor:samplerDescriptor]; } - (void)loadPipelines { { id vertexFunction = [_defaultLibrary newFunctionWithName:vertexFunctionName]; id fragmentFunction = [_defaultLibrary newFunctionWithName:fragmentFunctionName]; MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineDescriptor.vertexFunction = vertexFunction; pipelineDescriptor.fragmentFunction = fragmentFunction; pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormatInvalid; NSError *error = nil; _pipelineYuvRgb = [_device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error]; } { id vertexFunction = [_defaultLibrary newFunctionWithName:vertexFunctionName]; id fragmentFunction = [_defaultLibrary newFunctionWithName:fragmentPlainName]; MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineDescriptor.vertexFunction = vertexFunction; pipelineDescriptor.fragmentFunction = fragmentFunction; pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormatInvalid; NSError *error = nil; _pipelineThrough = [_device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error]; } { id vertexFunction = [_defaultLibrary newFunctionWithName:twoInputVertexName]; id fragmentFunction = [_defaultLibrary newFunctionWithName:transformAndBlendName]; MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineDescriptor.vertexFunction = vertexFunction; pipelineDescriptor.fragmentFunction = fragmentFunction; pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormatInvalid; NSError *error = nil; _pipelineTransformAndBlend = [_device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error]; } { id vertexFunction = [_defaultLibrary newFunctionWithName:vertexFunctionName]; id fragmentFunction = [_defaultLibrary newFunctionWithName:scaleAndBlurName]; MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipelineDescriptor.vertexFunction = vertexFunction; pipelineDescriptor.fragmentFunction = fragmentFunction; pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormatInvalid; NSError *error = nil; _pipelineScaleAndBlur = [_device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error]; } } -(id)device { return _device; } -(id)pipelineYuvRgb { return _pipelineYuvRgb; } -(id)pipelineTransformAndBlend { return _pipelineTransformAndBlend; } -(id)pipelineScaleAndBlur { return _pipelineScaleAndBlur; } -(id)pipelineThrough { return _pipelineThrough; } -(id)sampler { return _sampler; } -(CGDirectDisplayID)displayId { return _displayId; } @end