Group Group Group Group Group Group Group Group Group

Core Image: From CIImage to Metal and Beyond · Display Video Frames with Metal | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/5428948-core-image-from-ciimage-to-metal-and-beyond/lessons/17

Hey! I’m getting random BAD_ACCESS, After adding Exception breakpoint and allowing Zombie Objects, it points to:

func renderImage() {
        guard let ciImage = ciImage else { return }
        let commandBuffer = commandQueue?.makeCommandBuffer()
        // I tried to retain the currentDrawable, but it doesn't help
        if let currentDrawable = currentDrawable {
            let renderDestination = CIRenderDestination(
                width: Int(drawableSize.width),
                height: Int(drawableSize.height),
                pixelFormat: .rgba8Unorm,
                commandBuffer: commandBuffer) { ()-> MTLTexture in
                    // random crash here: [CAMetalDrawable presentScheduledInsertSeedValid]: message sent to deallocated instance 0x604001bac950, the address is of currentDrawable...
                    
                    return currentDrawable.texture
            }
            try! ciContext.startTask(toRender: ciImage, to: renderDestination)
            
            commandBuffer?.present(currentDrawable)
            commandBuffer?.commit()
            draw()
        } 
    }

I tried retaining currentDrawable by if let currentDrawable = currentDrawable, but it doesn’t help.

I’ve read the documentation and it seems the problem was with currentDrawable which can be nil during the drawing. My solution (not crashing) is:

func renderImage() {
        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()
    }
1 Like

Hi @standinga

Nice work on debugging that, and thanks for explaining it for future people who come across this problem. I’m not 100% why that happens—but your solution looks great.

Thanks again for helping the community out with these posts! :heart:

sam