Skia는 C++로 작성된 고성능 오픈 소스 2D 그래픽 라이브러리로, Flutter의 기본 렌더링 엔진 역할을 합니다. 높은 수준의 위젯과 인터페이스 요소를 화면의 픽셀로 변환하는 역할을 담당하며, CPU를 통한 소프트웨어 렌더링과 OpenGL, Vulkan 및 Metal을 통한 하드웨어 가속을 지원합니다. Skia Documentation (2025)에 따르면, Skia는 Android, Chrome 및 Flutter 기기에서 매일 20억 개 이상의 렌더링된 프레임을 처리합니다.
핵심 요약
Skia는 Google이 개발하고 BSD 라이선스로 제공되는 크로스 플랫폼 2D 그래픽 라이브러리입니다. 기하학적 도형, 텍스트, 이미지 및 그림자를 그리기 위한 통합 API를 제공하며, 기본 그래픽 백엔드를 추상화합니다. Skia는 C++로 작성되었으며 모바일 폰에서 서버에 이르기까지 다양한 기기에서 작동하도록 최적화되어 있습니다.
Skia의 역사는 2005년 Skia Inc.의 독점 라이브러리로 시작되었습니다. 2007년 Google이 인수하여 소스를 공개하고 자사 제품에 사용하기 시작했습니다. 오늘날 Skia는 Google Chrome(Chrome OS 포함), Android(버전 4.0부터), 그리고 물론 Flutter의 기본 그래픽 엔진입니다. 이 라이브러리는 Google 팀이 유지 관리하며 지속적으로 개선되고 있습니다. 새로운 백엔드, 성능 최적화 및 최신 그래픽 API 지원이 추가되고 있습니다.
Skia의 핵심 특징은 단순한 기본 요소 그리기 함수 모음이 아니라는 점입니다. 곡선 래스터화(경로), 안티앨리어싱, 마스크 오버레이, 투명도 처리 및 색상 보정을 포함하는 완전한 그래픽 파이프라인입니다. Skia는 PNG, JPEG, WebP 및 GIF 이미지 형식을 지원하며, HarfBuzz 엔진을 통한 글리프 셰이핑으로 텍스트를 렌더링할 수 있습니다.
Cairo(GTK에서 사용)나 Quartz 2D(macOS에서 사용)와 달리, Skia는 원래부터 다양한 그래픽 API를 가진 여러 플랫폼에서 작동하도록 설계되었습니다. 이는 Flutter와 같은 크로스 플랫폼 프레임워크에서 장점을 제공합니다. Cairo는 소프트웨어 렌더링 중심인 반면, Skia는 초기부터 GPU 가속을 지원하여 UI 애니메이션에 매우 중요합니다.
Skia 아키텍처는 다계층 파이프라인으로 구축되어 있으며, 각 계층은 그래픽 명령을 픽셀로 변환하는 특정 단계를 담당합니다. 이 구조는 기본 그래픽 API와 독립적으로 상위 계층을 재사용할 수 있게 합니다.
최상위 계층 — Canvas API — 개발자에게 그리기를 위한 추상화를 제공합니다. drawRect, drawCircle, drawPath, drawText 메서드는 기하학적 매개변수와 스타일(색상, 투명도, 변환)을 받습니다. Canvas는 이러한 명령을 일련의 작업으로 변환하여 Skia Pipeline — 실행 전에 최적화되는 내부 명령 그래프 — 으로 전달합니다.
중간 계층 — Surface와 Device — 렌더링이 발생하는 대상 버퍼를 관리합니다. Surface는 지정된 크기, 색상 공간 및 백엔드 유형으로 생성됩니다. Device는 특정 렌더링 백엔드(CPU 래스터화 장치(Raster), OpenGL(GL), Vulkan(Vk) 또는 Metal(Mt))를 구현합니다. Device에는 특정 백엔드에 최적화된 각 그리기 작업의 구현이 포함되어 있습니다.
최하위 계층 — Ganesha(GPU 백엔드) — 하드웨어 가속 렌더링을 구현합니다. Ganesha는 GPU를 사용하여 경로 래스터화, 그래디언트 채우기 및 효과 오버레이를 수행합니다. 명령을 배치로 모아 GPU 상태 전환을 최소화합니다. 각 그래픽 API에는 자체 Ganesha 구현이 있습니다: Skia GL(OpenGL용), Skia Vulkan(Vulkan용), Skia Metal(Metal용).
Skia는 효과를 설명하기 위해 자체 셰이더 언어 SkSL(Skia Shading Language)을 사용합니다. SkSL 코드는 SPIR-V(중간 표현)로 컴파일된 후, 백엔드별 셰이더 형식(GLSL, HLSL, MSL)으로 변환됩니다. 이는 플랫폼에 관계없이 그래픽 효과를 설명하는 통합된 방법을 제공합니다.
Flutter는 모든 플랫폼(Android, iOS, Web, Windows, macOS, Linux)에서 Skia를 기본 렌더링 엔진으로 사용합니다. Flutter 앱이 프레임을 렌더링할 때, 위젯은 RenderObject 트리로 변환된 후 Engine 계층(C++)으로 전달되며, Engine은 최종 렌더링에 Skia를 사용합니다.
프레임 렌더링 프로세스는 여러 단계로 구성됩니다. 먼저 Flutter Engine이 Display List — 무엇을 어떻게 그릴지 설명하는 Canvas API 호출의 시퀀스 — 를 구축합니다. 그런 다음 이 목록은 Skia로 전달되며, Skia는 작업을 파티션(화면 영역)으로 분할하고, 깊이별로 정렬한 후 해당 렌더링 백엔드로 전달합니다. GPU 가속은 Skia가 사용 가능한 그래픽 API를 감지하면 자동으로 활성화됩니다.
Flutter에서 Skia의 주요 장점 중 하나는 Flutter Impeller Preview — 셰이더를 미리 볼 수 있는 기능입니다. Skia는 첫 사용 시 셰이더를 컴파일하여 지연(셰이더 점크)이 발생할 수 있습니다. 이 문제를 해결하기 위해 Flutter는 Impeller — 새로운 렌더링 엔진으로 전환 중이지만, 안정적인 Flutter 버전에서는 Skia가 주요 선택으로 남아 있습니다.
Flutter는 Layer Tree(각 계층이 UI의 일부를 나타내는 레이어 트리) 개념을 사용합니다. Skia는 각 레이어에 대한 그리기 명령을 받고 여러 레이어를 단일 렌더링 패스로 결합할 수 있는지 결정합니다. 레이어 합성은 각 픽셀에 대해 투명도와 블렌드 모드를 고려해야 하므로 복잡한 작업이며, Skia는 GPU 셰이더를 통해 이를 구현합니다.
Skia는 HarfBuzz(셰이핑) 및 ICU(유니코드) 라이브러리와의 통합을 통해 텍스트를 렌더링합니다. Flutter에서 각 텍스트 위젯은 Paragraph 객체를 생성하여 텍스트를 글리프 그리기용 Skia 명령 시리즈로 변환합니다. Skia는 서브픽셀 안티앨리어싱, 폰트 힌팅 및 SkUnicode 라이브러리를 통한 이모지 작업을 지원합니다.
Skia의 성능은 수년간의 최적화와 명령 배치 처리, 텍스처 캐싱, GPU 컨텍스트 전환 최소화 등 여러 기술의 조합 결과입니다. 이는 Flutter에서 각 프레임을 16ms(60FPS) 또는 8ms(120FPS) 내에 렌더링해야 하므로 매우 중요합니다.
| 기술 | 설명 | 향상 |
|---|---|---|
| 배치 처리 | 유사한 작업을 하나의 드로우 콜로 그룹화 | 최대 3배 |
| 텍스처 캐시 | GPU에 이미 로드된 텍스처 재사용 | 최대 2배 |
| Atlas | 작은 텍스처를 하나의 큰 텍스처 아틀라스로 결합 | 최대 1.5배 |
| 지연 렌더링 | 명령 재정렬을 통한 지연 실행 | 최대 2배 |
| 셰이더 사전 컴파일 | Spark/Dart용 셰이더 사전 컴파일 | 최대 4배 |
Flutter 팀의 벤치마크에 따르면, 중간급 기기(Qualcomm Snapdragon 700 시리즈)에서 GPU 가속과 함께 Skia를 사용하면 30개 이상의 위젯이 있는 복잡한 인터페이스를 렌더링할 때 안정적인 60FPS를 제공합니다. 소프트웨어 렌더링(CPU)의 경우 성능이 40~60% 떨어지지만, 단순한 화면에서는 허용 가능한 수준입니다.
Flutter에서 Skia의 주요 성능 문제는 셰이더 점크입니다. 새로운 시각 효과 조합을 가진 요소가 화면에 나타나면 Skia는 즉석에서 새 셰이더를 컴파일합니다. 컴파일에는 50~200ms가 소요될 수 있으며, 그 동안 앱은 프레임을 드롭합니다. 이는 사용자 정의 장식이 있는 긴 목록을 스크롤할 때 특히 두드러집니다. Google은 셰이더를 미리 컴파일하는 새로운 렌더링 엔진 Impeller로 이 문제를 해결하고 있습니다.
Skia는 다양한 플랫폼을 지원하며, 각 플랫폼은 자체 렌더링 백엔드를 사용합니다. 백엔드 선택은 대상 플랫폼과 사용 가능한 그래픽 API에 따라 Flutter Engine 빌드 시 결정됩니다.
Android에서 Skia는 OpenGL ES(모든 기기) 및 Vulkan(Android 7.0+ Vulkan 지원 기기)을 통해 작동합니다. 백엔드는 자동으로 선택되며, Vulkan이 더 낮은 드라이버 지연 시간을 제공하므로 선호됩니다. Android는 HWUI(Hardware Accelerated UI)를 통한 시스템 UI 렌더링에도 Skia를 사용하므로, Skia는 Flutter뿐만 아니라 운영 체제의 일부가 됩니다.
iOS에서 Skia는 Apple의 독점 그래픽 API인 Metal을 사용합니다. Metal은 최소한의 오버헤드로 GPU에 대한 저수준 액세스를 제공합니다. Metal(2014) 도입 전에는 iOS에서 Skia가 OpenGL ES를 사용했지만, 현재 Flutter 버전에서는 Metal이 iOS의 유일한 GPU 백엔드이며, OpenGL 대비 최대 30%의 성능 향상을 제공합니다.
데스크톱에서 Skia는 OpenGL(macOS, Linux)과 Direct3D 12(Windows)를 사용합니다. Direct3D 12 지원은 Flutter 3.13에서 Windows용으로 추가되었으며, Windows에서 OpenGL 대비 상당한 성능 향상을 제공합니다. Skia는 또한 이전 그래픽 드라이버와의 하위 호환성을 위해 Windows에서 ANGLE(Direct3D 위의 OpenGL)을 통한 소프트웨어 렌더링도 지원합니다.
Flutter for Web에서 Skia는 WebAssembly(Emscripten을 통해)로 컴파일되어 WebGL을 통해 렌더링합니다. 이 모드에서 Skia는 네이티브 코드 없이 브라우저 내에서 완전히 작동합니다. Skia의 WebGL 버전 성능은 네이티브 백엔드보다 낮지만, 대부분의 웹 애플리케이션에서는 WebGL 하드웨어 가속을 지원하는 최신 브라우저에서 60FPS를 달성합니다.
자주 묻는 질문
셰이더 점크는 셰이더의 즉석 컴파일로 인한 렌더링 지연입니다. Skia가 새로운 시각 효과 조합을 만나면 셰이더를 컴파일하는데 50~200ms가 걸릴 수 있으며, 그 동안 프레임이 드롭됩니다. 이 문제는 Impeller에서 셰이더 사전 컴파일로 해결됩니다.
네, Skia는 독립적인 그래픽 라이브러리로 사용할 수 있습니다. Google Chrome, Android, Mozilla Firefox(Skia 계층을 통해) 및 고성능 2D 그래픽이 필요한 프로젝트에서 사용됩니다. Skia API는 C++, Python 및 다른 언어의 바인딩을 통해 사용할 수 있습니다.
Flutter는 Skia의 포크(일반적으로 Google 메인 리포지토리의 최신 안정 커밋)를 사용합니다. 버전은 Flutter Engine 릴리스마다 업데이트됩니다. 현재 커밋은 GitHub의 flutter/engine 리포지토리에 있는 DEPS 파일에서 확인할 수 있습니다.
Skia는 런타임에 셰이더를 컴파일하여 셰이더 점크가 발생합니다. Impeller는 셰이더를 오프라인에서 사전 컴파일하고, SPIR-V를 사용하며 Vulkan/Metal/Direct3D 12를 통해 직접 작동합니다. Impeller는 셰이더 점크의 영향을 받지 않으며 더 예측 가능한 성능을 제공합니다.
Skia 자체는 애니메이션 엔진이 아니라 개별 프레임의 렌더링을 담당합니다. Flutter의 애니메이션은 프레임워크 수준(AnimationController, Tween)에서 구현되며, Skia는 Canvas API와 하드웨어 가속을 사용하여 각 프레임의 빠른 렌더링을 보장합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.