У меня есть массив UIImages
, который я хочу скомпоновать с помощью MTKView
, используя различные специфические режимы компоновки (источник, стирание и т. Д.). С подходом, который я описываю ниже, я обнаружил, что самые большие издержки, по-видимому, заключаются в преобразовании каждого UIImage
в MTLTexture
, который я могу использовать для заполнения MTKView's
currentDrawable
буфера.
Цикл рисования выглядит следующим образом:
for strokeDataCurrent in strokeDataArray {
let strokeImage = UIImage(data: strokeDataCurrent.image) // brushstroke
let strokeBbox = strokeDataCurrent.bbox // brush bounding box
let strokeType = strokeDataCurrent.strokeType // used to define comp mode
// convert strokeImage to a MTLTexture and composite
drawStrokeImage(paintingViewMetal: self.canvasMetalViewPainting, strokeImage: strokeImage!, strokeBbox: strokeBbox, strokeType: strokeType)
} // end of for strokeDataCurrent in strokeDataArray
Внутри drawStrokeImage я конвертирую каждый штрих в MTLTexture
следующим образом:
guard let stampTexture = device!.makeTexture(descriptor: texDescriptor) else { return }
let destCGImage = strokeImage.cgImage!
let dstData: CFData = (destCGImage!.dataProvider!.data)!
let pixelData = CFDataGetBytePtr(dstData)
let region = MTLRegionMake2D(0, 0, Int(width), Int(height))
stampTexture.replace(region: region, mipmapLevel: 0, withBytes: pixelData!, bytesPerRow: Int(rowBytes))
со всем этим, я определяю буфер вершин, устанавливаю commandEncoder
:
defineCommandEncoder(renderCommandEncoder: renderCommandEncoder, vertexArrayStamps: vertexArrayStamps, metalTexture: stampTexture)
и вызовите setNeedsDisplay()
для рендеринга. Это происходит для каждого хода в цикле выше.
Пока я получаю нормальную производительность при таком подходе, мне интересно, смогу ли я увеличить производительность где-нибудь по пути? Как я уже сказал, я думаю, что текущее узкое место находится в CGImage -> MTLTexture
.
Обратите внимание, что я выполняю рендеринг для определенного MTLTexture
metalDrawableTextureComposite, который я блещу в currentDrawable
для каждого удара:
copyTexture(buffer: commandBuffer!, from: metalDrawableTextureComposite, to: self.currentDrawable!.texture)
Надеюсь, этого достаточно, чтобы представить контекст моего вопроса. Также, если у кого-то есть идеи для других (надеюсь, на GPU / Metal) более быстрых подходов к компоновке, это было бы замечательно. Любые мысли будут оценены.