GPU texture atlas pipeline for Skia painting on GTK/WPE
Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp
GTK/WPE 환경의 Skia painting engine은 record/replay 모델을 기반으로 동작합니다. drawing 명령을 먼저 picture 형태로 기록한 뒤, GPU 가속을 활용하는 worker thread에서 재생하는 구조입니다. 이번 commit은 이 흐름에 batching 최적화를 도입합니다. 기록 단계에서 발견된 raster(CPU 측) image를 하나의 GPU texture atlas에 모아 단 한 번만 업로드하고, 재생 단계에서는 atlas의 sub-region으로 활용하여 image별 GPU upload 오버헤드를 제거한 것이 핵심입니다.
이 pipeline은 세 단계로 구성됩니다. 기록 단계에서는 collectRasterImage()가 image를 atlas layout에 배치하고, 기록이 완료되면 createAtlas()가 pixel data를 GPU texture에 업로드합니다. 업로드 방식은 두 가지로 나뉘는데, GBM buffer를 memory-mapping하여 CPU에서 직접 기록하는 DMA-buf 경로(worker thread 처리)와 main thread에서 동기적으로 실행되는 GL fallback 경로(updateContents())가 있습니다. 재생 단계에서는 SkiaReplayCanvas의 virtual override(onDrawImage2, onDrawImageRect2)가 raster image draw를 가로채어 atlas texture draw로 전환하고 좌표를 재매핑합니다. upload worker와 replay worker 간의 동기화는 AtlasUploadCondition이 담당합니다. 이는 Lock과 Condition 위에 구현된 커스텀 countdown latch입니다.
Recording (main) Upload (main or worker) Replay workers
│ │ │
├─ collectRasterImage() ──────►│ │
├─ finalize() → AtlasLayouts │ │
├─ createAtlas() ─────────────►│ │
│ DMA-buf: mmap GPU buf ├─ addPending()/signal() ──►│
│ GL: updateContents() │ │
│ ├─ GL fence inserted ───────►│
│ │ ├─ wait() [latch]
│ complete ├─ onDrawImage2()
│ │ └─ atlas draw
│ │ (remapped coords)
Significance
GPU texture batching, cross-thread 동기화, DMA-buf memory-mapped write, atlas 좌표 치환이 모두 concurrent worker 환경에서 맞물려 동작하는 대규모 rendering pipeline입니다. 이처럼 복잡하게 상호작용하는 구조는 역사적으로 race condition과 lifetime 버그가 자주 발생하는 영역입니다.