RenderScript es un marco para ejecutar tareas computacionalmente intensivas con alto rendimiento en Android. Está diseñado para usarse con computación de datos en paralelo, 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 de múltiples núcleos, lo que permite a los desarrolladores centrarse 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 por computadora.
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 alternativa de la CPU y se encuentra directamente en
/system/lib
; el otro conjunto es para la ruta de la GPU y proviene de/system/lib/vndk-sp
. - Las bibliotecas internas de RS en
/system/lib
se crean como parte de la plataforma y se actualizan a medida que se actualizasystem.img
. Sin embargo, las bibliotecas en/system/lib/vndk-sp
están creadas para el proveedor y no se actualizan cuando se actualizasystem.img
(si bien se pueden actualizar para una solución de seguridad, su ABI sigue siendo la misma). - El código del proveedor (RS HAL, controlador RS y el
bcc plugin
) están vinculados a las bibliotecas internas de RenderScript ubicadas en/system/lib/vndk-sp
. No pueden vincularse con bibliotecas en/system/lib
porque las bibliotecas en ese directorio están creadas para la plataforma y, por lo tanto, pueden no ser compatibles con el código del proveedor (es decir, los símbolos pueden eliminarse). Hacerlo haría imposible una OTA basada únicamente en el marco.
Diseño
Las siguientes secciones detallan el diseño de RenderScript en Android 8.0 y superior.
Bibliotecas 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 de 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 con el 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 | Bibliotecas que no son de RenderScript |
---|---|
|
|
Configuración del espacio de nombres del vinculador
La restricción de vinculación que evita que el código del proveedor utilice bibliotecas que no están en VNDK-SP se aplica en tiempo de ejecución mediante el espacio de nombres del vinculador. (Para obtener más detalles, consulte la presentación de Diseño VNDK ).
En un dispositivo con Android 8.0 y superior, todos los 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 ligeramente más flexible para 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 de estas bibliotecas.
Cargando controladores
Ruta de respaldo de la CPU
Dependiendo de la existencia del bit RS_CONTEXT_LOW_LATENCY
al crear un contexto RS, se selecciona la ruta de CPU o 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 vinculador predeterminado donde se proporciona la versión de plataforma de las bibliotecas RS.
La implementación RS HAL del proveedor no se utiliza en absoluto cuando se toma la ruta alternativa de la CPU y se crea un objeto RsContext
con mVendorDriverName
nulo. libRSDriver.so
está (de forma predeterminada) dlopen
ed 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 la GPU
Para la ruta de la 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 vinculador diferente llamado sphal
. Luego, RS HAL dlopen
libRS_internal.so
en otro espacio de nombres del vinculador 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 de la ruta de la GPU.
La creación del objeto RsContext
se delega a la implementación RS HAL. HAL vuelve a llamar al marco RS utilizando la función rsContextCreateVendor()
con el nombre del controlador que se utilizará como argumento. Luego, el marco RS carga el controlador especificado cuando se inicializa RsContext
. En este caso, la biblioteca del controlador 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 realizar la transición 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 realizar la transición 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 la biblioteca no se puede encontrar/cargar desde el espacio de nombres sphal
(que siempre es el caso porque el espacio de nombres sphal
no busca /system/lib/vndk-sp
donde reside libRS_internal.so
). 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 CCO
bcc plugin
es una biblioteca proporcionada por el proveedor cargada en el compilador bcc
. Debido a que bcc
es un proceso del sistema en el directorio /system/bin
, la biblioteca bcc plugin
puede considerarse un SP-HAL (es decir, un HAL de proveedor que se puede cargar directamente en el proceso del sistema sin estar enlazado). Como SP-HAL, la biblioteca bcc-plugin
:
- No se puede vincular con bibliotecas exclusivas del marco, como
libLLVM.so
. - Puede vincularse únicamente con las bibliotecas VNDK-SP disponibles para el proveedor.
Esta restricción se aplica cargando el bcc plugin
en el espacio de nombres sphal
usando la función android_sphal_load_library()
. En versiones anteriores de Android, el nombre del complemento se especificaba usando la opción -load
y la biblioteca se cargaba usando el simple dlopen()
de libLLVM.so
. En Android 8.0 y superiores, esto se especifica en la opción -plugin
y el propio bcc
carga directamente la biblioteca. 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 al vinculador. El código de bits RS de la aplicación está vinculado a las bibliotecas de tiempo de ejecución y cuando el código de bits convertido se carga en un proceso de aplicación, las bibliotecas de tiempo de ejecución nuevamente se vinculan dinámicamente desde el código de bits convertido.
Las bibliotecas en 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 estuviera disponible cuando se vinculó.
Para hacerlo, RS framework utiliza diferentes rutas de búsqueda para las bibliotecas en tiempo de ejecución al ejecutar ld.mc
, dependiendo de si el propio marco RS está cargado desde /system/lib
o desde /system/lib/vndk-sp
. Esto se puede determinar leyendo la dirección de un símbolo arbitrario de una biblioteca de marco RS y usando dladdr()
para asignar la ruta del archivo a la dirección.
Política 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 de neverallows
) al etiquetar archivos adicionales en la partición vendor
:
-
vendor_file
debe ser la etiqueta predeterminada para todos los archivos en la particiónvendor
. La política de la plataforma requiere esto para acceder a implementaciones HAL de paso. - Todos los nuevos
exec_types
agregados en la particiónvendor
a través del proveedor SEPolicy deben tener el atributovendor_file_type
. Esto se aplica a través deneverallows
. - Para evitar conflictos con futuras actualizaciones de plataforma/marco, evite etiquetar archivos que no sean
exec_types
en la particiónvendor
. - Todas las dependencias de biblioteca para HAL del mismo proceso identificados 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 habrá ningún aumento en la versión de HAL, los marcos RS seguirán usando el controlador GPU (HAL 1.0) existente.
Para 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 cambios importantes de HAL (HAL 2.0) que afectan la compilación/enlace de código de bits, los marcos RS deben optar por no cargar los controladores de GPU proporcionados por el proveedor y, en su lugar, utilizar la CPU o la ruta 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 en 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 versiones 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 funcione correctamente.
Módulos de controlador
- Los módulos de controlador 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 dependencias que no son 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 RenderScript específico del proveedor en
/vendor/bin/
(método preferido de compilación de GPU). Al igual que otros módulos de controlador, 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 . - Invocar sistema 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
y libbcc.so
) en /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 RS HAL.
Política SELinux
La política de SELinux afecta tanto al controlador como a los ejecutables del compilador. Todos los módulos de controlador deben estar etiquetados same_process_hal_file
en los 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 al actualizar a Android 8.0 y superior, lo que significa que los controladores pueden continuar 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
; De no hacerlo, el tiempo de ejecución de RenderScript se verá obligado a recurrir a la ruta de la CPU.
Para obtener información sobre los motivos de la desactivación de Renderscript, consulte el blog de desarrolladores de Android: Computación de GPU de Android en el futuro . La información de recursos para esta desaprobación incluye lo siguiente:
- Migrar desde Renderscript
- Muestra de migración de RenderScript
- README del kit de herramientas de reemplazo de elementos intrínsecos
- Kit de herramientas de reemplazo de intrínsecos.kt