TL / DR:在XPC服务中解码图像的最有效方法是什么,将数据移动到主应用程序然后显示它?
在几个处理macOS上的XPC服务的WWDC视频中,作为使用XPC服务的良好候选者的一个例子是图像和视频的解码。我有一个应用程序,它做了很多图像解码,我想进入XPC服务,但我想更好地理解如何有效地将解码图像数据从XPC服务移动到主应用程序。在处理图像时可以使用许多API,而且我不清楚在XPC服务中使用哪种API是最有效的(和高性能的)。
图片阅读:
CGImage
CIImage
OpenImage IO
所有这三个API都可以获取文件路径并返回“图像数据”。 Apple的API倾向于进行“延迟解码”,只在需要绘制图像时解压缩图像数据。第三方库往往只返回一个解码数据缓冲区,然后可以在以后用CGImage
包装。
在XPC服务中使用Apple的API解码图像时,您需要一种方法将结果返回到主应用程序,CGImage
和CIImage
都不能通过XPC连接本地传输。但是,Apple确实提供了两个API,用于通过XPC连接有效地传输通用数据:
IOSurface
dispatch_data
但是,使用其中任何一个都需要XPC服务完全解压缩映像。需要将CGImage
呈现给位图上下文或数据使用者,而需要使用CIImage
将CIContext
呈现到目标。这样做是否会否定在主应用程序中进行拆包时本来可以实现的任何好处?
(请注意,每个渲染图片的最终目的地都是contents
的{{1}}属性。)
使用CALayer
代替IOSurface
对象,似乎是更好的解决方案,因为dispatch_data
可以(显然)用作IOSurface
的{{1}} 1}}。 contents
有一个用于呈现CALayer
的API,但CIContext
没有。
(使用IOSurface
从CGImage / CGImageDestination
转到vImage
然后转到CGImage
有一种迂回的方式,但似乎......错了吗?)
当我想要做的就是显示每张图片的缩略图时,使用Core Image对我来说似乎有些过分。 Image IO提供了CVPixelBuffer
来完成这项工作并且效果很好。 (特别是在RAW文件中,它将使用嵌入的JPEG缩略图,如果存在,而Core Image将解码RAW内容。)
最后,金属在哪里适合所有这些?我是通过在XPC服务中渲染到金属纹理然后发送它来获得任何东西吗?
通过使用XPC服务,我如何影响Image IO或Core Image在适当时有效使用GPU的能力?如何最小化复制的数据量(在进程之间以及CPU和GPU之间)?这些缩略图在滚动网格视图中呈现,因此性能优先。