Ios 在哪里正确初始化MTLCommandBuffer?
使用GPU捕获按钮进行调试后,将显示一条警告:“您的应用程序在GPU工作期间创建了MTLBuffer对象。请在加载时创建缓冲区以获得最佳性能。” 在我的代码中,唯一与MTLBuffer相关的是每次调用draw时创建MTLCommandBuffer:Ios 在哪里正确初始化MTLCommandBuffer?,ios,swift,metal,Ios,Swift,Metal,使用GPU捕获按钮进行调试后,将显示一条警告:“您的应用程序在GPU工作期间创建了MTLBuffer对象。请在加载时创建缓冲区以获得最佳性能。” 在我的代码中,唯一与MTLBuffer相关的是每次调用draw时创建MTLCommandBuffer: override func draw(_ rect: CGRect){ let commandBuffer = commandQueue.makeCommandBuffer() guard var image =
override func draw(_ rect: CGRect){
let commandBuffer = commandQueue.makeCommandBuffer()
guard var
image = image,
let targetTexture:MTLTexture = currentDrawable?.texture else
{
return
}
let customDrawableSize:CGSize = drawableSize
let bounds = CGRect(origin: CGPoint.zero, size: customDrawableSize)
let originX = image.extent.origin.x
let originY = image.extent.origin.y
let scaleX = customDrawableSize.width / image.extent.width
let scaleY = customDrawableSize.height / image.extent.height
let scale = min(scaleX*IVScaleFactor, scaleY*IVScaleFactor)
image = image
.transformed(by: CGAffineTransform(translationX: -originX, y: -originY))
.transformed(by: CGAffineTransform(scaleX: scale, y: scale))
ciContext.render(image,
to: targetTexture,
commandBuffer: commandBuffer,
bounds: bounds,
colorSpace: colorSpace)
commandBuffer?.present(currentDrawable!)
commandBuffer?.commit()
}
我的第一个想法是将其移动到另一个范围,在这里我可以将命令缓冲区定义为变量,然后在初始化帧时使其等于commandQueue.makeCommandBuffer()。这会立即使应用程序崩溃
我不知道如何在没有警告或崩溃的情况下正确初始化它。MTLCommandQueue是一个惰性变量
以下是使其崩溃的更改:
class MetalImageView: MTKView
{
let colorSpace = CGColorSpaceCreateDeviceRGB()
var textureCache: CVMetalTextureCache?
var sourceTexture: MTLTexture!
var commandBuffer: MTLCommandBuffer?
lazy var commandQueue: MTLCommandQueue =
{
[unowned self] in
return self.device!.makeCommandQueue()
}()!
...
override init(frame frameRect: CGRect, device: MTLDevice?)
{
super.init(frame: frameRect,
device: device ?? MTLCreateSystemDefaultDevice())
if super.device == nil
{
fatalError("Device doesn't support Metal")
}
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self.device!, nil, &textureCache)
framebufferOnly = false
enableSetNeedsDisplay = true
isPaused = true
preferredFramesPerSecond = 30
commandBuffer = commandQueue.makeCommandBuffer()
}
然后,我当然删除了绘图函数中commandBuffer的定义。此警告与
MTLBuffer
s有关,而不是MTLCommandBuffer
s
您当然不应该在初始值设定项中主动创建命令缓冲区。在您即将对GPU工作进行编码时,精确地创建命令缓冲区(即,正如您最初在draw
方法中所做的那样)
至于诊断消息,可能是Core Image在渲染图像时代表您创建了一个临时缓冲区。对此您无能为力,但根据缓冲区的大小和绘图频率,这可能不是什么大问题