RenderScript es un marco para ejecutar tareas computacionalmente intensivas con alto rendimiento en Android. Está diseñado para usarse con computación paralela de datos, aunque las cargas de trabajo en serie también pueden beneficiarse. El tiempo de ejecución de RenderScript paraleliza el trabajo entre los procesadores disponibles en un dispositivo, como CPU y GPU multinúcleo, lo que permite a los desarrolladores concentrarse en expresar algoritmos en lugar de programar el trabajo. RenderScript es especialmente útil para aplicaciones que realizan procesamiento de imágenes, fotografía computacional o visión artificial.
Los dispositivos que ejecutan Android 8.0 y versiones posteriores utilizan el siguiente marco de RenderScript y HAL de proveedores:
Las diferencias con RenderScript en Android 7.x y versiones anteriores incluyen:
- Dos instancias de bibliotecas internas de RenderScript en un proceso. Un conjunto es para la ruta de respaldo de la CPU y proviene directamente de
/system/lib
; el otro conjunto es para la ruta de GPU y es de/system/lib/vndk-sp
. - Las bibliotecas internas de RS en
/system/lib
se construyen como parte de la plataforma y se actualizan a medida que se actualizasystem.img
. Sin embargo, las librerías en/system/lib/vndk-sp
están diseñadas para el proveedor y no se actualizan cuando se actualizasystem.img
(aunque se pueden actualizar para una solución de seguridad, su ABI sigue siendo la misma). - El código del proveedor (RS HAL, el controlador RS y el
bcc plugin
) están vinculados a las bibliotecas internas de RenderScript ubicadas en/system/lib/vndk-sp
. No se pueden vincular con bibliotecas en/system/lib
porque las bibliotecas en ese directorio están diseñadas para la plataforma y, por lo tanto, es posible que no sean compatibles con el código del proveedor (es decir, se pueden eliminar los símbolos). Hacerlo haría imposible una OTA solo de marco.
Diseño
Las siguientes secciones detallan el diseño de RenderScript en Android 8.0 y versiones posteriores.
Librerías de RenderScript disponibles para proveedores
Esta sección enumera las bibliotecas de RenderScript (conocidas como NDK de proveedor para HAL del mismo proceso o VNDK-SP) que están disponibles para el código del proveedor y con las que se pueden vincular. También detalla bibliotecas adicionales que no están relacionadas con RenderScript pero que también se proporcionan al código del proveedor.
Si bien la siguiente lista de bibliotecas puede diferir entre las versiones de Android, es inmutable para una versión específica de Android; para obtener una lista actualizada de las bibliotecas disponibles, consulte /system/etc/ld.config.txt
.
Bibliotecas de RenderScript | Librerías sin RenderScript |
---|---|
|
|
Configuración del espacio de nombres del enlazador
La restricción de vinculación que evita que el código del proveedor utilice las librerías que no están en VNDK-SP se aplica en el tiempo de ejecución mediante el espacio de nombres del vinculador. (Para obtener más información, consulte la presentación de diseño de VNDK ).
En un dispositivo que ejecuta Android 8.0 y versiones posteriores, todas las HAL del mismo proceso (SP-HAL) , excepto RenderScript , se cargan dentro del espacio de nombres del vinculador sphal
. RenderScript se carga en el espacio de nombres específico de RenderScript rs
, una ubicación que permite una aplicación un poco menos estricta de las bibliotecas de RenderScript. Debido a que la implementación de RS necesita cargar el código de bits compilado, /data/*/*.so
se agrega a la ruta del espacio de nombres rs
(otros SP-HAL no pueden cargar bibliotecas desde la partición de datos).
Además, el espacio de nombres rs
permite más bibliotecas que las proporcionadas por otros espacios de nombres. libmediandk.so
y libft2.so
están expuestos al espacio de nombres rs
porque libRS_internal.so
tiene una dependencia interna con estas bibliotecas.
Cargando controladores
Ruta de respaldo de la CPU
Según la existencia del bit RS_CONTEXT_LOW_LATENCY
al crear un contexto RS, se selecciona la ruta de la CPU o la GPU. Cuando se selecciona la ruta de la CPU, libRS_internal.so
(la implementación principal del marco RS) se dlopen
directamente desde el espacio de nombres del enlazador predeterminado donde se proporciona la versión de plataforma de RS libs.
La implementación de RS HAL del proveedor no se usa en absoluto cuando se toma la ruta de respaldo de la CPU y se crea un objeto RsContext
con mVendorDriverName
nulo. libRSDriver.so
está (de manera predeterminada) dlopen
y la biblioteca del controlador se carga desde el espacio de nombres default
porque la persona que llama ( libRS_internal.so
) también se carga en el espacio de nombres default
.
ruta de GPU
Para la ruta de GPU, libRS_internal.so
se carga de manera diferente. Primero, libRS.so
usa android.hardware.renderscript@1.0.so
(y su libhidltransport.so
subyacente) para cargar android.hardware.renderscript@1.0-impl.so
(una implementación de proveedor de RS HAL) en un espacio de nombres de enlazador diferente llamado sphal
El RS HAL entonces dlopen
s libRS_internal.so
en otro espacio de nombres del enlazador llamado rs
.
Los proveedores pueden proporcionar su propio controlador RS configurando el indicador de tiempo de compilación OVERRIDE_RS_DRIVER
, que está integrado en la implementación RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp
). Luego, este nombre de controlador se dlopen
para el contexto RS para la ruta de la GPU.
La creación del objeto RsContext
se delega a la implementación de RS HAL. El HAL vuelve a llamar al marco de trabajo de RS utilizando la función rsContextCreateVendor()
con el nombre del controlador para usar como argumento. El marco RS luego carga el controlador especificado cuando se inicializa RsContext
. En este caso, la biblioteca de controladores se carga en el espacio de nombres rs
porque el objeto RsContext
se crea dentro del espacio de nombres rs
y /vendor/lib
está en la ruta de búsqueda del espacio de nombres.
Al pasar del espacio de nombres default
al espacio de nombres sphal
, libhidltransport.so
usa la función android_load_sphal_library()
para ordenar explícitamente al vinculador dinámico que cargue la biblioteca -impl.so
desde el espacio de nombres sphal
.
Al pasar del espacio de nombres sphal
al espacio de nombres rs
, la carga se realiza indirectamente mediante la siguiente línea en /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Esta línea especifica que el vinculador dinámico debe cargar libRS_internal.so
desde el espacio de nombres rs
cuando no se puede encontrar/cargar lib desde el espacio de nombres sphal
(que siempre es el caso porque el espacio de nombres sphal
no busca /system/lib/vndk-sp
donde libRS_internal.so
reside). Con esta configuración, una simple llamada dlopen()
a libRS_internal.so
es suficiente para realizar la transición del espacio de nombres.
Cargando el complemento BCC
bcc plugin
es una biblioteca proporcionada por el proveedor cargada en el compilador bcc
. Dado que bcc
es un proceso del sistema en el directorio /system/bin
, la biblioteca de bcc plugin
se puede considerar una SP-HAL (es decir, una HAL de proveedor que se puede cargar directamente en el proceso del sistema sin vincularse). Como SP-HAL, la biblioteca bcc-plugin
bcc:
- No se puede vincular con bibliotecas solo de marco como
libLLVM.so
. - Puede vincularse solo con las bibliotecas VNDK-SP disponibles para el proveedor.
Esta restricción se aplica cargando el bcc plugin
bcc en el espacio de nombres sphal
mediante la función android_sphal_load_library()
. En versiones anteriores de Android, el nombre del complemento se especificaba con la opción -load
y la lib se cargaba con el simple dlopen()
de libLLVM.so
. En Android 8.0 y versiones posteriores, esto se especifica en la opción -plugin
y la lib la carga directamente el propio bcc
. Esta opción habilita una ruta no específica de Android al proyecto LLVM de código abierto.
Rutas de búsqueda para ld.mc
Al ejecutar ld.mc
, algunas bibliotecas de tiempo de ejecución de RS se proporcionan como entradas para el enlazador. El código de bits RS de la aplicación se vincula con las bibliotecas de tiempo de ejecución y cuando el código de bits convertido se carga en un proceso de la aplicación, las bibliotecas de tiempo de ejecución se vinculan de nuevo dinámicamente desde el código de bits convertido.
Las bibliotecas de tiempo de ejecución incluyen:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- Controlador RS (ya sea
libRSDriver.so
oOVERRIDE_RS_DRIVER
)
Al cargar el código de bits compilado en el proceso de la aplicación, proporcione exactamente la misma biblioteca que utilizó ld.mc
. De lo contrario, es posible que el código de bits compilado no encuentre un símbolo que estaba disponible cuando se vinculó.
Para hacerlo, el marco RS usa diferentes rutas de búsqueda para las librerías en tiempo de ejecución al ejecutar ld.mc
, dependiendo de si el marco RS se carga desde /system/lib
o desde /system/lib/vndk-sp
. Esto se puede determinar leyendo la dirección de un símbolo arbitrario de una lib de marco RS y usando dladdr()
para obtener la ruta del archivo asignada a la dirección.
Política de SELinux
Como resultado de los cambios en la política de SELinux en Android 8.0 y versiones posteriores, debe seguir reglas específicas (aplicadas a través neverallows
) al etiquetar archivos adicionales en la partición del vendor
:
-
vendor_file
debe ser la etiqueta predeterminada para todos los archivos en la partición delvendor
. La política de la plataforma requiere esto para acceder a las implementaciones HAL de acceso directo. - Todos los nuevos
exec_types
agregados en la partición delvendor
a través del proveedorvendor_file_type
deben tener el atributo de proveedor_archivo_tipo. Esto se aplica medianteneverallows
. - Para evitar conflictos con futuras actualizaciones de plataforma/marco, evite etiquetar archivos que no sean
exec_types
en la partición delvendor
. - Todas las dependencias de la biblioteca para las HAL del mismo proceso identificadas por AOSP deben etiquetarse como
same_process_hal_file
.
Para obtener detalles sobre la política de SELinux, consulte Linux con seguridad mejorada en Android .
Compatibilidad ABI para código de bits
Si no se agregan nuevas API, lo que significa que no hay un aumento de la versión HAL, los marcos RS seguirán usando el controlador de GPU (HAL 1.0) existente.
Para los cambios menores de HAL (HAL 1.1) que no afectan el código de bits, los marcos deben recurrir a la CPU para estas API recién agregadas y seguir usando el controlador GPU (HAL 1.0) en otros lugares.
Para los cambios importantes de HAL (HAL 2.0) que afectan la compilación/vinculación de códigos de bits, los marcos RS deben elegir no cargar los controladores de GPU proporcionados por el proveedor y, en su lugar, usar la ruta de CPU o Vulkan para la aceleración.
El consumo de código de bits de RenderScript se produce en tres etapas:
Escenario | Detalles |
---|---|
Compilar |
|
Enlace |
|
Carga |
|
Además de HAL, las API de tiempo de ejecución y los símbolos exportados también son interfaces. Ninguna interfaz ha cambiado desde Android 7.0 (API 24) y no hay planes inmediatos para cambiarla en Android 8.0 y posteriores. Sin embargo, si la interfaz cambia, la versión HAL también aumentará.
Implementaciones de proveedores
Android 8.0 y versiones posteriores requieren algunos cambios en el controlador de GPU para que el controlador de GPU funcione correctamente.
Módulos de controlador
- Los módulos de controladores no deben depender de ninguna biblioteca del sistema que no esté en la lista .
- El controlador debe proporcionar su propio
android.hardware.renderscript@1.0-impl_{NAME}
o declarar la implementación predeterminadaandroid.hardware.renderscript@1.0-impl
como su dependencia. - La implementación de CPU
libRSDriver.so
es un buen ejemplo de cómo eliminar las dependencias que no son de VNDK-SP.
compilador de código de bits
Puede compilar el código de bits de RenderScript para el controlador del proveedor de dos maneras:
- Invoque el compilador de RenderScript específico del proveedor en
/vendor/bin/
(método preferido de compilación de GPU). Al igual que otros módulos de controladores, el binario del compilador del proveedor no puede depender de ninguna biblioteca del sistema que no esté en la lista de bibliotecas de RenderScript disponibles para los proveedores . - Invoque system bcc:
/system/bin/bcc
con unbcc plugin
proporcionado por el proveedor; este complemento no puede depender de ninguna biblioteca del sistema que no esté en la lista de bibliotecas de RenderScript disponibles para los proveedores .
Si el bcc plugin
del proveedor necesita interferir con la compilación de la CPU y su dependencia de libLLVM.so
no se puede eliminar fácilmente, el proveedor debe copiar bcc
(y todas las dependencias que no sean LL-NDK, incluidas libLLVM.so
, libbcc.so
) en partición /vendor
.
Además, los proveedores deben realizar los siguientes cambios:
- Copie
libclcore.bc
a la partición/vendor
. Esto garantizalibclcore.bc
,libLLVM.so
ylibbcc.so
estén sincronizados. - Cambie la ruta al ejecutable
bcc
configurandoRsdCpuScriptImpl::BCC_EXE_PATH
desde la implementación de RS HAL.
Política de SELinux
La política de SELinux afecta tanto al controlador como a los ejecutables del compilador. Todos los módulos del controlador deben tener la etiqueta same_process_hal_file
en los contextos de file_contexts
del dispositivo. Por ejemplo:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
El ejecutable del compilador debe poder ser invocado por un proceso de aplicación, al igual que la copia del proveedor de bcc ( /vendor/bin/bcc
). Por ejemplo:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Dispositivos heredados
Los dispositivos heredados son aquellos que cumplen las siguientes condiciones:
- PRODUCT_SHIPPING_API_LEVEL es inferior a 26.
- PRODUCT_FULL_TREBLE_OVERRIDE no está definido.
Para los dispositivos heredados, las restricciones no se aplican cuando se actualiza a Android 8.0 y versiones posteriores, lo que significa que los controladores pueden seguir vinculándose a las bibliotecas en /system/lib[64]
. Sin embargo, debido al cambio de arquitectura relacionado con OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
debe instalarse en la partición /vendor
; si no lo hace, obliga al tiempo de ejecución de RenderScript a volver a la ruta de la CPU.
Para obtener información sobre los motivos de la desaprobación de Renderscript, consulte el blog de desarrolladores de Android: Android GPU Compute Going Forward . La información de recursos para esta degradación incluye lo siguiente:
- Migrar desde Renderscript
- Ejemplo de migración de RenderScript
- LÉAME del kit de herramientas de reemplazo intrínseco
- Kit de herramientas de reemplazo intrínseco.kt