Non-sRGB Gradient Rendering via Sampled CGGradient
Source/WebCore/platform/graphics/SampledGradientBuilder.h
CSS gradient는 color interpolation space를 지정할 수 있습니다. 웹 플랫폼이 OKLab을 채택한 이후, CoreGraphics가 sRGB만 네이티브로 지원하기 때문에 WebKit이 직접 interpolation을 수행해야 합니다. 기존 방식은 CGShading을 사용했습니다. 이는 callback 기반 API로, CoreGraphics가 scanline마다 WebKit을 호출해 색상을 가져오는 구조입니다. 결과적으로 매 프레임 draw 시점에 interpolation 비용이 반복적으로 발생했습니다. 반면 CGGradient는 pre-baked 방식으로, discrete color stop을 공급하면 CoreGraphics가 내부적으로 linear interpolation을 처리합니다.
이 commit은 새로운 SampledGradientBuilder를 통해 두 방식의 간극을 해소합니다. OKLab curve를 충분한 수의 linear segment로 pre-sampling하여, CGGradient의 linear interpolation이 실제 curve와 시각적으로 구별되지 않도록 합니다. adaptive bisection 알고리즘은 stop 범위를 재귀적으로 분할합니다. 각 구간의 중간 지점 색상을 계산해 linear interpolation 값과 비교하고, 차이가 8/255 tolerance를 초과하면 더 분할합니다. 최소 segment 폭은 1/2048입니다. 생성된 CGGradient 객체는 ColorInterpolationMethod와 stop vector를 key로 LRU cache에 저장됩니다.
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
draw 시점의 반복적인 colorstop interpolation을 제거함으로써 MotionMark 1.4 Chess subtest 성능이 직접적으로 개선됩니다. 매 프레임마다 발생하던 callback overhead가 일회성 pre-sampling으로 대체됩니다. SampledGradientBuilder는 342줄 규모의 floating-point geometry 및 caching 로직을 hot rendering path에 추가합니다.