RenderScript es un framework para ejecutar tareas con mucha carga de procesamiento y alto rendimiento en Android. Está diseñado para usarse con procesamiento paralelo de datos, aunque las cargas de trabajo en serie también pueden beneficiarse. El entorno de ejecución de RenderScript permite trabajar en paralelo con todos los procesadores disponibles en un dispositivo, como las GPU y CPU de varios núcleos, lo que permite que los desarrolladores se concentren en la expresión de algoritmos en lugar de en la programación del trabajo. RenderScript es especialmente útil para las apps que ejecutan procesamiento de imágenes, fotografía computacional o visión artificial.
Los dispositivos que ejecutan Android 8.0 y versiones posteriores usan los siguientes HALs del proveedor y el framework de RenderScript:

Figura 1: Es la vinculación del código del proveedor a las bibliotecas internas.
Las diferencias con RenderScript en Android 7.x y versiones anteriores incluyen lo siguiente:
- Dos instancias de libs internas de RenderScript en un proceso. Un conjunto es para la ruta de resguardo de la CPU y proviene directamente de
/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 compilan como parte de la plataforma y se actualizan a medida que se actualizasystem.img
. Sin embargo, las bibliotecas de/system/lib/vndk-sp
se compilan para el proveedor y no se actualizan cuando se actualizasystem.img
(aunque se pueden actualizar para una corrección de seguridad, su ABI sigue siendo la misma). - El código del proveedor (HAL de RS, controlador de RS y
bcc plugin
) se vincula con las bibliotecas internas de RenderScript ubicadas en/system/lib/vndk-sp
. No se pueden vincular a las bibliotecas en/system/lib
porque las bibliotecas en ese directorio se compilan para la plataforma y, por lo tanto, es posible que no sean compatibles con el código del proveedor (es decir, es posible que se quiten símbolos). Si lo haces, no se podrá realizar una OTA solo del framework.
Diseño
En las siguientes secciones, se detalla el diseño de RenderScript en Android 8.0 y versiones posteriores.
Libs de RenderScript disponibles para los proveedores
En esta sección, se enumeran las bibliotecas de RenderScript (conocidas como VNDK-SP o NDK del proveedor para HALs del mismo proceso) que están disponibles para el código del proveedor y con las que se pueden vincular. También detalla bibliotecas adicionales que no se relacionan 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, consulta /system/etc/ld.config.txt
.
Libs de RenderScript | Libs que no son de RenderScript |
---|---|
|
|
Configuración del espacio de nombres del vinculador
La restricción de vinculación que impide que el código del proveedor use libs que no están en VNDK-SP se aplica en el tiempo de ejecución con el espacio de nombres del vinculador. (Para obtener más detalles, consulta la presentación VNDK Design).
En un dispositivo que ejecuta Android 8.0 y versiones posteriores, todos los HALs de mismo proceso (SP-HALs) excepto RenderScript se cargan dentro del espacio de nombres del vinculador sphal
. RenderScript se carga en el espacio de nombres rs
específico de RenderScript, una ubicación que permite una aplicación un poco más flexible para las bibliotecas de RenderScript. Dado que la implementación de RS necesita cargar el código de bits compilado, se agrega /data/*/*.so
a la ruta de acceso del espacio de nombres rs
(no se permite que otros SP-HAL carguen libs desde la partición de datos).
Además, el espacio de nombres rs
permite más bibliotecas que las que proporcionan otros espacios de nombres. libmediandk.so
y libft2.so
se exponen al espacio de nombres rs
porque
libRS_internal.so
tiene una dependencia interna de estas bibliotecas.

Figura 2: Es la configuración del espacio de nombres para el vinculador.
Carga de conductores
Ruta de resguardo de la CPU
Según la existencia del bit RS_CONTEXT_LOW_LATENCY
cuando se crea un contexto de RS, se selecciona la ruta de CPU o GPU. Cuando se selecciona la ruta de CPU, libRS_internal.so
(la implementación principal del framework de RS) se dlopen
directamente desde el espacio de nombres del vinculador predeterminado en el que se proporcionan las versiones de la plataforma de las bibliotecas de RS.
La implementación del HAL de RS del proveedor no se usa en absoluto cuando se toma la ruta de resguardo de la CPU, y se crea un objeto RsContext
con mVendorDriverName
nulo. libRSDriver.so
se dlopen
de forma predeterminada, y la biblioteca del controlador se carga desde el espacio de nombres default
porque el llamador (libRS_internal.so
) también se carga en el espacio de nombres default
.

Figura 3: Es la ruta de resguardo de la CPU.
Ruta de GPU
En el caso de la ruta de la GPU, el objeto 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 del proveedor de RS HAL) en un espacio de nombres del vinculador diferente llamado sphal
. Luego, el HAL de RS dlopen
s libRS_internal.so
en otro espacio de nombres del vinculador llamado rs
.
Los proveedores pueden proporcionar su propio controlador de RS configurando la marca de tiempo de compilación OVERRIDE_RS_DRIVER
, que se incorpora en la implementación del HAL de RS (hardware/interfaces/renderscript/1.0/default/Context.cpp
). Luego, este nombre del controlador se dlopen
para el contexto de RS de la ruta de GPU.
La creación del objeto RsContext
se delega en la implementación del HAL de RS. El HAL llama al framework de RS con la función rsContextCreateVendor()
y el nombre del controlador que se usará como argumento. Luego, el framework de 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.

Figura 4: Es la ruta de resguardo de la GPU.
Cuando se realiza 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 de forma explícita al vinculador dinámico que cargue la biblioteca -impl.so
desde el espacio de nombres sphal
.
Cuando se realiza la transición del espacio de nombres sphal
al espacio de nombres rs
, la carga se realiza de forma indirecta con 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 pueda encontrar o cargar la biblioteca desde el espacio de nombres sphal
(lo que siempre sucede porque el espacio de nombres sphal
no busca /system/lib/vndk-sp
donde reside libRS_internal.so
). Con esta configuración, una simple llamada a dlopen()
en libRS_internal.so
es suficiente para realizar la transición del espacio de nombres.
Carga el complemento de Cco
bcc plugin
es una biblioteca proporcionada por el proveedor que se carga en el compilador bcc
. Dado que bcc
es un proceso del sistema en el directorio /system/bin
, la biblioteca bcc plugin
se puede considerar un SP-HAL (es decir, un HAL del proveedor que se puede cargar directamente en el proceso del sistema sin estar vinculado). Como SP-HAL, la biblioteca bcc-plugin
hace lo siguiente:
- No se puede vincular con bibliotecas solo de framework, como
libLLVM.so
. - Solo se puede vincular con las bibliotecas del VNDK-SP disponibles para el proveedor.
Esta restricción se aplica cargando bcc plugin
en el espacio de nombres sphal
con 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 biblioteca se cargaba con el simple dlopen()
por libLLVM.so
. En Android 8.0 y versiones posteriores, esto se especifica en la opción -plugin
y la biblioteca se carga directamente con bcc
. Esta opción habilita una ruta de acceso no específica de Android al proyecto de código abierto de LLVM.

Figura 5: Se está cargando el complemento de bcc en Android 7.x y versiones anteriores.

Figura 6: Se está cargando el complemento de bcc, Android 8.0 y versiones posteriores.
Rutas de acceso de búsqueda para ld.mc
Cuando se ejecuta ld.mc
, algunas bibliotecas de tiempo de ejecución de RS se proporcionan como entradas al vinculador. El bitcode de RS de la app se vincula con las bibliotecas de tiempo de ejecución y, cuando el bitcode convertido se carga en un proceso de la app, las bibliotecas de tiempo de ejecución se vuelven a vincular de forma dinámica desde el bitcode convertido.
Las bibliotecas de tiempo de ejecución incluyen lo siguiente:
libcompiler_rt.so
libm.so
libc.so
- Conductor de RS (
libRSDriver.so
oOVERRIDE_RS_DRIVER
)
Cuando cargues el bitcode compilado en el proceso de la app, proporciona la misma biblioteca que usó 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 ello, el framework de RS usa diferentes rutas de búsqueda para las bibliotecas de tiempo de ejecución cuando se ejecuta ld.mc
, según si el framework de 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 biblioteca del framework de RS y usando dladdr()
para obtener la ruta de acceso al 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, debes seguir reglas específicas (que se aplican a través de neverallows
) cuando etiquetes archivos adicionales en la partición vendor
:
vendor_file
debe ser la etiqueta predeterminada para todos los archivos de la particiónvendor
. La política de la plataforma requiere esto para acceder a las implementaciones de HAL de transferencia.- Todos los
exec_types
nuevos agregados en la particiónvendor
a través de la SEPolicy del proveedor deben tener el atributovendor_file_type
. Esto se aplica a través deneverallows
. - Para evitar conflictos con futuras actualizaciones de la plataforma o el framework, no etiquetes archivos que no sean
exec_types
en la particiónvendor
. - Todas las dependencias de biblioteca para los HALs del mismo proceso identificados por el AOSP deben etiquetarse como
same_process_hal_file
.
Para obtener detalles sobre la política de SELinux, consulta Security-Enhanced Linux en Android.
Compatibilidad con ABI para código de bits
Si no se agregan APIs nuevas, lo que significa que no se incrementa la versión del HAL, los frameworks de RS seguirán usando el controlador de GPU existente (HAL 1.0).
En el caso de los cambios menores en el HAL (HAL 1.1) que no afectan el bitcode, los frameworks deben recurrir a la CPU para estas APIs agregadas recientemente y seguir usando el controlador de la GPU (HAL 1.0) en otros lugares.
En el caso de los cambios importantes en el HAL (HAL 2.0) que afectan la compilación o la vinculación de bitcode, los frameworks de RS no deben cargar los controladores de GPU proporcionados por el proveedor y, en cambio, deben usar la CPU o la ruta de Vulkan para la aceleración.
El consumo de código de bits de RenderScript se produce en tres etapas:
Estado | Detalles |
---|---|
Compile |
|
Vínculo |
|
Cargar |
|
Además del HAL, las APIs de tiempo de ejecución y los símbolos exportados también son interfaces. Ninguna de las interfaces cambió desde Android 7.0 (API nivel 24), y no hay planes inmediatos para cambiarlas en Android 8.0 ni en versiones posteriores. Sin embargo, si la interfaz cambia, también aumentará la versión del HAL.
Implementaciones de proveedores
Android 8.0 y versiones posteriores requieren algunos cambios en el controlador de GPU para que este funcione correctamente.
Módulos del conductor
- 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 la CPU
libRSDriver.so
es un buen ejemplo de cómo quitar las dependencias que no son de VNDK-SP.
Compilador de bitcode
Puedes compilar el código de bits de RenderScript para el controlador del proveedor de dos maneras:
- Invoca 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 controladores, el compilador binario del proveedor no puede depender de ninguna biblioteca del sistema que no se encuentre en la lista de bibliotecas de RenderScript disponibles para los proveedores. - Invoca el bcc del sistema:
/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 proveedor bcc plugin
necesita interferir en la compilación de la CPU y su dependencia de libLLVM.so
no se puede quitar fácilmente, el proveedor debe copiar bcc
(y todas las dependencias que no sean del LL-NDK, incluidas libLLVM.so
y libbcc.so
) en la partición /vendor
.
Además, los proveedores deben realizar los siguientes cambios:

Figura 7: Se realizaron cambios en el controlador del proveedor.
- Copia
libclcore.bc
en la partición/vendor
. Esto garantiza quelibclcore.bc
,libLLVM.so
ylibbcc.so
estén sincronizados. - Cambia la ruta de acceso al ejecutable
bcc
configurandoRsdCpuScriptImpl::BCC_EXE_PATH
desde la implementación de HAL de RS.
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 etiquetarse como same_process_hal_file
en el 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 invocarse mediante un proceso de la app, 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 con las siguientes condiciones:
- PRODUCT_SHIPPING_API_LEVEL es inferior a 26.
- No se definió PRODUCT_FULL_TREBLE_OVERRIDE.
En el caso de los dispositivos heredados, las restricciones no se aplican cuando se actualizan 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
, se debe instalar android.hardware.renderscript@1.0-impl
en la partición /vendor
. Si no se hace, el entorno de ejecución de RenderScript recurre a la ruta de CPU.
Para obtener información sobre la motivación de la baja de Renderscript, consulta el blog de Android Developers: Android GPU Compute Going Forward. La información del recurso para esta baja incluye lo siguiente:
- Cómo migrar desde RenderScript
- Ejemplo de RenderScriptMigration
- README del kit de herramientas de reemplazo de funciones intrínsecas
- Intrinsics ReplacementToolkit.kt