From 70993ea330cc37a0e8d55cac13ff736dc449cc66 Mon Sep 17 00:00:00 2001 From: Oddur Sigurdsson Date: Fri, 11 Sep 2026 02:00:58 -0400 Subject: [PATCH] fix: split the bloom blur so every toolchain can type-check it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Swift 6.3.1 compiles the nested closure fine; the toolchain on the macOS runner gives up on it, which is the worst way to find out — green locally, red in CI. The two passes are now separate methods with explicit signatures and the index arithmetic hoisted into named locals, so nothing in the expression is large enough to strain inference. The composited frame is byte-identical before and after at a fixed seed. --- Sources/Windflow/Canvas.swift | 80 +++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/Sources/Windflow/Canvas.swift b/Sources/Windflow/Canvas.swift index c176c37..c9ecd93 100644 --- a/Sources/Windflow/Canvas.swift +++ b/Sources/Windflow/Canvas.swift @@ -444,38 +444,64 @@ final class Canvas { blurBloom(radius: 4) } + /// Separable box blur over the bloom buffer. + /// + /// The two passes are separate methods with explicit signatures rather than + /// index arithmetic inlined into nested closures. Written that way, the + /// expression is large enough that some Swift toolchains give up type-checking + /// it — it compiles locally and fails on CI, which is the worst way to find out. private func blurBloom(radius: Int) { - let bw = bloomW, bh = bloomH + let bw = bloomW + let bh = bloomH + let inv = 1 / Float(radius * 2 + 1) bloom.withUnsafeMutableBufferPointer { src in bloomScratch.withUnsafeMutableBufferPointer { dst in - let inv = 1 / Float(radius * 2 + 1) - for y in 0.., dst: UnsafeMutableBufferPointer, + bw: Int, bh: Int, radius: Int, inv: Float + ) { + for y in 0.., dst: UnsafeMutableBufferPointer, + bw: Int, bh: Int, radius: Int, inv: Float + ) { + for x in 0..