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 resmi çizmeye başlar. Resim henüz belleğe çizilmemiş olsa da arabellek işaretçisi, GPU işinin 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 tamamlandığında ekran denetleyicisi görüntüyü hemen gösterir.
Senkronizasyon çerçevesi, uygulayıcıların kendi donanım bileşenlerinde senkronizasyon kaynaklarını kullanmasına da olanak tanır. Son olarak, çerçeve, hata ayıklamaya yardımcı olmak için grafik ardışık düzeni 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
- Geliştirilmiş test metrikleri
Senkronizasyon çerçevesinde üç nesne türü bulunur:
sync_timelinesync_ptsync_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 olarak 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şlem sırasını sağlar
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_strvept_value_stroperatörlerini uygulayın. - Gerekirse kullanıcı alanı kitaplıklarının (ör. GL kitaplığı) özel zaman çizelgesi verilerine erişmesini sağlamak için doldurma
driver_dataişlevini uygulayın.data_driver, satıcıların değişmezsync_fencevesync_ptshakkında bilgi iletmesine olanak tanır. Böylece, bu bilgilere dayalı komut satırları oluşturulabilir. - Kullanıcı alanının açıkça ç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_ptveyasync_fenceöğelerine açıkça 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 görüntü tüketicisinin artık arabelleğe ihtiyacı kalmadığında sync_pt sinyali verilir. Böylece görüntü ü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ü veya donanım bloğu komutları sırayla yürüttüğünden bariyerden önce verilen tüm komutlar tamamlanır.
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 bir 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 sinyali verildiğinde, görüntü üreticiler her iki tüketicinin de tüketimi tamamladığını anlar.
sync_pt değerleri gibi çitler etkin olarak başlar ve durumları, noktalarının durumuna göre değişir. Tüm sync_pt değerleri sinyal verirse sync_fence sinyal verir. Bir sync_pt hata durumuna girerse tüm sync_fence hata durumuna girer.
Ç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ıçtaki sınırlama içinde işaretlenmişse ve diğeri işaretlenmemişse üçüncü sınırlama da 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ındalığına sahip olması gereken sürücüler genellikle Hardware Composer'a (HWC) erişen veya onunla iletişim kuran her şeydir.
Başlıca dosyalar:
- Temel uygulama:
kernel/common/include/linux/sync.hkernel/common/drivers/base/sync.c
kernel/common/Documentation/sync.txtadresindeki belgelerplatform/system/core/libsynciçinde çekirdek alanı ile iletişim kurmak için kullanılan kitaplık
- Temel uygulama:
- Tedarikçi, donanım soyutlama katmanındaki (HAL)
validateDisplay()vepresentDisplay()işlevlerine parametre olarak uygun senkronizasyon çitlerini sağlamalıdır. - İki çitle ilgili GL uzantısı (
EGL_ANDROID_native_fence_syncveEGL_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 ekranda gösterilirken 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.
Çalışmayı sıraya alma ve sınırlama kaldırıldıktan sonra başlatma, hiçbir şeyi engellemez. Arabellek, ekranın dışında olduğunda sinyal veren kendi çitinizi hemen döndürürsünüz. Arabellekleri sıraya aldığınızda ç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_ptdeğerine karşılık gelen 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_ptiçeren bir dosya tanımlayıcısı geçirirse 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ıralanan 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 için çit parametreleri var.
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ı sarmalama veya oluşturma yöntemi sağlar.EGL_ANDROID_wait_sync, CPU tarafı yerine GPU tarafında duraklamalara izin vererek GPU'nunEGLSyncKHRbeklemesine neden olur.EGL_ANDROID_wait_syncuzantısı,EGL_KHR_wait_syncuzantısıyla aynıdır.
Bu uzantıları bağımsız olarak kullanmak için EGL_ANDROID_native_fence_sync uzantısını ilişkili çekirdek desteğiyle birlikte 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. 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 ilgili bir yerel çit dosyası 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ı
EGLSyncKHRnesnesine sarmalar. - -1,
EGLSyncKHRnesnesinden yerel bir Android fence 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
HWC üç tür senkronizasyon bariyerini işler:
- Acquire fences, giriş arabellekleriyle birlikte
setLayerBuffervesetClientTargetç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ı,
getReleaseFencesaraması kullanılarakpresentDisplayaraması yapıldıktan sonra alınır. Bunlar, aynı katmandaki önceki arabellekten bekleyen bir okuma işlemini temsil eder. HWC, geçerli arabellek ekranda önceki arabelleğin yerini aldığından önceki arabelleği kullanmayı bıraktığında yayınlanma sınırı 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ın bariyeri 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üğündepresentDisplaymevcut çitleri 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 sınırlar döndürülür.