После отладки с помощью кнопки Capture GPU отображается предупреждение: «Ваше приложение создало объект MTLBuffer во время работы GPU. Создайте буферы во время загрузки для лучшей производительности».
Единственное, что связано с MTLBuffer вмой код - создание MTLCommandBuffer каждый раз, когда вызывается draw:
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 в моей функции рисования.