RenderScript là một framework để chạy các tác vụ tính toán chuyên sâu với hiệu suất cao trên Android. Nó được thiết kế để sử dụng với tính toán song song dữ liệu, mặc dù khối lượng công việc nối tiếp cũng có thể được hưởng lợi. Thời gian chạy RenderScript song song hóa công việc trên các bộ xử lý có sẵn trên thiết bị, chẳng hạn như CPU và GPU đa lõi, cho phép các nhà phát triển tập trung vào việc thể hiện các thuật toán thay vì lên lịch làm việc. RenderScript đặc biệt hữu ích cho các ứng dụng thực hiện xử lý hình ảnh, chụp ảnh tính toán hoặc thị giác máy tính.
Các thiết bị chạy Android 8.0 trở lên sử dụng khung RenderScript và HAL của nhà cung cấp sau:
Sự khác biệt so với RenderScript trong Android 7.x trở xuống bao gồm:
- Hai phiên bản lib nội bộ của RenderScript trong một quy trình. Một bộ dành cho đường dẫn dự phòng CPU và được lấy trực tiếp tại
/system/lib
; bộ còn lại dành cho đường dẫn GPU và từ/system/lib/vndk-sp
. - Các lib nội bộ RS trong
/system/lib
được xây dựng như một phần của nền tảng và được cập nhật khisystem.img
được nâng cấp. Tuy nhiên, lib trong/system/lib/vndk-sp
được xây dựng cho nhà cung cấp và không được cập nhật khi nâng cấpsystem.img
(mặc dù chúng có thể được cập nhật để sửa lỗi bảo mật nhưng ABI của chúng vẫn giữ nguyên). - Mã nhà cung cấp (RS HAL, trình điều khiển RS và
bcc plugin
) được liên kết với các lib nội bộ của RenderScript có tại/system/lib/vndk-sp
. Chúng không thể liên kết với các lib trong/system/lib
vì các lib trong thư mục đó được xây dựng cho nền tảng và do đó có thể không tương thích với mã nhà cung cấp (tức là các ký hiệu có thể bị xóa). Làm như vậy sẽ khiến OTA chỉ có khung không thể thực hiện được.
Thiết kế
Các phần sau đây trình bày chi tiết về thiết kế RenderScript trong Android 8.0 trở lên.
Thư viện RenderScript có sẵn cho nhà cung cấp
Phần này liệt kê các thư viện RenderScript (được gọi là NDK của nhà cung cấp cho HAL cùng quy trình hoặc VNĐK-SP) có sẵn cho mã nhà cung cấp và có thể được liên kết với. Nó cũng nêu chi tiết các thư viện bổ sung không liên quan đến RenderScript nhưng cũng được cung cấp cho mã nhà cung cấp.
Mặc dù danh sách thư viện sau đây có thể khác nhau giữa các bản phát hành Android nhưng nó không thể thay đổi đối với một bản phát hành Android cụ thể; để biết danh sách cập nhật các thư viện có sẵn, hãy tham khảo /system/etc/ld.config.txt
.
Thư viện RenderScript | Thư viện không phải RenderScript |
---|---|
|
|
Cấu hình không gian tên của trình liên kết
Hạn chế liên kết nhằm ngăn chặn các lib không có trong VNĐK-SP được mã nhà cung cấp sử dụng được thực thi trong thời gian chạy bằng cách sử dụng không gian tên trình liên kết. (Để biết thêm chi tiết, tham khảo phần trình bày của VNDK Design .)
Trên thiết bị chạy Android 8.0 trở lên, tất cả các HAL cùng quy trình (SP-HAL) ngoại trừ RenderScript đều được tải bên trong không gian tên của trình liên kết sphal
. RenderScript được tải vào không gian tên dành riêng cho RenderScript rs
, một vị trí cho phép thực thi lỏng lẻo hơn một chút đối với các thư viện RenderScript. Vì việc triển khai RS cần tải mã bit đã biên dịch nên /data/*/*.so
được thêm vào đường dẫn của không gian tên rs
(các SP-HAL khác không được phép tải lib từ phân vùng dữ liệu).
Ngoài ra, không gian tên rs
cho phép nhiều lib hơn so với các không gian tên khác. libmediandk.so
và libft2.so
được hiển thị trong không gian rs
vì libRS_internal.so
có phần phụ thuộc nội bộ vào các thư viện này.
Đang tải trình điều khiển
Đường dẫn dự phòng CPU
Tùy thuộc vào sự tồn tại của bit RS_CONTEXT_LOW_LATENCY
khi tạo bối cảnh RS, đường dẫn CPU hoặc GPU sẽ được chọn. Khi đường dẫn CPU được chọn, libRS_internal.so
(triển khai chính của khung RS) sẽ được dlopen
trực tiếp khỏi không gian tên trình liên kết mặc định nơi cung cấp phiên bản nền tảng của lib lib.
Việc triển khai RS HAL từ nhà cung cấp hoàn toàn không được sử dụng khi đường dẫn dự phòng CPU được thực hiện và đối tượng RsContext
được tạo bằng null mVendorDriverName
. libRSDriver.so
là (theo mặc định) dlopen
ed và trình điều khiển lib được tải từ không gian tên default
vì người gọi ( libRS_internal.so
) cũng được tải trong không gian tên default
.
Đường dẫn GPU
Đối với đường dẫn GPU, libRS_internal.so
được tải khác nhau. Đầu tiên, libRS.so
sử dụng android.hardware.renderscript@1.0.so
(và libhidltransport.so
cơ bản của nó) để tải android.hardware.renderscript@1.0-impl.so
(một nhà cung cấp triển khai RS HAL) vào một không gian tên trình liên kết khác được gọi là sphal
. RS HAL sau đó dlopen
s libRS_internal.so
trong một không gian tên trình liên kết khác có tên rs
.
Các nhà cung cấp có thể cung cấp trình điều khiển RS của riêng họ bằng cách đặt cờ thời gian xây dựng OVERRIDE_RS_DRIVER
, được nhúng vào quá trình triển khai RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp
). Tên trình điều khiển này sau đó dlopen
sửa cho bối cảnh RS cho đường dẫn GPU.
Việc tạo đối tượng RsContext
được ủy quyền cho việc triển khai RS HAL. HAL gọi lại khung RS bằng cách sử dụng hàm rsContextCreateVendor()
với tên của trình điều khiển để sử dụng làm đối số. Sau đó, khung RS sẽ tải trình điều khiển được chỉ định khi RsContext
được khởi tạo. Trong trường hợp này, thư viện trình điều khiển được tải vào không gian rs
vì đối tượng RsContext
được tạo bên trong không gian tên rs
và /vendor/lib
nằm trong đường dẫn tìm kiếm của không gian tên.
Khi chuyển từ không gian tên default
không gian tên sphal
, libhidltransport.so
sử dụng hàm android_load_sphal_library()
để ra lệnh rõ ràng cho trình liên kết động tải thư viện -impl.so
từ không gian tên sphal
.
Khi chuyển từ không gian tên sphal
sang không gian rs
, việc tải được thực hiện gián tiếp bằng dòng sau trong /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Dòng này chỉ định trình liên kết động sẽ tải libRS_internal.so
từ không gian tên rs
khi không thể tìm thấy/tải lib từ không gian tên sphal
(điều này luôn xảy ra vì không gian tên sphal
không tìm kiếm /system/lib/vndk-sp
ở đâu libRS_internal.so
cư trú). Với cấu hình này, một lệnh gọi dlopen()
đơn giản tới libRS_internal.so
là đủ để thực hiện chuyển đổi không gian tên.
Đang tải plugin bcc
bcc plugin
là thư viện do nhà cung cấp cung cấp được tải vào trình biên dịch bcc
. Vì bcc
là một quy trình hệ thống trong thư mục /system/bin
nên thư viện bcc plugin
có thể được coi là SP-HAL (tức là HAL của nhà cung cấp có thể được tải trực tiếp vào quy trình hệ thống mà không bị ràng buộc). Là SP-HAL, thư viện bcc-plugin
:
- Không thể liên kết với các thư viện chỉ có khung như
libLLVM.so
. - Chỉ có thể liên kết với các thư viện VNĐK-SP có sẵn của nhà cung cấp.
Hạn chế này được thực thi bằng cách tải bcc plugin
vào không gian tên sphal
bằng hàm android_sphal_load_library()
. Trong các phiên bản trước của Android, tên plugin đã được chỉ định bằng tùy chọn -load
và lib được tải bằng cách sử dụng dlopen()
đơn giản bởi libLLVM.so
. Trong Android 8.0 trở lên, điều này được chỉ định trong tùy chọn -plugin
và lib được chính bcc
tải trực tiếp. Tùy chọn này cho phép đường dẫn không dành riêng cho Android tới dự án LLVM nguồn mở.
Đường dẫn tìm kiếm cho ld.mc
Khi thực thi ld.mc
, một số lib thời gian chạy RS được cung cấp làm đầu vào cho trình liên kết. Mã bit RS từ ứng dụng được liên kết với các lib thời gian chạy và khi mã bit đã chuyển đổi được tải vào một quy trình ứng dụng, các lib thời gian chạy lại được liên kết động từ mã bit đã chuyển đổi.
Các lib thời gian chạy bao gồm:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- Trình điều khiển RS (
libRSDriver.so
hoặcOVERRIDE_RS_DRIVER
)
Khi tải bitcode đã biên dịch vào quy trình ứng dụng, hãy cung cấp chính xác thư viện đã được ld.mc
sử dụng. Nếu không, bitcode đã biên dịch có thể không tìm thấy ký hiệu có sẵn khi được liên kết.
Để làm như vậy, khung RS sử dụng các đường dẫn tìm kiếm khác nhau cho các lib thời gian chạy khi thực thi ld.mc
, tùy thuộc vào việc bản thân khung RS được tải từ /system/lib
hay từ /system/lib/vndk-sp
. Điều này có thể được xác định bằng cách đọc địa chỉ của một ký hiệu tùy ý của lib khung RS và sử dụng dladdr()
để ánh xạ đường dẫn tệp tới địa chỉ.
Chính sách SELinux
Do những thay đổi về chính sách SELinux trong Android 8.0 trở lên, bạn phải tuân theo các quy tắc cụ thể (được thực thi thông qua neverallows
) khi gắn nhãn các tệp bổ sung trong phân vùng vendor
:
-
vendor_file
phải là nhãn mặc định cho tất cả các tệp trong phân vùngvendor
. Chính sách nền tảng yêu cầu điều này để truy cập vào việc triển khai HAL chuyển tiếp. - Tất cả
exec_types
mới được thêm vào phân vùngvendor
thông qua SEPolicy của nhà cung cấp phải có thuộc tínhvendor_file_type
. Điều này được thực thi thông quaneverallows
. - Để tránh xung đột với các bản cập nhật nền tảng/khung trong tương lai, hãy tránh gắn nhãn các tệp khác ngoài
exec_types
trong phân vùngvendor
. - Tất cả các phần phụ thuộc thư viện cho cùng một quy trình HAL được AOSP xác định phải được gắn nhãn là
same_process_hal_file
.
Để biết chi tiết về chính sách SELinux, hãy xem Linux được tăng cường bảo mật trong Android .
Khả năng tương thích ABI cho bitcode
Nếu không có API mới nào được thêm vào, nghĩa là không có phiên bản HAL nào, thì khung RS sẽ tiếp tục sử dụng trình điều khiển GPU (HAL 1.0) hiện có.
Đối với những thay đổi HAL nhỏ (HAL 1.1) không ảnh hưởng đến bitcode, các khung sẽ chuyển sang CPU cho các API mới được thêm này và tiếp tục sử dụng trình điều khiển GPU (HAL 1.0) ở nơi khác.
Đối với những thay đổi lớn về HAL (HAL 2.0) ảnh hưởng đến quá trình biên dịch/liên kết mã bit, khung RS nên chọn không tải trình điều khiển GPU do nhà cung cấp cung cấp và thay vào đó sử dụng đường dẫn CPU hoặc Vulkan để tăng tốc.
Việc sử dụng mã bit RenderScript xảy ra theo ba giai đoạn:
Sân khấu | Chi tiết |
---|---|
Biên dịch |
|
liên kết |
|
Trọng tải |
|
Ngoài HAL, các API thời gian chạy và các ký hiệu được xuất cũng là các giao diện. Cả hai giao diện đều không thay đổi kể từ Android 7.0 (API 24) và hiện chưa có kế hoạch thay đổi giao diện đó trong Android 8.0 trở lên. Tuy nhiên, nếu giao diện thay đổi thì phiên bản HAL cũng sẽ tăng lên.
Triển khai của nhà cung cấp
Android 8.0 trở lên yêu cầu một số thay đổi trình điều khiển GPU để trình điều khiển GPU hoạt động chính xác.
Mô-đun trình điều khiển
- Các mô-đun trình điều khiển không được phụ thuộc vào bất kỳ thư viện hệ thống nào không có trong danh sách .
- Trình điều khiển phải cung cấp
android.hardware.renderscript@1.0-impl_{NAME}
của chính nó hoặc khai báo cách triển khai mặc địnhandroid.hardware.renderscript@1.0-impl
làm phần phụ thuộc của nó. - Việc triển khai CPU
libRSDriver.so
là một ví dụ điển hình về cách loại bỏ các phần phụ thuộc không phải VNĐK-SP.
Trình biên dịch mã bit
Bạn có thể biên dịch mã bit RenderScript cho trình điều khiển của nhà cung cấp theo hai cách:
- Gọi trình biên dịch RenderScript dành riêng cho nhà cung cấp trong
/vendor/bin/
(phương pháp biên dịch GPU ưa thích). Tương tự như các mô-đun trình điều khiển khác, tệp nhị phân của trình biên dịch của nhà cung cấp không thể phụ thuộc vào bất kỳ thư viện hệ thống nào không có trong danh sách các thư viện RenderScript có sẵn cho các nhà cung cấp . - Gọi bcc hệ thống:
/system/bin/bcc
bằngbcc plugin
do nhà cung cấp cung cấp ; plugin này không thể phụ thuộc vào bất kỳ thư viện hệ thống nào không có trong danh sách lib RenderScript có sẵn cho nhà cung cấp .
Nếu bcc plugin
của nhà cung cấp cần can thiệp vào quá trình biên dịch CPU và không thể dễ dàng xóa phần phụ thuộc của nó vào libLLVM.so
, thì nhà cung cấp nên sao chép bcc
(và tất cả các phần phụ thuộc không phải LL-NDK, bao gồm libLLVM.so
, libbcc.so
) vào /vendor
.
Ngoài ra, nhà cung cấp cần thực hiện những thay đổi sau:
- Sao chép
libclcore.bc
vào phân vùng/vendor
. Điều này đảm bảolibclcore.bc
,libLLVM.so
vàlibbcc.so
được đồng bộ hóa. - Thay đổi đường dẫn đến tệp thực thi
bcc
bằng cách đặtRsdCpuScriptImpl::BCC_EXE_PATH
từ quá trình triển khai RS HAL.
Chính sách SELinux
Chính sách SELinux ảnh hưởng đến cả trình điều khiển và trình thực thi của trình biên dịch. Tất cả các mô-đun trình điều khiển phải được gắn nhãn same_process_hal_file
trong file_contexts
của thiết bị. Ví dụ:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
Trình thực thi trình biên dịch phải có khả năng được gọi bởi một quy trình ứng dụng, cũng như bản sao bcc của nhà cung cấp ( /vendor/bin/bcc
). Ví dụ:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Thiết bị cũ
Thiết bị cũ là thiết bị thỏa mãn các điều kiện sau:
- product_SHIPPING_API_LEVEL thấp hơn 26.
- product_FULL_TREBLE_OVERRIDE không được xác định.
Đối với các thiết bị cũ, các hạn chế không được thực thi khi nâng cấp lên Android 8.0 trở lên, nghĩa là trình điều khiển có thể tiếp tục liên kết với các thư viện trong /system/lib[64]
. Tuy nhiên, do thay đổi kiến trúc liên quan đến OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
phải được cài đặt vào phân vùng /vendor
; không làm như vậy buộc phải chuyển thời gian chạy RenderScript sang đường dẫn CPU.
Để biết thông tin về lý do ngừng sử dụng Renderscript, hãy xem Blog dành cho nhà phát triển Android: Hướng tới tính toán GPU của Android . Thông tin tài nguyên cho việc ngừng sử dụng này bao gồm:
- Di chuyển từ bản kết xuất
- Mẫu di chuyển RenderScript
- Bộ công cụ thay thế nội tại README
- Bộ công cụ thay thế nội tại.kt