CATiledLayer renders too few tiles on macOS

CATiledLayer doesn't work as expected on macOS.
It's choosing to render too few tiles.

In my example, my view is 300px wide. I set layer's transform scale to 4x.
In that case, CATiledLayer renders only two tiles: 50px wide at 2x scale, and stretches them.

Interestingly, when I run similar code on iOS, it works correctly - it renders 3 tiles, 25px wide at 4x scale.

Is it a bug or am I missing something here?

My code below:

Code Block swift
class WaveformView: NSView {
var scale: CGFloat = 1.0 {
didSet {
layer?.transform = CATransform3DScale(CATransform3DIdentity, scale, 1.0, 1.0)
layer?.setNeedsDisplay(bounds)
}
}
private var tiledLayer: CATiledLayer { layer as! CATiledLayer }
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
wantsLayer = true
tiledLayer.levelsOfDetail = 8
tiledLayer.levelsOfDetailBias = 8
tiledLayer.tileSize = CGSize(width: 100.0, height: .infinity)
tiledLayer.contentsScale = 1.0
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ dirtyRect: NSRect) {
let nsContext = NSGraphicsContext.current!
let cgContext = nsContext.cgContext
cgContext.saveGState()
let scaleX: CGFloat = cgContext.ctm.a
NSColor.red.setStroke()
NSBezierPath(rect: dirtyRect)
.stroke()
let fontSize: CGFloat = 12.0
let attr = [
NSAttributedString.Key.font: NSFont.systemFont(ofSize: fontSize)
]
let str = "S: \(scaleX)\n\(dirtyRect.width)" as NSString
str.draw(at: NSPoint(x: dirtyRect.minX, y: dirtyRect.midY), withAttributes: attr)
nsContext.cgContext.restoreGState()
}
override func makeBackingLayer() -> CALayer {
return CATiledLayer()
}
}

Ok, it appears that CATiledLayer behaves unexpectedly when it's scaled only in one axis. When I applied scale transform to both X and Y axis, tiles were rendered correctly.

Any chance that some Apple engineer could relate to this and confirm whether this is intended?
I just ran into this same issue... did you find a work around?
CATiledLayer renders too few tiles on macOS
 
 
Q