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 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, GL bağlamında, görüntü kontrolörü ya da 2D Blitter olarak, her bir tahrik, örneğin uygulanması gereken bir monoton artan bir zaman çizgisidir. sync_timeline sayımları işler belirli bir donanım parçası için çekirdeğe sundu. sync_timeline operasyonların sipariş konusunda garanti sağlar ve donanıma özgü uygulamalarına olanak verir.

Uygularken aşağıdaki yönergeleri izleyin sync_timeline :

  • Hata ayıklamayı basitleştirmek için tüm sürücüler, zaman çizelgeleri ve çitler için yararlı adlar sağlayın.
  • Uygulamak timeline_value_str ve pt_value_str ayıklama çıkışı daha okunabilir hale getirmek için zaman çizelgeleri operatörleri.
  • Dolguyu uygulamak driver_data için vermek userspace kütüphaneler, böyle istenirse özel zaman çizelgesi verilerine GL kütüphane, erişimi gibi. data_driver satıcıları değişmez hakkında bilgi aktarmak sağlayan sync_fence ve sync_pts bunlara dayalı inşa komut satırlarına.
  • 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.
  • Erişemediğiniz Do sync_timeline , sync_pt veya sync_fence açıkça elemanları. API, gerekli tüm işlevleri sağlar.

sync_pt

sync_pt bir tek değeri veya bir yer sync_timeline . 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. Bir görüntü tüketici artık bir tampon ihtiyacı olduğunda Örneğin, bir sync_pt bir görüntü yapımcı tekrar tampon içine yazmaya sorun olmadığını bilmesi için bildirilir.

sync_fence

sync_fence topluluğudur sync_pt genellikle farklı olan değerler sync_timeline (örneğin ekran denetleyicisi ve GPU gibi) anne. sync_fence , sync_pt ve sync_timeline sürücüleri ve kullanıcı alanı kullanımı onların bağımlılıklarını iletişim ana temellerdir. 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 içerebilir sync_pt iki ayrı görüntü tüketicilerin bir tampon okuma yapılır gerektiğini göstermek değerleri. Çit sinyali verildiğinde, görüntü üreticileri her iki tüketicinin de tüketmesinin bittiğini biliyor.

Parmaklıklar gibi sync_pt değerler, onların noktalarının durumuna dayalı aktif ve değişim durumunu başlatın. Tüm Eğer sync_pt değerleri işaret hale, sync_fence sinyal olur. Biri varsa sync_pt bir hata durumuna girer, tüm sync_fence bir hata durumu vardır.

Bir üyelik sync_fence çit oluşturulduktan sonra sabittir. 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
    • Belgeleme kernel/common/Documentation/sync.txt
    • Çekirdek alanı ile iletişim kurmak için Kütüphane platform/system/core/libsync
  • Satıcı için parametre olarak uygun senkronizasyon çitler sağlamalıdır validateDisplay() ve presentDisplay() HAL işlevleri.
  • İki çit ile ilişkili GL uzantıları ( EGL_ANDROID_native_fence_sync ve 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 var önce bu fonksiyon alacak dma-buf tamponu görünür ise, nesne ekranda bu tamponlar koymak ve blok. Ö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 başvuran bir dosya tanıtıcı sağlıyorsa sync_pt , satıcının sürücü veya API kullanarak HAL dosya tanıtıcı kapatılması gerekiyor.
  • Satıcı sürücüsü veya HAL bir içeren bir dosya tanıtıcı geçerse sync_pt bir API fonksiyonu, satıcı sürücüsü veya HAL gerekir değil yakın dosya tanımlayıcısı için.
  • Ç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. Senkron çerçeve penceresi adını kullanır ve bu şekilde çit, isim sıraya ediliyor endeksi tampon böylece Çekirdek çit desteği, çitler adları için dizeleri olmasını sağlar SurfaceView:0 . İsimler çıkışında görünecek gibi bu bir çıkmaz kaynağını belirlemek için hata ayıklama yardımcı olur /d/sync ve hata raporları.

ANativeWindow entegrasyonu

ANativeWindow çit farkındadır. dequeueBuffer , queueBuffer ve cancelBuffer çit parametreleri vardır.

OpenGL ES entegrasyonu

OpenGL ES senkronizasyon entegrasyonu, iki EGL uzantısına dayanır:

  • EGL_ANDROID_native_fence_sync sarmak veya yerli Android çit dosya tanımlayıcıları oluşturmak için bir yol sağlar EGLSyncKHR nesneler.
  • EGL_ANDROID_wait_sync GPU tarafı için GPU beklemek yapma yerine CPU tarafı daha durdurulmasıdır verir EGLSyncKHR . EGL_ANDROID_wait_sync uzantısı ile aynıdır EGL_KHR_wait_sync uzantısı.

Bağımsız bir şekilde, bu uzantılar kullanmak için, uygulanması EGL_ANDROID_native_fence_sync ilgili çekirdek desteği ile birlikte uzantı. Daha sonra, etkinleştirmek EGL_ANDROID_wait_sync sürücünüzde uzantıyı. EGL_ANDROID_native_fence_sync uzantısı farklı bir doğal çit oluşur EGLSyncKHR nesne türü. Sonuç olarak, mevcut için geçerli uzantıları EGLSyncKHR nesne türleri mutlaka uygulanmaz EGL_ANDROID_native_fence istenmeyen etkileşimler kaçınarak, nesneler.

EGL_ANDROID_native_fence_sync uzantısı sadece oluşturma sırasında ayarlanabilir ve direkt olarak var olan bir senkronizasyon nesneden ileriye sorgulanamaz karşılık gelen doğal çit dosya tanıtıcısı özelliği kullanmaktadır. Bu öznitelik iki moddan birine ayarlanabilir:

  • Geçerli bir çit dosya tanıtıcı bir varolan yerel Android çit dosya tanıtıcı sarar EGLSyncKHR nesne.
  • -1 bir bir yerel Android çit dosya tanıtıcı oluşturur EGLSyncKHR nesne.

Kullan DupNativeFenceFD() ayıklamak için işlev çağrısı EGLSyncKHR yerel Android çit dosya tanımlayıcı nesneyi. 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, tahrip EGLSyncKHR nesneyi iç çit niteliğini kapatır.

Donanım Besteci entegrasyonu

Hardware Composer, üç tür eşitleme çitini işler:

  • Edinme duvarları giriş tampon ile birlikte geçirilir setLayerBuffer ve setClientTarget aramalar. 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.
  • Yayın çitler için çağrısından sonra alınır presentDisplay kullanarak getReleaseFences çağrıyı. 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 çağrısının bir parçası olarak, kare başına bir tane döndürülür presentDisplay . 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 ekranlar için, presentDisplay geçerli çerçeve ekranda göründüğünde mevcut çitler 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.