Skia: bản chất, kiến trúc và vai trò trong công cụ đồ họa Flutter

Tác giả: IT Sectr Đã đăng: 2026-06-04 Thời gian đọc: 10 phút

Skia là một thư viện đồ họa 2D hiệu suất cao với mã nguồn mở, được viết bằng C++, đóng vai trò là công cụ kết xuất chính của Flutter. Nó chịu trách nhiệm chuyển đổi các widget cấp cao và các phần tử giao diện thành pixel trên màn hình, hỗ trợ kết xuất phần mềm qua CPU và tăng tốc phần cứng qua OpenGL, Vulkan và Metal. Theo Skia Documentation (2025), Skia xử lý hơn 2 tỷ khung hình được kết xuất mỗi ngày trên các thiết bị Android, Chrome và Flutter.

Những điểm chính

  • Skia — thư viện đồ họa 2D mã nguồn mở bằng C++, trình kết xuất chính của Flutter
  • Kiến trúc bao gồm kết xuất phần mềm CPU và tăng tốc phần cứng GPU
  • Backend hỗ trợ OpenGL, Vulkan, Metal và Direct3D cho mỗi nền tảng
  • Flutter sử dụng Skia để vẽ tất cả widget, văn bản và hoạt ảnh
  • Hiệu suất được đảm bảo nhờ kết xuất theo lô và đường ống tối ưu hóa

Skia là gì?

Skia là một thư viện đồ họa 2D đa nền tảng được phát triển bởi Google và có sẵn theo giấy phép BSD. Nó cung cấp một API thống nhất để vẽ các hình dạng hình học, văn bản, hình ảnh và bóng, trừu tượng hóa backend đồ họa bên dưới. Skia được viết bằng C++ và được tối ưu hóa để hoạt động trên nhiều loại thiết bị — từ điện thoại di động đến máy chủ.

Lịch sử của Skia bắt đầu vào năm 2005 như một thư viện độc quyền của công ty Skia Inc. Năm 2007, Google mua lại, mở mã nguồn và bắt đầu sử dụng trong các sản phẩm của mình. Ngày nay, Skia là công cụ đồ họa chính của Google Chrome (bao gồm Chrome OS), Android (từ phiên bản 4.0) và tất nhiên là Flutter. Thư viện được duy trì bởi nhóm Google và liên tục được cải thiện: các backend mới, tối ưu hóa hiệu suất và hỗ trợ các API đồ họa hiện đại được thêm vào.

Tính năng chính của Skia là nó không chỉ là một tập hợp các hàm vẽ nguyên thủy. Nó là một đường ống đồ họa hoàn chỉnh bao gồm rasterization đường cong (đường dẫn), khử răng cưa, lớp phủ mặt nạ, xử lý độ trong suốt và hiệu chỉnh màu sắc. Skia hỗ trợ các định dạng hình ảnh PNG, JPEG, WebP và GIF, đồng thời có thể kết xuất văn bản thông qua công cụ HarfBuzz để định hình glyph.

Skia so với các thư viện đồ họa khác

Không giống như Cairo (được sử dụng trong GTK) hay Quartz 2D (được sử dụng trong macOS), Skia được thiết kế ngay từ đầu để hoạt động trên nhiều nền tảng với các API đồ họa khác nhau. Điều này mang lại lợi thế cho nó trong các framework đa nền tảng như Flutter. Cairo tập trung vào kết xuất phần mềm, trong khi Skia đã hỗ trợ tăng tốc GPU ngay từ đầu, điều rất quan trọng cho hoạt ảnh giao diện.

Kiến trúc Skia

Kiến trúc Skia được xây dựng như một đường ống đa lớp, trong đó mỗi lớp chịu trách nhiệm cho một giai đoạn cụ thể của việc chuyển đổi lệnh đồ họa thành pixel. Cấu trúc này cho phép tái sử dụng các lớp trên một cách độc lập với API đồ họa bên dưới.

Lớp trên cùng — Canvas API — cung cấp cho nhà phát triển một sự trừu tượng để vẽ. Các phương thức drawRect, drawCircle, drawPath, drawText nhận các tham số hình học và kiểu (màu sắc, độ trong suốt, phép biến đổi). Canvas chuyển đổi các lệnh này thành một chuỗi các hoạt động được chuyển đến Skia Pipeline — một đồ thị lệnh nội bộ được tối ưu hóa trước khi thực thi.

Lớp giữa — Surface và Device — quản lý bộ đệm đích nơi kết xuất diễn ra. Surface được tạo với kích thước, không gian màu và loại backend được chỉ định. Device triển khai một backend kết xuất cụ thể: bộ rasterizer CPU (Raster), OpenGL (GL), Vulkan (Vk) hoặc Metal (Mt). Device chứa các triển khai được tối ưu hóa của mỗi hoạt động vẽ cho một backend cụ thể.

Lớp dưới cùng — Ganesha (backend GPU) — triển khai kết xuất tăng tốc phần cứng. Ganesha sử dụng GPU để rasterization đường dẫn, tô màu chuyển sắc và lớp phủ hiệu ứng. Nó thu thập các lệnh thành lô và giảm thiểu việc chuyển đổi trạng thái GPU. Mỗi API đồ họa có triển khai Ganesha riêng: Skia GL cho OpenGL, Skia Vulkan cho Vulkan, Skia Metal cho Metal.

Biểu diễn trung gian — SkSL

Skia sử dụng ngôn ngữ shader riêng SkSL (Skia Shading Language) để mô tả các hiệu ứng. Mã SkSL được biên dịch thành SPIR-V (biểu diễn trung gian), sau đó được dịch sang định dạng shader cụ thể cho backend (GLSL, HLSL, MSL). Điều này cung cấp một cách thống nhất để mô tả các hiệu ứng đồ họa bất kể nền tảng.

Cách Skia hoạt động trong Flutter

Flutter sử dụng Skia làm công cụ kết xuất chính trên tất cả các nền tảng: Android, iOS, Web, Windows, macOS và Linux. Khi một ứng dụng Flutter kết xuất một khung hình, các widget được chuyển đổi thành cây RenderObject, sau đó được chuyển đến lớp Engine (bằng C++), và Engine sử dụng Skia để kết xuất cuối cùng.

Quá trình kết xuất khung hình bao gồm nhiều giai đoạn. Đầu tiên, Flutter Engine xây dựng Display List — một chuỗi các lệnh gọi Canvas API mô tả vẽ gì và vẽ như thế nào. Danh sách này sau đó được chuyển đến Skia, nó chia các hoạt động thành các phân vùng (vùng màn hình), sắp xếp theo độ sâu và chuyển đến backend kết xuất tương ứng. Tăng tốc GPU được tự động bật nếu Skia phát hiện một API đồ họa khả dụng.

Một trong những lợi thế chính của Skia trong Flutter là Flutter Impeller Preview — khả năng xem trước shader. Skia biên dịch shader tại thời điểm sử dụng lần đầu, có thể gây ra độ trễ (shader jank). Để giải quyết vấn đề này, Flutter đang chuyển sang Impeller — một công cụ kết xuất mới, nhưng Skia vẫn là lựa chọn chính cho các phiên bản Flutter ổn định.

Layer Tree và Paint

Flutter sử dụng khái niệm Layer Tree — một cây các lớp, mỗi lớp đại diện cho một phần của UI. Skia nhận các lệnh vẽ cho mỗi lớp và xác định liệu có thể kết hợp nhiều lớp thành một lượt kết xuất hay không. Việc tổng hợp lớp là một tác vụ phức tạp, vì đối với mỗi pixel cần xem xét độ trong suốt và chế độ hòa trộn (blend modes), mà Skia triển khai thông qua shader GPU.

Kết xuất văn bản qua Skia

Skia kết xuất văn bản thông qua tích hợp với các thư viện HarfBuzz (định hình) và ICU (unicode). Trong Flutter, mỗi widget văn bản tạo một đối tượng Paragraph chuyển đổi văn bản thành một chuỗi các lệnh Skia để vẽ glyph. Skia hỗ trợ khử răng cưa subpixel, hinting phông chữ và làm việc với biểu tượng cảm xúc thông qua thư viện SkUnicode.

Hiệu suất của Skia

Hiệu suất của Skia là kết quả của nhiều năm tối ưu hóa và sự kết hợp của nhiều kỹ thuật: xử lý theo lô lệnh, lưu trữ đệm texture và giảm thiểu chuyển đổi ngữ cảnh GPU. Điều này rất quan trọng đối với Flutter, vì mỗi khung hình phải được kết xuất trong 16 ms (60 FPS) hoặc 8 ms (120 FPS).

Kỹ thuậtMô tảCải thiện
Xử lý theo lôNhóm các hoạt động tương tự vào một lệnh gọi vẽlên đến 3x
Bộ nhớ đệm textureTái sử dụng texture đã tải trong GPUlên đến 2x
AtlasKết hợp các texture nhỏ thành một atlas texture lớnlên đến 1.5x
Kết xuất trì hoãnThực thi lệnh bị trì hoãn với sắp xếp lạilên đến 2x
Biên dịch trước shaderBiên dịch trước shader cho Spark/Dartlên đến 4x

Theo điểm chuẩn của Nhóm Flutter, việc sử dụng Skia với tăng tốc GPU trên các thiết bị tầm trung (Qualcomm Snapdragon 700 series) mang lại 60 FPS ổn định khi kết xuất các giao diện phức tạp với hơn 30 widget trên màn hình. Với kết xuất phần mềm (CPU), hiệu suất giảm 40–60%, nhưng vẫn chấp nhận được cho các màn hình đơn giản.

Shader Jank — vấn đề chính của Skia

Vấn đề hiệu suất chính của Skia trong Flutter là shader jank (giật lag shader). Khi một phần tử trực quan mới với sự kết hợp hiệu ứng chưa từng biết xuất hiện trên màn hình, Skia biên dịch một shader mới ngay lập tức. Việc biên dịch có thể mất 50–200 ms, trong thời gian đó ứng dụng bỏ qua khung hình. Điều này đặc biệt đáng chú ý khi cuộn các danh sách dài với trang trí tùy chỉnh. Google đang giải quyết vấn đề này với Impeller, một công cụ kết xuất mới biên dịch shader trước.

Skia trên các nền tảng khác nhau

Skia hỗ trợ nhiều nền tảng, mỗi nền tảng sử dụng backend kết xuất riêng. Việc chọn backend được xác định trong quá trình xây dựng Flutter Engine dựa trên nền tảng mục tiêu và các API đồ họa khả dụng.

Android

Trên Android, Skia hoạt động qua OpenGL ES (trên tất cả thiết bị) và Vulkan (trên thiết bị Android 7.0+ hỗ trợ Vulkan). Việc chọn backend diễn ra tự động: Vulkan được ưu tiên vì độ trễ driver thấp hơn. Android cũng sử dụng Skia để kết xuất UI hệ thống qua HWUI (Hardware Accelerated UI), biến Skia thành một phần của hệ điều hành, không chỉ của Flutter.

iOS

Trên iOS, Skia sử dụng Metal — API đồ họa độc quyền của Apple. Metal cung cấp quyền truy cập cấp thấp vào GPU với chi phí tối thiểu. Trước khi Metal ra đời (2014), Skia trên iOS sử dụng OpenGL ES, nhưng trong các phiên bản Flutter hiện tại, Metal là backend GPU duy nhất cho iOS, mang lại cải thiện hiệu suất lên đến 30% so với OpenGL.

Máy tính để bàn (Windows, macOS, Linux)

Trên máy tính để bàn, Skia sử dụng OpenGL (macOS, Linux) và Direct3D 12 (Windows). Hỗ trợ Direct3D 12 được thêm vào Flutter 3.13 cho Windows và mang lại cải thiện hiệu suất đáng kể so với OpenGL trên Windows. Skia cũng hỗ trợ kết xuất phần mềm qua ANGLE (OpenGL trên Direct3D) trên Windows để tương thích ngược với các driver đồ họa cũ.

Web

Trong Flutter for Web, Skia được biên dịch sang WebAssembly (qua Emscripten) và kết xuất qua WebGL. Trong chế độ này, Skia hoạt động hoàn toàn trong trình duyệt mà không sử dụng mã gốc. Hiệu suất của phiên bản WebGL của Skia thấp hơn so với backend gốc, nhưng đối với hầu hết các ứng dụng web, 60 FPS đạt được trên các trình duyệt hiện đại với tăng tốc phần cứng WebGL.

Câu hỏi thường gặp

Shader jank trong Skia là gì?

Shader jank là độ trễ kết xuất do biên dịch shader ngay lập tức. Khi Skia gặp sự kết hợp mới của các hiệu ứng trực quan, nó biên dịch một shader, có thể mất 50–200 ms, trong thời gian đó các khung hình bị bỏ qua. Vấn đề này được giải quyết trong Impeller bằng cách biên dịch trước shader.

Có thể sử dụng Skia mà không có Flutter không?

Có, Skia có thể được sử dụng như một thư viện đồ họa độc lập. Nó được sử dụng trong Google Chrome, Android, Mozilla Firefox (qua lớp Skia) và trong các dự án yêu cầu đồ họa 2D hiệu suất cao. API Skia có sẵn bằng C++, Python và thông qua các ràng buộc trong các ngôn ngữ khác.

Phiên bản Skia nào được sử dụng trong Flutter?

Flutter sử dụng một nhánh của Skia (thường là commit ổn định mới nhất từ kho chính của Google). Phiên bản được cập nhật với mỗi bản phát hành Flutter Engine. Commit hiện tại có thể được tìm thấy trong tệp DEPS trong kho lưu trữ flutter/engine trên GitHub.

Skia khác Impeller như thế nào?

Skia biên dịch shader trong thời gian chạy, gây ra shader jank. Impeller biên dịch shader ngoại tuyến (trước), sử dụng SPIR-V và hoạt động trực tiếp qua Vulkan/Metal/Direct3D 12. Impeller không bị ảnh hưởng bởi shader jank và cung cấp hiệu suất dễ dự đoán hơn.

Skia có hỗ trợ hoạt ảnh không?

Bản thân Skia không phải là một công cụ hoạt ảnh — nó chịu trách nhiệm kết xuất các khung hình riêng lẻ. Hoạt ảnh trong Flutter được triển khai ở cấp độ framework (AnimationController, Tween), trong khi Skia đảm bảo kết xuất nhanh mỗi khung hình bằng Canvas API và tăng tốc phần cứng.

Tổng kết

  • Skia — thư viện đồ họa 2D hiệu suất cao của Google, trình kết xuất chính của Flutter
  • Kiến trúc bao gồm Canvas API, Surface/Device và backend GPU Ganesha
  • Hỗ trợ backend: OpenGL, Vulkan, Metal và Direct3D 12 cho mỗi nền tảng
  • Flutter sử dụng Skia để chuyển đổi widget thành pixel qua lớp Engine
  • Hiệu suất đạt được nhờ xử lý theo lô, lưu trữ đệm texture và kết xuất trì hoãn
  • Shader jank — nhược điểm chính của Skia, được giải quyết trong Impeller
  • Sử dụng Skia cho đồ họa 2D đa nền tảng và chọn Impeller cho dự án Flutter mới

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm