Bu sayfada, yüksek kullanılabilirlik oluşturucunun (HAR) tam grafik işlem hattı ayrıntılı olarak açıklanmakta ve verilerin akışı, bir Figma tasarım belgesinden ekranda görüntülenen son piksellere kadar izlenmektedir.
Genel Bakış
Ardışık düzen, üst düzey kullanıcı arayüzü tanımlarını alt düzey grafik komutlarına dönüştürür ve bunları donanım ekranlarında verimli bir şekilde gösterir. Bu ardışık düzen, otomotivde güvenliğin kritik önem taşıdığı uygulamalar için tasarlanmıştır. Deterministik oluşturma, verimli durum yönetimi ve Direct Rendering Manager (DRM) ile Generic Buffer Management (GBM) gibi platform grafikleri alt sistemleriyle güçlü etkileşim özelliklerini vurgular.
İşlem hattı dört ana aşamaya ayrılabilir:
- Önceden oluşturma: Sahne grafiğini işleme, özelleştirmeleri uygulama ve düzeni çözme.
- Komut oluşturma: Çözümlenen sahne grafiğini arka uçtan bağımsız bir görüntüleme listesine dönüştürme.
- Oluşturma: Impeller grafik motorunu kullanarak çizim komutlarını yürütme.
- Sunu: Çerçeve arabelleklerini yönetme ve ekran donanımıyla senkronize etme.
Şekil 1. HAR grafikleri akışı.
1. aşama: Önceden oluşturma
Bu aşamada statik Figma tasarımı ve dinamik uygulama durumu, tamamen çözümlenmiş ve oluşturmaya hazır bir bellek içi kullanıcı arayüzü ağacına dönüştürülür. Bu aşama, ana ekran döngüsünden ayrı olarak özel bir azaltıcı iş parçacığında çalışır.
1.1 DesignCompose temeli
HAR ardışık düzeni, DesignCompose ekosistemi üzerine kurulmuştur.
- Kaynak: Kullanıcı arayüzü Figma'da tasarlanır ve DesignCompose eklentisi kullanılarak dışa aktarılır.
- Tanım: Çıkış, tasarımın (düğümler, stiller, varyantlar) serileştirilmiş bir temsili olan
DesignComposeDefinitionörneğidir. - Veri bağlama: Uygulamanın kullanıcı arayüzü modeli, Rust yapı alanlarını Figma belgesindeki belirli adlandırılmış düğümlere açıkça bağlamak için prosedürel makrolar (ör.
#[Design(node = "#speed")]) kullanır. Bu sayede uygulama durumu, görsel öğelerin özelliklerini otomatik olarak yönlendirebilir.
Bu temelin temel bileşenleri şunlardır:
- Reducer: İşlemleri işleyip mevcut durumu güncelleyerek merkezi etkinlik döngüsü olarak işlev görür. Çerçeve
DefaultReducersağlar ancak gerekirse özel bir azaltıcı uygulama sağlanabilir. - Sunucu: Mevcut durumu kullanıcı arayüzü modeline bağlar.
Presenterözelliğiharryçerçeve sandığı tarafından belirtilir veharry-app-coresandığında bir referans uygulaması (UIModelPresenter) sağlanır. - Kullanıcı arayüzü modeli: Mevcut duruma göre özelleştirmeler oluşturur. Kullanıcı arayüzü modeli kodu,
DesignDocumentsandığı tarafından sağlananderive_customizationsmakrosu kullanılarak oluşturulur.harry-app-corepaketindekiUIModelyapısı bunun bir örneğini sunar. - Squoosh: Tasarıma göre kullanıcı arayüzünü oluşturmak için kullanılan
SquooshViewveri yapısını ve varyant deposunu sağlar. Serileştirilmiş bir tasarım belgesi, DesignCompose kitaplığındakidc_bundlesandığı tarafından yüklenir ve verimli çalışma zamanı performansı içinSquooshViewyapıları ağacına dönüştürülür.
1.2 Azaltıcı döngü
Ardışık düzen, işlemler tarafından yönlendirilir. Çerçeve, Actions
çerçevenin kendisi tarafından kullanılan dahili işlemleri tanımlayan numaralandırılmış türü belirtir ancak
kullanıcıların uygulamaya özel ek işlemler (örneğin, UpdateVehicleSpeed veya
ButtonPress) tanımlamasına olanak tanıyan bir CustomAction varyantını da içerir.
Çerçeve, uygulama durumunu etkileyen işlemlerin uygulanmasını basitleştiren ve isteğe bağlı olarak, işlenmek üzere indirgeyiciden uygulamaya geri aktarılan yan etkiler oluşturan StateAction özelliğini de sağlar. harry-app-core paketindeki CustomActions enum'ı bu konuda ayrıntılı bir örnek sunar.
Bu, azaltıcı döngüsünün temel bir ana hattıdır:
- İşlem işleme:
Reducerbir işlem alır ve mevcut durumu günceller. Bu, mevcut hız veya hangi gösterge lambalarının (uyarı ışıkları) etkin olduğu gibi ham verilerdir. Bu durum, yan etkilere de neden olabilir (ör. emniyet kemeri ışığı yanıp söndüğünde bir sinyal ses çıkarabilir). - Sunum:
Presenter, yeni durumuUIModelile eşler.UIModel, kullanıcı arayüzü için özel olarak biçimlendirilmiş verileri tutan bir görünüm modelidir (örneğin, "120" hızını "65 km/sa" dizesine biçimlendirme). - Özelleştirme oluşturma:
applyyöntemi, bir diziRenderCustomizationörneği oluşturmak için kullanıcı arayüzü modelinde çağrılır. Bunlar, Figma tasarımını değiştirmeye yönelik açık talimatlardır (ör. "Düğüm #speed metnini "65 mph" olarak ayarla"). - Optimizasyon için
UpdatePolicy: Her önceden oluşturma geçişinden sonra, birUpdatePolicydeğeri döndürülür. Bu değer, bir sonraki oluşturma güncellemesinin ne zaman gerekli olduğunu gösterir. Bekleyen durum değişikliği yoksa ve animasyon çalışmıyorsa,UpdatePolicybaşka güncellemeye gerek olmadığını gösterir. Bu gibi durumlarda, Reducer yeni görüntüleme listeleri oluşturmayı durdurur. Böylece, yeni bir işlem veya etkinlik değişikliği tetikleyene kadar gereksiz oluşturma döngüleri önlenir ve kaynaklar korunur.
1.3 Alma ve depo başlatma işlemlerini görüntüleme
İşlem hattı, DesignComposeDefinition örneğiyle başlar. Bu, DesignCompose tarafından protokol arabelleği yapısına dönüştürülen Figma tasarım dokümanıdır.
İlk yükleme: Başlangıçta, ana tasarım (kök düğümüyle belirtilir)
DesignComposeDefinitionbiçiminden ilkSquooshViewağacına dönüştürülür. Bu tek seferlik bir işlemdir.Depo:
SquooshVariantRepositoryYeniden kullanılabilir bileşen varyantlarını ve başlangıçta yüklenen görünümleri yönetir.Geç yükleme: Başlatma süresini ve bellek kullanımını en aza indirmek için ek görünümler (ilk kök düğüm ağacının parçası olmayanlar) yalnızca açıkça referans verildiğinde ve oluşturma mantığı tarafından ihtiyaç duyulduğunda (ör. liste özelleştirme sırasında) belgeden geç yüklenir.
1.4 Özelleştirme kartı
Dinamik uygulama durumunu uygulamak için SquooshView ağacında gezinilir:
Varyant değişimleri: Bileşen örnekleri, çalışma zamanı mantığına göre belirli varyantlarla değiştirilir (ör. mevcut sürüş modunu temsil eden bir simgeyi spor modundan eko moduna değiştirme).
Liste genişletme: Figma'daki tek bir şablon öğesi, dinamik bir alt öğe listesiyle değiştirilir. Bu alt öğeler için, animasyonlarda kararlı bir kimlik doğrulamak amacıyla yeni benzersiz kimlikler oluşturulur.
Metin ve stil geçersiz kılmaları: Metin içeriği (ör. hız değeri) ve stiller (ör. opaklık, renk) mevcut durumdan güncellenir.
1.5 Değişken çözünürlük
Figma'da veya uygulamada yerel olarak tanımlanan tasarım jetonları ve değişkenler çözümlenir.
- Bağlama: Değişkenlere (ör. renkler veya boyutlar) referans veren
SquooshViewözellikleri, mevcut çerçeve için somut değerleriyle değiştirilir.
1.6 Düzen hesaplaması
Dinamik düzen:
DynamicLayout,SquooshViewağacındaki her düğümün son konumunu ve boyutunu (sınırlarını) hesaplar.Metin düzeni:
TextHelper, metin metriklerini, sarmayı ve şekillendirmeyi hesaplamak içinLayoutHelperözelliğinin bir uygulamasını kullanır. Bu, metnin oluşturulmadan önce kısıtlamaları dahilinde doğru şekilde aktığını doğrulamaya yardımcı olur.
1.7 Kadranlar ve göstergeler
Bu, otomotiv kullanıcı arayüzleri için özel bir adımdır.
MeterData: Bir düğümde ölçüm verileri (Figma'da tanımlanır) varsa geometrisimeter_value'ye (örneğin, araç hızı) göre dinamik olarak değiştirilir.- Yaylar: Süpürme açısı ayarlanır.
- Dönüşler: Dönüşüm, başlangıç ve bitiş açılarına göre hesaplanır.
- İlerleme çubukları: Dikdörtgenin genişliği veya yüksekliği ölçeklendirilir.
- İlerleme vektörleri: Vektör yolunun uzunluğu ayarlanır.
1.8 Animation
Fark karşılaştırması: Geçerli
SquooshView,PreRenderCachetarih aralığındakiprevious_squoosh_viewile karşılaştırılır.İnterpolasyon: Özellikler değiştiyse
Squoosh, değerlerin (ör. opaklık veya dönüştürme) zaman içinde sorunsuz bir şekilde geçişini sağlamak için interpolasyonlar oluşturur.
2. aşama: Komut oluşturma
SquooshView ağacı tamamen çözülüp animasyon haline getirildikten sonra, çizim komutlarının doğrusal bir dizisine dönüştürülür.
Bu aşamanın temel bileşeni DisplayList sandığıdır:
generate_dl: Bu işlev,SquooshViewağacında yinelemeli olarak gezinir.Çeviri:
- Şekiller ve yollar: Uygun
DisplayListAppearancevaryantıyla (örneğin,RectveyaPath)DisplayListEntryolarak dönüştürülür. - Metin:
TextHelperile metin çizimi girişlerine dönüştürülür. - Dönüşümler ve kırpmalar: Çizim durumu yığınını yönetmek için
PushTransform3DvePopTransform3DveyaPushClipRegionvePopClipRegionçiftlerine dönüştürülür. - Maskeleme: Katmanları doğru şekilde oluşturmak ve karıştırmak için
PushMaskLayervePopMaskLayerçiftlerine dönüştürülür.
- Şekiller ve yollar: Uygun
Sonuç, nasıl çizileceğinden bağımsız olarak ne çizileceğini açıklayan bir Vec<DisplayListEntry> örneğidir.
2.1 Döngü oluşturucuya aktarma
DisplayList oluşturulduktan sonra Reducer, bunu ViewDescriptor örneğine sarar ve Rust MPSC kanalı (LooperMessage) üzerinden looper iş parçacığına gönderir. Looper, oluşturma ve görüntüleme aşamalarından sorumludur. Bu sayede, Reducer iş parçacığının grafik işlem hattını engellemesi önlenir.
3. aşama: Oluşturma
Platformdan bağımsız DisplayList, soyut komutların GPU talimatlarına çevrildiği oluşturma arka ucuna aktarılır.
HAR, başlangıçta Flutter için oluşturulmuş bir oluşturma motoru olan Impeller'ı kullanır. Impeller, derleme sırasında küçük ve verimli bir gölgelendirici grubu önceden derleyerek gölgelendirici derlemesinden kaynaklanan kare hızı aksaklıkları sorununu çözmek için tasarlanmıştır. Bu yaklaşım, etkili toplu işleme ve son derece optimize edilmiş bir arka uçla birlikte şunları sağlar:
- Belirleyici performans: Çalışma zamanı gölgelendirici derleme hatalarını neredeyse tamamen ortadan kaldırır.
- Hızlı başlatma: Başlatma ek yükünü azaltır.
- Küçük yer kaplama: Kompakt bir ikili boyut üretir.
Impeller'ın mimarisine dair kapsamlı bir giriş için [Introducing Impeller - Flutter's new rendering engine][impeller-video] başlıklı videoyu izleyin. Videoda Flutter ele alınsa da bu temel avantajlar, HAR otomotiv yığınını doğrudan destekler.
Oluşturma aşamasının temel bileşenleri şunlardır:
ImpellerRenderer: Görüntüleme listesini önceden oluşturma aşamasından Impeller oluşturma komutlarına dönüştürür.Impeller Rust API: Impeller kitaplığını Rust'ta kullanılmak üzere sarmalar (
impellerveimpeller-rs-bindgenkasaları).TypographyContext: Yazı tipi kaydını ve metin şekillendirmeyi yönetir.
3.1 Başlatma ve yüzey yönetimi
Bağlam oluşturma: Oluşturucu, OpenGL ES arka ucuyla
impeller::Contextörneğini başlatır ve platformun GL bağlamından OpenGL ES işlev işaretçilerini çözmek için bir geri çağırma iletir.Sarmalanmış FBO yüzeyi: Impeller, kendi penceresini oluşturmak yerine 4. Aşama tarafından sağlanan mevcut bir OpenGL çerçeve arabelleği nesnesine (FBO) oluşturur. Bu işlem,
Surface::create_wrapped_fboçağrılarak yapılır.
3.2 Kaynak yönetimi
Görseller: Standart biçimleri ve KTX2 sıkıştırılmış dokuları destekler. Bunlar, GPU dokularına yüklenir ve dahili bir
Resourcesyapısı tarafından yönetilir.Yazı tipleri: TrueType ve OpenType yazı tipleri, metin oluşturma için
TypographyContextile yüklenir ve kaydedilir.Harici resimler: Harici dokular (ör. kamera feed'leri ve harici 3D oluşturucular) için özel işleme, sıfır kopyalı oluşturma için
EGLImageörneklerinin veya harici OpenGL dokularının ImpellerTexturenesnelerine bağlanmasını içerir.
3.3 Oluşturma kartı
render döngüsü, DisplayListBuilder kullanarak bir Impeller DisplayList örneği oluşturur (önceden oluşturma aşamasında oluşturulan Vec<DisplayListEntry> ile karıştırılmamalıdır):
Arabelleği temizler ve DPI ölçeklendirme ile ekran döndürme için genel dönüşümleri uygular.
Giriş
DisplayListEntryöğeleri arasında yinelenir:- Durum:
save()verestore(), dönüştürmeleri ve kırpma bölgelerini itip açmak için kullanılır. - Temel öğeler:
RectveRoundedRect, standart boyama işlemleri kullanılarak çizilir. - Yollar: Dinamik
Arcörnekleri de dahil olmak üzere karmaşık vektör yolları oluşturulur ve çizilir. - Metin:
TextveStyledText,TypographyContextkullanılarak oluşturulur. - Resimler: Standart ve harici resimler
draw_texture_rectkullanılarak çizilir.
- Durum:
Oluşturulan Impeller görüntüleme listesini
surface.draw_display_list()kullanarak yüzeye gönderir ve temel GL komutlarını oluşturur.4. Aşamayı tetiklemek için temel bağlamda
swap_buffers()işlevini çağırır.
4. Aşama: Sunum
Bu son aşamada, oluşturulan kareyi göstermek için ekran donanımıyla etkileşim ele alınır. HAR, Android Automotive OS (AAOS) yazılımla tanımlanmış araçta (SDV) güçlü bir doğrudan oluşturma yolu kullanır.
Bu aşamanın temel bileşeni HarDirectRenderingContext (har-gl-context sandığında) şeklindedir.
4.1 Mimari
Sunum katmanında, ekran dışı çizim hedefiyle çift arabellekli bir yaklaşım kullanılır:
Çizim arabelleği: Impeller'in sahneyi oluşturduğu ekran dışı FBO.
Çözüm arabelleği (isteğe bağlı): Çok örnekli kenar yumuşatma (MSAA) özelliğini desteklemek için isteğe bağlı yardımcı arabellek
- Bu, temel OpenGL ES uygulaması veya yapılandırması tarafından gerektiğinde etkinleştirilebilir. Bu gibi durumlarda, çok örnekli çizim arabelleğini oluşturma arabelleğine blit (bit blok aktarımı) işleminden önce çözmek için ara hedef olarak kullanılır.
Oluşturma arabelleği: Tipik bir grafik değişim zincirindeki arka arabelleğe karşılık gelen bir GBM nesnesiyle desteklenen genel arabellek.
Ön arabellek: Ekrana taranan GBM arabelleği.
4.2 Zinciri değiştirme
swap_buffers çağrıldığında HAR şu adımları uygular:
Çizim arabelleğinin içeriğini oluşturma arabelleğine aktarır (uygulama tarafından gerekirse çözme arabelleğine ara aktarma ile).
GL bağlamında
glFlush()çağrıları yapar ve GPU tamamlanmasını izlemek içinEGL_SYNC_NATIVE_FENCE_ANDROIDörneği oluşturur.Render arabelleğini ekranla değiştirmek için bir DRM atomik isteği oluşturur. Bu istek, GPU'nun çizimi bitirmeden önce ekran denetleyicisinin oluşturma arabelleğini göstermesini önlemek için GPU çit FD'sini (in fence olarak adlandırılır) içerir.
Önceki arabellek (önceki kare için ön arabellek) artık ekranda olmadığında sinyal vermek için DRM'den eşzamanlı olarak yeni bir sınır (çıkış sınırı olarak adlandırılır) ister.
Grafik alt sistemleri senkronize kalırken ana iş parçacığının devam etmesini sağlamak için engellemeyen işareti kullanarak atomik isteği işler.
Yeni çıkış çitini bağlamda depolar. Böylece HAR, sonraki karede
swap_buffersişleminin başlangıcında sinyal verilmesini bekleyebilir. Bu, GPU'nun hâlâ görüntülenmekte olan bir arabelleğe çizim yapmasını engeller.
4.3 Doğrudan mod ayarı
HAR, ekran çözünürlüğünü AAOS SDV olarak yapılandırmak için DRM ve Kernel Mode Setting (KMS) alt sistemlerini kullanarak doğrudan çekirdekle etkileşime girer. SurfaceFlinger gibi pencere yöneticileriyle etkileşimi (belirli yapılandırmalarda) atlayarak ekran donanımının özel ve yüksek öncelikli kontrolüne olanak tanır.
4.4 Harici oluşturma
HAR, belirli kullanıcı arayüzü öğelerinin (Figma'daki etiketlerle tanımlanır) oluşturulmasını harici işlemlere veya iş parçacıklarına devretmeyi destekler. Bu, karmaşık 3D sahneleri (örneğin, Kanzi veya Unity gibi motorlardan alınan bir ego araba görselleştirmesi) ya da özel bir OpenGL bağlamı gerektiren diğer içerikleri entegre etmek için kullanışlıdır.
4.4.1 Temel bileşenler
HarExternalRenderContext: Harici hizmet için özel bir ekran dışı EGL bağlamı.SurfacePool: Çift veya üçlü arabelleğe alma için bir diziLocalSurface(TextureartıEGLImage) arabelleği yönetir.SharedSurfaceExternalImage: Harici hizmet ile ana oluşturucu arasındaEGLImageişleyicilerini geçirmek için iş parçacığı açısından güvenli bir sarmalayıcı.
4.4.2 İş Akışı
İş akışı şu sırayı izler:
Harici hizmet başlatılır ve ana döngüyle kendini kaydeder. Hangi Figma etiketlerini (ör.
#cluster/3d-car) oluşturduğunu tanımlar.Hizmet, oluşturma işlemini ekranın VSYNC sinyaliyle uyumlu hale getirmek için döngücüden
RenderStartsinyallerini bekler.Hizmet, ekran dışında içeriğini
SurfacePooltarafından sağlanan bir çerçeve arabelleğine oluşturur.Hizmet, bağlamında
swap_buffersçağrısı yapar. Bu çağrı, havuzu döndürür ve tamamlanan kareyiSharedSurfaceörneği olarak kullanılabilir hale getirir.SharedSurface,ExternalImageiçine sarmalanır ve Rust MPSC kanalı üzerinden döngücüye gönderilir.Ana Impeller oluşturucusu (3. Aşama), bilinmeyen kaynaktan gelen resmi alır. Piksel verilerini kopyalamak yerine, temel
EGLImageöğesini doğrudan bir dokuya bağlar ve ana sahnenin bir parçası olarak çizerek sıfır kopyalı kompozisyon elde eder.
4.5 Geliştirme ve test platformları (har-platform-linux)
HAR uygulamaları, geliştirme ve test amacıyla standart Linux masaüstü ortamlarını ve başsız kurulumları hedefleyebilir. Bu platformlar crates/reference/platforms/har-platform-linux kasasında uygulanır.
Üretim AAOS SDV hedefinin aksine, bu platformlar ekran çıkışı için har-gl-context'nin direct-rendering alt sistemini kullanmaz. Bunun yerine, standart Rust OpenGL paketlerini kullanırlar:
Pencere modu: Pencere yönetimi ve etkinlik döngüleri için
winit, OpenGL ES bağlamları oluşturmak ve pencere sistemiyle entegre etmek içinglutinkullanılır.Gözetimsiz mod: Varsayılan EGL ekranıyla ekran dışı pbuffer bağlamı oluşturmak için
har-gl-contextkasasını kullanır. Bu, öncelikle otomatik test veya arka uç işleme için kullanılan, görünür bir pencereye ya da doğrudan ekran donanım erişimine gerek kalmadan ekran dışı bir arabelleğe oluşturmayı sağlar.