Created
December 16, 2019 19:36
-
-
Save standinga/1608d4ea6bbc331886f95511a50d376d to your computer and use it in GitHub Desktop.
MTKView sometimes crashes when drawing CVImageBuffer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AppKit | |
import AVFoundation | |
import MetalKit | |
class PlayerView: MTKView { | |
private var ciImage: CIImage? { | |
didSet { | |
renderImage() | |
} | |
} | |
private lazy var commandQueue: MTLCommandQueue? = { [unowned self] in | |
return self.device!.makeCommandQueue() | |
}() | |
private lazy var ciContext: CIContext = { [unowned self] in | |
return CIContext(mtlDevice: self.device!) | |
}() | |
override init(frame frameRect: CGRect, device: MTLDevice?) { | |
super.init(frame: frameRect, device:device) | |
if super.device == nil { | |
fatalError("No metal") | |
} | |
framebufferOnly = false | |
} | |
required init(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
// sometimes crashes | |
func renderImage() { | |
if let currentDrawable = currentDrawable { // crashes here sometimes | |
guard let ciImage = ciImage else { return } | |
let commandBuffer = commandQueue?.makeCommandBuffer() | |
let renderDestination = CIRenderDestination(mtlTexture: currentDrawable.texture, commandBuffer: commandBuffer) | |
_ = try? ciContext.startTask(toRender: ciImage, to: renderDestination) | |
commandBuffer?.present(currentDrawable) | |
commandBuffer?.commit() | |
draw() | |
} | |
} | |
// this seems to work | |
func renderImage1() { | |
guard let currentDrawable = (layer as? CAMetalLayer)?.nextDrawable() else { return } | |
guard let ciImage = ciImage else { return } | |
let commandBuffer = commandQueue?.makeCommandBuffer() | |
let renderDestination = CIRenderDestination(mtlTexture: currentDrawable.texture, commandBuffer: commandBuffer) | |
_ = try? ciContext.startTask(toRender: ciImage, to: renderDestination) | |
commandBuffer?.present(currentDrawable) | |
commandBuffer?.commit() | |
} | |
func renderPixelBuffer(_ pixelBuffer: CVImageBuffer) { | |
ciImage = CIImage(cvImageBuffer: pixelBuffer) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment