做什么的API,我需要用的,我需要采取什么预防措施,在这也被用来作为备份存储的IOSurface
在主应用程序的XPC过程写入到一个MTLTexture
什么时候?
在我的XPC服务,我有以下几点:
IOSurface *surface = ...;
CIRenderDestination *renderDestination = [... initWithIOSurface:surface];
// Send the IOSurface to the client using an NSXPCConnection.
// In the service, periodically write to the IOSurface.
在我的应用程序具备以下条件:
IOSurface *surface = // ... fetch IOSurface from NSXPConnection.
id<MTLTexture> texture = [device newTextureWithDescriptor:... iosurface:surface];
// The texture is used in a fragment shader (Read-only)
我有一台运行是正常的更新循环的MTKView
。我希望我的XPC服务能够定期编写与使用核心形象IOSurface
,然后有由金属在应用程序方面呈现的新内容。
什么同步需要确保这是正确的呢?双或三缓冲策略之一,但并没有真正适合我,因为我可能没有足够的内存来分配2倍或3倍面数。 (上面的例子使用为了清楚一个表面上,但在现实中我可能有几十个表面我画到的每个表面表示图像的一个区域。一种图像可以是大到JPG / TIFF /等允许)。
WWDC约IOSurface
2010-442会谈,并简要地提到,一切“只是工作”,但是这是在OpenGL的情况下,不提核图像或金属。
我原本认为核心的图像和/或金属将打电话IOSurfaceLock()
和IOSurfaceUnlock()
保护读/写访问,但是,这并不似乎是在所有的情况。 (而在IOSurfaceRef.h
头文件中的注释表明,锁定只对CPU的访问。)
可我真的只是让随意的CIRenderDestination
核心形象的IOSurface
写,而我从我的应用程序的更新循环对应的MTLTexture
读?如果是这样,那么怎么可能如果作为WWDC视频状态,所有纹理绑定到IOSurface
共享相同的显存?当然我能得到表面的内容有些撕裂,如果阅读和写作一样传递期间发生的。
你需要做的事情是确保CoreImage图纸已经在XPC完成使用IOSurface
之前在应用程序中进行绘制。如果你是使用OpenGL或金属两侧,你要么打电话glFlush()
或[-MTLRenderCommandEncoder waitUntilScheduled]
。我假设的东西在CoreImage正在这些电话中的一个。
我可以说,它可能会很明显,如果这没有发生,因为你会得到撕裂或者是半新的渲染和半老的渲染,如果事情不正确同步的图像。我已经看到了整个XPCs使用IOSurface
s当这种情况发生。
有一两件事你可以做的就是把上-waitUntilScheduled
和-waitUntilCompleted
一些象征性的断点,看看CI是你的XPC打电话给他们(假设documentation没有明确告诉你)。还有在金属等同步原语,但我不是很熟悉他们。他们可能是有用的。 (这是我的理解是CI是引擎盖下的所有金属了。)
此外,IOSurface
对象有方法-incrementUseCount
,-decrementUseCount
和-localUseCount
。这可能是值得一试的,看看CI适当地设置它们。 (见<IOSurface/IOSurfaceObjC.h>
了解详细信息。)