Swiftgram/submodules/TelegramUI/Components/MediaEditor/Sources/StickerOutlineRenderPass.swift
2024-04-06 15:01:03 +04:00

63 lines
2.3 KiB
Swift

import Foundation
import Metal
import simd
import CoreImage
final class StickerOutlineRenderPass: RenderPass {
var value: simd_float1 = 0.0
var context: CIContext?
var maskFilter: CIFilter?
private var outputTexture: MTLTexture?
func setup(device: MTLDevice, library: MTLLibrary) {
self.context = CIContext(mtlDevice: device, options: [.workingColorSpace : CGColorSpaceCreateDeviceRGB()])
}
func process(input: MTLTexture, device: MTLDevice, commandBuffer: MTLCommandBuffer) -> MTLTexture? {
guard self.value > 0.005, let context = self.context else {
return input
}
if self.maskFilter == nil {
self.maskFilter = CIFilter(name: "CIMorphologyMaximum")
}
if self.outputTexture == nil {
let textureDescriptor = MTLTextureDescriptor()
textureDescriptor.textureType = .type2D
textureDescriptor.width = input.width
textureDescriptor.height = input.height
textureDescriptor.pixelFormat = input.pixelFormat
textureDescriptor.storageMode = .private
textureDescriptor.usage = [.shaderRead, .shaderWrite, .renderTarget]
guard let texture = device.makeTexture(descriptor: textureDescriptor) else {
return nil
}
self.outputTexture = texture
texture.label = "outlineOutputTexture"
}
guard let maskFilter = self.maskFilter, let image = CIImage(mtlTexture: input) else {
return input
}
maskFilter.setValue(self.value * 30, forKey: kCIInputRadiusKey)
maskFilter.setValue(image, forKey: kCIInputImageKey)
guard let eroded = maskFilter.outputImage, let outputTexture = self.outputTexture else {
return input
}
if #available(iOS 13.0, *) {
let colorized = CIBlendKernel.sourceAtop.apply(foreground: .white, background: eroded)!.cropped(to: eroded.extent)
let resultImage = image.composited(over: colorized)
let renderDestination = CIRenderDestination(mtlTexture: outputTexture, commandBuffer: commandBuffer)
_ = try? context.startTask(toRender: resultImage, to: renderDestination)
return outputTexture
} else {
return input
}
}
}