iosswiftrenderingglkview

Core Image slow rendering


I created test application with ViewController, GLKView and UISlider. Slider change value in selected filter. Rendering image very slow. What's wrong with my code?

Test class of GLKview:

import UIKit
import CoreImage
import GLKit

class CustomGLView: GLKView {
    //test filters 
    let clampFilter = CIFilter(name: "CIAffineClamp")!
    let blurFilter = CIFilter(name: "CIGaussianBlur")!
    let ciContext:CIContext

    override init(frame: CGRect) {
        let glContext = EAGLContext(api: .openGLES2)
        ciContext = CIContext(
            eaglContext: glContext!,
            options: [
                kCIContextWorkingColorSpace: NSNull()
            ]
        )
        super.init(frame: frame, context: glContext!)
        enableSetNeedsDisplay = true
    }

    required init(coder aDecoder: NSCoder) {
        let glContext = EAGLContext(api: .openGLES2)
        ciContext = CIContext(
            eaglContext: glContext!,
            options: [
                kCIContextWorkingColorSpace: NSNull()
            ]
        )
        super.init(coder: aDecoder)!
        context = glContext!
        enableSetNeedsDisplay = true
    }

      var inputImage: UIImage? {
        didSet {
            inputCIImage = inputImage.map { CIImage(image: $0)! }
        }
    }

     var blurRadius: Float = 0 {
        didSet {
            blurFilter.setValue(blurRadius, forKey: "inputRadius")
            setNeedsDisplay()
        }
    }

    var inputCIImage: CIImage? {
        didSet { setNeedsDisplay() }
    }

    override func draw(_ rect: CGRect) {
        if let inputCIImage = inputCIImage {
            clampFilter.setValue(inputCIImage, forKey: kCIInputImageKey)
            blurFilter.setValue(clampFilter.outputImage!, forKey: kCIInputImageKey)
            let rect = CGRect(x: 0, y: 0, width: drawableWidth, height: drawableHeight)
            ciContext.draw(blurFilter.outputImage!, in: rect, from: inputCIImage.extent)
        }
    } 
}

How I change value in CIFilter:

import UIKit
import GLKit
import CoreImage

    class ViewController: UIViewController {
        //image
         let imageOriginal = UIImage(named: "pic_2")
         //my GLKView
        @IBOutlet weak var glView: CustomGLView!

        override func viewDidLoad() {
                super.viewDidLoad()
                //test image
                self.glView.inputImage = self.imageOriginal

            }

        @IBAction func mySlider(_ sender: UISlider) {

                self.glView.blurRadius = sender.value
            }
    }

Solution

  • Creating a CIImage from UIImage may require extra time to copy the image data from memory to GPU memory. Try loading your image into a GPU texture and then creating a CIImage backed by this texture using CIImage(texture:size:flipped:colorSpace:)

    Make sure you're only creating the texture once, not at the start of every draw(_:).

    You could also try: