Slint, Servo와 만나 웹 렌더링 성능을 혁신하다!
Slint는 Rust 기반 GUI 툴킷으로, Servo 브라우저 엔진과의 통합을 통해 웹 콘텐츠 렌더링을 지원한다.
이벤트 루프 동기화(Event Loop Synchronization)를 위해 `EventLoopWaker`를 구현하고, 플랫폼별 GPU 메모리 공유(GPU Memory Sharing)를 통해 렌더링 성능을 최적화했다.
macOS, Linux, Android, Windows 등 다양한 플랫폼에서 Vulkan, Metal, OpenGL을 활용한 렌더링 백엔드를 구현하여 크로스 플랫폼 지원을 강화했다.
터치, 키보드 입력 처리(Touch & Keyboard Input Handling)를 구현하여 웹 뷰(Web View)의 상호작용성을 확보하고, 개발 과정에서의 기술적 도전과 성장을 공유했다.
이벤트 루프 동기화(Event Loop Synchronization) 구현
Servo는 자체 스레드에서 실행되지만, Slint는 메인 스레드의 이벤트 루프를 사용한다. 이를 통합하기 위해, Servo가 새로운 프레임을 그릴 준비가 되었을 때 Slint에 알리기 위한 메커니즘이 필요했다. EventLoopWaker 트레이트를 구현하는 커스텀 `Waker` 구조체를 도입하여 `smol::channel`을 사용해 이 문제를 해결했다. `Waker`는 채널의 송신 측을 보유하고, `wake()`가 호출되면 신호를 보낸다. Slint 메인 루프는 수신 측에서 이를 수신하여 Servo가 필요할 때마다 이벤트 루프를 언블록한다. 이 간단한 메커니즘이 두 엔진을 동기화하는 핵심이다.
플랫폼별 GPU 메모리 공유를 통한 렌더링 최적화
성능 병목 현상을 해결하기 위해 Servo가 GPU에서 직접 렌더링하고, Slint 내에서 해당 텍스처를 재사용하는 방식을 구현했다. macOS에서는 IOSurface를 활용하여 GPU 메모리를 효율적으로 공유한다. 구체적으로, Surfman을 통해 기본 네이티브 표면 핸들을 가져오고, WGPU 인스턴스에서 원시 Metal 장치 포인터를 추출하여 Metal 텍스처를 생성한다. 이후, HAL 텍스처를 생성하고, WGPU 텍스처로 변환한다. 텍스처 좌표계 차이로 인한 문제 해결을 위해, WGPU 렌더링 패스를 사용하여 텍스처를 샘플링하고 수직으로 뒤집는 셰이더를 적용했다.
Vulkan 기반 렌더링 백엔드 구현 (Linux & Android)
Linux에서는 Vulkan 기반 구현을 선택하여 Servo의 OpenGL 컨텍스트와 Slint의 Vulkan 컨텍스트 간에 텍스처를 효율적으로 공유했다. Vulkan 이미지를 생성하고, 전용 메모리를 할당하여 `VK_KHR_external_memory`를 활성화하고, `OPAQUE_FD`를 핸들 유형으로 지정했다. 할당된 메모리에 대한 파일 디스크립터를 `vkGetMemoryFdKHR` API를 사용하여 가져왔다. OpenGL 측에서는 `GL_EXT_memory_object_fd` 확장을 사용하여 해당 파일 디스크립터를 메모리 객체로 가져왔다. Servo의 프레임버퍼 내용을 공유 텍스처에 복사하기 위해 `glBlitFramebuffer`를 사용했으며, 좌표계 차이도 처리했다. 마지막으로, 기본 메모리가 유효한 Vulkan 이미지이므로, `create_texture_from_hal`을 사용하여 wgpu::Texture로 직접 래핑했다.
입력 처리 및 상호작용 구현
웹 뷰의 상호 작용성을 위해 Slint의 포인터 이벤트를 Servo의 입력 시스템에 매핑했다. `TouchPressed`, `TouchReleased`, `TouchMoved` 이벤트를 `WindowEvent`에 추가하여 Android 및 Qt와 같은 백엔드에서 정밀한 터치 처리를 가능하게 했다. 키보드 이벤트 전파를 구현하여 HTML 폼이 자연스럽게 입력을 받을 수 있도록 키 코드를 정확하게 변환했다. 이러한 입력 처리 메커니즘을 통해 사용자는 웹 콘텐츠와 원활하게 상호 작용할 수 있다.
DirectX 기반 렌더링 구현 (Windows)
Windows 환경에서 macOS 및 Linux 구현과 동일한 성능을 달성하기 위해 하드웨어 렌더링 구현을 시작했다. 현재는 소프트웨어 렌더링으로 대체하여 통합이 작동함을 증명했다. 향후 DirectX 기반 하드웨어 렌더링 구현을 통해 성능을 개선할 예정이다.