Implementasi Komposer Perangkat Keras HAL

Lapisan komposit HAL Komposer Perangkat Keras (HWC) yang diterima dari SurfaceFlinger, mengurangi jumlah komposisi OpenGL ES (GLES) dan kinerja GPU.

Objek abstrak HWC, seperti overlay dan blitter 2D, ke permukaan komposit dan berkomunikasi dengan perangkat keras komposisi jendela khusus ke jendela komposit. Gunakan HWC untuk menggabungkan jendela alih-alih menggunakan komposit SurfaceFlinger dengan GPU. Sebagian besar GPU tidak dioptimalkan untuk komposisi, dan saat GPU membuat lapisan dari SurfaceFlinger, aplikasi tidak dapat menggunakan GPU untuk renderingnya sendiri.

Implementasi HWC harus mendukung:

  • Setidaknya empat overlay:
    • Status bar
    • Bilah sistem
    • Aplikasi
    • Wallpaper/latar belakang
  • Lapisan yang lebih besar dari tampilan (misalnya wallpaper)
  • Pencampuran alfa per piksel dan pencampuran alfa per bidang yang dikalikan secara simultan
  • Jalur perangkat keras untuk pemutaran video yang dilindungi
  • Urutan pengepakan RGBA, format YUV, dan properti ubin, swizzling, dan stride

Untuk menerapkan HWC:

  1. Terapkan HWC nonoperasional dan kirimkan semua pekerjaan komposisi ke GLES.
  2. Menerapkan algoritma untuk mendelegasikan komposisi ke HWC secara bertahap. Misalnya, delegasikan hanya tiga atau empat permukaan pertama ke perangkat keras overlay HWC.
  3. Optimalkan HWC. Ini mungkin termasuk:
    • Memilih permukaan yang memaksimalkan beban yang diambil dari GPU dan mengirimkannya ke HWC.
    • Mendeteksi apakah layar sedang diperbarui. Jika tidak, delegasikan komposisi ke GLES dan bukan ke HWC untuk menghemat daya. Saat layar diperbarui lagi, lanjutkan memindahkan komposisi ke HWC.
    • Mempersiapkan kasus penggunaan umum seperti:
      • Layar beranda, yang mencakup bilah status, bilah sistem, jendela aplikasi, dan wallpaper animasi
      • Game layar penuh dalam mode potret dan lanskap
      • Video layar penuh dengan teks tertutup dan kontrol pemutaran
      • Pemutaran video terlindungi
      • Multijendela layar terpisah

Primitif HWC

HWC menyediakan dua primitif, lapisan dan tampilan , untuk mewakili pekerjaan komposisi dan interaksinya dengan perangkat keras tampilan. HWC juga memberikan kontrol atas VSYNC dan panggilan balik ke SurfaceFlinger untuk memberi tahu ketika peristiwa VSYNC terjadi.

antarmuka HIDL

Android 8.0 dan lebih tinggi menggunakan antarmuka HIDL yang disebut Composer HAL untuk IPC yang diikat antara HWC dan SurfaceFlinger. Composer HAL menggantikan antarmuka hwcomposer2.h yang lama. Jika vendor menyediakan implementasi Composer HAL pada HWC, Composer HAL langsung menerima panggilan HIDL dari SurfaceFlinger. Jika vendor menyediakan implementasi warisan HWC, Komposer HAL memuat penunjuk fungsi dari hwcomposer2.h , meneruskan panggilan HIDL ke panggilan penunjuk fungsi.

HWC menyediakan fungsi untuk menentukan properti tampilan tertentu; untuk beralih di antara konfigurasi tampilan yang berbeda (seperti resolusi 4k atau 1080p) dan mode warna (seperti warna asli atau sRGB sebenarnya); dan untuk menghidupkan, mematikan, atau mode daya rendah jika didukung.

Penunjuk fungsi

Jika vendor mengimplementasikan Composer HAL secara langsung, SurfaceFlinger memanggil fungsinya melalui HIDL IPC. Misalnya, untuk membuat lapisan, SurfaceFlinger memanggil createLayer() pada Composer HAL.

Jika vendor mengimplementasikan antarmuka hwcomposer2.h , Composer HAL memanggil pointer fungsi hwcomposer2.h . Dalam komentar hwcomposer2.h , fungsi antarmuka HWC dirujuk dengan nama lowerCamelCase yang tidak ada di antarmuka sebagai bidang bernama. Hampir setiap fungsi dimuat dengan meminta penunjuk fungsi menggunakan getFunction yang disediakan oleh hwc2_device_t . Misalnya, fungsi createLayer adalah penunjuk fungsi bertipe HWC2_PFN_CREATE_LAYER , yang dikembalikan ketika nilai yang disebutkan HWC2_FUNCTION_CREATE_LAYER diteruskan ke getFunction .

Untuk dokumentasi mendetail tentang fungsi Composer HAL dan fungsi passthrough fungsi HWC, lihat composer . Untuk dokumentasi mendetail tentang penunjuk fungsi HWC, lihat hwcomposer2.h .

Pegangan lapisan dan tampilan

Lapisan dan tampilan dimanipulasi oleh pegangan yang dihasilkan oleh HWC. Pegangannya buram terhadap SurfaceFlinger.

Saat SurfaceFlinger membuat lapisan baru, ia akan memanggil createLayer , yang mengembalikan tipe Layer untuk implementasi langsung atau hwc2_layer_t untuk implementasi passthrough. Ketika SurfaceFlinger memodifikasi properti lapisan tersebut, SurfaceFlinger meneruskan nilai hwc2_layer_t ke dalam fungsi modifikasi yang sesuai bersama dengan informasi lain yang diperlukan untuk melakukan modifikasi. Tipe hwc2_layer_t cukup besar untuk menampung pointer atau indeks.

Tampilan fisik dibuat dengan hotplug. Saat tampilan fisik di-hotplug, HWC membuat pegangan dan meneruskan pegangan ke SurfaceFlinger melalui panggilan balik hotplug. Tampilan virtual dibuat oleh SurfaceFlinger yang memanggil createVirtualDisplay() untuk meminta tampilan. Jika HWC mendukung komposisi tampilan virtual, HWC akan mengembalikan sebuah pegangan. Kemudian, SurfaceFlinger mendelegasikan komposisi tampilan ke HWC. Jika HWC tidak mendukung komposisi tampilan virtual, SurfaceFlinger membuat pegangan dan menggabungkan tampilan.

Menampilkan operasi komposisi

Sekali per VSYNC, SurfaceFlinger aktif jika memiliki konten baru untuk digabungkan. Konten baru ini dapat berupa buffering gambar baru dari aplikasi atau perubahan properti pada satu atau beberapa lapisan. Saat SurfaceFlinger membangunkannya:

  1. Menangani transaksi, jika ada.
  2. Mengunci buffer grafis baru, jika ada.
  3. Melakukan komposisi baru, jika langkah 1 atau 2 mengakibatkan perubahan pada konten tampilan.

Untuk melakukan komposisi baru, SurfaceFlinger membuat dan menghancurkan lapisan atau mengubah status lapisan, sebagaimana berlaku. Itu juga memperbarui lapisan dengan kontennya saat ini, menggunakan panggilan seperti setLayerBuffer atau setLayerColor . Setelah semua lapisan diperbarui, SurfaceFlinger memanggil validateDisplay , yang memberitahu HWC untuk memeriksa keadaan lapisan dan menentukan bagaimana komposisi akan diproses. Secara default, SurfaceFlinger mencoba mengonfigurasi setiap lapisan sedemikian rupa sehingga lapisan tersebut digabungkan oleh HWC; meskipun dalam beberapa keadaan, SurfaceFlinger menggabungkan lapisan melalui fallback GPU.

Setelah panggilan ke validateDisplay , SurfaceFlinger memanggil getChangedCompositionTypes untuk melihat apakah HWC ingin jenis komposisi lapisan diubah sebelum melakukan komposisi. Untuk menerima perubahan, SurfaceFlinger memanggil acceptDisplayChanges .

Jika ada lapisan yang ditandai untuk komposisi SurfaceFlinger, SurfaceFlinger menggabungkannya ke dalam buffer target. SurfaceFlinger kemudian memanggil setClientTarget untuk memberikan buffer pada tampilan sehingga buffer tersebut dapat ditampilkan di layar atau dikomposisikan lebih lanjut dengan lapisan yang belum ditandai untuk komposisi SurfaceFlinger. Jika tidak ada lapisan yang ditandai untuk komposisi SurfaceFlinger, SurfaceFlinger melewati langkah komposisi.

Terakhir, SurfaceFlinger memanggil presentDisplay untuk memberitahu HWC menyelesaikan proses komposisi dan menampilkan hasil akhirnya.

Beberapa tampilan

Android 10 mendukung banyak tampilan fisik. Saat merancang implementasi HWC yang dimaksudkan untuk digunakan pada Android 7.0 dan lebih tinggi, ada beberapa batasan yang tidak ada dalam definisi HWC:

  • Diasumsikan hanya terdapat satu tampilan internal . Tampilan internal adalah tampilan yang dilaporkan hotplug awal saat boot. Setelah layar internal di-hotplug, sambungannya tidak dapat dilepas.
  • Selain layar internal, sejumlah layar eksternal mungkin dicolokkan selama pengoperasian normal perangkat. Kerangka kerja ini mengasumsikan bahwa semua hotplug setelah tampilan internal pertama adalah tampilan eksternal, jadi jika ada tampilan internal lagi yang ditambahkan, tampilan tersebut salah dikategorikan sebagai Display.TYPE_HDMI dan bukan Display.TYPE_BUILT_IN .

Meskipun operasi SurfaceFlinger yang dijelaskan di atas dilakukan per tampilan, operasi tersebut dilakukan secara berurutan untuk semua tampilan aktif, meskipun konten hanya satu tampilan yang diperbarui.

Misalnya, jika tampilan eksternal diperbarui, urutannya adalah:

// 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>)

Komposisi tampilan virtual

Komposisi tampilan virtual mirip dengan komposisi tampilan eksternal. Perbedaan antara komposisi tampilan virtual dan komposisi tampilan fisik adalah tampilan virtual mengirimkan output ke buffer Gralloc, bukan ke layar. Hardware Composer (HWC) menulis output ke buffer, menyediakan pagar penyelesaian, dan mengirimkan buffer ke konsumen (seperti encoder video, GPU, CPU, dan sebagainya). Tampilan virtual dapat menggunakan 2D/blitter atau overlay jika saluran tampilan menulis ke memori.

Mode

Setiap frame berada dalam salah satu dari tiga mode setelah SurfaceFlinger memanggil metode validateDisplay() HWC:

  • GLES — GPU menggabungkan semua lapisan, menulis langsung ke buffer keluaran. HWC tidak terlibat dalam komposisi.
  • CAMPURAN — GPU menggabungkan beberapa lapisan ke framebuffer dan HWC menggabungkan framebuffer dan lapisan lainnya, menulis langsung ke buffer output.
  • HWC — HWC menggabungkan semua lapisan dan menulis langsung ke buffer keluaran.

Format output

Format output buffer tampilan virtual bergantung pada modenya:

  • Mode GLES — Driver EGL menyetel format buffer keluaran dalam dequeueBuffer() , biasanya RGBA_8888 . Konsumen harus dapat menerima format keluaran yang ditetapkan driver atau buffer tidak dapat dibaca.
  • Mode CAMPURAN dan HWC — Jika konsumen memerlukan akses CPU, konsumen akan mengatur formatnya. Jika tidak, formatnya adalah IMPLEMENTATION_DEFINED , dan Gralloc menetapkan format terbaik berdasarkan tanda penggunaan. Misalnya, Gralloc menetapkan format YCbCr jika konsumen adalah pembuat enkode video dan HWC dapat menulis format tersebut secara efisien.

Pagar sinkronisasi

Pagar sinkronisasi (sync) merupakan aspek krusial pada sistem grafis Android. Pagar memungkinkan pekerjaan CPU berjalan secara independen dari pekerjaan GPU secara bersamaan, hanya memblokir jika terdapat ketergantungan yang sebenarnya.

Misalnya, saat aplikasi mengirimkan buffer yang diproduksi di GPU, aplikasi tersebut juga mengirimkan objek pagar sinkronisasi. Pagar ini memberi sinyal ketika GPU telah selesai menulis ke dalam buffer.

HWC mengharuskan GPU menyelesaikan penulisan buffer sebelum buffer ditampilkan. Pagar sinkronisasi dilewatkan melalui pipa grafis dengan buffer dan memberi sinyal saat buffer ditulis. Sebelum buffer ditampilkan, HWC memeriksa apakah pagar sinkronisasi telah memberi sinyal, dan jika sudah, maka buffer akan ditampilkan.

Untuk informasi selengkapnya tentang pagar sinkronisasi, lihat Integrasi Komposer Perangkat Keras .