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 года. Мы проконсультируем вас и предложим наилучшее решение.