Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Kerangka Sinkronisasi

Kerangka kerja sinkronisasi secara eksplisit menjelaskan dependensi antara berbagai operasi asinkron dalam sistem grafis Android. Kerangka kerja menyediakan API yang memungkinkan komponen untuk menunjukkan kapan buffer dilepaskan. Kerangka kerja ini juga memungkinkan primitif sinkronisasi untuk diteruskan antara driver dari kernel ke ruang pengguna dan antara proses ruang pengguna itu sendiri.

Misalnya, aplikasi mungkin mengantrekan pekerjaan untuk dilakukan di GPU. GPU mulai menggambar gambar itu. Meskipun gambar belum ditarik ke dalam memori, pointer buffer diteruskan ke compositor jendela bersama dengan pagar yang menunjukkan kapan pekerjaan GPU akan selesai. Penggabung jendela mulai memproses sebelumnya dan meneruskan pekerjaan ke pengontrol tampilan. Dengan cara yang sama, pekerjaan CPU dilakukan sebelumnya. Setelah GPU selesai, pengontrol tampilan segera menampilkan gambar.

Kerangka kerja sinkronisasi juga memungkinkan pelaksana memanfaatkan sumber daya sinkronisasi dalam komponen perangkat keras mereka sendiri. Terakhir, framework menyediakan visibilitas ke dalam pipeline grafis untuk membantu proses debug.

Sinkronisasi eksplisit

Sinkronisasi eksplisit memungkinkan produsen dan konsumen buffer grafis untuk memberi sinyal saat mereka selesai menggunakan buffer. Sinkronisasi eksplisit diimplementasikan di ruang kernel.

Manfaat sinkronisasi eksplisit meliputi:

  • Lebih sedikit variasi perilaku antar perangkat
  • Dukungan debugging yang lebih baik
  • Metrik pengujian yang ditingkatkan

Kerangka kerja sinkronisasi memiliki tiga jenis objek:

  • sync_timeline
  • sync_pt
  • sync_fence

sync_timeline

sync_timeline adalah waktu monoton meningkat bahwa vendor harus menerapkan untuk setiap contoh driver, seperti konteks GL, kontroler display, atau blitter 2D. sync_timeline jumlah pekerjaan diserahkan ke kernel untuk bagian tertentu dari perangkat keras. sync_timeline memberikan jaminan tentang urutan operasi dan memungkinkan implementasi hardware khusus.

Ikuti panduan ini ketika mengimplementasikan sync_timeline :

  • Berikan nama yang berguna untuk semua driver, garis waktu, dan pagar untuk menyederhanakan proses debug.
  • Melaksanakan timeline_value_str dan pt_value_str operator di garis waktu untuk membuat debugging output yang lebih mudah dibaca.
  • Menerapkan mengisi driver_data untuk memberi userspace perpustakaan, seperti perpustakaan GL, akses ke data waktu pribadi, jika diinginkan. data_driver memungkinkan vendor menyampaikan informasi tentang berubah sync_fence dan sync_pts ke garis perintah membangun berdasarkan pada mereka.
  • Jangan izinkan ruang pengguna membuat atau memberi sinyal pagar secara eksplisit. Membuat sinyal/pagar secara eksplisit menghasilkan serangan penolakan layanan yang menghentikan fungsionalitas pipa.
  • Jangan akses sync_timeline , sync_pt , atau sync_fence elemen secara eksplisit. API menyediakan semua fungsi yang diperlukan.

sync_pt

sync_pt adalah nilai tunggal atau titik pada sync_timeline . Sebuah titik memiliki tiga status: aktif, bersinyal, dan error. Poin dimulai dalam status aktif dan transisi ke status bersinyal atau kesalahan. Sebagai contoh, ketika seorang konsumen gambar tidak lagi membutuhkan penyangga, sebuah sync_pt ditandai sehingga produsen citra tahu bahwa tidak apa-apa untuk menulis ke dalam buffer lagi.

sinkronisasi_pagar

sync_fence adalah kumpulan sync_pt nilai-nilai yang sering memiliki yang berbeda sync_timeline orang tua (seperti untuk kontroler display dan GPU). sync_fence , sync_pt , dan sync_timeline adalah primitif utama yang driver dan penggunaan userspace untuk berkomunikasi dependensi mereka. Ketika sebuah pagar diberi sinyal, semua perintah yang dikeluarkan sebelum pagar dijamin selesai karena driver kernel atau blok perangkat keras mengeksekusi perintah secara berurutan.

Kerangka kerja sinkronisasi memungkinkan banyak konsumen atau produsen untuk memberi sinyal saat mereka selesai menggunakan buffer, mengkomunikasikan informasi ketergantungan dengan satu parameter fungsi. Pagar didukung oleh deskriptor file dan diteruskan dari ruang kernel ke ruang pengguna. Sebagai contoh, pagar dapat berisi dua sync_pt nilai yang menunjukkan ketika dua konsumen gambar yang terpisah selesai membaca buffer. Saat pagar diberi isyarat, produsen gambar tahu bahwa kedua konsumen sudah selesai mengkonsumsi.

Pagar, seperti sync_pt nilai-nilai, mulai aktif dan perubahan negara berdasarkan keadaan poin mereka. Jika semua sync_pt nilai menjadi isyarat, yang sync_fence menjadi isyarat. Jika salah satu sync_pt jatuh menjadi negara kesalahan, seluruh sync_fence memiliki kesalahan negara.

Keanggotaan dalam sync_fence kekal setelah pagar dibuat. Untuk mendapatkan lebih dari satu titik pada sebuah pagar, dilakukan penggabungan dimana titik-titik dari dua pagar yang berbeda ditambahkan ke dalam pagar ketiga. Jika salah satu titik tersebut diberi sinyal di pagar asal dan yang lainnya tidak, pagar ketiga juga tidak akan dalam keadaan bersinyal.

Untuk menerapkan sinkronisasi eksplisit, berikan hal berikut:

  • Subsistem ruang kernel yang mengimplementasikan kerangka kerja sinkronisasi untuk driver perangkat keras tertentu. Driver yang perlu diwaspadai umumnya adalah segala sesuatu yang mengakses atau berkomunikasi dengan Komposer Perangkat Keras. File kunci termasuk:
    • Implementasi inti:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • Dokumentasi di kernel/common/Documentation/sync.txt
    • Perpustakaan untuk berkomunikasi dengan ruang kernel di platform/system/core/libsync
  • Vendor harus menyediakan pagar sinkronisasi yang tepat sebagai parameter ke validateDisplay() dan presentDisplay() fungsi dalam HAL tersebut.
  • Dua ekstensi terkait pagar GL ( EGL_ANDROID_native_fence_sync dan EGL_ANDROID_wait_sync ) dan dukungan pagar di driver grafis.

Studi kasus: Menerapkan driver tampilan

Untuk menggunakan API yang mendukung fungsi sinkronisasi, kembangkan driver tampilan yang memiliki fungsi buffer tampilan. Sebelum kerangka sinkronisasi ada, fungsi ini akan menerima dma-buf obyek, menempatkan orang-buffer pada layar, dan blok sementara buffer terlihat. Sebagai contoh:

/*
 * assumes buffer is ready to be displayed.  returns when buffer is no longer on
 * screen.
 */
void display_buffer(struct dma_buf *buffer);

Dengan kerangka sinkronisasi, display_buffer fungsi yang lebih kompleks. Saat meletakkan buffer di layar, buffer dikaitkan dengan pagar yang menunjukkan kapan buffer akan siap. Anda dapat mengantri dan memulai pekerjaan setelah pagar dibersihkan.

Antrian dan memulai pekerjaan setelah pagar dibersihkan tidak menghalangi apa pun. Anda segera mengembalikan pagar Anda sendiri, yang menjamin saat buffer akan mati dari tampilan. Saat Anda mengantri buffer, kernel mencantumkan dependensi dengan kerangka sinkronisasi:

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

Sinkronkan integrasi

Bagian ini menjelaskan cara mengintegrasikan kerangka sinkronisasi ruang kernel dengan bagian ruang pengguna kerangka kerja Android dan driver yang harus berkomunikasi satu sama lain. Objek ruang kernel direpresentasikan sebagai deskriptor file di ruang pengguna.

Konvensi integrasi

Ikuti konvensi antarmuka Android HAL:

  • Jika API menyediakan file descriptor yang mengacu pada sync_pt , pengemudi vendor atau HAL menggunakan API harus menutup file descriptor.
  • Jika vendor driver atau HAL melewati file descriptor yang berisi sync_pt ke fungsi API, driver vendor atau HAL tidak harus menutup file descriptor.
  • Untuk terus menggunakan deskriptor file pagar, driver vendor atau HAL harus menduplikasi deskriptor.

Objek pagar diganti namanya setiap kali melewati BufferQueue. Kernel dukungan pagar memungkinkan pagar untuk memiliki string untuk nama, sehingga kerangka sync menggunakan nama jendela dan penyangga indeks yang sedang antri untuk nama pagar, seperti SurfaceView:0 . Hal ini bermanfaat dalam debugging untuk mengidentifikasi sumber dari kebuntuan sebagai nama muncul dalam output /d/sync dan bug laporan.

Integrasi ANativeWindow

ANativeWindow sadar akan pagar. dequeueBuffer , queueBuffer , dan cancelBuffer memiliki parameter pagar.

Integrasi OpenGL ES

Integrasi sinkronisasi OpenGL ES bergantung pada dua ekstensi EGL:

  • EGL_ANDROID_native_fence_sync menyediakan cara untuk membungkus atau membuat native Android deskriptor file pagar di EGLSyncKHR objek.
  • EGL_ANDROID_wait_sync memungkinkan GPU-sisi warung daripada CPU-side, membuat GPU menunggu EGLSyncKHR . The EGL_ANDROID_wait_sync ekstensi adalah sama dengan EGL_KHR_wait_sync ekstensi.

Untuk menggunakan ekstensi ini secara independen, melaksanakan EGL_ANDROID_native_fence_sync ekstensi bersama dengan dukungan kernel terkait. Berikutnya, mengaktifkan EGL_ANDROID_wait_sync ekstensi pada driver Anda. The EGL_ANDROID_native_fence_sync ekstensi terdiri dari penduduk asli pagar yang berbeda EGLSyncKHR jenis objek. Akibatnya, ekstensi yang berlaku untuk yang ada EGLSyncKHR jenis objek tidak selalu berlaku untuk EGL_ANDROID_native_fence benda, menghindari interaksi yang tidak diinginkan.

The EGL_ANDROID_native_fence_sync ekstensi mempekerjakan file pagar asli atribut descriptor terkait yang dapat diatur hanya pada waktu penciptaan dan tidak dapat langsung bertanya seterusnya dari objek sync yang ada. Atribut ini dapat diatur ke salah satu dari dua mode:

  • Sebuah file pagar deskriptor berlaku membungkus sebuah native Android file descriptor pagar yang ada dalam EGLSyncKHR objek.
  • -1 menciptakan native Android file descriptor pagar dari EGLSyncKHR objek.

Gunakan DupNativeFenceFD() fungsi panggilan untuk mengekstrak EGLSyncKHR objek dari native Android file descriptor pagar. Ini memiliki hasil yang sama dengan kueri atribut set, tetapi mematuhi konvensi bahwa penerima menutup pagar (karenanya operasi duplikat). Akhirnya, menghancurkan EGLSyncKHR objek menutup atribut pagar internal.

Integrasi Komposer Perangkat Keras

Komposer Perangkat Keras menangani tiga jenis pagar sinkronisasi:

  • Pagar Acquire yang diteruskan dengan buffer masukan kepada setLayerBuffer dan setClientTarget panggilan. Ini mewakili penulisan yang tertunda ke buffer dan harus memberi sinyal sebelum SurfaceFlinger atau HWC mencoba membaca dari buffer terkait untuk melakukan komposisi.
  • Pagar rilis yang akan diambil setelah panggilan ke presentDisplay menggunakan getReleaseFences panggilan. Ini mewakili pembacaan tertunda dari buffer sebelumnya pada lapisan yang sama. Pagar pelepas memberi sinyal saat HWC tidak lagi menggunakan buffer sebelumnya karena buffer saat ini telah menggantikan buffer sebelumnya pada tampilan. Pagar rilis diteruskan kembali ke aplikasi bersama dengan buffer sebelumnya yang akan diganti selama komposisi saat ini. Aplikasi harus menunggu hingga sinyal pagar rilis sebelum menulis konten baru ke dalam buffer yang dikembalikan kepada mereka.
  • Pagar hadir dikembalikan, satu per frame, sebagai bagian dari panggilan untuk presentDisplay . Pagar yang ada mewakili saat komposisi bingkai ini telah selesai, atau secara bergantian, ketika hasil komposisi dari bingkai sebelumnya tidak diperlukan lagi. Untuk menampilkan fisik, presentDisplay kembali pagar hadir ketika frame muncul di layar. Setelah pagar yang ada dikembalikan, aman untuk menulis ke buffer target SurfaceFlinger lagi, jika berlaku. Untuk tampilan virtual, pagar saat ini dikembalikan saat aman untuk dibaca dari buffer output.