Skia và Impeller - Graphics Engines
Flutter sử dụng graphics engine để vẽ UI lên màn hình. Hiểu về Skia và Impeller giúp bạn nắm được cách Flutter render hiệu quả.
1. Graphics Engine là gì?
┌─────────────────────────────────────────────────────────────────────┐
│ Graphics Engine Role │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Flutter Framework │
│ │ │
│ │ "Vẽ hình chữ nhật đỏ, ở vị trí (100, 100)" │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Graphics Engine (Skia / Impeller) │ │
│ │ │ │
│ │ Chuyển đổi high-level commands → GPU instructions │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ GPU opcodes, shaders, textures │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ GPU │ │
│ │ (Vẽ pixels lên màn hình) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘2. Skia - Graphics Engine truyền thống
2.1 Skia là gì?
Skia là thư viện 2D graphics open-source được Google phát triển, sử dụng trong:
- Google Chrome
- Android
- Firefox
- Flutter (từ đầu đến nay)
┌─────────────────────────────────────────────────────────────────────┐
│ SKIA │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Đặc điểm: │
│ ├── Cross-platform (Windows, macOS, Linux, Android, iOS) │
│ ├── Hardware accelerated (OpenGL, Vulkan, Metal) │
│ ├── Software rendering fallback │
│ └── Mature, battle-tested (20+ years) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Skia Architecture │ │
│ │ │ │
│ │ Flutter Paint Commands │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ SkCanvas │ ← Drawing API │ │
│ │ └──────┬───────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ SkPicture │ ← Recorded commands │ │
│ │ └──────┬───────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ SkSL Shaders │────▶│ GPU Backend │ │ │
│ │ └──────────────┘ └──────┬───────┘ │ │
│ │ ▼ │ │
│ │ OpenGL / Vulkan / Metal │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘2.2 Vấn đề của Skia với Flutter
┌─────────────────────────────────────────────────────────────────────┐
│ Skia Limitations trong Flutter │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. SHADER COMPILATION JANK │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Frame 1: Animation bắt đầu │ │
│ │ ↓ │ │
│ │ Frame 2: Cần shader mới │ │
│ │ ↓ │ │
│ │ ⚠️ GPU ĐANG COMPILE SHADER... │ │
│ │ ↓ (có thể mất 100-200ms!) │ │
│ │ Frame 3, 4, 5: BỊ DROP (jank!) │ │
│ │ ↓ │ │
│ │ Frame 6: Shader ready, tiếp tục smooth │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 2. SHADER COMPILATION ĐÚNG LÚC RUNTIME │
│ • Skia compile shaders khi CẦN (just-in-time) │
│ • Không thể pre-compile tất cả shaders │
│ • Shader cache giúp nhưng không hoàn toàn │
│ │
│ 3. KHÔNG TỐI ƯU CHO MOBILE GPU │
│ • Skia thiết kế cho desktop/Chrome trước │
│ • Mobile GPU có đặc điểm khác (tile-based) │
│ │
└─────────────────────────────────────────────────────────────────────┘3. Impeller - Graphics Engine thế hệ mới
3.1 Impeller là gì?
Impeller là graphics engine mới được Flutter team xây dựng từ đầu, thiết kế riêng cho Flutter.
┌─────────────────────────────────────────────────────────────────────┐
│ IMPELLER │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Triết lý thiết kế: │
│ ├── PRE-COMPILED shaders (AOT, không JIT) │
│ ├── Thiết kế cho mobile GPU (tile-based rendering) │
│ ├── Modern API first (Metal, Vulkan) │
│ └── Simpler codebase, easier maintenance │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Impeller Architecture │ │
│ │ │ │
│ │ Flutter Paint Commands │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Display List │ ← Optimized command buffer │ │
│ │ └──────┬───────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ PRE-COMPILED SHADERS │ │ │
│ │ │ (Compiled at BUILD TIME, not runtime!) │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Metal │ │ Vulkan │ │ │
│ │ │ (iOS/macOS) │ │ (Android) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘3.2 Tại sao Impeller nhanh hơn?
┌─────────────────────────────────────────────────────────────────────┐
│ Impeller vs Skia: Shader Compilation │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ SKIA IMPELLER │
│ │
│ Build Time: Build Time: │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ App Code │ │ App Code │ │
│ │ Compile │ │ Compile │ │
│ │ │ │ SHADERS │ │
│ │ │ │ COMPILE │ ←NEW! │
│ └──────────────┘ └──────────────┘ │
│ │
│ Runtime: Runtime: │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ App Running │ │ App Running │ │
│ │ │ │ │ │
│ │ Need shader? │ │ Need shader? │ │
│ │ ↓ │ │ ↓ │ │
│ │ COMPILE │ ← JANK! │ USE │ ← SMOOTH!│
│ │ at runtime │ │ precompiled │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ Kết quả: Jank! Kết quả: Smooth! │
│ │
└─────────────────────────────────────────────────────────────────────┘4. So sánh Skia vs Impeller
┌─────────────────────────────────────────────────────────────────────┐
│ SKIA vs IMPELLER │
├────────────────────────┬────────────────────────────────────────────┤
│ SKIA │ IMPELLER │
├────────────────────────┼────────────────────────────────────────────┤
│ │ │
│ ✓ Mature, proven │ ✓ No shader jank │
│ ✓ Wide GPU support │ ✓ Designed for mobile │
│ ✓ Software fallback │ ✓ Modern GPU APIs │
│ │ ✓ Predictable performance │
│ ✗ Shader jank │ │
│ ✗ Complex codebase │ ✗ Newer, still evolving │
│ ✗ JIT shader compile │ ✗ Limited GPU support │
│ │ ✗ iOS/Android only (for now) │
│ │ │
├────────────────────────┼────────────────────────────────────────────┤
│ GPU Support: │ GPU Support: │
│ • OpenGL ES │ • Metal (iOS/macOS) │
│ • Vulkan │ • Vulkan (Android) │
│ • Metal │ • OpenGL ES (fallback, coming) │
│ • Direct3D │ │
│ │ │
└────────────────────────┴────────────────────────────────────────────┘5. Impeller Rendering Pipeline
┌─────────────────────────────────────────────────────────────────────┐
│ IMPELLER PIPELINE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. ENTITY PASS CONSTRUCTION │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Flutter's paint commands → EntityPass │ │
│ │ (Optimized for GPU submission) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 2. RENDER TARGET ALLOCATION │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Allocate GPU textures for render targets │ │
│ │ (Smart pooling and reuse) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 3. COMMAND ENCODING │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Encode GPU commands (Metal/Vulkan) │ │
│ │ Using PRE-COMPILED shaders │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 4. GPU SUBMISSION │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Submit command buffer to GPU │ │
│ │ GPU executes (parallel with CPU) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘6. Tình trạng hỗ trợ
┌─────────────────────────────────────────────────────────────────────┐
│ IMPELLER SUPPORT STATUS (2024) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Platform Status Notes │
│ ───────── ────── ───── │
│ iOS ✅ Default Stable since Flutter 3.10 │
│ Android ✅ Default Stable since Flutter 3.16 │
│ macOS 🔄 Preview Opt-in, improving │
│ Windows ❌ Not yet Planned │
│ Linux ❌ Not yet Planned │
│ Web ❌ Not planned Uses CanvasKit (Skia) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Enable Impeller preview (nếu chưa default): │ │
│ │ │ │
│ │ Android: flutter run --enable-impeller │ │
│ │ iOS: Info.plist: FLTEnableImpeller = YES │ │
│ │ │ │
│ │ Disable Impeller: │ │
│ │ flutter run --no-enable-impeller │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘📝 Tóm tắt
| Aspect | Skia | Impeller |
|---|---|---|
| Shader compilation | Runtime (JIT) | Build time (AOT) |
| Jank risk | Có | Không |
| GPU design target | Desktop-first | Mobile-first |
| Codebase | Complex, mature | Simple, new |
| Platform support | Wide | iOS, Android (mở rộng) |
Kết luận:
Impeller là tương lai của Flutter graphics. Với pre-compiled shaders, nó loại bỏ shader jank - một trong những vấn đề lớn nhất của Flutter on mobile.
Last updated on