RenderScript

RenderScript es un marco de trabajo para ejecutar aplicaciones de procesamiento intensivo. tareas con alto rendimiento en Android. Está diseñada para usarse con del procesamiento paralelo de datos, aunque las cargas de trabajo en serie también pueden beneficiarse. El El entorno de ejecución de RenderScript permite trabajar en paralelo con todos los procesadores disponibles en un de procesamiento de datos, como CPU y GPU de varios núcleos, lo que permite a los desarrolladores enfocarse para expresar algoritmos, en lugar de programar el trabajo. RenderScript es especialmente útil para las apps que realizan procesamiento de imágenes, procesamiento fotografía o visión artificial.

Los dispositivos con Android 8.0 y versiones posteriores usan el siguiente RenderScript HALs de framework y proveedores:

Figura 1: Vinculación de código de proveedor a bibliotecas internas

Entre las diferencias con RenderScript en Android 7.x y versiones anteriores, se incluyen las siguientes:

  • Dos instancias de bibliotecas internas de RenderScript en un proceso. Un conjunto es para Ruta de acceso de resguardo de la CPU que proviene directamente de /system/lib. el otro es para la ruta de GPU y es de /system/lib/vndk-sp.
  • Las bibliotecas internas de RS en /system/lib se compilan como parte del y se actualizan a medida que se actualiza system.img. Sin embargo, las bibliotecas en /system/lib/vndk-sp se compilan para el proveedor y no se se actualizará cuando se actualice system.img (mientras se puede actualizar) para recibir una solución de seguridad, su ABI sigue siendo la misma).
  • El código del proveedor (RS HAL, controlador RS y bcc plugin) son los siguientes: se vincula con las bibliotecas internas de RenderScript ubicadas en /system/lib/vndk-sp No pueden vincularse a bibliotecas de /system/lib porque las bibliotecas de ese directorio se compilan para el y, por lo tanto, puede no ser compatible con el código del proveedor (es decir, símbolos puede quitarse). Si lo hicieras, sería imposible implementar una tecnología inalámbrica solo en el framework.

Diseño

En las siguientes secciones, se detalla el diseño de RenderScript en Android 8.0 y versiones posteriores.

Bibliotecas de RenderScript disponibles para los proveedores

En esta sección, se enumeran las bibliotecas de RenderScript (conocidas como Vendor NDK for Same-Process) HAL o VNDK-SP) que están disponibles para el código del proveedor y se pueden vincular. y defenderte. También detalla las 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, consulta /system/etc/ld.config.txt.

Bibliotecas de RenderScript Bibliotecas que no son de 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

Configuración del espacio de nombres del vinculador

La restricción de vinculación que impide que se usen bibliotecas que no están en VNDK-SP el código del proveedor se aplica en el entorno de ejecución mediante el espacio de nombres del vinculador. (Para obtener más información, consulta la página de diseño de VNDK. la presentación).

En un dispositivo con Android 8.0 o una versión posterior, todas las HAL del mismo proceso (SP-HAL) excepto RenderScript que se cargan dentro del espacio de nombres del vinculador sphal RenderScript se carga en la API específica de RenderScript el espacio de nombres rs, una ubicación que habilita un ancho un poco más flexible aplicación forzosa 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 de acceso del rs (otras HAL de SP no pueden cargar bibliotecas del partición de datos).

Además, el espacio de nombres rs permite más bibliotecas que las proporcionadas para 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 a estas bibliotecas.

Figura 2: Configuración del espacio de nombres para el vinculador.

Controladores de carga

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 la CPU o la GPU. Cuando Se seleccionó la ruta de acceso de la CPU, libRS_internal.so (la implementación principal del framework de RS) se realiza directamente dlopendel vinculador predeterminado espacio de nombres en el que se proporciona la versión de plataforma de las bibliotecas de RS.

La implementación de RS HAL del proveedor no se usa en absoluto cuando la CPU se toma la ruta de resguardo y se crea un objeto RsContext con mVendorDriverName nulo libRSDriver.so es (por (configuración predeterminada) dlopen, y la biblioteca del controlador se carga desde el Espacio de nombres default porque el llamador (libRS_internal.so) también se carga en default espacio de nombres.

Figura 3: Ruta de resguardo de la CPU.

Ruta de acceso de la GPU

Para la ruta de acceso de la GPU, libRS_internal.so se carga de manera diferente. Primero, libRS.so usa android.hardware.renderscript@1.0.so (y sus políticas libhidltransport.so) para cargar android.hardware.renderscript@1.0-impl.so (un proveedor de RS HAL) en un espacio de nombres de vinculador diferente llamado sphal La RS HAL luego dlopen libRS_internal.so en otra del vinculador llamado rs.

Los proveedores pueden proporcionar su propio controlador de RS si configuran la marca de tiempo de compilación OVERRIDE_RS_DRIVER, que está incorporado en la HAL de RS implementación (hardware/interfaces/renderscript/1.0/default/Context.cpp) Esta El nombre del controlador se aplica a dlopen para el contexto RS de la ruta de acceso de la GPU.

La creación del objeto RsContext se delega a la HAL de RS para implementarlos. La HAL vuelve a llamar al framework de RS con Función rsContextCreateVendor() con el nombre del controlador a usar como argumento. El framework de RS carga el controlador especificado cuando el Se inicializó RsContext. En este caso, la biblioteca del controlador es se cargan en el espacio de nombres rs porque RsContext se crea dentro del espacio de nombres rs /vendor/lib está en la ruta de búsqueda del espacio de nombres.

Figura 4: Ruta de resguardo de GPU.

Cuando realizas la transición del espacio de nombres default al El espacio de nombres sphal, libhidltransport.so usa el android_load_sphal_library() para ordenar de forma explícita los vinculador dinámico para cargar la biblioteca -impl.so desde el Espacio de nombres sphal.

Cuando realizas la transición del espacio de nombres sphal al rs, la carga se realiza de forma indirecta mediante la siguiente línea de /system/etc/ld.config.txt:

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

Esta línea especifica que se debe cargar el vinculador dinámico. libRS_internal.so del espacio de nombres rs cuando la biblioteca no pueden encontrarse/cargarse desde el espacio de nombres sphal (que siempre es este es el caso porque el espacio de nombres sphal no busca /system/lib/vndk-sp, donde libRS_internal.so el sitio web). Con esta configuración, una simple llamada dlopen() a libRS_internal.so es suficiente para realizar la transición del espacio de nombres.

Cargar complemento Cco

bcc plugin es una biblioteca que proporciona el proveedor y que se carga en la Compilador bcc. Como bcc es un proceso del sistema /system/bin, la biblioteca bcc plugin se puede considera una SP-HAL (es decir, una HAL de proveedor que puede cargarse directamente en la proceso del sistema sin ser vinculante). Como una SP-HAL, el Biblioteca bcc-plugin:

  • No se pueden vincular con bibliotecas exclusivas del framework, como libLLVM.so
  • Se puede vincular solo con las bibliotecas de VNDK-SP disponibles para el proveedor.

Para aplicar esta restricción, se debe cargar bcc plugin en la sphal con el elemento Función android_sphal_load_library(). En versiones anteriores de Android, el nombre del complemento se especificó con la opción -load y la biblioteca se cargó usando el simple dlopen() libLLVM.so En Android 8.0 y versiones posteriores, esto se especifica en el -plugin, y la biblioteca cargará directamente la biblioteca bcc. Esta opción habilita una ruta de acceso no específica de Android a el proyecto de LLVM de código abierto.

Figura 5: Cargando el complemento Cco, Android 7.x y versiones anteriores.



Figura 6: Cargando el complemento Cco, Android 8.0 y versiones posteriores.

Rutas 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 código de bits RS de la app se vincula con las bibliotecas de tiempo de ejecución. y, cuando se carga el código de bits convertido en un proceso de la app, las bibliotecas de entorno de ejecución están vinculadas de forma dinámica desde el código de bits convertido.

Las bibliotecas de entorno de ejecución incluyen lo siguiente:

  • libcompiler_rt.so
  • libm.so
  • libc.so
  • Controlador de RS (ya sea libRSDriver.so o OVERRIDE_RS_DRIVER)

Cuando cargues el código de bits compilado en el proceso de la app, proporciona la misma biblioteca usada por ld.mc. De lo contrario, el código de bits compilado Es posible que 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 entorno de ejecución cuando mediante la ejecución de ld.mc, dependiendo de si el framework de 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 RS. la biblioteca de framework y cómo usar 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, debes sigue reglas específicas (aplicadas a través de neverallows) cuando etiquetar archivos adicionales en la partición vendor:

  • vendor_file debe ser la etiqueta predeterminada para todos los archivos de vendor. La política de la plataforma requiere esto para acceder implementaciones de HAL de transferencia.
  • Se agregaron todos los exec_types nuevos en la partición vendor a través de SEPolicy del proveedor debe tener el atributo vendor_file_type. Esto se aplica mediante neverallows.
  • Para evitar conflictos con futuras actualizaciones de la plataforma o el framework, evita el etiquetado otros archivos que no sean exec_types en una partición vendor.
  • Todas las dependencias de bibliotecas para las mismas HAL de proceso identificadas por AOSP se deben etiquetado como same_process_hal_file.

Para obtener detalles sobre la política de SELinux, consulta Security-Enhanced Linux en Android:

Compatibilidad de ABI para código de bits

Si no se agregan APIs nuevas, lo que significa que no hay cambio de versión de HAL, los frameworks de RS seguirá usando el controlador de GPU existente (HAL 1.0).

En el caso de los cambios menores en la HAL (HAL 1.1) que no afectan el código de bits, los frameworks deben recurrir a la CPU para estas APIs recién agregadas y seguir usando el controlador de GPU (HAL 1.0) en otro lugar.

Para cambios importantes en la HAL (HAL 2.0) que afectan la compilación/vinculación de código de bits, RS los frameworks deben elegir no cargar los controladores de GPU que proporciona el proveedor y, en su lugar, usar la ruta de CPU o de Vulkan para acelerar la ejecución.

El consumo del código de bits de RenderScript se produce en tres etapas:

Etapa Detalles
Compilar
  • El código de bits de entrada (.bc) para bcc debe estar en LLVM 3.2 formato de código de bits y bcc deben estar hacia atrás compatibles con apps existentes (heredadas).
  • Sin embargo, los metadatos en .bc podrían cambiar (podría funciones, p.ej., Establecedores de asignación ∓ métodos get, funciones matemáticas, etcétera). Parte de las funciones del entorno de ejecución se encuentra en libclcore.bc, parte de ellas residen en LibRSDriver o un proveedor equivalente.
  • Las nuevas funciones del entorno de ejecución o los cambios rotundos en los metadatos requieren aumentar el nivel de API de código de bits. Como los conductores de los proveedores no podrán consumirlo, la versión de HAL también debe aumentarse.
  • Los proveedores pueden tener sus propios compiladores, pero las conclusiones o los requisitos para bcc también se aplican a esos compiladores.
Vínculo
  • El archivo .o compilado se vinculará con el controlador del proveedor, p.ej., libRSDriver_foo.so y libcompiler_rt.so. La CPU la ruta de acceso se vinculará con libRSDriver.so.
  • Si .o requiere una nueva API de entorno de ejecución de libRSDriver_foo, el controlador del proveedor debe actualizarse para admitirlo.
  • Ciertos proveedores pueden tener sus propios vinculadores, pero el argumento para ld.mc también se aplican a ellas.
Carga
  • libRSCpuRef carga el objeto compartido. Si hay cambios a esta interfaz, se necesita un cambio de versión de HAL.
  • Los proveedores dependerían de libRSCpuRef para cargar el archivo un objeto o implementar los suyos.

Además de la HAL, las APIs de tiempo de ejecución y los símbolos exportados interfaces. Ninguna de las interfaces ha cambiado desde Android 7.0 (nivel de API 24) y, no hay planes inmediatos de cambiarlo en Android 8.0 y versiones posteriores. Sin embargo, si el cambia la versión de HAL, también aumentará.

Implementaciones de proveedores

Android 8.0 y las versiones posteriores requieren algunos cambios en el controlador de GPU para que este se ejecute funcionen correctamente.

Módulos de controladores

  • Los módulos de controlador no deben depender de ninguna biblioteca del sistema que no esté en la lista.
  • El conductor debe proporcionar un android.hardware.renderscript@1.0-impl_{NAME} o declara el implementación predeterminada android.hardware.renderscript@1.0-impl como su dependencia.
  • La implementación de CPU libRSDriver.so es un buen ejemplo de cómo quita las dependencias que no pertenecen al VNDK-SP.

Compilador de códigos de bits

Puedes compilar el código de bits de RenderScript para el controlador del proveedor de dos maneras:

  1. 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 controlador, el El objeto binario del compilador del proveedor no puede depender de ninguna biblioteca del sistema que no se encuentre en el lista de bibliotecas de RenderScript disponibles para los proveedores.
  2. Invoca el campo Cco del sistema: /system/bin/bcc con un valor proporcionado por el proveedor bcc plugin; este complemento no puede depender de ninguna biblioteca del sistema que no está en la lista de Bibliotecas de RenderScript disponibles a los proveedores.

Qué hacer si el proveedor bcc plugin necesita interferir en la CPU compilación y su dependencia en libLLVM.so no se pueden el proveedor, deberá copiar bcc (y todas las instancias dependencias, incluidas libLLVM.so y libbcc.so) en /vendor.

Además, los proveedores deben realizar los siguientes cambios:

Figura 7: Cambios en el controlador de proveedor.

  1. Copia libclcore.bc en la partición /vendor. Esta garantiza que libclcore.bc, libLLVM.so y libbcc.so están sincronizados.
  2. Cambiar la ruta de acceso al ejecutable bcc mediante la configuración RsdCpuScriptImpl::BCC_EXE_PATH de la implementación de RS HAL

Política de SELinux

La política de SELinux afecta al controlador y a los ejecutables del compilador. Todo los módulos de controlador deben tener la etiqueta 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 a través de un proceso de la app, al igual que la copia del proveedor de Cco (/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:

  1. PRODUCT_SHIPPING_API_LEVEL es inferior a 26.
  2. PRODUCT_FULL_TREBLE_OVERRIDE no está definido.

En el caso de 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 vinculando a las bibliotecas en /system/lib[64]. Sin embargo, debido a los cambios en la arquitectura relacionadas con OVERRIDE_RS_DRIVER, Se debe instalar android.hardware.renderscript@1.0-impl en /vendor partición; De lo contrario, se fuerza el entorno de ejecución de RenderScript. y el resguardo de la ruta de acceso de la CPU.

Para obtener información sobre los motivos por los que Renderscript dejó de estar disponible, consulta la página de Android Developers Blog: El procesamiento con GPU de Android: El futuro. La información de los recursos de esta baja incluye la siguiente información: