Mengimplementasikan HAL Hardware Composer

Lapisan komposit HAL Hardware Composer (HWC) yang diterima dari SurfaceFlinger, mengurangi jumlah komposisi OpenGL ES (GLES) dan performa GPU.

HWC memisahkan objek, seperti overlay dan blitter 2D, ke permukaan komposit dan berkomunikasi dengan hardware komposisi jendela khusus untuk jendela komposit. Menggunakan HWC untuk jendela komposit daripada memiliki Komposit SurfaceFlinger dengan GPU. Sebagian besar GPU tidak dioptimalkan untuk komposisi, dan kapan GPU menyusun lapisan dari SurfaceFlinger, aplikasi tidak dapat menggunakan GPU untuk renderingnya sendiri.

Implementasi HWC harus mendukung:

  • Minimal empat overlay:
    • Status bar
    • Kolom sistem
    • Aplikasi
    • Wallpaper/latar belakang
  • Lapisan yang lebih besar dari tampilan (misalnya, wallpaper)
  • Pencampuran alfa per piksel yang di-premultiply secara simultan dan pencampuran alfa per bidang
  • Jalur hardware untuk pemutaran video yang dilindungi
  • Urutan pengemasan RGBA, format YUV, pemasangan ubin, swizzling, dan stride properti

Untuk menerapkan HWC:

  1. Terapkan HWC nonoperasional dan kirim semua pekerjaan komposisi ke GLES.
  2. Terapkan algoritma untuk mendelegasikan komposisi ke HWC secara bertahap. Misalnya, hanya delegasikan tiga atau empat platform pertama ke hardware overlay HWC.
  3. Optimalkan HWC. Konten ini dapat mencakup:
    • Memilih platform yang memaksimalkan beban yang diambil dari GPU dan mengirimkannya ke HWC.
    • Mendeteksi apakah layar sedang diperbarui. Jika tidak, delegasikan ke GLES, bukan HWC untuk menghemat daya. Saat layar memperbarui lagi, terus memindahkan komposisi ke HWC.
    • Bersiap untuk kasus penggunaan umum seperti:
      • Layar utama, yang mencakup status bar, panel 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 yang dilindungi
      • Multi-aplikasi layar terpisah

Primitif HWC

HWC menyediakan dua primitif, lapisan dan tampilan, untuk merepresentasikan karya komposisi dan interaksinya dengan perangkat keras tampilan. Tujuan HWC juga menyediakan kontrol atas VSYNC dan callback ke SurfaceFlinger untuk memberi tahunya saat peristiwa VSYNC terjadi.

Antarmuka HIDL

Android 8.0 dan yang lebih tinggi menggunakan antarmuka HIDL yang disebut Composer HAL untuk IPC binderized antara HWC dan SurfaceFlinger. HAL Composer menggantikan antarmuka hwcomposer2.h lama. Jika vendor menyediakan implementasi HAL Composer dari HWC, HAL Composer akan langsung menerima panggilan HIDL dari SurfaceFlinger. Jika vendor memberikan implementasi HWC lama, Composer HAL memuat pointer fungsi dari hwcomposer2.h, meneruskan panggilan HIDL ke panggilan pointer fungsi.

HWC menyediakan fungsi untuk menentukan properti layar tertentu; untuk beralih di antara berbagai konfigurasi layar (seperti resolusi 4k atau 1080p) dan mode warna (seperti warna native atau sRGB sejati); dan untuk mengaktifkan layar, menonaktifkan, atau mengubahnya ke mode daya rendah jika didukung.

Pointer fungsi

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

Jika vendor menerapkan antarmuka hwcomposer2.h, Composer HAL panggilan ke pointer fungsi hwcomposer2.h. Dalam hwcomposer2.h komentar, Fungsi antarmuka HWC adalah dirujuk oleh nama lowerCamelCase yang tidak ada di antarmuka sebagai {i>field<i} bernama. Hampir setiap fungsi dimuat dengan meminta sebuah pointer fungsi menggunakan getFunction yang disediakan oleh hwc2_device_t. Misalnya, fungsi createLayer adalah pointer fungsi jenis HWC2_PFN_CREATE_LAYER, yang ditampilkan saat nilai yang dienumerasi HWC2_FUNCTION_CREATE_LAYER diteruskan ke getFunction.

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

Tuas lapisan dan tampilan

Lapisan dan tampilan dimanipulasi oleh tuas yang dihasilkan oleh HWC. Tuasnya buram untuk SurfaceFlinger.

Saat membuat lapisan baru, SurfaceFlinger akan memanggil createLayer, yang menampilkan jenis Layer untuk implementasi langsung atau hwc2_layer_t untuk implementasi passthrough. Saat SurfaceFlinger mengubah properti lapisan tersebut, SurfaceFlinger akan meneruskan nilai hwc2_layer_t ke fungsi modifikasi yang sesuai beserta informasi lain yang diperlukan untuk melakukan modifikasi. Jenis hwc2_layer_t cukup besar untuk menyimpan pointer atau indeks.

Layar fisik dibuat dengan hotplug. Ketika tampilan fisik {i>hotplugged<i}, HWC membuat {i>handle<i} dan meneruskan {i>handle<i} ke SurfaceFlinger melalui callback hotplug. Tampilan virtual dibuat oleh SurfaceFlinger memanggil createVirtualDisplay() untuk meminta tampilan. Jika HWC mendukung komposisi tampilan virtual, fungsi ini menampilkan handle. Kemudian, SurfaceFlinger mendelegasikan komposisi layar ke HWC. Jika HWC tidak mendukung layanan virtual tampilan, SurfaceFlinger membuat handle dan menggabungkan tampilan.

Menampilkan operasi komposisi

Sekali per VSYNC, SurfaceFlinger akan aktif jika memiliki konten baru untuk komposit. Konten baru ini dapat berupa buffering gambar baru dari aplikasi atau perubahan pada properti 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 menghasilkan perubahan ke konten tampilan.

Untuk melakukan komposisi baru, SurfaceFlinger membuat dan menghancurkan lapisan atau memodifikasi status lapisan, sebagaimana yang berlaku. Fungsi ini juga memperbarui lapisan dengan konten saat ini, menggunakan panggilan seperti setLayerBuffer atau setLayerColor. Setelah semua lapisan diupdate, SurfaceFlinger memanggil validateDisplay, yang memberi tahu HWC untuk memeriksa status lapisan dan menentukan cara komposisi akan dilanjutkan. Secara default, SurfaceFlinger mencoba mengonfigurasi setiap lapisan sehingga lapisan tersebut disusun oleh HWC; meskipun di beberapa dalam kondisi ini, SurfaceFlinger mengomposisikan lapisan melalui penggantian GPU.

Setelah panggilan ke validateDisplay, SurfaceFlinger akan memanggil getChangedCompositionTypes untuk melihat apakah HWC ingin agar salah satu jenis komposisi lapisan berubah sebelum melakukan komposisi. Untuk menerima perubahan, SurfaceFlinger memanggil acceptDisplayChanges.

Jika ada lapisan yang ditandai untuk komposisi SurfaceFlinger, SurfaceFlinger akan mengomposisinya ke dalam buffer target. SurfaceFlinger kemudian memanggil setClientTarget untuk memberikan buffer ke layar sehingga buffer dapat ditampilkan di layar atau dikomposisi lebih lanjut dengan lapisan yang belum ditandai untuk komposisi SurfaceFlinger. Jika tidak ada lapisan yang ditandai untuk Komposisi SurfaceFlinger, SurfaceFlinger mengabaikan langkah komposisi.

Terakhir, SurfaceFlinger memanggil presentDisplay untuk memberi tahu HWC agar menyelesaikan proses komposisi dan menampilkan hasil akhir.

Beberapa layar

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

  • Diasumsikan bahwa hanya ada satu tampilan internal. Elemen internal adalah tampilan yang dilaporkan oleh hotplug awal selama booting. Setelah layar internal dicolokkan, layar internal tidak dapat terputus.
  • Selain layar internal, sejumlah layar eksternal dapat dihubungkan secara hotplug selama pengoperasian normal perangkat. Framework mengasumsikan bahwa semua hotplug setelah layar internal pertama adalah layar eksternal, sehingga jika ada layar internal lainnya yang ditambahkan, layar tersebut salah dikategorikan sebagai Display.TYPE_HDMI, bukan Display.TYPE_BUILT_IN.

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

Misalnya, jika layar 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 mengirim output ke buffer Gralloc, bukan ke layar. Hardware Composer (HWC) menulis output ke buffer, menyediakan fence penyelesaian, dan mengirimkan buffer ke konsumen (seperti encoder video, GPU, CPU, dan sebagainya). Layar virtual dapat menggunakan overlay 2D/blitter atau jika pipeline tampilan menulis ke memori.

Mode

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

  • GLES — GPU menggabungkan semua lapisan, yang menulis langsung ke buffer output. HWC tidak terlibat dalam komposisi.
  • MIXED — GPU menggabungkan beberapa lapisan ke {i>framebuffer<i} dan HWC menggabungkan {i>framebuffer<i} dan lapisan yang tersisa, menulis secara langsung ke buffer output.
  • HWC — HWC menggabungkan semua lapisan dan menulis langsung ke buffer output.

Format output

Format output buffer tampilan virtual bergantung pada modenya:

  • Mode GLES — Driver EGL menetapkan buffer output dalam dequeueBuffer(), biasanya RGBA_8888. Konsumen harus dapat menerima format {i>output<i} yang ditetapkan {i>driver<i} atau {i>buffer <i}tidak dapat dibaca.
  • Mode MIXED dan HWC — Jika konsumen memerlukan akses CPU, konsumen akan menetapkan format. Jika tidak, formatnya adalah IMPLEMENTATION_DEFINED, dan Gralloc menetapkan format terbaik berdasarkan flag penggunaan. Misalnya, Gralloc menetapkan format YCbCr jika konsumen adalah encoder video dan HWC dapat menulis format secara efisien.

Pagar sinkronisasi

Pagar sinkronisasi (sinkronisasi) adalah aspek penting dari sistem grafis Android. Pagar memungkinkan pekerjaan CPU dilanjutkan secara independen dari pekerjaan GPU serentak, memblokir hanya jika ada dependensi yang benar.

Misalnya, saat aplikasi mengirimkan buffer yang sedang dihasilkan di GPU, aplikasi 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. fence sinkronisasi diteruskan melalui pipeline grafis dengan buffer dan memberi sinyal pada saat {i>buffer<i} ditulis. Sebelum {i>buffer<i} ditampilkan, HWC memeriksa apakah fence sinkronisasi telah memberi sinyal, dan jika sudah, fence akan menampilkan {i>buffer<i} (penyangga).

Untuk informasi selengkapnya tentang pembatasan sinkronisasi, lihat Integrasi Hardware Composer.