在写入同时用作主应用程序中IOSurface
的后备存储的 XPC 进程中时,我需要使用哪些 API,需要采取哪些预防措施?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
使用的 Core Image,然后让 Metal 在应用程序端呈现新内容。
需要什么同步来确保正确完成?双重或三重缓冲策略是一种,但这对我来说并不适用,因为我可能没有足够的内存来分配 2 倍或 3 倍的表面数量。(上面的例子为了清晰起见使用了一个表面,但实际上我可能有几十个表面我正在绘制。每个表面代表图像的一个平铺。图像可以像 JPG/TIFF/etc 允许的那样大。)
WWDC 2010-442 谈到IOSurface
并简要提到这一切都“正常工作”,但这是在 OpenGL 的上下文中,并没有提到 Core Image 或 Metal。
我最初认为 Core Image 和/或 Metal 会调用IOSurfaceLock()
并IOSurfaceUnlock()
保护读/写访问,但事实并非如此。(头文件中的注释IOSurfaceRef.h
表明锁定仅用于 CPU 访问。)
我真的可以让 Core Image 随意CIRenderDestination
写入我从应用程序更新循环中IOSurface
读取的相应内容吗?MTLTexture
如果是这样,那么如果正如 WWDC 视频所述,绑定到一个的所有纹理IOSurface
共享相同的视频内存,那怎么可能呢?如果读取和写入发生在同一个通道中,我肯定会撕裂表面的内容。