Donanım Composer HAL'sini uygulama

Donanım Oluşturucu (HWC) HAL, SurfaceFlinger'dan alınan katmanları birleştirerek OpenGL ES (GLES) ve GPU'nun gerçekleştirdiği kompozisyon miktarını azaltır.

HWC, yüzeyleri birleştirmek için yer paylaşımları ve 2D blitter'ler gibi nesneleri soyutlar ve pencereleri birleştirmek için özel pencere oluşturma donanımıyla iletişim kurar. SurfaceFlinger'ın GPU ile birleştirmesini beklemek yerine pencereleri birleştirmek için HWC'yi kullanın. Çoğu GPU, oluşturma için optimize edilmemiştir ve GPU, SurfaceFlinger'dan katmanlar oluşturduğunda uygulamalar kendi oluşturma işlemleri için GPU'yu kullanamaz.

HWC uygulamaları şunları desteklemelidir:

  • En az dört yer paylaşımı:
    • Durum çubuğu
    • Sistem çubuğu
    • Uygulama
    • Duvar kağıdı/arka plan
  • Ekrandan daha büyük katmanlar (ör. duvar kağıdı)
  • Aynı anda piksel başına önceden çarpılmış alfa harmanlaması ve düzlem başına alfa harmanlaması
  • Korunan video oynatma için donanım yolu
  • RGBA paketleme sırası, YUV biçimleri ve tiling, swizzling ve stride özellikleri

HWC'yi uygulamak için:

  1. İşlevsel olmayan bir HWC uygulayın ve tüm kompozisyon çalışmalarını GLES'e gönderin.
  2. Oluşturma işlemini HWC'ye kademeli olarak devretmek için bir algoritma uygulayın. Örneğin, HWC'nin yer paylaşımı donanımına yalnızca ilk üç veya dört yüzeyi atayın.
  3. Donanım ara birimini optimize edin. Buna şunlar dahil olabilir:
    • GPU'dan alınan yükü en üst düzeye çıkaran yüzeyleri seçip bunları HWC'ye gönderme.
    • Ekranın güncellenip güncellenmediğini algılama. Aksi takdirde, güç tasarrufu yapmak için derlemeyi HWC yerine GLES'e atayın. Ekran tekrar güncellendiğinde, oluşturma işlemini HWC'ye aktarmaya devam edin.
    • Aşağıdakiler gibi yaygın kullanım alanlarına hazırlanma:
      • Durum çubuğu, sistem çubuğu, uygulama penceresi ve canlı duvar kağıtlarını içeren ana ekran
      • Dikey ve yatay modda tam ekran oyunlar
      • Altyazı ve oynatma kontrolü içeren tam ekran video
      • Korunan video oynatma
      • Bölünmüş ekran çoklu pencere

HWC primitifleri

HWC, kompozisyon çalışmasını ve ekran donanımıyla etkileşimini temsil etmek için katmanlar ve ekranlar olmak üzere iki primitif sağlar. HWC, VSYNC üzerinde kontrol sağlar ve VSYNC etkinliği gerçekleştiğinde SurfaceFlinger'ı bilgilendirmek için geri çağırma işlevi sunar.

HIDL arayüzü

Android 8.0 ve sonraki sürümler, HWC ile SurfaceFlinger arasında bağlayıcılı IPC için Composer HAL adlı bir HIDL arayüzü kullanır. Composer HAL, eski hwcomposer2.h arayüzünün yerini alır. Tedarikçiler HWC için bir Composer HAL uygulaması sağlarsa Composer HAL, SurfaceFlinger'dan gelen HIDL çağrılarını doğrudan kabul eder. Tedarikçiler HWC'nin eski bir uygulamasını sağlıyorsa Composer HAL, işlev işaretçilerini hwcomposer2.h'den yükler ve HIDL çağrılarını işlev işaretçisi çağrılarına yönlendirir.

HWC, belirli bir ekranın özelliklerini belirleme, farklı ekran yapılandırmaları (ör. 4K veya 1080p çözünürlük) ve renk modları (ör. doğal renk veya gerçek sRGB) arasında geçiş yapma ve ekranı açma, kapatma ya da destekleniyorsa düşük güç moduna geçirme işlevleri sağlar.

İşlev işaretçileri

Tedarikçiler Composer HAL'i doğrudan uygularsa SurfaceFlinger, işlevlerini HIDL IPC aracılığıyla çağırır. Örneğin, SurfaceFlinger bir katman oluşturmak için Composer HAL'de createLayer() işlevini çağırır.

Tedarikçi firmalar hwcomposer2.h arayüzünü uygularsa Composer HAL, hwcomposer2.h işlev işaretçilerini çağırır. hwcomposer2.h yorumlarında, HWC arayüz işlevlerine adlandırılmış alanlar olarak arayüzde bulunmayan küçük harfli CamelCase adlarıyla başvurulur. Neredeyse her işlev, hwc2_device_t tarafından sağlanan getFunction kullanılarak işlev işaretçisi istenerek yüklenir. Örneğin, createLayer işlevi, HWC2_PFN_CREATE_LAYER türüne sahip bir işlev işaretçisidir ve HWC2_FUNCTION_CREATE_LAYER listelenmiş değeri getFunction'a iletildiğinde döndürülür.

Composer HAL işlevleri ve HWC işlev aktarma işlevleri hakkında ayrıntılı dokümanlar için composer adresine bakın. HWC işlev işaretçileri hakkında ayrıntılı dokümanlar için hwcomposer2.h bölümüne bakın.

Katman ve ekran sapları

Katmanlar ve ekranlar, HWC tarafından oluşturulan tutamaçlarla değiştirilir. Herkese açık kullanıcı adları SurfaceFlinger için opaktır.

SurfaceFlinger yeni bir katman oluşturduğunda createLayer işlevini çağırır. Bu işlev, doğrudan uygulamalar için Layer türü veya geçiş uygulamaları için hwc2_layer_t türü döndürür. SurfaceFlinger, ilgili katmanın bir özelliğini değiştirdiğinde hwc2_layer_t değerini, değişikliği yapmak için gereken diğer bilgilerle birlikte uygun değişiklik işlevine iletir. hwc2_layer_t türü, bir işaretçi veya dizin tutacak kadar büyüktür.

Fiziksel ekranlar, hotplug ile oluşturulur. Fiziksel bir ekran hotplug ile bağlandığında HWC bir tutamaç oluşturur ve hotplug geri çağırma işlevi aracılığıyla tutanağı SurfaceFlinger'a iletir. Sanal ekranlar, SurfaceFlinger tarafından ekran istemek için createVirtualDisplay() çağrısı yapılarak oluşturulur. HWC sanal ekran kompozisyonunu destekliyorsa bir tutamaç döndürür. Ardından SurfaceFlinger, ekranların kompozisyonunu HWC'ye atar. HWC sanal ekran kompozisyonunu desteklemiyorsa SurfaceFlinger, imleci oluşturur ve ekranı birleştirir.

Görüntü bileşimi işlemleri

SurfaceFlinger, birleştirilecek yeni içeriği varsa VSYNC başına bir kez uyanır. Bu yeni içerik, uygulamalardan gelen yeni resim arabellekleri veya bir ya da daha fazla katmanın özelliklerindeki bir değişiklik olabilir. SurfaceFlinger onu uyandırdığında:

  1. Varsa işlemleri yönetir.
  2. Varsa yeni grafik arabelleklerini sabitler.
  3. 1. veya 2. adımda görüntüleme içeriklerinde bir değişiklik yapıldıysa yeni bir kompozisyon oluşturur.

SurfaceFlinger, yeni bir kompozisyon oluşturmak için katmanlar oluşturup yok eder veya geçerli olduğu durumlarda katman durumlarını değiştirir. Ayrıca setLayerBuffer veya setLayerColor gibi çağrılar kullanarak katmanları mevcut içerikleriyle günceller. Tüm katmanlar güncellendikten sonra SurfaceFlinger, validateDisplay işlevini çağırır. Bu işlev, HWC'ye katmanların durumunu incelemesini ve kompozisyonun nasıl ilerleyeceğini belirlemesini söyler. SurfaceFlinger, varsayılan olarak her katmanı HWC tarafından birleştirilecek şekilde yapılandırmaya çalışır. Ancak bazı durumlarda SurfaceFlinger, katmanları GPU yedekleme üzerinden birleştirir.

validateDisplay çağrısından sonra SurfaceFlinger, HWC'nin, kompozisyonu gerçekleştirmeden önce katman kompozisyonu türlerinden herhangi birinin değiştirilmesini isteyip istemediğini görmek için getChangedCompositionTypes'i çağırır. SurfaceFlinger, değişiklikleri kabul etmek için acceptDisplayChanges işlevini çağırır.

SurfaceFlinger kompozisyonu için işaretlenen katmanlar, hedef arabelleğe kompoze edilir. Ardından SurfaceFlinger, arabelleği ekrana vermek için setClientTarget çağrır. Böylece arabellek ekranda görüntülenebilir veya SurfaceFlinger kompozisyonu için işaretlenmemiş katmanlarla daha da birleştirilebilir. SurfaceFlinger kompozisyonu için hiçbir katman işaretlenmemişse SurfaceFlinger, kompozisyon adımını atlar.

Son olarak SurfaceFlinger, HWC'ye kompozisyon işlemini tamamlayıp nihai sonucu göstermesini söylemek için presentDisplay'ü çağırır.

Çoklu görüntülü ağlar

Android 10, birden fazla fiziksel ekranı destekler. Android 7.0 ve sonraki sürümlerde kullanılmak üzere tasarlanan bir HWC uygulamasında, HWC tanımında bulunmayan bazı kısıtlamalar vardır:

  • Tam olarak bir dahili ekran olduğu varsayılır. Dahili ekran, önyükleme sırasında ilk hotplug'ın bildirdiği ekrandır. Dahili ekran, sıcak takıldıktan sonra bağlantısı kesilemez.
  • Dahili ekrana ek olarak, cihazın normal çalışması sırasında herhangi bir sayıda harici ekran takılabilir. Çerçeve, ilk dahili ekrandan sonraki tüm hotplug'ların harici ekran olduğunu varsayar. Bu nedenle, daha fazla dahili ekran eklenirse bunlar Display.TYPE_BUILT_IN yerine Display.TYPE_HDMI olarak yanlış kategorize edilir.

Yukarıda açıklanan SurfaceFlinger işlemleri ekran başına gerçekleştirilir ancak yalnızca bir ekranın içeriği güncellense bile tüm etkin ekranlar için sırayla gerçekleştirilir.

Örneğin, harici ekran güncellenirse sıra şu şekildedir:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

Sanal ekran kompozisyonu

Sanal ekran kompozisyonu, harici ekran kompozisyonuna benzer. Sanal ekran kompozisyonu ile fiziksel ekran kompozisyonu arasındaki fark, sanal ekranların çıkışı ekrana değil bir Gralloc arabelleğine göndermesidir. Donanım Oluşturucu (HWC), çıkışı bir arabelleğe yazar, tamamlama çitini sağlar ve arabelleği bir tüketiciye (ör. video kodlayıcı, GPU, CPU vb.) gönderir. Görüntü ardışık düzeni belleğe yazarsa sanal ekranlar 2D/blitter veya yer paylaşımları kullanabilir.

Modlar

SurfaceFlinger, validateDisplay() HWC yöntemini çağırdıktan sonra her çerçeve üç moddan birinde olur:

  • GLES: GPU, doğrudan çıkış arabelleğine yazarak tüm katmanları birleştirir. HWC, beste sürecine dahil değildir.
  • KARIŞIK: GPU, bazı katmanları çerçeve arabelleğiyle, HWC ise çerçeve arabelleğini ve kalan katmanları birleştirerek doğrudan çıkış arabelleğiye yazar.
  • HWC: HWC tüm katmanları birleştirir ve doğrudan çıkış arabelleğine yazar.

Çıkış biçimi

Sanal görüntüleme arabelleği çıkış biçimleri, modlarına bağlıdır:

  • GLES modu: EGL sürücüsü, çıkış arabelleği biçimini dequeueBuffer() olarak (genellikle RGBA_8888) ayarlar. Tüketici, sürücünün belirlediği çıkış biçimini kabul edebilmelidir. Aksi takdirde arabellek okunamaz.
  • MIXED ve HWC modları: Tüketicinin CPU erişimine ihtiyacı varsa biçimi tüketici belirler. Aksi takdirde biçim IMPLEMENTATION_DEFINED olur ve Gralloc, kullanım işaretlerine göre en iyi biçimi ayarlar. Örneğin, tüketici video kodlayıcıysa ve HWC biçimi verimli bir şekilde yazabiliyorsa Gralloc bir YCbCr biçimi ayarlar.

Senkronizasyon çitleri

Senkronizasyon (eşleme) çitleri, Android grafik sisteminin önemli bir parçasıdır. Çitler, CPU çalışmasının eşzamanlı GPU çalışmasından bağımsız olarak ilerlemesine olanak tanır ve yalnızca gerçek bir bağımlılık olduğunda engeller.

Örneğin, bir uygulama GPU'da üretilen bir arabellek gönderirken senkronizasyon çiti nesnesi de gönderir. Bu çit, GPU'nun arabelleğe yazmayı tamamladığını gösterir.

HWC, GPU'nun arabellekleri yazma işlemini tamamlamasını, ardından arabellekleri görüntülemesini gerektirir. Senkronizasyon çitleri, grafik ardışık düzeninden arabellekler ve arabellekler yazılırken sinyal ile geçirilir. HWC, bir arabellek gösterilmeden önce senkronizasyon çitinin sinyal gönderip göndermediğini kontrol eder ve sinyal gönderdiyse arabelleği gösterir.

Senkronizasyon çitleri hakkında daha fazla bilgi için Donanım Oluşturucu Entegrasyonu başlıklı makaleyi inceleyin.