ken*_*nyc 5 macos xpc core-image metal iosurface
在写入IOSurface同时用MTLTexture作主应用程序中的后备存储的 XPC 进程时,我需要使用哪些 API,以及需要采取哪些预防措施?
在我的 XPC 服务中,我有以下内容:
IOSurface *surface = ...;
CIRenderDestination *renderDestination = [... initWithIOSurface:surface];
// Send the IOSurface to the client using an NSXPCConnection.
// In the service, periodically write to the IOSurface.
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我有以下内容:
IOSurface *surface = // ... fetch IOSurface from NSXPConnection.
id<MTLTexture> texture = [device newTextureWithDescriptor:... iosurface:surface];
// The texture is used in a fragment shader (Read-only)
Run Code Online (Sandbox Code Playgroud)
我有一个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写入吗?如果是这样,那么如果正如 WWDC 视频所说的那样,所有纹理绑定到一个共享相同的视频内存,那怎么可能呢?如果在同一次通过期间进行读取和写入,我肯定会撕裂表面的内容。IOSurfaceMTLTextureIOSurface
您需要做的事情是确保 CoreImage 绘制已在 XPC 中完成,然后再IOSurface用于在应用程序中绘制。如果双方都使用 OpenGL 或 Metal,则可以调用glFlush()或[-MTLRenderCommandEncoder waitUntilScheduled]。我假设 CoreImage 中的某些内容正在进行其中一个调用。
我可以说,如果没有发生这种情况,情况可能会很明显,因为如果事情没有正确同步,您将会看到撕裂或图像一半是新渲染,一半是旧渲染。我见过IOSurface在 XPC 上使用 s 时会发生这种情况。
您可以做的一件事是放置一些符号断点-waitUntilScheduled,然后-waitUntilCompleted查看 CI 是否在您的 XPC 中调用它们(假设文档没有明确告诉您)。Metal 中还有其他同步原语,但我对它们不是很熟悉。它们也可能有用。(据我所知,CI 现在在幕后都是金属的。)
此外,该IOSurface对象还具有方法-incrementUseCount、-decrementUseCount和-localUseCount。可能值得检查这些内容,看看 CI 设置是否正确。(<IOSurface/IOSurfaceObjC.h>详情请参阅。)
| 归档时间: |
|
| 查看次数: |
1082 次 |
| 最近记录: |