Senkronizasyon çerçevesi

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 tamponların ne zaman serbest bırakıldığını belirtmesine olanak tanıyan bir API sağlar. Çerçeve, senkronizasyon primitiflerinin çekirdekten kullanıcı alanına ve kullanıcı alanı süreçleri arasında iletilmesine de olanak tanır.

Örneğin, bir uygulama GPU'da gerçekleştirilecek işleri sıraya alabilir. GPU bu resmi çizmeye başlar. Resim çizilmemiş olsa da belleğe henüz eklenmemişse, arabellek işaretçisi pencereye ve GPU çalışmasının ne zaman biteceğini belirten bir çitle somut olarak ortaya koyar. Pencere derleyici, işlemeyi önceden başlatır ve işi ekran denetleyicisine iletir. Benzer şekilde, CPU çalışması da önceden yapılır. GPU işlem bittikten sonra ekran denetleyicisi resmi hemen gösterir.

Senkronizasyon çerçevesi, uygulayıcıların kendi donanım bileşenlerindeki senkronizasyon kaynaklarından da yararlanmasına olanak tanır. Son olarak, çerçeve, hata ayıklama işlemine yardımcı olmak için grafik ardışık düzenine 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 göndermelerini sağlar. Açık senkronizasyon: örneğidir.

Açık senkronizasyonun avantajları şunlardır:

  • Cihazlar arasında daha az davranış varyasyonu
  • Daha iyi hata ayıklama desteği
  • İyileştirilmiş test metrikleri

Senkronizasyon çerçevesi üç nesne türüne sahiptir:

  • sync_timeline
  • sync_pt
  • sync_fence

sync_timeline

sync_timeline, tedarikçi firmaların GL bağlamı, ekran denetleyici veya 2D blitter gibi her sürücü örneği için uygulaması gereken monoton olarak artan bir zaman çizelgesidir. sync_timeline, belirli bir donanım parçası için çekirdeğe gönderilen işlerin sayısını belirtir. sync_timeline, işlemlerin sırası hakkında garantiler sağlar ve donanıma özel uygulamaları etkinleştirir.

sync_timeline'ü uygularken aşağıdaki yönergeleri izleyin:

  • Sürücüler, zaman çizelgeleri ve sınırları basitleştirmek için yararlı adlar verin hata ayıklama.
  • Hata ayıklama çıkışını daha okunaklı hale getirmek için zaman çizelgelerinde timeline_value_str ve pt_value_str operatörlerini uygulayın.
  • Kullanıcı alanı kitaplıkları sağlamak için driver_data dolgusunu uygulayın. Örneğin, GL kitaplığı gibi, gizli zaman çizelgesi verilerine erişebilir. data_driver, tedarikçilerin sabit öğe ile ilgili bilgileri iletmesine olanak tanır Komut satırları oluşturmak için sync_fence ve sync_pts karar verebilir.
  • Kullanıcı alanının açıkça bir çit oluşturmasına veya sinyalini göstermesine izin vermeyin. Açıkça sinyal/çit oluşturmak, ardışık düzen işlevini durduran bir hizmet reddi saldırısına neden olur.
  • sync_timeline, sync_pt veya sync_fence öğelerine açıkça erişmeyin. API, gerekli tüm işlevleri sağlar.

senkronizasyon_pt

sync_pt, sync_timeline üzerinde tek bir değer veya noktadır. Nokta üç durumu vardır: etkin, sinyalli ve hata. Noktalar etkin durumda başlar ve sinyal veya hata durumlarında geçiş yapar. Örneğin, bir resim tüketicisinin artık arabelleğe ihtiyacı olmadığında sync_pt sinyali gönderilir. Böylece resim üretici, arabelleğe tekrar yazmanın uygun olduğunu bilir.

senkronizasyon_fence

sync_fence, sync_pt değerden oluşan bir koleksiyondur sıklıkla farklı sync_timeline üst öğeleri vardır (ekran için denetleyici ve GPU) ekleyin. 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 primitiflerdir. Bir çit sinyali aldığında, ç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 tamamlanacağı garanti edilir.

Senkronizasyon çerçevesi, birden fazla tüketicinin veya üreticinin, ve bağımlılık bilgilerini tek bir fonksiyonla paylaşarak tampon kullanmayı parametresinden sonra bir değer girin. Çitler bir dosya tanımlayıcısı ile desteklenir ve örneğine bakalım. Örneğin, bir çit iki İki ayrı imaj tüketicisinin tamamlandığını belirten sync_pt değerleri bir tampon okumayı öğreteceğim. Çit sinyali alındığında, görüntü üreticileri hem tükettiğini görüyoruz.

sync_pt değerleri gibi çitler etkin olarak başlar ve noktalarının durumuna göre durum değiştirir. Tüm sync_pt değerleri sinyal haline gelirse sync_fence sinyale dönüşür. Bir sync_pt hata durumuna girerse sync_fence'un tamamı hata durumunda olur.

sync_fence üyeliği, kurallar bittikten sonra değiştirilemez oluşturuldu. 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 gerçekleştirilir. Bu noktalardan biri başlangıçtaki çimde işaret edilmiş, diğeri ise işaretlenmemişse devre dışı da bırakabilirsiniz.

Belirli bir senkronizasyon uygulamak için aşağıdakileri sağlayın:

  • Belirli bir donanım sürücüsü için senkronizasyon çerçevesini uygulayan çekirdek alanı alt sistemi. Çitlere karşı dikkatli olması gereken sürücüler Donanım Oluşturucu'ya erişen veya iletişim kuran her şeyi içerir. Önemli dosyalar şunlardır:
    • Temel uygulama:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • kernel/common/Documentation/sync.txt adresindeki belgeler
    • platform/system/core/libsync alanındaki çekirdek alanıyla iletişim kurmak için kullanılan kitaplık
  • Tedarikçi firma, HAL'deki validateDisplay() ve presentDisplay() işlevlerine parametre olarak uygun senkronizasyon çitlerini sağlamalıdır.
  • Çitlerle ilgili iki GL uzantısı (EGL_ANDROID_native_fence_sync ve EGL_ANDROID_wait_sync) ve grafiklerde çit desteği gerekir.

Örnek olay: Görüntü sürücüsü uygulama

Senkronizasyon işlevini destekleyen API'yi kullanmak için Ekran arabellek işlevine sahip bir ekran sürücüsü geliştirmenize yardımcı olabilir. Şu tarihten önce: senkronizasyon çerçevesi vardı, bu işlev dma-buf bu arabellekleri ekrana koyun ve arabellek görünür durumdayken engelleyin. Ö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. Arabellek ekranda gösterilirken arabellek, tamponun ne zaman hazır olacağını belirten bir çitle ekleyebilirsiniz. Sıraya alabilirsiniz ve sınır ortadan kalktıktan sonra işe başlayabileceksiniz.

İşleri sıraya alındıktan sonra başlatmak ve işleri bir engel ortadan kalktıktan sonra başlatmak hiçbir şeyi engellemez. Kendi çitinizi hemen iade edersiniz. Böylece proje tamponun devre dışı bırakılır. Arabellekleri sıraya eklediğinizde ç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ü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ındaki nesneler, kullanıcı alanında dosya tanımlayıcıları olarak temsil edilir.

Entegrasyon kuralları

Android HAL arayüz kurallarını uygulayın:

  • API, bir sync_pt ile ilişkili bir dosya tanımlayıcısı sağlarsa Tedarikçi firmanın sürücüsünün veya API'yi kullanan HAL'nin, dosya açıklayıcıyı kapatması gerekir.
  • Tedarikçi sürücü veya HAL, bir API işlevine sync_pt içeren bir dosya tanımlayıcısı iletirse tedarikçi sürücü veya HAL, dosya tanımlayıcıyı kapatmamalıdır.
  • Çit dosya tanımlayıcısını kullanmaya devam etmek için tedarikçi sürücü veya HAL, tanımlayıcıyı kopyalamalıdır.

Çit nesnesi, BufferQueue'dan her geçtiğinde yeniden adlandırılır. Çekirdek çit desteği, çitlerin adlar için dizelere sahip olmasını sağlar. Bu nedenle, çerçeve, adını belirtmek için sıraya alınan pencere adını ve arabellek dizinini kullanır görebilirsiniz. Örneğin SurfaceView:0. Adlar /d/sync ve hata raporlarının çıktısında göründüğü için bu, kilitlenmenin kaynağını belirlemek için hata ayıklamada faydalıdır.

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, şurada yerel Android çit dosyası tanımlayıcılarını sarmala veya oluştur: EGLSyncKHR nesne.
  • EGL_ANDROID_wait_sync, CPU tarafında değil GPU tarafında duraklamalar yapılmasına izin verir ve GPU'nun EGLSyncKHR için beklemesini sağlar. İlgili içeriği oluşturmak için kullanılan EGL_ANDROID_wait_sync uzantısı ile aynı EGL_KHR_wait_sync uzantısı.

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. Sonra, EGL_ANDROID_wait_sync etkinleştirin uzantısına sahip olursunuz. EGL_ANDROID_native_fence_sync uzantısı, farklı bir yerel çit EGLSyncKHR nesne türünden oluşur. Bu nedenle, mevcut EGLSyncKHR için geçerli olan uzantılar nesne türlerinin EGL_ANDROID_native_fence için geçerli olması gerekmez kullanarak istenmeyen etkileşimleri önler.

EGL_ANDROID_native_fence_sync uzantısı, yalnızca oluşturulma sırasında ayarlanabilen ve mevcut bir senkronizasyon nesnesinden doğrudan sorgulanamayacak karşılık gelen bir doğal çit dosyası tanımlayıcısı özelliği kullanır. Bu özellik 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 EGLSyncKHR nesnesine sarar.
  • -1, EGLSyncKHR nesnesinden yerel bir Android çit dosya tanımlayıcısı oluşturur.

Şunu ayıklamak için DupNativeFenceFD() işlev çağrısını kullanın: Yerel Android çit dosyası tanımlayıcısından EGLSyncKHR nesnesi. Bu işlem, set özelliğini sorgulamakla aynı sonucu verir ancak alıcının çiti kapatması (bu nedenle kopyalama işlemi) kuralı geçerlidir. Son olarak, EGLSyncKHR nesnesi yok edildiğinde dahili çit özelliği kapatılır.

Donanım Composer entegrasyonu

Donanım Derleyici üç tür senkronizasyon çiti işler:

  • Parmaklıkları edinme, giriş arabellekleriyle birlikte setLayerBuffer ve setClientTarget çağrıları. Bunlar, arabelleğe alma için bekleyen bir yazma işlemini temsil eder ve SurfaceFlinger veya HWC, ilişkili arabellekteki verileri okuyarak performansı artırır.
  • Sınırların serbest bırakılması, getReleaseFences çağrısı kullanılarak presentDisplay çağrısından sonra alınır. Bunlar, aynı katmandaki önceki arabellekten bekleyen bir okuma işlemini temsil eder. Mevcut arabellek ekrandaki önceki arabelleğin yerini aldığı için HWC artık önceki arabelleği kullanmıyorsa serbest bırakma çiti sinyalleri gönderilir. Sürüm çitleri, mevcut kompozisyon sırasında değiştirilecek önceki arabellekler ile birlikte uygulamaya geri aktarılır. Uygulamanın bir sonraki aşamaya kadar beklemesi gerekir arabelleğe almaya devam edecek yeni içerikler yazmadan önce geri döndü.
  • Mevcut çitler, presentDisplay adlı kişiye çağrı. Mevcut çitler, bu karenin derlemesinin tamamlandığını veya alternatif olarak önceki karenin derleme sonucuna artık ihtiyaç duyulmadığını gösterir. Fiziksel için ifadesi görüntülenirse presentDisplay, ekranda geçerli kare görünür. Mevcut çitler döndürüldükten sonra güvenli değilse SurfaceFlinger hedef arabelleğine tekrar yazmak güvenlidir geçerlidir. Sanal ekranlarda, çıkış arabelleğinden okumanın güvenli olduğu durumlarda mevcut çitler döndürülür.