CATiledLayer drawLayer:始终在主线程上调用inContext - MacOS El Capitan

时间:2016-09-19 02:56:29

标签: macos core-animation calayer nsview catiledlayer

我正在使用CATiledLayer支持的NSView(Mac而不是iOS)并且根据Apple文档https://developer.apple.com/reference/quartzcore/catiledlayer我希望在多个线程上异步调用它以帮助提高性能,但它似乎只是被调用主线。

我正在drawLayer(layer: CALayer, inContext ctx: CGContext)

中完成工作

我在NSView上启用了canDrawConcurrently,并确保窗口allowsConcurrentViewDrawing设置为true(默认值),但它仍然总是调用每个tile rect的主线程。

我需要在显示之前进行一些图像处理,这取决于需要显示的矩形区域,并且在主线程上运行会影响性能。

我是如何强迫它在后台线程上调用的?

我尝试将操作编组到后台线程上,然后使用以下内容调用主队列,但它显示一个空白的矩形:

backgroundQueue.addOperationWithBlock({ [ weak self ] in            
    guard let strongSelf = self else { return }

    // ** This is the part I nee to do in background that can take some time
    guard let image = strongSelf.imageForTileRect(layerBounds, imageSize: imageSize) else { return }
    // ** End background bit

    var rect = layerBounds
    let rectImageRef = image.CGImageForProposedRect(&rect, context: nil, hints: nil)

    if (rectImageRef != nil) {
        NSOperationQueue.mainQueue().addOperationWithBlock({ 
            CGContextDrawImage(ctx, rect, rectImageRef)
        })
    }
})

2 个答案:

答案 0 :(得分:2)

当CATiledLayer是主要层时,我们从未真正设法让它工作,我不确定它为什么不起作用,我们从来没有得到Apple提出的错误答案。

然而,我们让它通过使主层成为标准CALayer然后将CATiledLayer作为subLayer添加到这个主层来进行后台渲染,类似于下面的代码。

我们还注意到,如果在NSView中托管CATiledLayer

,它会按预期工作

希望这会有所帮助......

class HostingLayer : CALayer {

    var tiledLayer : CATiledLayer!

    override init() {
        super.init()

        self.tiledLayer = CATiledLayer.init()

        self.addSublayer(tiledLayer!)
    }
}

答案 1 :(得分:0)

所以这就是我所做的工作,虽然它并不理想。在我drawRect:支持CATiledLayer的{​​{1}}中,我绘制了一个简单的背景(在我的例子中是一个简单的网格)。我创建了另一个NSView,并将我的NSView层添加为子层,并将NSView设置为其委托。第二个“CATiledLayer”正在后台线程上获取委托绘制调用。