Skia — یک کتابخانه گرافیکی دو بعدی با عملکرد بالا و متنباز است که به زبان C++ نوشته شده و به عنوان موتور رندر اصلی Flutter عمل میکند. این کتابخانه وظیفه تبدیل ویجتها و عناصر رابط کاربری سطح بالا به پیکسلهای روی صفحه را بر عهده دارد و از رندرینگ نرمافزاری از طریق CPU و شتابدهی سختافزاری از طریق OpenGL، Vulkan و Metal پشتیبانی میکند. بر اساس Skia Documentation (2025)، Skia روزانه بیش از 2 میلیارد فریم رندر شده را در دستگاههای Android، Chrome و Flutter پردازش میکند.
نکات کلیدی
Skia — یک کتابخانه گرافیکی دو بعدی چندپلتفرمی است که توسط 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 | تا 3x |
| کش بافت | استفاده مجدد از بافتهای بارگذاری شده در GPU | تا 2x |
| Atlas | ترکیب بافتهای کوچک در یک بافت بزرگ (texture atlas) | تا 1.5x |
| Deferred rendering | اجرای تأخیری دستورات با مرتبسازی مجدد | تا 2x |
| Shader precompilation | کامپایل پیشاپیش سایهزنها برای Spark/Dart | تا 4x |
بر اساس بنچمارکهای Flutter Team، استفاده از Skia با شتابدهی GPU در دستگاههای میانرده (Qualcomm Snapdragon 700 series) FPS 60 پایدار را در رندرینگ رابطهای پیچیده با 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 تنها بکاند GPU برای iOS است که افزایش عملکرد تا 30% نسبت به OpenGL دارد.
در دسکتاپ، Skia از OpenGL (macOS، Linux) و Direct3D 12 (Windows) استفاده میکند. پشتیبانی از Direct3D 12 برای Windows در Flutter 3.13 اضافه شد و بهبود قابل توجهی در عملکرد نسبت به OpenGL در Windows ایجاد میکند. Skia همچنین از رندرینگ نرمافزاری از طریق ANGLE (OpenGL روی Direct3D) در Windows برای سازگاری با درایورهای گرافیکی قدیمی پشتیبانی میکند.
در Flutter for Web، Skia به WebAssembly (از طریق Emscripten) کامپایل میشود و از طریق WebGL رندر میکند. در این حالت، Skia کاملاً در مرورگر کار میکند و از کد بومی استفاده نمیکند. عملکرد نسخه WebGL Skia کمتر از بکاندهای بومی است، اما برای اکثر برنامههای وب، 60 FPS در مرورگرهای مدرن با شتاب سختافزاری WebGL قابل دستیابی است.
سوالات متداول
Shader jank — تأخیر رندرینگ به دلیل کامپایل سایهزنها در لحظه است. وقتی Skia با ترکیب جدیدی از افکتهای بصری مواجه میشود، سایهزن را کامپایل میکند که ممکن است 50–200 میلیثانیه طول بکشد و در طی آن فریمها از دست میروند. این مشکل در Impeller با کامپایل پیشاپیش سایهزنها حل میشود.
بله، Skia میتواند به عنوان یک کتابخانه گرافیکی مستقل استفاده شود. این کتابخانه در Google Chrome، Android، Mozilla Firefox (از طریق لایه Skia) و در پروژههایی که نیاز به گرافیک دو بعدی با عملکرد بالا دارند استفاده میشود. برای اتصال از Skia API که به زبانهای C++، Python و از طریق绑定ها در زبانهای دیگر در دسترس است استفاده میشود.
Flutter از یک فورک Skia (معمولاً آخرین کامیت پایدار از مخزن اصلی Google) استفاده میکند. نسخه با هر انتشار Flutter Engine به روز میشود. کامیت جاری را میتوان در فایل DEPS در مخزن flutter/engine در GitHub پیدا کرد.
Skia سایهزنها را در زمان اجرا کامپایل میکند که باعث shader jank میشود. Impeller سایهزنها را از قبل (آفلاین) کامپایل میکند، از SPIR-V استفاده میکند و مستقیماً از طریق Vulkan/Metal/Direct3D 12 کار میکند. Impeller از تأخیر سایهزن رنج نمیبرد و عملکرد قابل پیشبینیتری ارائه میدهد.
Skia به خودی خود یک موتور انیمیشن نیست — این کتابخانه مسئول رندرینگ فریمهای جداگانه است. انیمیشن در Flutter در سطح فریمورک (AnimationController، Tween) پیادهسازی میشود و Skia رندرینگ سریع هر فریم را از طریق Canvas API و شتابدهی سختافزاری تضمین میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.