I'm using a CATiledLayer backed NSView (Mac not iOS) and according to Apple docs https://developer.apple.com/reference/quartzcore/catiledlayer I expect this to be called asynchronously, on multiple threads to aid performance, however it only appears to ever get called on the main thread.
I'm doing the work in drawLayer(layer: CALayer, inContext ctx: CGContext)
I have enabled canDrawConcurrently on the NSView as well as ensuring the window has allowsConcurrentViewDrawing set as true (default), but it still always calls on the main thread for each tile rect.
I need to do some image manipulation prior to display dependant on the rect area needing display, and running on the main thread impacts performance.
Any ideas how I can either force it to call on a background thread?
I have tried marshalling the image a operation onto background thread and then recalling the main queue with the following but it displays a blank 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)
})
}
})
So here is what I did that is working, though it is not ideal. In the
drawRect:for myCATiledLayerbackedNSViewI draw a simple background (in my case a simple grid). I created anotherCATiledLayerand added it my NSView's layer as a sublayer and set the NSView as its delegate. This second `CATiledLayer' is getting the delegate draw calls on a background thread.