Sitemap

Flutter Impeller Engine Hakkında

8 min readJun 16, 2025

--

Merhaba değerli okurlar. Bu yazımda sizlere Flutter ekibinin geçmiş dönemlerde başlattığı Render Motor güncellemesinden bahsedeceğim.

Madem geçmiş dönemlerde başladı neden şimdi bahsetme gereksinimi duyuyorum? Şöyle izah edeyim; Apple tarafının WWDC2025 etkinliğinde tanıttığı Liquid Glass isimli tasarımın Flutter tarafında ne kadar efektif ve sorunsuz şekilde uygulanabileceği konusu geliştiricilerin kafasında bir soru işareti olmuş.

Bilenler bilir ancak bilmeyenler için Liquid Glass, GlassMorphism gibi render motorlarının maharetli kollarına ihtiyaç duyan tasarımlarda render motoru güçlü olan bu gibi tasarım ve yapıları daha net bir biçimde kullanıcısına sunar!

Lafı çok fazla uzatmadan ve balıklama olarak konuya atlamadan önce bilmeniz gereken kavramları açıklamaya çalışacağım. Adım adım Impelleri tanıyacak, önceden hangi render motorunu kullandığınızı öğrenecek ve neden Impeller Engine’nin çıktığını göreceksiniz.

Temel Kavramlar

Render motorlarını ve akışlarını anlayabilmek için teknik anlamda arka planda nelerin olduğunu bilmek zorundayız. Aslında bazı kavramlar günlük hayatta ara sıra karşımıza çıksada render motorları tarafında anlamları biraz faklılaşabiliyor.

a) CPU (Central Processing Unit): Uygulamanın mantıksal beynidir. Flutter’da UI Thread üzerinde çalışır. Görevi, widget ağacını (Widget Tree) oluşturmak, layout (yerleşim) ve paint (boyama) bilgilerini içeren RenderObject ağacını inşa etmek ve son olarak Layer Tree’yi oluşturmaktır. CPU, “neyin, nerede ve hangi özelliklerle çizileceğini” belirler, ancak bu çizim işlemini kendisi yapmaz.

Bu satırları okuyan bazı geliştirici arkadaşların hayatına yeni kavramlar girmiş olabilir diye biraz daha detay ekliyorum;

  1. Widget Ağacı (Widget Tree): Flutter ilk olarak Dart kodunuzu okur ve bir plan taslağı oluşturur: “Bir Stack’im var, içinde bir Container ve bir Icon bulunuyor.” Bu, konfigürasyonunuzun bir temsilidir, henüz ekranda çizilecek bir şey yoktur.
  2. Render Nesnesi Ağacı (RenderObject Tree): İşte işin ciddileştiği yer burası. Flutter, Widget ağacındaki her bir widget için bir “işçi” atar. Bu işçiler RenderObject’lardır.
  • Örneğin ekrandaki bir Stack widget’ı, RenderStack nesnesine dönüşür. Onun işi, çocuklarını nasıl üst üste yığacağını bilmektir.
  • Container widget’ı, RenderDecoratedBox’a dönüşür. Artık soyut değildir. Somut bilgilere sahiptir: “Benim genişliğim tam olarak 200 piksel, yüksekliğim 200 piksel. Boyama tarifim ise yukarıdan aşağıya maviden yeşile doğru bir lineer gradyan. Ayrıca, kenarlarım 20 piksellik bir yarıçapla yuvarlatılmalı.”
  • Icon widget’ı, RenderParagraph’a dönüşür. O da kendi görevini bilir: “Ben, ‘star’ ikonunu temsil eden font glifiyim. Rengim beyaz ve boyutlarım 100x100 piksel olmalı.”

3. Katman Ağacı (Layer Tree): CPU’nun son görevi, bu render nesnelerini boyama için en verimli şekilde gruplamaktır. RenderDecoratedBox’ın yuvarlak köşeleri bir kırpma (clipping) işlemi gerektirir. CPU, “Bu kutuyu çizmeden önce, bir ClipRRectLayer oluştur ve sadece bu yuvarlak alanın içine çizim yapılmasına izin ver” diyebilir. Bu, GPU’ya verilecek optimize edilmiş, son “yapılacaklar listesi”dir.

Bu noktada CPU’nun işi biter. Elinde, neyin, nerede, hangi boyut ve tarifle çizileceğini anlatan son derece detaylı bir plan (Layer Tree) vardır. Ama bu planı hayata geçirecek güce sahip değildir. Bu yüzden Bu Layer Tree GPU tarafına transfer edilir ve diğer işlemlere GPU tarafında devam edilir.

b) GPU (Graphics Processing Unit): Binlerce paralel çekirdeğe sahip, yüksek oranda paralelleştirilmiş bir işlemcidir. Flutter’da Raster Thread (veya platforma göre GPU Thread) tarafından kullanılır. Görevi, CPU’dan gelen üst düzey çizim komutlarını alıp ekrandaki piksellere dönüştürmektir.

Yani GPU kendisine Layer Tree yapısını alır ve ekranımızı şenlendirir..

Ancak CPU ve GPU’nun doğrudan iletişim kurması için bir arayüz diline, yani bir Grafik API’sine ihtiyaç vardır.

  • OpenGL/OpenGL ES: Yüksek seviyeli (high-level), platformdan bağımsız, köklü bir standarttır. Sürücüye (driver) büyük bir sorumluluk yükler. Geliştirici “bir daire çiz” der, sürücü bunu GPU’nun anlayacağı dile çevirmek için arka planda pek çok “sihir” yapar. Bu sihir, kolaylık sağlasa da performans açısından öngörülemezliğe ve ek yüke (overhead) neden olabilir.
  • Metal (Apple) & Vulkan (Android, Linux, Windows): Düşük seviyeli (low-level), “bare-metal”e yakın API’lerdir. Sürücünün sorumluluğunu azaltıp kontrolü doğrudan uygulamaya (veya render motoruna) verirler. Bellek yönetimi, senkronizasyon, pipeline state yönetimi gibi kritik görevler artık motorun sorumluluğundadır. Bu, daha fazla kod ve karmaşıklık anlamına gelse de, ek yükü ortadan kaldırır ve performansı maksimize ederek öngörülebilirlik sağlar. Impeller’ın varlık sebebi bu API’lerdir.

Skia Render Motoru

Skia motoru, Flutter’in ilk çıktığı andan itibaren kullandığımız motordu. Skia oldukça köklü, geçmişi olan, geniş çevrelerce bilinen 2D destekli bir render motoruydu.

Ancak karmaşık animasyon ve ui işlemlerinde yeterli kalmıyordu. Özellikle GlassMorphism, Blur Effect gibi işlemlerde çok fazla takılmalar meydana geliyordu. Örneğin Flutter tarafında BackDropFilter kullandığınızda Skia şu şekilde işlemler yapıyordu;

  1. Komut Oluşturma: UI Thread, bir RenderBackdropFilter nesnesi oluşturur.
  2. Shader Gereksinimi Tespiti: Raster Thread üzerindeki Skia, bu bulanıklaştırma işlemini gerçekleştirecek bir GPU programına (shader) ihtiyaç duyar.
  3. Anında Kod Üretimi (JIT): Skia, kendi iç dili olan SkSL (Skia Shading Language) kullanarak o anki parametrelere (örneğin, blur yarıçapı) özel bir shader kaynak kodu üretir.
  4. Platforma Çeviri: Bu SkSL kodu, hedef platformun anladığı dile (OpenGL için GLSL, iOS için MSL) çevrilir.
  5. Sürücüye Teslim ve Derleme: Üretilen bu kaynak kodu, GPU sürücüsüne gönderilir.
  6. KRİTİK GECİKME (JANK): GPU sürücüsü, bu metin tabanlı kaynak kodunu alır, onu ayrıştırır (parse), derler (compile), optimize eder ve GPU’nun çalıştırabileceği makine koduna dönüştürür. Bu işlem, cihazın gücüne ve shader’ın karmaşıklığına bağlı olarak onlarca, hatta yüzlerce milisaniye sürebilir. Bu işlem Raster Thread’i bloke ettiği için, o karenin 16.6ms (60 FPS için) bütçesi aşılır ve animasyonda gözle görülür bir takılma meydana gelir.

Kabaca özetleyecek olursak BackdropFilter ile bir blur işlemi uygulamak istediğinizde Skia bunu (JIT) çalışma zamanında derleyerek anlamlı hale getirmeye çalışıyordu. Bu da anlık olarak takılmalara ve gecikmelere neden oluyordu. Bu durum toplantı içinde aniden bir toplantı daha yapmak gibi ani ve beklenmedik bir gelişme oluyordu…

Peki bu sorun için bir çözüm üretilemez miydi? Elbette üretilebilirdi ve üretildi ancak yeteri kadar bir çözüm getirmedi. Offstage gibi yöntemlerle animasyonları, widgetleri önbelleğe alıp, Shader yapılarını o şekilde çalıştırabiliyordunuz ancak bu çok açık ve yeterli bir çözüm olmadı zira her yerde Offstage kullanımı yapmak mümkün değildi..

Impeller Render Motoru

Bir çok Flutter geliştiricisinin özellikle son zamanlarda duyduğu bir motor Impeller. Skia kadar aşina olunduğunu düşünmüyorum..

Bu motor, Skia motorunun JIT prensibiyle hareket etmesinden kaynaklanan sorunları çözmek, daha modern görüntü apilerini kullanabilmek, daha güncel bir render alt yapısına sahip olmak için 2023 yılında ortaya çıktı. Ancak 2023 yılında sadece iOS tarafı için ve oldukça ilkel sürümüyle çıktı. Elbette Flutter’in 3.10 sürümünden sonraki sürümlerinde performansını katladı ve çok daha iyi bir hale geldi.

Android tarafı için bu motoru hemen kullanmak mümkün olmadı zira bir çoğumuzun duyduğu Vulkan yapısı buna izin vermedi. Çünkü farklı üreticiler, farklı GPU’lar ve farklı Vulkan sürümleri var. Bu nedenle Impeller’ın Android’e gelmesi daha uzun sürdü. 2024 ve Flutter 3.24 sürümüyle Impeller ayağını Android dünyasına attı..

Burada ek bir bilgi vermek isterim. Android dünyası çok çeşitli bir cihaz sistemine sahip olduğu için Skia fallbackEngine olarak hala eski cihazlarda Flutter adına hizmet vermektedir!

Impeller Motorunun Jank Sorununu Çözümü

Daha önceden bahsettiğim gibi Skia derleme zamanında yapıları anlamlı hale getirdiği için hazırlıksız olarak yakalandığı zamanlar oluyordu. Bu sorunu çözmek için derlemeden daha önce tüm yapıların hazır olda beklediği bir yapıya geçiş yapıldı; AOT (Ahead-of-Time).

AOT çalışma biçimi şu şekilde gerçekleşiyor;

  1. Statik Analiz: Uygulama derlenirken (flutter build komutuyla), Flutter toolchain’i projenizdeki Dart kodunu tarar. Material, ShaderMask, BackdropFilter, ColorFilter gibi shader gerektiren tüm widget kullanımlarını tespit eder.
  2. Shader Kütüphanesinden Seçim: Impeller, içinde bu efektler için önceden yazılmış, yüksek derecede optimize edilmiş ve parametrize edilebilir bir shader kütüphanesi barındırır. Skia gibi anlık olarak kod üretmez.
  3. AOT Derleme ve Paketleme: Toolchain, tespit edilen ihtiyaçlara göre bu kütüphanedeki ilgili shader’ları alır. Onları önce Impeller’ın kendi ara formatına (.iplr), ardından hedef platformun nihai binary formatına derler:
  • iOS/macOS için: .metallib dosyası (Metal Shading Language’in derlenmiş kütüphanesi)
  • Android/Desktop için: SPIR-V (Vulkan ve modern OpenGL için standart, taşınabilir ara format)

4. Pakete Dahil Etme: Bu önceden derlenmiş binary shader’lar, uygulamanızın son paketiyle (APK/AAB/IPA) birlikte dağıtılır.

5. Anında Yürütme: Uygulama çalıştığında ve o bulanıklık efekti gerektiğinde, Impeller GPU sürücüsüne kaynak kodu göndermez. Bunun yerine, “Paketteki my_app.metallib dosyasından ‘gaussianBlurWithRadius’ fonksiyonunu (Pipeline State Object — PSO) yükle ve şu parametrelerle (uniforms) çalıştır” der. Bu işlem bir derleme değil, bir hafıza yüklemesidir ve mikrosaniyeler sürer. Jank tamamen ortadan kalkar.

Yani blur efekti için BackDropFilter kullandığımızda önce bu yapıların varlığına bakar daha sonra çeşitli denetimlerle hazırlık yapar ve çalışma sırasında akıcı bir deneyim yaratır.

Skia ve Impeller’in en büyük savaşı budur. Derleme zamanında ve derleme zamanından önce her şeyi hazırda tutmak..

Yine bir bilgi vermek isterim. Vs Code, Cursor, Android Emülatör vb editör ya da IDE’leri açıp kod yazıp çıktıları görmek istediğiniz zaman debug modda olduğunuzdanJIT prensibi çalışır. Bunu lütfen render motorlarının çalışma prensibiyle karıştırmayın! Yani debug modda skia çalışıyor apk, ipa alınca impeller çalışıyor gibi bir durum yok! Güncell Flutter sürümlerinde Impeller çalışıyor, debug ya da apk vs almanız bir şeyi değiştirmiyor elbette özel konfigürasyon yapmadıysanız!

Çok güzel Impeller harika bir dönemin kapılarını açıyor bizlere ancak bir olumsuzluğu ya da negatif yönü yok mu ya da Skia mı Impeller mi daha iyi diyecek olursanız şöyle yanıt vereyim;

Tabloda yer almıyor ancak Flutter ekibinin Impeller ile build aldığı Flutter Gallery uygulamasının boyutunda 500kb gibi küçük bir artış yaşandığı belirtilmiş. Yani Impeller motoru kilobayt olarak uygulama boyutunuzu artırma yönünde hareket ediyor!

Flutter’in desteklediği Diğer Platformlar?

Flutter ile çok sayıda mobil uygulama geliştirildiği bir gerçek ancak Flutter Windows, Linux, Mac, Web platformlarının yanı sıra birde oyun geliştirme konusunda da kullanılıyor. Impeller motoru sadece mobil tarafa etki etmiyor. Bu konuda lafı çok uzatmayacağım.

Mac, Linux ve Windows işletim sistemlerine uygulama geliştirenler için Impeller motoruna geçiş sürüyor. Vulkan, Metal, DirectX destekleri kazandırılmaya çalışıyor. Bu motora geçiş bir süreçtir ve sürekli iyileştirilmeye devam edecektir.

Peki oyun tarafında etkisi ne olur?

Flutter ile oyun geliştirme konusunda Impeller bir çağ atlatmayacak ancak performans noktasında oluşan janklar için çözüm olacaktır. Performansı yüksek 2D oyunlar geliştirmek gelişirek daha iyi seviyelere gelecektir.

Sözlerimi bitirirken değerli geliştirici arkadaşlara bir not iletmek istiyorum;
Kullandığınız Framework, dil, yapı artık adına siz ne derseniz sizin için neler sunuyor, arka planında hangi gelişmeleri barındırıyor, neler oluyor diye sorun lütfen. Biz geliştiricilerin amacı sadece kod yazmak olmamalı kodu yazdığımız aracın yeteneklerini de bilmeliyiz.

Buraya kadar okuduğunuz için teşekkür ederim. İyi çalışmalar dilerim herkese..

KAYNAKLAR

https://github.com/flutter/flutter/blob/main/engine/src/flutter/impeller/docs/ubo_gles2.md

--

--

AbdullahTaş
AbdullahTaş

Written by AbdullahTaş

FLUTTER DEVELOPER AT IWWOMI | HASURA-GRAPHQL & FIREBASE |

No responses yet