Swift CametLayer初始化仅在主线程上工作
我有一个直接的CametLayer设置,除了CametLayer在全局线程上初始化,如下所示(调用init、设置基本属性和添加为子层): 此代码运行时没有任何运行时错误,但不幸的是,当渲染到Swift CametLayer初始化仅在主线程上工作,swift,multithreading,metal,Swift,Multithreading,Metal,我有一个直接的CametLayer设置,除了CametLayer在全局线程上初始化,如下所示(调用init、设置基本属性和添加为子层): 此代码运行时没有任何运行时错误,但不幸的是,当渲染到CametLayerdrawable时,屏幕上没有显示渲染输出。测试表明,camertallayerdrawable确实具有适当的纹理(具有所需的大小),数据按预期写入,但未显示在屏幕上 令我惊讶的是,在主线程上运行CAMetalLayer初始化可以解决这个问题。因此,以下是一个解决方案: DispatchQ
CametLayer
drawable时,屏幕上没有显示渲染输出。测试表明,camertallayer
drawable确实具有适当的纹理(具有所需的大小),数据按预期写入,但未显示在屏幕上
令我惊讶的是,在主线程上运行CAMetalLayer
初始化可以解决这个问题。因此,以下是一个解决方案:
DispatchQueue.global().async {
var renderLayer: CAMetalLayer!
DispatchQueue.main.sync {
renderLayer = CAMetalLayer()
}
renderLayer.isOpaque = false
renderLayer.frame = frame
renderLayer.drawableSize = drawableSize
renderLayer.framebufferOnly = false
renderLayer.device = metalDevice
renderLayer.pixelFormat = metalPixelFormat
renderLayer.contentsScale = contentScale
DispatchQueue.main.async {
view.layer.addSublayer(renderLayer)
}
}
由于我希望能够在后台线程上完全运行CAMetalLayer
创建,因此我希望避免在主线程上调用CAMetalLayer()
。此外,我在文档中找不到在主线程上初始化camertallayer
的任何要求
所以我的问题是:
- 是否可以在后台线程上运行init
,如果可以,如何运行?CAMetalLayer()
- 如果不可能:为什么?
其他信息:我正在使用XCode 11并在iOS 13.1上运行代码。我对XCode 10和iOS版本12也有同样的问题。出色的研究!只调用主线程上的那一行有什么不好?顺便说一句,这个代码是错误的:您永远不应该调用
main.sync
。嗯,你可以,但一般来说不可以。@matt:我可以在主线程上调用这一行,但这样做感觉不对,因为我找不到需要在主线程上初始化的camertallayer
的信息。我也很好奇是否真的有这样的要求。同时在主线程上调用一行对我来说是不方便的,因为我当前的代码需要一些调整来避免主线程上的死锁。所以如果我能避免的话,我会的。
DispatchQueue.global().async {
var renderLayer: CAMetalLayer!
DispatchQueue.main.sync {
renderLayer = CAMetalLayer()
}
renderLayer.isOpaque = false
renderLayer.frame = frame
renderLayer.drawableSize = drawableSize
renderLayer.framebufferOnly = false
renderLayer.device = metalDevice
renderLayer.pixelFormat = metalPixelFormat
renderLayer.contentsScale = contentScale
DispatchQueue.main.async {
view.layer.addSublayer(renderLayer)
}
}