Senkronizasyon çerçevesi, Android grafik sistemindeki farklı asenkron işlemler arasındaki bağımlılıkları açıkça tanımlar. Çerçeve, bileşenlerin arabelleklerin ne zaman serbest bırakıldığını göstermesini sağlayan bir API sağlar. Çerçeve aynı zamanda senkronizasyon temellerinin sürücüler arasında çekirdekten kullanıcı alanına ve kullanıcı alanı süreçleri arasında geçirilmesine izin verir.
Örneğin, bir uygulama GPU'da gerçekleştirilecek işi sıraya alabilir. GPU bu görüntüyü çizmeye başlar. Görüntü henüz belleğe çekilmemiş olsa da, arabellek işaretçisi, GPU işinin ne zaman biteceğini gösteren bir çitle birlikte pencere birleştiricisine iletilir. Pencere oluşturucu önceden işlemeye başlar ve işi ekran denetleyicisine iletir. Benzer şekilde, CPU işi önceden yapılır. GPU bittiğinde, ekran denetleyicisi hemen görüntüyü görüntüler.
Senkronizasyon çerçevesi aynı zamanda uygulayıcıların kendi donanım bileşenlerinde senkronizasyon kaynaklarından faydalanmalarını sağlar. Son olarak, çerçeve, hata ayıklamaya yardımcı olmak için grafik ardışık düzenine görünürlük sağlar.
Açık senkronizasyon
Açık senkronizasyon, grafik arabellek üreticilerinin ve tüketicilerinin, bir arabellek kullanarak bitirdiklerinde sinyal vermelerini sağlar. Açık senkronizasyon, çekirdek alanında uygulanır.
Açık senkronizasyonun faydaları şunları içerir:
- Cihazlar arasında daha az davranış değişikliği
- Daha iyi hata ayıklama desteği
- Geliştirilmiş test metrikleri
Eşitleme çerçevesinin üç nesne türü vardır:
-
sync_timeline
-
sync_pt
-
sync_fence
sync_timeline
sync_timeline , satıcıların bir GL bağlamı, görüntü denetleyicisi veya 2D kırpıntı gibi her sürücü örneği için uygulaması gereken monoton artan bir zaman çizelgesidir.
sync_timeline , belirli bir donanım parçası için çekirdeğe gönderilen işleri sayar.
sync_timeline , işlem sırası hakkında garantiler sağlar ve donanıma özel uygulamaları etkinleştirir.
sync_timeline uygularken şu yönergeleri izleyin:
- Hata ayıklamayı basitleştirmek için tüm sürücüler, zaman çizelgeleri ve çitler için yararlı adlar sağlayın.
- Hata ayıklama çıktısını daha okunabilir hale getirmek için
timeline_value_strve
pt_value_stroperatörlerini zaman çizelgelerinde uygulayın.
- GL kitaplığı gibi kullanıcı alanı kitaplıklarına istenirse özel zaman çizelgesi verilerine erişim sağlamak için dolgu
driver_datauygulayın.
data_driver, satıcıların bunlara dayalı komut satırları oluşturmak için değişmez
sync_fenceve
sync_ptshakkında bilgi iletmesine izin verir.
- Kullanıcı alanının açıkça bir çit oluşturmasına veya işaret etmesine izin vermeyin. Açıkça sinyaller/çitler oluşturmak, boru hattı işlevselliğini durduran bir hizmet reddi saldırısına neden olur.
-
sync_timeline,
sync_ptveya
sync_fenceöğelerine açıkça erişmeyin. API, gerekli tüm işlevleri sağlar.
sync_pt
sync_pt , bir
sync_timeline üzerindeki tek bir değer veya noktadır. Bir noktanın üç durumu vardır: aktif, sinyal verildi ve hata. Noktalar aktif durumda başlar ve sinyal veya hata durumlarına geçiş yapar. Örneğin, bir görüntü tüketicisinin artık bir ara belleğe ihtiyacı kalmadığında, bir
sync_pt sinyali gönderilir, böylece bir görüntü üreticisi arabelleğe yeniden yazmanın uygun olduğunu bilir.
sync_fence
sync_fence , genellikle farklı
sync_timeline sahip bir
sync_pt değerleri topluluğudur (ekran denetleyicisi ve GPU için olduğu gibi).
sync_fence ,
sync_pt ve
sync_timeline sürücülerin ve kullanıcı alanının bağımlılıklarını iletmek için kullandığı ana temel öğelerdir. Bir çit sinyali verildiğinde, çekirdek sürücüsü veya donanım bloğu komutları sırayla yürüttüğü için çitten önce verilen tüm komutların tamamlanması garanti edilir.
Senkronizasyon çerçevesi, birden fazla tüketicinin veya üreticinin bir arabellek kullanarak bitirdiklerinde, bağımlılık bilgilerini tek bir işlev parametresiyle ileterek sinyal vermelerine olanak tanır. Çitler bir dosya tanımlayıcı tarafından desteklenir ve çekirdek alanından kullanıcı alanına iletilir. Örneğin, bir çit, iki ayrı görüntü tüketicisinin bir arabelleği okumasının ne zaman bittiğini belirten iki
sync_pt değeri içerebilir. Çit sinyali verildiğinde, görüntü üreticileri her iki tüketicinin de tüketmesinin bittiğini biliyor.
Fences,
sync_pt değerleri gibi aktif olmaya başlar ve noktalarının durumuna göre durum değiştirir. Tüm
sync_pt değerleri sinyallenirse,
sync_fence sinyallenir. Bir
sync_pt hata durumuna düşerse, tüm
sync_fence bir hata durumuna sahiptir.
Bir
sync_fence üyeliği, çit oluşturulduktan sonra değişmez. Bir çitte birden fazla nokta elde etmek için, iki farklı çitten gelen noktaların üçüncü bir çite eklendiği bir birleştirme gerçekleştirilir. Bu noktalardan biri başlangıç çitinde işaretlenmiş ve diğeri verilmemişse, üçüncü çit de işaretlenmiş durumda olmayacaktır.
Açık senkronizasyon uygulamak için aşağıdakileri sağlayın:
- Belirli bir donanım sürücüsü için eşitleme çerçevesini uygulayan bir çekirdek alanı alt sistemi. Çitlerin farkında olması gereken sürücüler genellikle Donanım Oluşturucuya erişen veya onunla iletişim kuran her şeydir. Anahtar dosyalar şunları içerir:
- Temel uygulama:
-
kernel/common/include/linux/sync.h
-
kernel/common/drivers/base/sync.c
-
-
kernel/common/Documentation/sync.txt
-
platform/system/core/libsynciçindeki çekirdek alanıyla iletişim kurmak için kitaplık
- Temel uygulama:
- Satıcı, HAL'deki
validateDisplay()ve
presentDisplay()işlevlerine parametre olarak uygun eşitleme çitlerini sağlamalıdır.
- İki çitle ilgili GL uzantısı (
EGL_ANDROID_native_fence_syncve
EGL_ANDROID_wait_sync) ve grafik sürücüsünde çit desteği.
Örnek olay: Bir görüntü sürücüsü uygulama
Senkronizasyon işlevini destekleyen API'yi kullanmak için, görüntü arabelleği işlevine sahip bir görüntü sürücüsü geliştirin. Senkronizasyon çerçevesi mevcut olmadan önce, bu fonksiyon
dma-buf nesnelerini alacak, bu arabellekleri ekrana yerleştirecek ve arabellek görünürken engelleyecekti. Örneğin:
/* * assumes buffer is ready to be displayed. returns when buffer is no longer on * screen. */ void display_buffer(struct dma_buf *buffer);
Senkronizasyon çerçevesi ile
display_buffer işlevi daha karmaşıktır. Bir arabellek ekrana getirilirken, arabellek, arabelleğin ne zaman hazır olacağını gösteren bir çit ile ilişkilendirilir. Çit temizlendikten sonra sıraya girebilir ve işi başlatabilirsiniz.
Çit temizlendikten sonra kuyruğa girmek ve işe başlamak hiçbir şeyi engellemez. Arabelleğin ne zaman ekrandan çıkacağını garanti eden kendi çitinizi hemen iade edersiniz. Siz arabellekleri sıraya koyarken, çekirdek, senkronizasyon çerçevesiyle olan bağımlılıkları listeler:
/* * displays buffer when fence is signaled. returns immediately with a fence * that signals when buffer is no longer displayed. */ struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence *fence);
Senkronizasyon entegrasyonu
Bu bölüm, çekirdek-alan eşitleme çerçevesinin, Android çerçevesinin kullanıcı alanı bölümleriyle ve birbirleriyle iletişim kurması gereken sürücülerle nasıl entegre edileceğini açıklar. Çekirdek alanı nesneleri, kullanıcı alanında dosya tanımlayıcıları olarak temsil edilir.
Entegrasyon kuralları
Android HAL arabirim kurallarını izleyin:
- API,
sync_ptbir dosya tanımlayıcı sağlıyorsa, satıcının sürücüsü veya API'yi kullanan HAL, dosya tanımlayıcıyı kapatmalıdır.
- Satıcı sürücüsü veya HAL, bir API işlevine
sync_ptiçeren bir dosya tanımlayıcı iletirse, satıcı sürücüsü veya HAL dosya tanımlayıcıyı kapatmamalıdır.
- Çit dosyası tanımlayıcısını kullanmaya devam etmek için satıcı sürücüsü veya HAL, tanımlayıcıyı çoğaltmalıdır.
Bir çit nesnesi, BufferQueue'dan her geçtiğinde yeniden adlandırılır. Çekirdek çit desteği, çitlerin adlar için dizelere sahip olmasına izin verir, bu nedenle eşitleme çerçevesi, çiti adlandırmak için sıraya alınan
SurfaceView:0 gibi pencere adını ve arabellek dizinini kullanır. Bu, adlar
/d/sync ve hata raporlarının çıktısında göründüğü için bir kilitlenmenin kaynağını belirlemek için hata ayıklamaya yardımcı olur.
ANativeWindow entegrasyonu
ANativeWindow çit farkındadır.
dequeueBuffer ,
queueBuffer ve
cancelBuffer çit parametrelerine sahiptir.
OpenGL ES entegrasyonu
OpenGL ES senkronizasyon entegrasyonu, iki EGL uzantısına dayanır:
-
EGL_ANDROID_native_fence_sync,
EGLSyncKHRnesnelerinde yerel Android çit dosyası tanımlayıcılarını sarmak veya oluşturmak için bir yol sağlar.
-
EGL_ANDROID_wait_sync, CPU tarafı yerine GPU tarafı duraklamalarına izin vererek GPU'nun
EGLSyncKHRiçin beklemesini sağlar.
EGL_ANDROID_wait_syncuzantısı,
EGL_KHR_wait_syncuzantısı ile aynıdır.
Bu uzantıları bağımsız olarak kullanmak için, ilişkili çekirdek desteğiyle birlikte
EGL_ANDROID_native_fence_sync uzantısını uygulayın. Ardından, sürücünüzde
EGL_ANDROID_wait_sync uzantısını etkinleştirin.
EGL_ANDROID_native_fence_sync uzantısı, ayrı bir yerel çit
EGLSyncKHR nesne türünden oluşur. Sonuç olarak, mevcut
EGLSyncKHR nesne türlerine uygulanan uzantılar, istenmeyen etkileşimlerden kaçınarak
EGL_ANDROID_native_fence nesnelerine mutlaka uygulanmaz.
EGL_ANDROID_native_fence_sync uzantısı, yalnızca oluşturma zamanında ayarlanabilen ve mevcut bir eşitleme nesnesinden doğrudan sorgulanamayan karşılık gelen bir yerel çit dosyası tanımlayıcı özniteliği kullanır. Bu öznitelik iki moddan birine ayarlanabilir:
- Geçerli bir çit dosyası tanımlayıcısı , mevcut bir yerel Android çit dosyası tanımlayıcısını bir
EGLSyncKHRnesnesine sarar.
- -1 , bir
EGLSyncKHRnesnesinden yerel bir Android çit dosyası tanımlayıcısı oluşturur.
EGLSyncKHR nesnesini yerel Android çit dosyası tanımlayıcısından çıkarmak için
DupNativeFenceFD() işlev çağrısını kullanın. Bu, set özniteliğini sorgulamakla aynı sonuca sahiptir, ancak alıcının çiti kapatması kuralına bağlıdır (dolayısıyla yinelenen işlem). Son olarak,
EGLSyncKHR nesnesinin yok edilmesi dahili çit niteliğini kapatır.
Donanım Besteci entegrasyonu
Hardware Composer, üç tür eşitleme çitini işler:
- Edinme çitleri , giriş arabellekleriyle birlikte
setLayerBufferve
setClientTargetçağrılarına geçirilir. Bunlar, arabelleğe bekleyen bir yazmayı temsil eder ve SurfaceFlinger veya HWC, kompozisyonu gerçekleştirmek için ilişkili arabellekten okumaya çalışmadan önce sinyal vermelidir.
-
getReleaseFencesçağrısı kullanılarak
presentDisplayçağrısından sonra serbest bırakma çitleri alınır. Bunlar, aynı katmandaki önceki tampondan bekleyen bir okumayı temsil eder. Geçerli arabellek ekranda önceki arabelleğin yerini aldığından, HWC artık önceki arabelleği kullanmadığında bir serbest bırakma çiti sinyali verir. Serbest bırakma çitleri, mevcut kompozisyon sırasında değiştirilecek olan önceki arabelleklerle birlikte uygulamaya geri gönderilir. Uygulama, kendilerine döndürülen arabelleğe yeni içerikler yazmadan önce bir yayın sınırı sinyali verene kadar beklemelidir.
- Mevcut çitler ,
presentDisplayçağrısının bir parçası olarak kare başına bir tane olacak şekilde döndürülür. Mevcut çitler, bu çerçevenin kompozisyonunun ne zaman tamamlandığını veya alternatif olarak, önceki çerçevenin kompozisyon sonucunun artık gerekli olmadığı zamanı temsil eder. Fiziksel görüntüler için,
presentDisplay, geçerli çerçeve ekranda göründüğünde mevcut çitleri döndürür. Mevcut çitler döndürüldükten sonra, varsa, SurfaceFlinger hedef arabelleğine yeniden yazmak güvenlidir. Sanal ekranlar için, çıktı arabelleğinden okumak güvenli olduğunda mevcut çitler döndürülür.