我正在编写一个视图来绘制Metal中的实时数据.我正在使用点基元绘制样本,并且我对顶点和统一数据进行三重缓冲.我遇到的问题是调用currentDrawable返回的时间似乎是不可预测的.这几乎就好像有时没有准备就绪,我必须等待一整帧才能获得.通常,currentDrawable返回的时间约为0.07毫秒(这与我的期望大致相同),但有时则是整整1/60秒.这导致整个主线程被阻塞,也就是说至少不是非常期望的.
我在iPhone 6S Plus和iPad Air上看到了这个问题.我还没有看到这种行为是Mac(我有一台带有AMD 460 GPU的2016 MPB).我的猜测是,这与iOS设备中的GPU基于TBDR的事实有某种关系.我不认为我的带宽有限,因为无论我绘制的样本数量多少或几乎没有,我都会得到完全相同的行为.
为了说明这个问题,我写了一个绘制静态正弦波的最小例子.这是一个简化的例子,因为我通常会将样本记忆到当前的vertexBuffer中,就像我对制服一样.这就是为什么我对顶点数据和制服进行三重缓冲.尽管如此,它仍然足以说明问题.只需将此视图设置为故事板中的基本视图,然后运行即可.在某些运行中,它工作得很好.其他时候currentDrawable以16.67 ms的返回时间开始,然后在几秒钟后跳转到0.07 ms,然后一段时间后回到16.67.如果由于某种原因旋转设备,它似乎从16.67跳到0.07.
MTKView子类
import MetalKit
let N = 500
class MetalGraph: MTKView {
typealias Vertex = Int32
struct Uniforms {
var offset: UInt32
var numSamples: UInt32
}
// Data
var uniforms = Uniforms(offset: 0, numSamples: UInt32(N))
// Buffers
var vertexBuffers = [MTLBuffer]()
var uniformBuffers = [MTLBuffer]()
var inflightBufferSemaphore = DispatchSemaphore(value: 3)
var inflightBufferIndex = 0
// Metal State
var commandQueue: MTLCommandQueue!
var pipeline: MTLRenderPipelineState!
// Setup
override func awakeFromNib() {
super.awakeFromNib() …Run Code Online (Sandbox Code Playgroud)