一套工具和扩展,允许在不同的图形 API 之间共享页对齐的内存分配,并为它们提供视图互操作性。 该库帮助 ZERO10 减少其计算机视觉流水线中的内存流量。
该库引入了一个 GraphicsDataProvider
协议。 任何符合此协议的类型都允许将其内容视为
vImage_Buffer
CVPixelBuffer
MLMultiArray
MTLBuffer
MTLTexture
默认情况下,这些类型是 vImage_Buffer
、CGContext
、CGImage
、CVPixelBuffer
、IOSurface
、MTLTexture
和 UIImage
。
这意味着可以创建一个 IOSurface
并重新解释其内容,例如 CVPixelBuffer
或 vImage_Buffer
。
let vImageBuffer: vImage_Buffer = try ioSurface.vImageBufferView()
let pixelBuffer: CVPixelBuffer = try vImageBuffer.cvPixelBufferView(cvPixelFormat: .type_32BGRA)
let texture: MTLTexture = try vImageBuffer.mtlTextureView(
device: context.device,
pixelFormat: .bgra8Unorm,
usage: [.shaderRead, .shaderWrite]
)
这非常方便,因为它允许减少样板代码以及内存复制操作。
在某些情况下,无法在某些图形数据上创建 MTLBuffer
或 MTLTexture
视图,因为 它要求数据的分配指针是页对齐的。 这样做是因为在内部,在创建 MTLBuffer
之前,Metal 将某些内存页标记为可供 GPU 访问,并且共享内存地址的起始位置应与页面地址对齐。
为了克服这种情况,提供了 MTLSharedGraphicsBuffer
。 在内部,这个类封装了页对齐内存的分配,并初始化了 MTLBuffer
、MTLTexture
、vImage_Buffer
、CVPixelBuffer
和 CGContext
,使它们看起来指向相同的内存。
鉴于此,您可以进行诸如将 CoreGraphics
渲染与 Metal
结合而无需内存传输之类的技巧
let context = try MTLContext()
let sharedBuffer = try MTLSharedGraphicsBuffer(
device: context.device,
width: 600,
height: 600,
pixelFormat: .bgra8Unorm
)
let rect = CGRect(
x: 125,
y: 125,
width: 300,
height: 300
)
let whiteColor = CGColor(
red: 1,
green: 1,
blue: 1,
alpha: 1
)
// Draw with CoreGraphics
sharedBuffer.cgContext.setFillColor(whiteColor)
sharedBuffer.cgContext.fill(rect)
// Continue with Metal
try context.schedule { commandBuffer in
someFancyMetalFilter.encode(
source: sharedBuffer.texture,
destination: resultTexture,
in: commandBuffer
)
}
SharedGraphicsTools
在 MIT 许可证 下获得许可。