Skia — це високопродуктивна 2D-графічна бібліотека з відкритим вихідним кодом, написана на C++, яка слугує основним рендеринговим рушієм Flutter. Вона відповідає за перетворення високорівневих віджетів та елементів інтерфейсу в пікселі на екрані, підтримуючи програмний рендеринг через CPU та апаратне прискорення через OpenGL, Vulkan і Metal. За даними Skia Documentation (2025), Skia обробляє понад 2 мільярди відрендерених кадрів щодня на пристроях Android, Chrome та Flutter.
Головне
Skia — це крос-платформна 2D-графічна бібліотека, розроблена Google і доступна під ліцензією BSD. Вона надає єдиний API для малювання геометричних фігур, тексту, зображень і тіней, абстрагуючись від графічного бекенду. Skia написана на C++ і оптимізована для роботи на широкому спектрі пристроїв — від мобільних телефонів до серверів.
Історія Skia почалася в 2005 році як закрита бібліотека компанії Skia Inc. У 2007 році її придбала Google, відкрила вихідний код і почала використовувати у своїх продуктах. Сьогодні Skia є основним графічним рушієм Google Chrome (включаючи Chrome OS), Android (починаючи з версії 4.0) і, звісно, Flutter. Бібліотека підтримується командою Google і постійно вдосконалюється: додаються нові бекенди, оптимізації продуктивності та підтримка сучасних графічних API.
Ключова особливість Skia — це не просто набір функцій для малювання примітивів. Це повноцінний графічний конвеєр, що включає растеризацію кривих (шляхів), згладжування (anti-aliasing), накладання масок, обробку прозорості та кольорокорекцію. Skia підтримує формати зображень PNG, JPEG, WebP та GIF, а також може рендерити текст через рушій HarfBuzz для шейпінгу гліфів.
На відміну від Cairo (використовується в GTK) або Quartz 2D (використовується в macOS), Skia спочатку проєктувалася для роботи на кількох платформах з різними графічними API. Це дає їй перевагу в крос-платформних фреймворках, таких як Flutter. Cairo орієнтований на програмний рендеринг, а Skia з самого початку підтримувала GPU-прискорення, що критично для анімацій інтерфейсу.
Архітектура 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 використовує Skia як основний рендеринговий рушій на всіх платформах: Android, iOS, Web, Windows, macOS і Linux. Коли Flutter-застосунок рендерить кадр, віджети перетворюються в дерево RenderObject, яке потім передається шару Engine (на C++), і саме Engine використовує Skia для фінального рендерингу.
Процес рендерингу кадру включає кілька етапів. Спочатку Flutter Engine будує список операцій (Display List) — послідовність викликів Canvas API, що описують що і як малювати. Потім цей список передається в Skia, яка розбиває операції на партиції (області екрану), сортує їх за глибиною та передає у відповідний бекенд рендерингу. GPU-прискорення вмикається автоматично, якщо Skia виявляє доступний графічний API.
Однією з ключових переваг Skia у Flutter є Flutter Impeller Preview — можливість попереднього перегляду шейдерів. Skia компілює шейдери в момент першого використання, що може викликати затримки (shader jank). Для вирішення цієї проблеми Flutter переходить на Impeller — новий рушій рендерингу, але Skia залишається основним вибором для стабільних версій Flutter.
Flutter використовує концепцію Layer Tree — дерева шарів, кожен з яких представляє частину UI. Skia отримує команди малювання для кожного шару та визначає, чи можна об'єднати кілька шарів в один прохід рендерингу. Змішування шарів (layer compositing) — складне завдання, оскільки для кожного пікселя потрібно враховувати прозорість і режими накладання (blend modes), які Skia реалізує через GPU-шейдери.
Skia рендерить текст через інтеграцію з бібліотеками HarfBuzz (шейпінг) та ICU (юнікод). У Flutter кожен текстовий віджет створює об'єкт Paragraph, який перетворює текст у серію команд Skia для малювання гліфів. Skia підтримує субпіксельне згладжування (subpixel anti-aliasing), хінтинг шрифтів та роботу з емодзі через бібліотеку SkUnicode.
Продуктивність Skia є результатом багаторічної оптимізації та комбінації кількох технік: батчингу команд, кешування текстур та мінімізації перемикання контексту GPU. Для Flutter це критично важливо, оскільки кожен кадр має бути відрендерений за 16 мс (60 FPS) або 8 мс (120 FPS).
| Техніка | Опис | Приріст |
|---|---|---|
| Батчинг | Групування однотипних операцій в один draw call | до 3x |
| Кеш текстур | Повторне використання вже завантажених текстур у GPU | до 2x |
| Atlas | Об'єднання дрібних текстур в одну велику (texture atlas) | до 1.5x |
| Deferred rendering | Відкладене виконання команд з переупорядкуванням | до 2x |
| Shader precompilation | Попередня компіляція шейдерів для Spark/Dart | до 4x |
За даними бенчмарків Flutter Team, використання Skia з GPU-прискоренням на пристроях середнього класу (Qualcomm Snapdragon 700 series) забезпечує стабільні 60 FPS при рендерингу складних інтерфейсів з 30+ віджетами на екрані. При програмному рендерингу (CPU) продуктивність падає на 40–60%, але залишається прийнятною для простих екранів.
Основна проблема продуктивності Skia у Flutter — це shader jank (шейдерні лаги). Коли на екрані з'являється новий візуальний елемент з невідомим раніше поєднанням ефектів, Skia компілює новий шейдер на льоту. Компіляція може зайняти 50–200 мс, протягом яких застосунок пропускає кадри. Це особливо помітно при скролі довгих списків з кастомними декораціями. Google вирішує цю проблему в Impeller, новому рушії рендерингу, який компілює шейдери заздалегідь.
Skia підтримує широкий спектр платформ, кожна з яких використовує свій рендеринговий бекенд. Вибір бекенду визначається на етапі збірки Flutter Engine на основі цільової платформи та доступних графічних API.
На Android Skia працює через OpenGL ES (на всіх пристроях) і Vulkan (на пристроях Android 7.0+ з підтримкою Vulkan). Вибір бекенду відбувається автоматично: Vulkan є більш бажаним, оскільки дає нижчу затримку драйвера. Android також використовує Skia для рендерингу системного UI через HWUI (Hardware Accelerated UI), що робить Skia частиною операційної системи, а не тільки Flutter.
На iOS Skia використовує Metal — пропрієтарний графічний API Apple. Metal забезпечує низькорівневий доступ до GPU та мінімальні накладні витрати. До появи Metal (2014) Skia на iOS використовувала OpenGL ES, але в поточних версіях Flutter Metal є єдиним GPU-бекендом для iOS, що дає приріст продуктивності до 30% порівняно з OpenGL.
На десктопі Skia використовує OpenGL (macOS, Linux) і Direct3D 12 (Windows). Для Windows підтримка Direct3D 12 була додана у Flutter 3.13 і дає значне покращення продуктивності порівняно з OpenGL на Windows. Skia також підтримує програмний рендеринг через ANGLE (OpenGL поверх Direct3D) на Windows для зворотної сумісності зі старими графічними драйверами.
У Flutter for Web Skia компілюється у WebAssembly (via Emscripten) і рендерить через WebGL. У цьому режимі Skia працює повністю в браузері, не використовуючи нативний код. Продуктивність WebGL-версії Skia нижча, ніж нативних бекендів, але для більшості веб-застосунків 60 FPS досягаються на сучасних браузерах з апаратним прискоренням WebGL.
Часті запитання
Shader jank — це затримка рендерингу через компіляцію шейдерів на льоту. Коли Skia зустрічає нове поєднання візуальних ефектів, вона компілює шейдер, що може зайняти 50–200 мс, протягом яких кадри пропускаються. Проблема вирішується в Impeller попередньою компіляцією шейдерів.
Так, Skia може використовуватися як самостійна графічна бібліотека. Її застосовують у Google Chrome, Android, Mozilla Firefox (через Skia-шар) і в проєктах, що потребують високопродуктивної 2D-графіки. Для підключення використовується Skia API, доступний на C++, Python і через біндинги на інших мовах.
Flutter використовує форк Skia (зазвичай останній стабільний коміт з основного репозиторію Google). Версія оновлюється з кожним релізом Flutter Engine. Актуальний коміт можна знайти у файлі DEPS у репозиторії flutter/engine на GitHub.
Skia компілює шейдери під час виконання, що викликає shader jank. Impeller компілює шейдери заздалегідь (offline), використовує SPIR-V і працює напряму через Vulkan/Metal/Direct3D 12. Impeller не страждає від шейдерних лагів і забезпечує більш передбачувану продуктивність.
Skia сама по собі не є анімаційним рушієм — вона відповідає за рендеринг окремих кадрів. Анімація у Flutter реалізується на рівні фреймворку (AnimationController, Tween), а Skia забезпечує швидкий рендеринг кожного кадру за допомогою Canvas API та апаратного прискорення.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.