iosopengl-es-2.0metalmetalkitmtkview

MTKView clear display


I want to set the contents of MTKView (or GLKView/CAEAGLLayer) to black as soon just as the application resigns active. What is the quickest and most reliable way to set it to it's clear color(say black) and display it?


Solution

  • In order to blank a MTKView upon entering the background, you must render a blank frame before returning from the delegate callback to the applicationDidEnterBackground(_:) method on your UIApplicationDelegate object.

    It is not sufficient to listen for the UIApplication.didEnterBackgroundNotification; snapshots are captured before notification observers are notified of the state change.

    This implies that you should pass the message that your application has entered the background down from your app delegate to the relevant view controller(s), and force them to immediately render a blank frame, before returning from the delegate method (meaning no posting notifications, and no dispatching async to different threads). Here's a method that clears a MTKView to black and waits for the drawing and presentation to be scheduled before returning:

    func drawBlankAndWait(_ mtkView: MTKView) {
        mtkView.clearColor = MTLClearColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
        let commandBuffer = commandQueue.makeCommandBuffer()!
        guard let renderPassDescriptor = mtkView.currentRenderPassDescriptor else { return }
        let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)!
        renderEncoder.endEncoding()
        let drawable = mtkView.currentDrawable!
        commandBuffer.present(drawable)
        commandBuffer.commit()
        commandBuffer.waitUntilScheduled()
    }
    

    Upon receiving an applicationWillEnterForeground(_:) call, you can restore any state you might have set when entering the background, including the view's paused state.