CATiledLayer drawLayer: inContext is always called on the main thread - MacOS El Capitan

I am using CATILELayer supported by NSView (Mac is not iOS) and according to Apple docs https://developer.apple.com/reference/quartzcore/catiledlayer I expect this to be called asynchronously, on multiple threads but apparently , it appears only in the main stream.

I am doing work in drawLayer(layer: CALayer, inContext ctx: CGContext)

I turned on canDrawConcurrently in NSView and also set the allowsConcurrentViewDrawing window to true (the default), but it still always calls the main thread for each rectangle of the rectangle.

I need to do some manipulations with the images before the display, depending on the area of ​​the rectangle that needs to be displayed, and working on the main thread affects performance.

Any ideas how I can get her to cause a background thread?

I tried to arrange the image in the background thread and then called the main queue as follows, but it displays an empty rectangle:

 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) }) } }) 
+7
core-animation calayer nsview macos catiledlayer
source share
2 answers

We never managed to get it to work when CATiledLayer was the main layer, I’m not sure why it doesn’t work, and we never received an answer from Apple error.

However, we got it by working on background rendering, making the main layer a standard CALayer, and then adding CATiledLayer as a sublayer to this primary, similar to the code below.

We also noticed that it worked as expected if hosting CATiledLayer in NSView

Hope this helps ...

 class HostingLayer : CALayer { var tiledLayer : CATiledLayer! override init() { super.init() self.tiledLayer = CATiledLayer.init() self.addSublayer(tiledLayer!) } } 
+1
source share

So, here is what I did, it works, although it is not perfect. In drawRect: for my CATiledLayer under NSView I draw a simple background (in my case, a simple grid). I created another CATiledLayer and added it with my NSView layer as a sublayer and set NSView as its delegate. This second `CATiledLayer 'receives delegate draw calls in the background thread.

0
source share

All Articles