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アクセラレーションをサポートしており、インターフェースアニメーションにとって重要です。
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は各レイヤーの描画コマンドを受け取り、複数のレイヤーを1回のレンダリングパスに統合できるか判断します。レイヤーコンポジットは複雑なタスクであり、各ピクセルについて透明度とブレンドモードを考慮する必要があり、SkiaはGPUシェーダを通じてこれらを実装します。
SkiaはHarfBuzz(シェーピング)およびICU(ユニコード)ライブラリとの統合を通じてテキストをレンダリングします。Flutterでは、各テキストウィジェットがParagraphオブジェクトを作成し、テキストをグリフ描画用のSkiaコマンドのシリーズに変換します。Skiaはサブピクセルアンチエイリアシング、フォントヒンティング、SkUnicodeライブラリによる絵文字処理をサポートしています。
Skiaのパフォーマンスは長年の最適化と、コマンドのバッチ処理、テクスチャキャッシング、GPUコンテキスト切り替えの最小化といった複数の技術の組み合わせの結果です。これはFlutterにとって非常に重要であり、各フレームは16ミリ秒(60 FPS)または8ミリ秒(120 FPS)でレンダリングされる必要があります。
| 技術 | 説明 | 向上 |
|---|---|---|
| バッチ処理 | 類似操作を1つのドローコールにグループ化 | 最大3倍 |
| テクスチャキャッシュ | GPUに既に読み込まれたテクスチャの再利用 | 最大2倍 |
| アトラス | 小さなテクスチャを1つの大きなテクスチャアトラスに結合 | 最大1.5倍 |
| 遅延レンダリング | 並び替えを伴うコマンドの遅延実行 | 最大2倍 |
| シェーダ事前コンパイル | Spark/Dart用シェーダの事前コンパイル | 最大4倍 |
Flutterチームのベンチマークによると、ミッドレンジデバイス(Qualcomm Snapdragon 700シリーズ)でGPUアクセラレーション付きSkiaを使用すると、30以上のウィジェットを持つ複雑なインターフェースのレンダリングで安定した60 FPSを達成します。ソフトウェアレンダリング(CPU)では、パフォーマンスが40〜60%低下しますが、シンプルな画面では許容範囲です。
FlutterにおけるSkiaの主要なパフォーマンス問題はシェーダジャンクです。これまでにない効果の組み合わせを持つ新しい視覚要素が画面に現れると、Skiaは新しいシェーダをその場でコンパイルします。コンパイルには50〜200ミリ秒かかることがあり、その間アプリケーションはフレームをドロップします。これはカスタムデコレーション付きの長いリストをスクロールする際に特に顕著です。Googleはシェーダを事前にコンパイルする新しいレンダリングエンジンImpellerでこの問題を解決しています。
Skiaは幅広いプラットフォームをサポートし、各プラットフォームは独自のレンダリングバックエンドを使用します。バックエンドの選択は、ターゲットプラットフォームと利用可能なグラフィックAPIに基づいてFlutter Engineビルド時に決定されます。
Androidでは、SkiaはOpenGL ES(全デバイス)およびVulkan(Android 7.0+でVulkan対応デバイス)を介して動作します。バックエンドは自動的に選択され、Vulkanの方がドライバレイテンシが低いため優先されます。AndroidはHWUI(ハードウェアアクセラレーテッド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バージョンのパフォーマンスはネイティブバックエンドより低いですが、ほとんどのWebアプリケーションでは、WebGLハードウェアアクセラレーションを備えた最新ブラウザで60 FPSを達成できます。
よくある質問
シェーダジャンクとは、シェーダのその場コンパイルによるレンダリング遅延です。Skiaが新しい視覚効果の組み合わせに遭遇すると、シェーダをコンパイルし、その間に50〜200ミリ秒かかり、フレームがドロップされます。この問題は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アプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。