Non-sRGB Gradient Rendering via Sampled CGGradient
Source/WebCore/platform/graphics/SampledGradientBuilder.h
CSS gradients can specify a color interpolation space — since the web platform adopted OKLab, WebKit must perform that interpolation itself because CoreGraphics only natively supports sRGB. The previous approach used CGShading, a callback-based API where CoreGraphics calls back into WebKit per scanline to get colors, incurring interpolation cost at draw time on every frame. CGGradient is a simpler, pre-baked representation: you supply discrete color stops and CoreGraphics handles linear interpolation internally.
This commit bridges the gap with a new SampledGradientBuilder that pre-samples the OKLab curve into enough linear segments that CGGradient's linear interpolation is perceptually indistinguishable from the real curve. The adaptive bisection algorithm recursively subdivides stop ranges, evaluating the midpoint color and comparing it to the linear interpolation — if the difference exceeds 8/255 tolerance, it subdivides further, bottoming out at 1/2048 segment width. The resulting CGGradient objects are cached in an LRU cache keyed on ColorInterpolationMethod and the stop vector.
Before (per draw): After (upfront + cached):
CSS OKLab gradient CSS OKLab gradient
│ │
▼ ▼
CGShading (callback) SampledGradientBuilder
│ ◄── called per scanline └─ bisect until Δ < tolerance
│ WebKit interpolates here └─ emit N sRGB stops
▼ │
CGContextDrawShading() CGGradient ◄── LRU cache
│
CGContextDraw{Linear,Radial,Conic}Gradient()
Significance
This directly improves MotionMark 1.4 Chess subtest performance by eliminating repeated colorstop interpolation at draw time, replacing per-frame callback overhead with a one-time pre-sampling step. The SampledGradientBuilder introduces 342 lines of floating-point geometry and caching logic into a hot rendering path.