62 lines
1.9 KiB
Swift

import Foundation
import AVFoundation
import Metal
import MetalKit
import Display
final class ImageTextureSource: TextureSource {
weak var output: TextureConsumer?
var textureLoader: MTKTextureLoader?
var texture: MTLTexture?
init(image: UIImage, renderTarget: RenderTarget) {
guard let device = renderTarget.mtlDevice, var cgImage = image.cgImage else {
return
}
let textureLoader = MTKTextureLoader(device: device)
self.textureLoader = textureLoader
if let bitsPerPixel = image.cgImage?.bitsPerPixel, bitsPerPixel > 32 {
let updatedImage = generateImage(image.size, contextGenerator: { size, context in
context.setFillColor(UIColor.black.cgColor)
context.fill(CGRect(origin: .zero, size: size))
context.draw(cgImage, in: CGRect(origin: .zero, size: size))
}, opaque: false)
cgImage = updatedImage?.cgImage ?? cgImage
}
self.texture = try? textureLoader.newTexture(cgImage: cgImage, options: [.SRGB : false])
}
func start() {
}
func pause() {
}
func connect(to consumer: TextureConsumer) {
self.output = consumer
if let texture = self.texture {
self.output?.consumeTexture(texture, rotation: .rotate0Degrees)
}
}
}
func pixelBufferToMTLTexture(pixelBuffer: CVPixelBuffer, textureCache: CVMetalTextureCache) -> MTLTexture? {
let width = CVPixelBufferGetWidth(pixelBuffer)
let height = CVPixelBufferGetHeight(pixelBuffer)
let format: MTLPixelFormat = .r8Unorm
var textureRef : CVMetalTexture?
let status = CVMetalTextureCacheCreateTextureFromImage(nil, textureCache, pixelBuffer, nil, format, width, height, 0, &textureRef)
if status == kCVReturnSuccess {
return CVMetalTextureGetTexture(textureRef!)
}
return nil
}