FramebufferUIView: disable CALayer implicit animations on frame updates
Every time Mac repainted a region we set imageLayer.contents to a new CGImage. CALayer's default action for .contents is a 0.25s crossfade, so big repaints (like after a click — cursor + button + window-focus) looked like a pulse. Tap seemed "flickery"; actually the whole view was doing quarter-second crossfades constantly, most just weren't big enough to notice until a chunky repaint hit. Override imageLayer.actions with NSNull for contents/contentsRect/frame/ transform so blits are instantaneous, and wrap apply() in a CATransaction.setDisableActions(true) for safety. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,17 @@ final class FramebufferUIView: UIView,
|
||||
imageLayer.magnificationFilter = .nearest
|
||||
imageLayer.minificationFilter = .linear
|
||||
imageLayer.contentsGravity = .resize
|
||||
// Kill CALayer's implicit animations — we want every framebuffer
|
||||
// update to be an instantaneous blit, not a 0.25s crossfade.
|
||||
imageLayer.actions = [
|
||||
"contents": NSNull(),
|
||||
"contentsRect": NSNull(),
|
||||
"position": NSNull(),
|
||||
"bounds": NSNull(),
|
||||
"frame": NSNull(),
|
||||
"transform": NSNull(),
|
||||
"backgroundColor": NSNull()
|
||||
]
|
||||
layer.addSublayer(imageLayer)
|
||||
|
||||
configureGestureRecognizers()
|
||||
@@ -161,8 +172,11 @@ final class FramebufferUIView: UIView,
|
||||
}
|
||||
|
||||
func apply(image: CGImage?, framebufferSize: CGSize) {
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
imageLayer.contents = image
|
||||
applyLayerFrame()
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
private func applyLayerFrame() {
|
||||
|
||||
Reference in New Issue
Block a user