Skia è una libreria grafica 2D ad alte prestazioni con codice sorgente aperto, scritta in C++, che funge da motore di rendering principale di Flutter. È responsabile della conversione di widget di alto livello ed elementi dell'interfaccia in pixel sullo schermo, supportando il rendering software tramite CPU e l'accelerazione hardware tramite OpenGL, Vulkan e Metal. Secondo Skia Documentation (2025), Skia elabora oltre 2 miliardi di fotogrammi renderizzati ogni giorno su dispositivi Android, Chrome e Flutter.
Punti chiave
Skia è una libreria grafica 2D multipiattaforma sviluppata da Google e disponibile sotto licenza BSD. Fornisce un'API unificata per disegnare forme geometriche, testo, immagini e ombre, astraendo il backend grafico sottostante. Skia è scritta in C++ e ottimizzata per funzionare su un'ampia gamma di dispositivi, dai telefoni cellulari ai server.
La storia di Skia iniziò nel 2005 come libreria proprietaria dell'azienda Skia Inc. Nel 2007 fu acquisita da Google, che ne aprì il codice sorgente e iniziò a utilizzarla nei propri prodotti. Oggi Skia è il motore grafico principale di Google Chrome (incluso Chrome OS), Android (a partire dalla versione 4.0) e, naturalmente, Flutter. La libreria è mantenuta dal team di Google e viene costantemente migliorata: vengono aggiunti nuovi backend, ottimizzazioni delle prestazioni e supporto per API grafiche moderne.
La caratteristica principale di Skia è che non è solo un insieme di funzioni per disegnare primitive. È una pipeline grafica completa che include rasterizzazione di curve (percorsi), anti-aliasing, sovrapposizione di maschere, gestione della trasparenza e correzione del colore. Skia supporta i formati immagine PNG, JPEG, WebP e GIF e può renderizzare testo tramite il motore HarfBuzz per lo shaping dei glifi.
A differenza di Cairo (usato in GTK) o Quartz 2D (usato in macOS), Skia è stata progettata fin dall'inizio per funzionare su più piattaforme con diverse API grafiche. Questo le dà un vantaggio in framework multipiattaforma come Flutter. Cairo è orientato al rendering software, mentre Skia ha supportato l'accelerazione GPU fin dall'inizio, aspetto fondamentale per le animazioni dell'interfaccia.
L'architettura di Skia è costruita come una pipeline multistrato, dove ogni strato è responsabile di una fase specifica della conversione dei comandi grafici in pixel. Questa struttura consente di riutilizzare gli strati superiori indipendentemente dall'API grafica sottostante.
Lo strato superiore — Canvas API — fornisce allo sviluppatore un'astrazione per il disegno. I metodi drawRect, drawCircle, drawPath, drawText accettano parametri geometrici e stili (colore, trasparenza, trasformazioni). Canvas converte questi comandi in una sequenza di operazioni che vengono passate alla Skia Pipeline — un grafo di comandi interno ottimizzato prima dell'esecuzione.
Lo strato intermedio — Surface e Device — gestisce il buffer di destinazione in cui avviene il rendering. Surface viene creata con le dimensioni, lo spazio colore e il tipo di backend specificati. Device implementa un backend di rendering specifico: rasterizzatore CPU (Raster), OpenGL (GL), Vulkan (Vk) o Metal (Mt). Device contiene implementazioni ottimizzate di ogni operazione di disegno per un backend specifico.
Lo strato inferiore — Ganesha (backend GPU) — implementa il rendering accelerato via hardware. Ganesha utilizza la GPU per la rasterizzazione dei percorsi, i riempimenti sfumati e la sovrapposizione di effetti. Raccoglie i comandi in batch e minimizza il cambio di stato della GPU. Ogni API grafica ha la propria implementazione Ganesha: Skia GL per OpenGL, Skia Vulkan per Vulkan, Skia Metal per Metal.
Skia utilizza un proprio linguaggio shader SkSL (Skia Shading Language) per descrivere gli effetti. Il codice SkSL viene compilato in SPIR-V (rappresentazione intermedia), che viene poi tradotto in un formato shader specifico del backend (GLSL, HLSL, MSL). Questo fornisce un modo unificato per descrivere gli effetti grafici indipendentemente dalla piattaforma.
Flutter utilizza Skia come motore di rendering principale su tutte le piattaforme: Android, iOS, Web, Windows, macOS e Linux. Quando un'applicazione Flutter renderizza un fotogramma, i widget vengono convertiti in un albero RenderObject, che viene poi passato al layer Engine (in C++), e l'Engine utilizza Skia per il rendering finale.
Il processo di rendering di un fotogramma include diverse fasi. Prima, il Flutter Engine costruisce una Display List — una sequenza di chiamate all'API Canvas che descrivono cosa e come disegnare. Questa lista viene poi passata a Skia, che divide le operazioni in partizioni (aree dello schermo), le ordina per profondità e le passa al backend di rendering corrispondente. L'accelerazione GPU viene attivata automaticamente se Skia rileva un'API grafica disponibile.
Uno dei principali vantaggi di Skia in Flutter è il Flutter Impeller Preview — la possibilità di visualizzare in anteprima gli shader. Skia compila gli shader al momento del primo utilizzo, il che può causare ritardi (shader jank). Per risolvere questo problema, Flutter sta migrando verso Impeller — un nuovo motore di rendering, ma Skia rimane la scelta principale per le versioni stabili di Flutter.
Flutter utilizza il concetto di Layer Tree — un albero di layer, ciascuno dei quali rappresenta una parte dell'interfaccia utente. Skia riceve comandi di disegno per ogni layer e determina se più layer possono essere combinati in un unico passaggio di rendering. La composizione dei layer è un'operazione complessa, poiché per ogni pixel è necessario considerare la trasparenza e le modalità di fusione (blend modes), che Skia implementa tramite shader GPU.
Skia renderizza il testo tramite l'integrazione con le librerie HarfBuzz (shaping) e ICU (unicode). In Flutter, ogni widget di testo crea un oggetto Paragraph che converte il testo in una serie di comandi Skia per disegnare i glifi. Skia supporta l'anti-aliasing subpixel, l'hinting dei font e il lavoro con le emoji tramite la libreria SkUnicode.
Le prestazioni di Skia sono il risultato di anni di ottimizzazione e della combinazione di diverse tecniche: raggruppamento dei comandi in batch, caching delle texture e minimizzazione del cambio di contesto della GPU. Questo è di fondamentale importanza per Flutter, poiché ogni fotogramma deve essere renderizzato in 16 ms (60 FPS) o 8 ms (120 FPS).
| Tecnica | Descrizione | Miglioramento |
|---|---|---|
| Batching | Raggruppamento di operazioni simili in un'unica chiamata di disegno | fino a 3x |
| Cache texture | Riutilizzo delle texture già caricate nella GPU | fino a 2x |
| Atlas | Combinazione di texture piccole in un unico texture atlas | fino a 1.5x |
| Rendering differito | Esecuzione ritardata dei comandi con riordino | fino a 2x |
| Precompilazione shader | Compilazione anticipata degli shader per Spark/Dart | fino a 4x |
Secondo i benchmark del Team Flutter, l'uso di Skia con accelerazione GPU su dispositivi di fascia media (Qualcomm Snapdragon 700 series) garantisce 60 FPS stabili durante il rendering di interfacce complesse con oltre 30 widget sullo schermo. Con il rendering software (CPU), le prestazioni calano del 40–60%, ma rimangono accettabili per schermate semplici.
Il principale problema di prestazioni di Skia in Flutter è lo shader jank (rallentamenti dovuti agli shader). Quando sullo schermo appare un nuovo elemento visivo con una combinazione sconosciuta di effetti, Skia compila un nuovo shader al volo. La compilazione può richiedere 50–200 ms, durante i quali l'applicazione perde fotogrammi. Questo è particolarmente evidente durante lo scorrimento di elenchi lunghi con decorazioni personalizzate. Google sta risolvendo questo problema con Impeller, un nuovo motore di rendering che compila gli shader in anticipo.
Skia supporta un'ampia gamma di piattaforme, ciascuna con il proprio backend di rendering. La scelta del backend viene determinata durante la compilazione del Flutter Engine in base alla piattaforma target e alle API grafiche disponibili.
Su Android, Skia funziona tramite OpenGL ES (su tutti i dispositivi) e Vulkan (su dispositivi Android 7.0+ con supporto Vulkan). La selezione del backend è automatica: Vulkan è preferito perché offre una latenza del driver inferiore. Android utilizza anche Skia per il rendering dell'interfaccia di sistema tramite HWUI (Hardware Accelerated UI), rendendo Skia parte del sistema operativo, non solo di Flutter.
Su iOS, Skia utilizza Metal — l'API grafica proprietaria di Apple. Metal fornisce accesso di basso livello alla GPU con overhead minimo. Prima dell'introduzione di Metal (2014), Skia su iOS utilizzava OpenGL ES, ma nelle versioni attuali di Flutter Metal è l'unico backend GPU per iOS, offrendo un miglioramento delle prestazioni fino al 30% rispetto a OpenGL.
Sul desktop, Skia utilizza OpenGL (macOS, Linux) e Direct3D 12 (Windows). Il supporto per Direct3D 12 è stato aggiunto in Flutter 3.13 per Windows e offre un miglioramento significativo delle prestazioni rispetto a OpenGL su Windows. Skia supporta anche il rendering software tramite ANGLE (OpenGL su Direct3D) su Windows per la retrocompatibilità con driver grafici più vecchi.
In Flutter for Web, Skia viene compilato in WebAssembly (tramite Emscripten) e renderizza attraverso WebGL. In questa modalità, Skia funziona interamente nel browser senza utilizzare codice nativo. Le prestazioni della versione WebGL di Skia sono inferiori rispetto ai backend nativi, ma per la maggior parte delle applicazioni web si raggiungono 60 FPS sui browser moderni con accelerazione hardware WebGL.
Domande frequenti
Lo shader jank è un ritardo nel rendering causato dalla compilazione degli shader al volo. Quando Skia incontra una nuova combinazione di effetti visivi, compila uno shader, che può richiedere 50–200 ms, durante i quali i fotogrammi vengono persi. Questo problema viene risolto in Impeller con la compilazione anticipata degli shader.
Sì, Skia può essere utilizzato come libreria grafica autonoma. Viene impiegato in Google Chrome, Android, Mozilla Firefox (tramite il layer Skia) e in progetti che richiedono grafica 2D ad alte prestazioni. L'API Skia è disponibile in C++, Python e tramite binding in altri linguaggi.
Flutter utilizza un fork di Skia (di solito l'ultimo commit stabile dal repository principale di Google). La versione viene aggiornata con ogni rilascio del Flutter Engine. Il commit attuale si trova nel file DEPS nel repository flutter/engine su GitHub.
Skia compila gli shader in fase di esecuzione, causando shader jank. Impeller compila gli shader offline (in anticipo), utilizza SPIR-V e funziona direttamente tramite Vulkan/Metal/Direct3D 12. Impeller non soffre di shader jank e offre prestazioni più prevedibili.
Skia di per sé non è un motore di animazione — è responsabile del rendering dei singoli fotogrammi. L'animazione in Flutter è implementata a livello di framework (AnimationController, Tween), mentre Skia garantisce un rendering rapido di ogni fotogramma utilizzando l'API Canvas e l'accelerazione hardware.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.