介绍的Metal Petal能力与最佳使用

前言

Metal Petal是一个基于Metal的图像处理框架,旨在通过易于使用的编程界面为静态图像和视频提供实时处理。

核心组件

MetalPetal 的一些核心概念与 Apple Core Image 框架中的概念非常相似。

提供渲染MTIImage的评估上下文。它还存储了大量缓存和状态信息,因此尽可能重用上下文更高效。

MTIImage对象是要处理或生成的图像的表示。它确实直接表示图像位图数据,相反,它拥有生成图像或更准确地说是aMTLTexture所需的所有信息。它由两部分组成,一个是如何生成纹理的配方(MTIImagePromise)和其他信息,例如上下文如何缓存图像(cachePolicy),以及如何采样纹理(samplerDescriptor)。

MTIFilter表示图像处理效果和控制该效果的任何参数。它产生一个MTIImage对象作为输出。要使用过滤器,您可以创建一个过滤器对象,设置其输入图像和参数,然后访问其输出图像。通常,过滤器类拥有静态内核(MTIKernel),当您访问其outputImage属性时,它会要求具有输入图像和参数的内核生成输出MTIImage

MTIKernel表示图像处理例程。MTIKernel负责为过滤器创建相应的渲染或计算管道状态,以及为aMTIImage构建MTIImagePromise

优化

MetalPetal做了很多优化,它会自动缓存函数、内核状态、采样器状态等。

它利用可编程混合、无内存渲染目标、资源堆和金属性能着色器等金属功能来实现快速高效的渲染。在macOS上,MetalPetal还可以利用苹果芯片的TBDR架构。

在渲染之前,MetalPetal可以查看您的图像渲染图,并计算出进行渲染所需的最小中间纹理数量,从而节省内存、能量和时间。

如果可以串联多个“食谱”,以消除冗余的渲染传递,它也可以重新组织图像渲染图。(MTIContext.isRenderGraphOptimizationEnabled

并发性考虑因素

MTIImage对象是不可变的,这意味着它们可以在线程之间安全地共享。

然而,MTIFilter对象是可变的,因此无法在线程之间安全共享。

MTIContext包含许多状态和缓存。MTIContext对象有一个线程安全机制,使得在线程之间共享MTIContext对象是安全的。

比 Core Image 的优势

不同:

Core Image可以使用GPU或者CPU渲染。

MetalPetal主要专注于使用GPU进行渲染。

优势:

内置过滤器

最佳实践

上下文是重量级对象,因此,如果您确实创建了对象,请尽早创建,并在每次需要渲染图像时重用它。

当您不想保留图像的渲染结果时,请使用MTIImageCachePolicyTransient,例如当图像只是过滤器链中的中间结果时,因此渲染结果的底层纹理可以重复使用。这是内存效率最高的选项。但是,当您要求上下文渲染之前渲染的图像时,它可能会重新渲染该图像,因为它的基础纹理已被重用。

默认情况下,过滤器的输出映像具有transient策略。

当您想防止底层纹理被重复使用时,请使用MTIImageCachePolicyPersistent

默认情况下,从外部来源创建的图像具有persistent策略。

每次您要求过滤器输入其输出图像时,即使输入与上次调用相同,过滤器也可能为您提供新的输出图像对象。因此,尽可能重复使用输出图像。

例如,

//          ╭→ filterB
// filterA ─┤
//          ╰→ filterC
// 
// filterB and filterC use filterA's output as their input.

在这种情况下,以下解决方案:

let filterOutputImage = filterA.outputImage
filterB.inputImage = filterOutputImage
filterC.inputImage = filterOutputImage

比以下更好:

filterB.inputImage = filterA.outputImage
filterC.inputImage = filterA.outputImage