我使用CoreImageHelpers作为使用Metal通过相机显示实时滤波输出的基础。问题是,当我希望Metal比更新UIImageView甚至OpenGL要好得多时,我意外地获得了很高的电池冲击力。
更新:使用my forked version进行测试,或
在测试原始项目之前,请务必更新以下内容:
- 在ImageView.swift中,必须在commandBuffer.commit()之后调用draw()
-wrap DispatchQueue.main.async围绕captureOutput中的connection.videoOrientation:
DispatchQueue.main.async{
connection.videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!
}
我在iPhone 6s Plus上进行测试,当在Debug Navigator中查看时,一个CICMYKHalftone效果会将电池冲击力提升到最高。
我认为使用这种金属视图可以极大地帮助提高性能,但即使以25-30 fps的较低帧速率运行,它似乎也没有。
是否有任何重要的缺失会使电池使用效果更好像其他现场相机效果应用程序?
更新:
我添加的另一个性能更新是对于preferredFramesPerSecond的MTKView设置,我将其设置为30,因为默认情况下它将每秒调用60次。我将其与较低的设备帧速率相结合,以实现更好的性能和更少的电池影响。
首先,由于您手动驱动绘图(通过调用draw()
),您应该将视图的isPaused
属性设置为true。如果你不这样做,那么当你调用它并在内部计时器上时,视图就会自动绘制。
其次,renderImage()
和draw()
之间的关系是倒置的。 image
didSet
观察员不应该叫renderImage()
。它应该调用draw()
。你应该覆盖draw(_ rect: CGRect)
来完成renderImage()
的工作(减去对draw()
的调用)。 (你可以让draw(_ rect: CGRect)
调用renderImage()
,或者你可以简单地将renderImage()
重命名为draw(_ rect: CGRect)
。)
根据您的确切需要,您还可以将enableSetNeedsDisplay
设置为true并更改image
didSet
以调用setNeedsDisplay()
而不是draw()
。这将有更多的延迟,但将避免尝试过于频繁。