[GPUProcess] Move the drawing Font functionalities to a new class named FontBase
Component: WebCore Graphics / GPU Process | 00ef398
Source/WebCore/platform/graphics/Font.h
Source/WebCore/platform/graphics/Font.cpp
WebKit의 렌더링은 두 개의 프로세스로 나뉘어 진행됩니다. 먼저 WebContent가 display list를 구성하는데, 이때 이미지나 font 같은 리소스는 RenderingResourceIdentifier로 참조합니다. 이후 GPU process가 이 목록을 별도 thread에서 재생하며 실제 페인팅을 담당합니다. 기존 Font는 이 모든 것을 하나의 RefCounted 객체에 담고 있었습니다. WebContent에서만 쓰이는 glyph shaping과 mapping이, GPU process가 필요로 하는 draw 호출과 같은 클래스 안에 함께 들어 있던 셈입니다.
이번 commit은 Font에서 FontBase라는 새 base 클래스를 분리했습니다. glyph를 그리는 기능은 이쪽으로 옮겨졌는데, platform draw 호출, rendering resource identifier, math data, metric override가 여기에 해당합니다. Font는 FontBase를 상속하면서 glyph table 소유권과 glyph mapping, text layout 로직을 그대로 유지합니다.
Before: After:
Font (RefCounted) FontBase (virtual ref/deref)
├─ drawing (drawGlyphsImmediate) ├─ drawing (drawGlyphsImmediate)
├─ renderingResourceIdentifier ├─ renderingResourceIdentifier
├─ mathData / metric overrides ├─ mathData / metric overrides
├─ glyph mapping / shaping │ ▲ inherits
└─ used by WebContent + GPUProcess Font : FontBase, RefCounted<Font>
(via DrawGlyphs) └─ glyph mapping / shaping (WebContent only)
(future) ThreadSafeFontBase : FontBase
└─ shareable with GPUProcess, draw-only
Significance
앞서 진행된 NativeImage/BitmapImageSource 분리와 같은 방식이며, RemoteRenderingBackend가 생성해서 thread 간에 공유할 수 있는 thread-safe FontBase 서브클래스를 위한 명시적인 사전 작업에 해당합니다. 핵심은 격리에 있습니다. 이렇게 해두면 앞으로 추가될 thread-safe 클래스가 그리기 관련 인터페이스만 상속할 수 있습니다. thread 경계를 절대 넘어가서는 안 되는 shaping 상태를 함께 끌고 올 이유가 사라지는 것입니다. 또한 GPU process는 drawGlyphsImmediate()만 호출하도록 의도되어 있고, 문자를 glyph로 매핑하는 작업은 직접 수행하지 않습니다. 결과적으로 DrawGlyphs display list 명령이 font 리소스를 참조하는 방식도 달라지게 됩니다.
Audit directions
이번 변경은 약 40개의 메서드와 여러 boolean 플래그를 Font의 명시적 생성자 초기화 리스트에서 FontBase로 옮긴 대규모 기계적 이동입니다. m_treatAsFixedPitch, m_isBrokenIdeographFallback, m_hasVerticalGlyphs, m_isUsedInSystemFallbackFontCache, m_shouldNotBeUsedForArabic이 여기에 포함됩니다. 좁게는, 각 플래그가 FontBase.h의 멤버 초기화를 통해 올바른 기본값을 갖는지 확인할 필요가 있습니다. 초기화되지 않은 채 조용히 남겨진 플래그가 없어야 합니다. 판별 단서는 간단합니다. 삭제된 초기화 리스트에는 있었지만 새 헤더에 대응하는 { false } / { true }가 보이지 않는 플래그를 찾으면 됩니다. shouldNotBeUsedForArabic이나 system fallback 표시용 플래그가 초기화되지 않은 상태라면, glyph fallback과 bidi 텍스트 렌더링에 영향을 줄 가능성이 있습니다. 이 영역은 과거 spoofing에 가까운 버그가 반복적으로 나온 지점이기도 합니다. 더 넓게는, FontInternalAttributes::ensureRenderingResourceIdentifier의 lazy identifier 로직이 thread-safe FontBase 서브클래스가 추가된 이후 어떻게 동작하는지 추적해 볼 필요가 있습니다. 여기서 identifier 충돌이나 race가 발생하면 RemoteRenderingBackend의 cross-process 리소스 매칭에 직접 영향을 미칩니다. 일반화하면, 곧 동시 생성이 가능해질 타입에서 identifier를 lazy하게 할당하는 패턴을 눈여겨보아야 합니다. 가장 넓게는, 초기화 리스트의 멤버를 base 클래스로 끌어올리는 기계적 작업 자체가 기본값이 조용히 사라질 위험을 항상 동반합니다. 이식 가능한 점검 방법은 빌드가 잡아주기를 기대하지 않는 것입니다. 제거된 초기화 리스트와 새 헤더의 멤버 초기화를 필드 단위로 하나씩 대조하면 됩니다.