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ı belirtmesini sağlayan bir API sunar. Çerçeve, senkronizasyon temel öğelerinin çekirdekten kullanıcı alanına ve kullanıcı alanı işlemleri arasında sürücüler arasında geçirilmesine de olanak tanır.
Örneğin, bir uygulama GPU'da yapılacak işleri sıraya alabilir. GPU, bu görüntüyü çizmeye başlar. Resim henüz belleğe çizilmemiş olsa da arabellek işaretçisi, GPU çalışmasının ne zaman tamamlanacağını belirten bir çitle birlikte pencere birleştiricisine iletilir. Pencere birleştirici, işlemeye önceden başlar ve işi ekran denetleyicisine aktarır. Benzer şekilde, CPU çalışması önceden yapılır. GPU işlemi tamamladığında ekran denetleyicisi görüntüyü hemen gösterir.
Senkronizasyon çerçevesi, uygulayıcıların kendi donanım bileşenlerinde senkronizasyon kaynaklarından yararlanmasına da olanak tanır. Son olarak, çerçeve, hata ayıklamaya yardımcı olmak için grafik işlem hattı hakkında görünürlük sağlar.
Açık senkronizasyon
Açık senkronizasyon, grafik arabelleklerinin üreticilerinin ve tüketicilerinin bir arabelleği kullanmayı bitirdiklerinde sinyal vermesini sağlar. Açık senkronizasyon, çekirdek alanında uygulanır.
Açık senkronizasyonun avantajları şunlardır:
- Cihazlar arasında daha az davranış farklılığı
- Daha iyi hata ayıklama desteği
- İyileştirilmiş test metrikleri
Senkronizasyon çerçevesinde üç nesne türü vardır:
sync_timeline
sync_pt
sync_fence
sync_timeline
sync_timeline
, satıcıların her sürücü örneği (ör. GL bağlamı, ekran denetleyicisi veya 2D blitter) için uygulaması gereken, tekdüze şekilde artan bir zaman çizelgesidir. sync_timeline
Belirli bir donanım parçası için çekirdeğe gönderilen işlerin sayısı.
sync_timeline
, işlemlerin sırası hakkında garantiler sunar ve donanıma özel uygulamaları etkinleştirir.
sync_timeline
işaretlemesini uygularken aşağıdaki yönergeleri izleyin:
- Hata ayıklamayı kolaylaştırmak için tüm sürücülere, zaman çizelgelerine ve sınırlara yararlı adlar verin.
- Hata ayıklama çıkışını daha okunabilir hale getirmek için zaman çizelgelerinde
timeline_value_str
vept_value_str
operatörlerini uygulayın. - İstenirse kullanıcı alanı kitaplıklarının (ör. GL kitaplığı) özel zaman çizelgesi verilerine erişmesini sağlamak için doldurma
driver_data
işlevini uygulayın.data_driver
, satıcıların değişmezsync_fence
vesync_pts
hakkında bilgi iletmesine olanak tanır. Böylece, bu bilgilere dayalı komut satırları oluşturulabilir. - Kullanıcı alanının açıkça bir çit oluşturmasına veya sinyal vermesine izin vermeyin. Açıkça sinyal/çit oluşturmak, işlem hattı işlevselliğini durduran bir hizmet reddi saldırısına neden olur.
sync_timeline
,sync_pt
veyasync_fence
öğelerine doğrudan erişmeyin. API, gerekli tüm işlevleri sağlar.
sync_pt
sync_pt
, sync_timeline
üzerinde tek bir değer veya noktadır. Bir noktanın üç durumu vardır: etkin, sinyal verilmiş ve hata. Puanlar etkin durumda başlar ve sinyal verilen veya hata durumlarına geçer. Örneğin, bir resim tüketicisinin artık arabelleğe ihtiyacı kalmadığında sync_pt
sinyali verilir. Böylece resim üreticisi, arabelleğe tekrar yazmanın sorun olmayacağını anlar.
sync_fence
sync_fence
, genellikle farklı sync_timeline
üst öğelere (ör. ekran denetleyicisi ve GPU) sahip olan sync_pt
değerlerinden oluşan bir koleksiyondur. sync_fence
, sync_pt
ve
sync_timeline
, sürücülerin ve kullanıcı alanının bağımlılıklarını bildirmek için kullandığı temel öğelerdir. Bir bariyer sinyal verdiğinde, çekirdek sürücüsü veya donanım bloğu komutları sırayla yürüttüğünden bariyerden önce verilen tüm komutların tamamlanacağı garanti edilir.
Senkronizasyon çerçevesi, birden fazla tüketicinin veya üreticinin bir arabellek kullanmayı bitirdiklerinde sinyal vermesine olanak tanır ve bağımlılık bilgilerini tek bir işlev parametresiyle iletir. Çitler, dosya tanımlayıcısı tarafından desteklenir ve çekirdek alanından kullanıcı alanına geçirilir. Örneğin, bir çit, iki ayrı görüntü tüketicisi bir arabelleği okumayı bitirdiğinde bunu belirten iki sync_pt
değeri içerebilir. Sınır işaretlendiğinde, görüntü üreticiler her iki tüketicinin de tüketimi tamamladığını bilir.
sync_pt
değerleri gibi çitler etkin olarak başlar ve durumlarını noktalarının durumuna göre değiştirir. Tüm sync_pt
değerleri sinyalli hâle gelirse sync_fence
sinyalli hâle gelir. Bir sync_pt
hata durumuna düşerse tüm sync_fence
hata durumuna düşer.
Çit oluşturulduktan sonra sync_fence
üyeliği değiştirilemez. Bir çitte birden fazla nokta elde etmek için iki farklı çitten gelen noktaların üçüncü bir çite eklendiği bir birleştirme işlemi yapılır.
Bu noktalardan biri başlangıç çitinde işaretlenmişse ve diğeri işaretlenmemişse üçüncü çit de işaretlenmiş durumda olmaz.
Açık senkronizasyonu uygulamak için aşağıdakileri sağlayın:
- Belirli bir donanım sürücüsü için senkronizasyon çerçevesini uygulayan bir çekirdek alanı alt sistemi. Çit farkında olması gereken sürücüler genellikle Donanım Birleştirici'ye erişen veya onunla iletişim kuran her şeydir.
Başlıca dosyalar:
- Temel uygulama:
kernel/common/include/linux/sync.h
kernel/common/drivers/base/sync.c
kernel/common/Documentation/sync.txt
adresindeki belgelerplatform/system/core/libsync
içinde çekirdek alanı ile iletişim kurmak için kullanılan kitaplık
- Temel uygulama:
- Tedarikçi, HAL'deki
validateDisplay()
vepresentDisplay()
işlevlerine parametre olarak uygun senkronizasyon çitlerini sağlamalıdır. - İki çitle ilgili GL uzantısı (
EGL_ANDROID_native_fence_sync
veEGL_ANDROID_wait_sync
) ve grafik sürücüsünde çit desteği.
Örnek olay: Ekran sürücüsü uygulama
Senkronizasyon işlevini destekleyen API'yi kullanmak için
görüntü arabelleği işlevi olan bir ekran sürücüsü geliştirin. Senkronizasyon çerçevesi oluşturulmadan önce bu işlev, dma-buf
nesneleri alır, bu arabellekleri ekrana yerleştirir ve arabellek görünürken engellerdi. Ö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çevesiyle display_buffer
işlevi daha karmaşıktır. Bir arabellek ekrana yerleştirilirken arabellek, hazır olma zamanını belirten bir çitle ilişkilendirilir. Çalışmayı sıraya alabilir ve sınırlama kaldırıldıktan sonra başlatabilirsiniz.
Çit temizlendikten sonra işi sıraya koymak ve başlatmak hiçbir şeyi engellemez. Arabellek ne zaman ekrandan çıkacaksa bunu garanti eden kendi çitinizi hemen döndürürsünüz. Arabellekleri sıraya alırken çekirdek, senkronizasyon çerçevesiyle 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ümde, çekirdek alanı senkronizasyon ç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ği açıklanmaktadır. Çekirdek alanı nesneleri, kullanıcı alanında dosya tanımlayıcıları olarak gösterilir.
Entegrasyon kuralları
Android HAL arayüzü kurallarına uyun:
- API,
sync_pt
öğesine referans veren bir dosya tanımlayıcısı sağlıyorsa API'yi kullanan satıcının sürücüsü veya HAL, dosya tanımlayıcısını kapatmalıdır. - Tedarikçi sürücüsü veya HAL, bir API işlevine
sync_pt
içeren bir dosya tanımlayıcısı iletirse tedarikçi sürücüsü veya HAL, dosya tanımlayıcısını kapatmamalıdır. - Çit dosyası tanımlayıcısını kullanmaya devam etmek için tedarikçi sürücüsünün veya HAL'nin tanımlayıcıyı kopyalaması gerekir.
Bir çit nesnesi, BufferQueue'dan her geçtiğinde yeniden adlandırılır.
Çekirdek çit desteği, çitlerin ad için dizeler içermesine olanak tanır. Bu nedenle, senkronizasyon çerçevesi, çiti adlandırmak için sıraya alınan pencere adını ve arabellek dizinini kullanır (ör. SurfaceView:0
). Bu, /d/sync
çıkışında ve hata raporlarında adlar göründüğünden kilitlenmenin kaynağını belirlemek için hata ayıklamada faydalıdır.
ANativeWindow entegrasyonu
ANativeWindow, çit farkındadır. dequeueBuffer
,
queueBuffer
ve cancelBuffer
'de sınır parametreleri bulunur.
OpenGL ES entegrasyonu
OpenGL ES senkronizasyon entegrasyonu iki EGL uzantısına dayanır:
EGL_ANDROID_native_fence_sync
,EGLSyncKHR
nesnelerinde yerel Android çit dosyası tanımlayıcılarını sarmalama veya oluşturma yöntemi sağlar.EGL_ANDROID_wait_sync
, CPU tarafı yerine GPU tarafında duraklamalara izin vererek GPU'nunEGLSyncKHR
beklemesine neden olur.EGL_ANDROID_wait_sync
uzantısı,EGL_KHR_wait_sync
uzantısıyla 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ı, farklı bir yerel çit EGLSyncKHR
nesne türünden oluşur. Bu nedenle, mevcut EGLSyncKHR
nesne türleri için geçerli olan uzantılar, EGL_ANDROID_native_fence
nesneleri için geçerli olmayabilir ve istenmeyen etkileşimler önlenir.
EGL_ANDROID_native_fence_sync
uzantısı, yalnızca oluşturma sırasında ayarlanabilen ve mevcut bir senkronizasyon nesnesinden doğrudan sorgulanamayan, karşılık gelen bir yerel fence dosya tanımlayıcı özelliği kullanır. Bu özellik iki moddan birine ayarlanabilir:
- Geçerli bir fence dosyası tanımlayıcısı, mevcut bir yerel Android fence dosyası tanımlayıcısını bir
EGLSyncKHR
nesnesine sarmalar. - -1,
EGLSyncKHR
nesnesinden yerel bir Android çit dosya tanımlayıcısı oluşturur.
Yerel Android çit dosya tanımlayıcısından DupNativeFenceFD()
nesnesini çıkarmak için DupNativeFenceFD()
işlev çağrısını kullanın.EGLSyncKHR
Bu, set özelliğine sorgu göndermekle aynı sonucu verir ancak alıcının çiti kapatması (dolayısıyla yinelenen işlem) kuralına uyar. Son olarak, EGLSyncKHR
nesnesinin yok edilmesi dahili çit özelliğini kapatır.
Donanım Composer entegrasyonu
Donanım Composer üç tür senkronizasyon bariyerini işler:
- Acquire fences, giriş arabellekleriyle birlikte
setLayerBuffer
vesetClientTarget
çağrılarına iletilir. Bunlar, arabelleğe yazma işleminin beklemede olduğunu gösterir ve SurfaceFlinger veya HWC, kompozisyon gerçekleştirmek için ilişkili arabellekten okumaya çalışmadan önce sinyal vermelidir. - Yayın sınırları,
getReleaseFences
araması kullanılarakpresentDisplay
araması yapıldıktan sonra alınır. Bunlar, aynı katmandaki önceki arabellekten okunmayı bekleyen verileri gösterir. A HWC, geçerli arabellek ekranda önceki arabelleğin yerini aldığından önceki arabelleği kullanmayı bıraktığında yayın bariyeri sinyalleri gönderir. Yayın sınırları, mevcut kompozisyon sırasında değiştirilecek önceki arabelleklerle birlikte uygulamaya geri iletilir. Uygulama, kendisine döndürülen arabelleğe yeni içerik yazmadan önce yayınlanma sınırı sinyallerini beklemelidir. - Mevcut çitler,
presentDisplay
çağrısının bir parçası olarak kare başına bir tane döndürülür. Mevcut bariyerler, bu karenin kompozisyonunun tamamlandığı veya alternatif olarak, önceki karenin kompozisyon sonucunun artık gerekli olmadığı zamanı gösterir. Fiziksel ekranlarda, geçerli çerçeve ekranda göründüğündepresentDisplay
mevcut sınırlayıcıları döndürür. Mevcut çitler döndürüldükten sonra, geçerliyse SurfaceFlinger hedef arabelleğine tekrar yazmak güvenlidir. Sanal ekranlarda, çıkış arabelleğinden okumanın güvenli olduğu durumlarda mevcut çitler döndürülür.