RenderScript

RenderScript adalah framework untuk menjalankan komputasi yang intensif tugas dengan performa tinggi di Android. Alat ini dirancang untuk digunakan bersama komputasi paralel data, meskipun beban kerja serial juga dapat memanfaatkannya. Tujuan Runtime RenderScript memparalelkan pekerjaan di seluruh prosesor yang tersedia pada seperti CPU dan GPU multi-core, sehingga developer dapat berfokus pada mengekspresikan algoritma daripada menjadwalkan pekerjaan. RenderScript sangat berguna untuk aplikasi yang melakukan pemrosesan gambar, komputasi fotografi, atau computer vision.

Perangkat yang menjalankan Android 8.0 dan yang lebih tinggi menggunakan RenderScript berikut HAL vendor dan kerangka kerja:

Gambar 1. Kode vendor yang tertaut ke library internal.

Perbedaan dengan RenderScript di Android 7.x dan yang lebih lama meliputi:

  • Dua instance lib internal RenderScript dalam sebuah proses. Satu rangkaian ditujukan untuk Jalur penggantian CPU dan berasal langsung dari /system/lib; yang lain yang disetel untuk jalur GPU dan berasal dari /system/lib/vndk-sp.
  • Library internal RS di /system/lib dibuat sebagai bagian dari platform ini dan diperbarui saat system.img diupgrade. Namun, library di /system/lib/vndk-sp dibuat untuk vendor dan tidak diperbarui saat system.img di-upgrade (meskipun dapat juga diupdate untuk perbaikan keamanan, ABI-nya akan tetap sama).
  • Kode vendor (RS HAL, driver RS, dan bcc plugin) adalah yang ditautkan dengan lib internal RenderScript yang terletak di /system/lib/vndk-sp. Mereka tidak bisa terhubung dengan libs di /system/lib karena lib dalam direktori itu dibuat untuk sehingga mungkin tidak kompatibel dengan kode vendor (yaitu, simbol mungkin dihapus). Melakukan hal tersebut akan membuat OTA khusus framework tidak mungkin dilakukan.

Desain

Bagian berikut menjelaskan desain RenderScript di Android 8.0 dan yang lebih tinggi.

Library RenderScript yang tersedia untuk vendor

Bagian ini mencantumkan lib RenderScript (dikenal sebagai Vendor NDK untuk Proses yang Sama HAL atau VNDK-SP) yang tersedia untuk kode vendor dan dapat ditautkan lawan. Dokumen ini juga merinci perpustakaan tambahan yang tidak terkait dengan RenderScript, tetapi juga disediakan ke kode vendor.

Meskipun daftar library berikut mungkin berbeda di antara rilis Android, proses ini tidak dapat diubah untuk rilis Android tertentu; untuk mengetahui daftar terbaru library yang tersedia, lihat /system/etc/ld.config.txt.

Lib RenderScript Lib Non-RenderScript
  • android.hardware.graphics.renderscript@1.0.so
  • libRS_internal.so
  • libRSCpuRef.so
  • libblas.so
  • libbcinfo.so
  • libcompiler_rt.so
  • libRSDriver.so
  • libc.so
  • libm.so
  • libdl.so
  • libstdc++.so
  • liblog.so
  • libnativewindow.so
  • libsync.so
  • libvndksupport.so
  • libbase.so
  • libc++.so
  • libcutils.so
  • libutils.so
  • libhardware.so
  • libhidlbase.so
  • libhidltransport.so
  • libhwbinder.so
  • liblzma.so
  • libz.so
  • libEGL.so
  • libGLESv1_CM.so
  • libGLESv2.so

Konfigurasi namespace linker

Batasan penautan yang mencegah lib yang tidak ada di VNDK-SP digunakan oleh kode vendor diterapkan saat runtime menggunakan namespace penaut. (Untuk detailnya, lihat Desain VNDK presentasi.)

Pada perangkat yang menjalankan Android 8.0 dan yang lebih tinggi, semua Same-Process HAL (SP-HAL) kecuali RenderScript dimuat di dalam namespace penaut sphal. RenderScript dimuat ke dalam RenderScript khusus namespace rs, lokasi yang sedikit lebih longgar penerapan untuk library RenderScript. Karena implementasi RS perlu memuat bitcode yang dikompilasi, /data/*/*.so ditambahkan ke jalur Namespace rs (SP-HAL lain tidak diizinkan untuk memuat library dari partisi data).

Selain itu, namespace rs memungkinkan lebih banyak lib daripada yang disediakan untuk oleh namespace lain. libmediandk.so dan libft2.so diekspos ke namespace rs karena libRS_internal.so memiliki dependensi internal pada library ini.

Gambar 2. Konfigurasi namespace untuk penaut.

Memuat driver

Jalur penggantian CPU

Bergantung pada keberadaan bit RS_CONTEXT_LOW_LATENCY saat membuat konteks RS, jalur CPU atau GPU akan dipilih. Jika Jalur CPU dipilih, libRS_internal.so (implementasi utama dari framework RS) langsung dlopendari linker default namespace tempat versi platform library RS disediakan.

Implementasi RS HAL dari vendor tidak digunakan sama sekali ketika CPU jalur penggantian diambil, dan objek RsContext dibuat dengan mVendorDriverName null. libRSDriver.so (berdasarkan default) dlopen dan library driver dimuat dari Namespace default karena pemanggil (libRS_internal.so) juga dimuat di default namespace.

Gambar 3. Jalur penggantian CPU.

Jalur GPU

Untuk jalur GPU, libRS_internal.so dimuat secara berbeda. Pertama, libRS.so menggunakan android.hardware.renderscript@1.0.so (dan elemen libhidltransport.so) untuk memuat android.hardware.renderscript@1.0-impl.so (vendor implementasi RS HAL) ke dalam namespace penaut berbeda yang disebut sphal. RS HAL lalu dlopen melakukan libRS_internal.so dalam namespace penaut yang disebut rs.

Vendor dapat menyediakan driver RS mereka sendiri dengan menyetel flag waktu build OVERRIDE_RS_DRIVER, yang disematkan ke dalam RS HAL implementasi (hardware/interfaces/renderscript/1.0/default/Context.cpp). Ini nama driver kemudian dlopen untuk konteks RS untuk jalur GPU.

Pembuatan objek RsContext didelegasikan ke RS HAL terlepas dari implementasi layanan. HAL memanggil kembali ke kerangka kerja RS menggunakan fungsi rsContextCreateVendor() dengan nama driver untuk gunakan sebagai argumen. Kemudian, framework RS memuat {i>driver<i} yang ditentukan RsContext diinisialisasi. Dalam hal ini, pustaka {i>driver<i} dimuat ke namespace rs karena RsContext dibuat di dalam namespace rs dan /vendor/lib berada di jalur penelusuran namespace.

Gambar 4. Jalur penggantian GPU.

Saat beralih dari namespace default ke namespace Namespace sphal, libhidltransport.so menggunakan fungsi android_load_sphal_library() untuk mengurutkan penaut dinamis untuk memuat library -impl.so dari Namespace sphal.

Saat beralih dari namespace sphal ke namespace Namespace rs, pemuatan dilakukan secara tidak langsung melalui baris berikut di /system/etc/ld.config.txt:

namespace.sphal.link.rs.shared_libs = libRS_internal.so

Baris ini menentukan linker dinamis yang harus dimuat libRS_internal.so dari namespace rs saat lib tidak dapat ditemukan/dimuat dari namespace sphal (yang selalu ini karena namespace sphal tidak mencari /system/lib/vndk-sp dengan libRS_internal.so tinggal). Dengan konfigurasi ini, panggilan dlopen() sederhana ke libRS_internal.so sudah cukup untuk melakukan transisi namespace.

Muat plugin bcc

bcc plugin adalah library yang disediakan vendor yang dimuat ke dalam Compiler bcc. Karena bcc adalah proses sistem di /system/bin, library bcc plugin dapat dianggap sebagai SP-HAL (yaitu, HAL vendor yang dapat langsung dimuat ke proses sistem tanpa dibinder). Sebagai SP-HAL, Library bcc-plugin:

  • Tidak dapat menautkan ke library khusus framework seperti libLLVM.so.
  • Hanya dapat menautkan ke library VNDK-SP yang tersedia untuk vendor.

Pembatasan ini diterapkan dengan memuat bcc plugin ke dalam namespace sphal menggunakan Fungsi android_sphal_load_library(). Di versi sebelumnya Android, nama plugin ditentukan menggunakan opsi -load dan lib dimuat menggunakan dlopen() sederhana oleh libLLVM.so. Di Android 8.0 dan yang lebih tinggi, hal ini ditetapkan dalam -plugin dan lib akan langsung dimuat oleh bcc itu sendiri. Opsi ini mengaktifkan jalur khusus non-Android untuk project LLVM open source.

Gambar 5. Memuat plugin bcc, Android 7.x dan versi yang lebih lama.



Gambar 6. Memuat plugin bcc, Android 8.0 dan yang lebih tinggi.

Telusuri jalur untuk ld.mc

Saat menjalankan ld.mc, beberapa library runtime RS diberikan sebagai input ke linker. Bitcode RS dari aplikasi ditautkan ke library runtime dan ketika bitcode yang dikonversi dimuat ke dalam proses aplikasi, library sekali lagi ditautkan secara dinamis dari bitcode yang dikonversi.

Library runtime meliputi:

  • libcompiler_rt.so
  • libm.so
  • libc.so
  • Pengemudi RS (libRSDriver.so atau OVERRIDE_RS_DRIVER)

Saat memuat bitcode yang dikompilasi ke dalam proses aplikasi, berikan kode library yang digunakan oleh ld.mc. Jika tidak, bitcode yang dikompilasi mungkin tidak menemukan simbol yang tersedia saat ditautkan.

Untuk melakukannya, framework RS menggunakan jalur pencarian yang berbeda untuk library runtime saat yang mengeksekusi ld.mc, tergantung apakah framework RS itu sendiri dimuat dari /system/lib atau dari /system/lib/vndk-sp. Ini dapat ditentukan dengan membaca alamat simbol arbitrer dari RS lib framework dan menggunakan dladdr() untuk mendapatkan jalur file yang dipetakan ke dari alamat tersebut.

Kebijakan SELinux

Akibat perubahan kebijakan SELinux di Android 8.0 dan yang lebih tinggi, Anda harus mengikuti aturan tertentu (diterapkan hingga neverallows) saat melabeli file tambahan di partisi vendor:

  • vendor_file harus menjadi label default untuk semua file di Partisi vendor. Kebijakan platform mengharuskan ini untuk mengakses implementasi HAL passthrough.
  • Semua exec_types baru ditambahkan di partisi vendor melalui SEPolicy vendor harus memiliki atribut vendor_file_type. Hal ini diterapkan melalui neverallows.
  • Untuk menghindari konflik dengan update platform/framework di masa mendatang, hindari pelabelan file selain exec_types dalam partisi vendor.
  • Semua dependensi library untuk HAL proses yang sama yang diidentifikasi oleh AOSP harus diberi label sebagai same_process_hal_file.

Untuk mengetahui detail tentang kebijakan SELinux, lihat Security-Enhanced Linux di Android.

Kompatibilitas ABI untuk bitcode

Jika tidak ada API baru yang ditambahkan, berarti tidak ada penambahan versi HAL, framework RS akan tetap menggunakan driver GPU (HAL 1.0) yang ada.

Untuk perubahan HAL kecil (HAL 1.1) yang tidak mempengaruhi bitcode, kerangka kerja harus kembali ke CPU untuk API yang baru ditambahkan ini dan tetap menggunakan driver GPU (HAL 1.0) di tempat lain.

Untuk perubahan HAL utama (HAL 2.0) yang memengaruhi kompilasi/penautan bitcode, RS framework harus memilih untuk tidak memuat driver GPU yang disediakan vendor, menggunakan jalur CPU atau Vulkan untuk akselerasi.

Pemakaian bitcode RenderScript terjadi dalam tiga tahap:

Stage Detail
Kompilasi
  • Bitcode input (.bc) untuk bcc harus dalam Format kode bit LLVM 3.2 dan bcc harus mundur kompatibel dengan aplikasi (lama) yang sudah ada.
  • Akan tetapi, meta-data di .bc dapat berubah (mungkin ada runtime baru fungsi, misalnya, Penyetel alokasi &mp; pengambil, fungsi matematika, dll.). Bagian fungsi runtime berada di libclcore.bc, yang merupakan bagian darinya tinggal di LibRSDriver atau yang setara dengan vendor.
  • Fungsi runtime baru atau perubahan metadata yang rusak memerlukan penambahan level API bitcode. Karena {i>driver<i} vendor tidak akan dapat memakainya, versi HAL juga harus ditambahkan.
  • Vendor mungkin memiliki compiler sendiri, tetapi kesimpulan/persyaratannya untuk bcc juga berlaku untuk compiler tersebut.
Link
  • File .o yang dikompilasi akan ditautkan dengan driver vendor, misalnya, libRSDriver_foo.so dan libcompiler_rt.so. CPU jalur akan ditautkan dengan libRSDriver.so.
  • Jika .o memerlukan API runtime baru dari libRSDriver_foo, {i>driver<i} vendor harus diperbarui untuk mendukungnya.
  • Vendor tertentu mungkin memiliki penaut mereka sendiri, tetapi argumen untuk ld.mc juga berlaku untuk elemen tersebut.
Pemuatan
  • libRSCpuRef memuat objek yang dibagikan. Jika ada perubahan pada antarmuka ini, bump versi HAL diperlukan.
  • Vendor akan mengandalkan libRSCpuRef untuk memuat file bersama atau mengimplementasikannya sendiri.

Selain HAL, API runtime dan simbol yang diekspor juga antarmuka. Tidak ada antarmuka yang berubah sejak Android 7.0 (API 24) dan tidak ada rencana segera untuk mengubahnya di Android 8.0 dan yang lebih baru. Namun, jika memang berubah, versi HAL juga akan bertambah.

Implementasi vendor

Android 8.0 dan yang lebih tinggi memerlukan beberapa perubahan driver GPU untuk driver GPU bekerja dengan benar.

Modul driver

  • Modul {i>driver<i} tidak boleh bergantung pada pustaka sistem apa pun yang tidak ada di daftar.
  • Pengemudi harus memberikan android.hardware.renderscript@1.0-impl_{NAME}, atau deklarasikan atribut implementasi default android.hardware.renderscript@1.0-impl sebagai dependensinya.
  • Implementasi CPU libRSDriver.so adalah contoh yang baik tentang cara menghapus dependensi non-VNDK-SP.

Compiler bitcode

Anda dapat mengompilasi bitcode RenderScript untuk driver vendor dengan dua cara:

  1. Memanggil compiler RenderScript khusus vendor di /vendor/bin/ (metode kompilasi GPU yang disukai). Mirip dengan modul {i>driver<i} lainnya, biner compiler vendor tidak dapat bergantung pada perpustakaan sistem apa pun yang tidak ada di daftar lib RenderScript RenderScript yang tersedia untuk vendor.
  2. Panggil bcc sistem: /system/bin/bcc dengan yang disediakan vendor bcc plugin; plugin ini tidak dapat bergantung pada perpustakaan sistem apa pun yang tidak ada dalam daftar Library RenderScript tersedia ke vendor.

Jika vendor bcc plugin perlu mengganggu CPU dan dependensinya pada libLLVM.so tidak mudah dihapus, vendor harus menyalin bcc (dan semua file non-LL-NDK dependensi, termasuk libLLVM.so, libbcc.so) ke dalam partisi /vendor.

Selain itu, vendor harus melakukan perubahan berikut:

Gambar 7. Perubahan pada driver vendor.

  1. Salin libclcore.bc ke partisi /vendor. Ini memastikan libclcore.bc, libLLVM.so, dan libbcc.so sedang disinkronkan.
  2. Ubah jalur ke file bcc yang dapat dieksekusi dengan menetapkan RsdCpuScriptImpl::BCC_EXE_PATH dari implementasi RS HAL.

Kebijakan SELinux

Kebijakan SELinux memengaruhi driver dan file yang dapat dieksekusi compiler. Semua modul driver harus diberi label same_process_hal_file dalam file_contexts perangkat. Contoh:

/vendor/lib(64)?/libRSDriver_EXAMPLE\.so     u:object_r:same_process_hal_file:s0

Compiler yang dapat dieksekusi harus dapat dipanggil oleh proses aplikasi, seperti halnya salinan bcc vendor (/vendor/bin/bcc). Contoh:

device/vendor_foo/device_bar/sepolicy/file_contexts:
/vendor/bin/bcc                    u:object_r:same_process_hal_file:s0

Perangkat lama

Perangkat lama adalah perangkat yang memenuhi kondisi berikut:

  1. PRODUCT_SHIPPING_API_LEVEL lebih rendah dari 26.
  2. PRODUCT_FULL_TREBLE_OVERRIDE tidak ditetapkan.

Untuk perangkat lama, pembatasan tidak diterapkan saat mengupgrade ke Android 8.0 dan yang lebih tinggi, artinya driver dapat terus terhubung ke library di /system/lib[64]. Namun, karena perubahan arsitektur terkait dengan OVERRIDE_RS_DRIVER, android.hardware.renderscript@1.0-impl harus diinstal untuk partisi /vendor; jika gagal melakukannya, runtime RenderScript akan kembali ke jalur CPU.

Untuk informasi tentang motivasi penghentian Renderscript, lihat laporan Android Developers Blog: Ke depannya, Komputasi GPU Android. Informasi resource untuk penghentian ini mencakup hal-hal berikut: