使用GPU Capture按钮进行调试后,将显示一条警告:“您的应用程序在GPU工作期间创建了MTLBuffer对象。在加载时创建缓冲区以获得最佳性能。”
在我的代码中与MTLBuffer有关的唯一事情是每次调用绘图时都会创建MTLCommandBuffer:
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的定义中。
答案 0 :(得分:1)
此警告涉及MTLBuffer
S,不MTLCommandBuffer
秒。
您当然不应该主动建立在你的初始化命令缓冲区。精确地在您要对GPU工作进行编码时(即,如您最初在draw
方法中所做的那样)创建命令缓冲区。
关于诊断消息,很可能是Core Image在渲染图像时代表您创建了一个临时缓冲区。您对此无能为力,但是取决于缓冲区的大小和绘制的频率,这可能并不重要。