CAMetalLayer初始化仅适用于主线程

时间:2019-10-11 01:23:23

标签: swift multithreading metal

我确实有一个简单的CAMetalLayer设置,除了CAMetalLayer是在全局线程上初始化的,它看起来像这样(调用init,设置基本属性并添加为子层):

DispatchQueue.global().async {
    let 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可绘制对象确实具有适当的纹理(具有所需的大小),并且数据已按预期写入其中,但未在屏幕上显示。

令我惊讶的是,在主线程上运行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()。另外,我找不到在文档的主线程上初始化CAMetalLayer的任何要求。

所以我的问题是:

  • 是否可以在后台线程上运行初始化CAMetalLayer()?如果可以,怎么办?
  • 如果不可能:为什么?

其他信息:我正在使用XCode 11,并在iOS 13.1上运行代码。 XCode 10和iOS版本12也存在相同的问题。

0 个答案:

没有答案