RenderScript est un framework qui permet d'exécuter des tâches nécessitant beaucoup de ressources de calcul sur Android. Il est conçu pour être utilisé avec le calcul parallèle des données, même si les charges de travail en série peuvent également en bénéficier. L'environnement d'exécution RenderScript exécute les tâches en parallèle sur les processeurs disponibles sur l'appareil tels que les GPU et les processeurs multicœurs, ce qui permet aux développeurs de se concentrer sur l'expression d'algorithmes plutôt que sur la planification des tâches. RenderScript est particulièrement utile pour les applications de traitement d'images, de photographie computationnelle ou de vision par ordinateur.
Les appareils équipés d'Android 8.0 ou version ultérieure utilisent les HAL du fournisseur et le framework RenderScript suivants :

Figure 1 : Liaison du code du fournisseur à des bibliothèques internes.
Voici les différences avec RenderScript dans Android 7.x et versions antérieures :
- Deux instances de bibliothèques internes RenderScript dans un processus. Un ensemble est destiné au chemin de secours du processeur et provient directement de
/system/lib
. L'autre ensemble est destiné au chemin du GPU et provient de/system/lib/vndk-sp
. - Les bibliothèques internes RS dans
/system/lib
sont créées dans le cadre de la plate-forme et sont mises à jour lorsquesystem.img
est mis à niveau. Toutefois, les libs de/system/lib/vndk-sp
sont conçues pour le fournisseur et ne sont pas mises à jour lorsquesystem.img
est mis à niveau (bien qu'elles puissent être mises à jour pour corriger un problème de sécurité, leur ABI reste la même). - Le code du fournisseur (RS HAL, pilote RS et
bcc plugin
) est lié aux bibliothèques internes RenderScript situées à l'adresse/system/lib/vndk-sp
. Ils ne peuvent pas établir de lien avec les bibliothèques dans/system/lib
, car les bibliothèques de ce répertoire sont conçues pour la plate-forme et peuvent donc ne pas être compatibles avec le code du fournisseur (c'est-à-dire que des symboles peuvent être supprimés). Cela rendrait impossible une mise à jour OTA du framework uniquement.
Conception
Les sections suivantes décrivent la conception de RenderScript dans Android 8.0 et versions ultérieures.
Bibliothèques RenderScript disponibles pour les fournisseurs
Cette section liste les bibliothèques RenderScript (appelées Vendor NDK pour les HAL Same-Process ou VNDK-SP) qui sont disponibles pour le code du fournisseur et qui peuvent être liées. Il détaille également les bibliothèques supplémentaires qui ne sont pas liées à RenderScript, mais qui sont également fournies au code du fournisseur.
Bien que la liste de bibliothèques suivante puisse varier d'une version d'Android à l'autre, elle est immuable pour une version d'Android spécifique. Pour obtenir une liste à jour des bibliothèques disponibles, consultez /system/etc/ld.config.txt
.
Bibliothèques RenderScript | Bibliothèques non RenderScript |
---|---|
|
|
Configuration de l'espace de noms du linker
La restriction d'association qui empêche le code du fournisseur d'utiliser des bibliothèques qui ne se trouvent pas dans VNDK-SP est appliquée au moment de l'exécution à l'aide de l'espace de noms de l'éditeur de liens. (Pour en savoir plus, consultez la présentation VNDK Design.)
Sur un appareil équipé d'Android 8.0 ou version ultérieure, toutes les HAL (Hardware Abstraction Layer) du même processus (SP-HAL) sauf RenderScript sont chargées dans l'espace de noms de l'éditeur de liens sphal
. RenderScript est chargé dans l'espace de noms rs
spécifique à RenderScript, un emplacement qui permet une application légèrement moins stricte pour les bibliothèques RenderScript. Étant donné que l'implémentation RS doit charger le bitcode compilé, /data/*/*.so
est ajouté au chemin d'accès de l'espace de noms rs
(les autres SP-HAL ne sont pas autorisés à charger des bibliothèques à partir de la partition de données).
De plus, l'espace de noms rs
autorise plus de bibliothèques que les autres espaces de noms. libmediandk.so
et libft2.so
sont exposés à l'espace de noms rs
, car libRS_internal.so
a une dépendance interne à ces bibliothèques.

Figure 2. Configuration de l'espace de noms pour l'outil d'association.
Charger les pilotes
Chemin de remplacement du processeur
Selon l'existence du bit RS_CONTEXT_LOW_LATENCY
lors de la création d'un contexte RS, le chemin d'accès au processeur ou au GPU est sélectionné. Lorsque le chemin d'accès au processeur est sélectionné, libRS_internal.so
(l'implémentation principale du framework RS) est directement dlopen
à partir de l'espace de noms de l'éditeur de liens par défaut où la version de plate-forme des bibliothèques RS est fournie.
L'implémentation RS HAL du fournisseur n'est pas du tout utilisée lorsque le chemin de secours du processeur est emprunté, et un objet RsContext
est créé avec mVendorDriverName
nul. libRSDriver.so
est (par défaut) dlopen
et la bibliothèque de pilotes est chargée à partir de l'espace de noms default
, car l'appelant (libRS_internal.so
) est également chargé dans l'espace de noms default
.

Figure 3. Chemin de remplacement du processeur.
Chemin d'accès au GPU
Pour le chemin d'accès au GPU, libRS_internal.so
est chargé différemment.
Tout d'abord, libRS.so
utilise android.hardware.renderscript@1.0.so
(et son libhidltransport.so
sous-jacent) pour charger android.hardware.renderscript@1.0-impl.so
(une implémentation fournisseur de RS HAL) dans un autre espace de noms de l'éditeur de liens appelé sphal
. La HAL RS dlopen
ensuite libRS_internal.so
dans un autre espace de noms de l'éditeur de liens appelé rs
.
Les fournisseurs peuvent fournir leur propre pilote RS en définissant l'indicateur de compilation OVERRIDE_RS_DRIVER
, qui est intégré à l'implémentation RS HAL (hardware/interfaces/renderscript/1.0/default/Context.cpp
). Ce nom de pilote est ensuite dlopen
pour le contexte RS pour le chemin d'accès au GPU.
La création de l'objet RsContext
est déléguée à l'implémentation RS HAL. Le HAL rappelle le framework RS à l'aide de la fonction rsContextCreateVendor()
avec le nom du pilote à utiliser comme argument. Le framework RS charge ensuite le pilote spécifié lors de l'initialisation de RsContext
. Dans ce cas, la bibliothèque de pilotes est chargée dans l'espace de noms rs
, car l'objet RsContext
est créé dans l'espace de noms rs
et /vendor/lib
se trouve dans le chemin de recherche de l'espace de noms.

Figure 4. Chemin de secours du GPU.
Lors du passage de l'espace de noms default
à l'espace de noms sphal
, libhidltransport.so
utilise la fonction android_load_sphal_library()
pour ordonner explicitement au linker dynamique de charger la bibliothèque -impl.so
à partir de l'espace de noms sphal
.
Lors du passage de l'espace de noms sphal
à l'espace de noms rs
, le chargement est effectué indirectement par la ligne suivante dans /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Cette ligne indique que l'éditeur de liens dynamiques doit charger libRS_internal.so
à partir de l'espace de noms rs
lorsque la bibliothèque ne peut pas être trouvée ni chargée à partir de l'espace de noms sphal
(ce qui est toujours le cas, car l'espace de noms sphal
ne recherche pas /system/lib/vndk-sp
où se trouve libRS_internal.so
). Avec cette configuration, un simple appel dlopen()
à libRS_internal.so
suffit pour effectuer la transition de l'espace de noms.
Charger le plug-in Cci
bcc plugin
est une bibliothèque fournie par le fournisseur et chargée dans le compilateur bcc
. Étant donné que bcc
est un processus système dans le répertoire /system/bin
, la bibliothèque bcc plugin
peut être considérée comme une SP-HAL (c'est-à-dire une HAL du fournisseur qui peut être directement chargée dans le processus système sans être binderisée). En tant que SP-HAL, la bibliothèque bcc-plugin
:
- Vous ne pouvez pas créer de lien vers des bibliothèques de framework uniquement, telles que
libLLVM.so
. - Il ne peut être associé qu'aux bibliothèques VNDK-SP disponibles pour le fournisseur.
Cette restriction est appliquée en chargeant bcc plugin
dans l'espace de noms sphal
à l'aide de la fonction android_sphal_load_library()
. Dans les versions précédentes d'Android, le nom du plug-in était spécifié à l'aide de l'option -load
et la bibliothèque était chargée à l'aide du simple dlopen()
par libLLVM.so
. Dans Android 8.0 ou version ultérieure, cette option est spécifiée dans l'option -plugin
et la bibliothèque est directement chargée par bcc
lui-même. Cette option permet d'accéder à un chemin d'accès non spécifique à Android vers le projet LLVM Open Source.

Figure 5. Chargement du plug-in bcc, Android 7.x et versions antérieures.

Figure 6. Chargement du plug-in bcc, Android 8.0 et versions ultérieures.
Chemins de recherche pour ld.mc
Lors de l'exécution de ld.mc
, certaines bibliothèques d'exécution RS sont fournies en tant qu'entrées au linker. Le bitcode RS de l'application est lié aux bibliothèques d'exécution. Lorsque le bitcode converti est chargé dans un processus d'application, les bibliothèques d'exécution sont à nouveau liées dynamiquement à partir du bitcode converti.
Les bibliothèques d'exécution incluent :
libcompiler_rt.so
libm.so
libc.so
- Pilote RS (
libRSDriver.so
ouOVERRIDE_RS_DRIVER
)
Lorsque vous chargez le bitcode compilé dans le processus de l'application, fournissez exactement la même bibliothèque que celle utilisée par ld.mc
. Sinon, le bitcode compilé risque de ne pas trouver un symbole qui était disponible lors de sa liaison.
Pour ce faire, le framework RS utilise différents chemins de recherche pour les bibliothèques d'exécution lors de l'exécution de ld.mc
, selon que le framework RS lui-même est chargé à partir de /system/lib
ou de /system/lib/vndk-sp
.
Pour ce faire, lisez l'adresse d'un symbole arbitraire d'une bibliothèque de framework RS et utilisez dladdr()
pour obtenir le chemin d'accès au fichier mappé à l'adresse.
Règle SELinux
En raison des modifications apportées aux règles SELinux dans Android 8.0 et versions ultérieures, vous devez suivre des règles spécifiques (appliquées via neverallows
) lorsque vous ajoutez des libellés à des fichiers dans la partition vendor
:
vendor_file
doit être le libellé par défaut pour tous les fichiers de la partitionvendor
. La règle de la plate-forme exige cela pour accéder aux implémentations HAL pass-through.- Tous les nouveaux
exec_types
ajoutés dans la partitionvendor
via la SEPolicy du fournisseur doivent avoir l'attributvendor_file_type
. Cela est appliqué par le biais deneverallows
. - Pour éviter les conflits avec les futures mises à jour de la plate-forme/du framework, évitez de libeller les fichiers autres que
exec_types
dans la partitionvendor
. - Toutes les dépendances de bibliothèque pour les HAL de même processus identifiés par l'AOSP doivent être étiquetées
same_process_hal_file
.
Pour en savoir plus sur la stratégie SELinux, consultez Security-Enhanced Linux dans Android.
Compatibilité ABI pour le bitcode
Si aucune nouvelle API n'est ajoutée, ce qui signifie qu'aucune version HAL n'est mise à jour, les frameworks RS continueront d'utiliser le pilote GPU existant (HAL 1.0).
Pour les modifications mineures de HAL (HAL 1.1) n'affectant pas le bitcode, les frameworks doivent revenir au processeur pour ces API nouvellement ajoutées et continuer à utiliser le pilote GPU (HAL 1.0) ailleurs.
Pour les modifications majeures de HAL (HAL 2.0) affectant la compilation/l'association de bitcode, les frameworks RS ne doivent pas charger les pilotes GPU fournis par le fournisseur et doivent plutôt utiliser le chemin d'accès CPU ou Vulkan pour l'accélération.
La consommation de bitcode RenderScript se déroule en trois étapes :
Scène | Détails |
---|---|
Compiler |
|
Lien |
|
Charger |
|
En plus de la HAL, les API d'exécution et les symboles exportés sont également des interfaces. Aucune des deux interfaces n'a changé depuis Android 7.0 (API 24) et il n'est pas prévu de les modifier dans Android 8.0 et les versions ultérieures. Toutefois, si l'interface change, la version HAL sera également incrémentée.
Implémentations par les fournisseurs
Android 8.0 et versions ultérieures nécessitent certaines modifications du pilote GPU pour que celui-ci fonctionne correctement.
Modules de pilote
- Les modules de pilotes ne doivent dépendre d'aucune bibliothèque système qui ne figure pas dans la liste.
- Le pilote doit fournir son propre
android.hardware.renderscript@1.0-impl_{NAME}
ou déclarer l'implémentation par défautandroid.hardware.renderscript@1.0-impl
comme dépendance. - L'implémentation du processeur
libRSDriver.so
est un bon exemple de la façon de supprimer les dépendances non-VNDK-SP.
Compilateur Bitcode
Vous pouvez compiler le bitcode RenderScript pour le pilote du fournisseur de deux manières :
- Invoquez le compilateur RenderScript spécifique au fournisseur dans
/vendor/bin/
(méthode de compilation GPU recommandée). Comme les autres modules de pilote, le binaire du compilateur du fournisseur ne peut dépendre d'aucune bibliothèque système qui ne figure pas dans la liste des bibliothèques RenderScript disponibles pour les fournisseurs. - Appelez le système Ccn :
/system/bin/bcc
avec unbcc plugin
fourni par le fournisseur. Ce plug-in ne peut dépendre d'aucune bibliothèque système qui ne figure pas dans la liste des bibliothèques RenderScript disponibles pour les fournisseurs.
Si le fournisseur bcc plugin
doit interférer avec la compilation du processeur et que sa dépendance à libLLVM.so
ne peut pas être facilement supprimée, il doit copier bcc
(et toutes les dépendances non-LL-NDK, y compris libLLVM.so
et libbcc.so
) dans la partition /vendor
.
De plus, les fournisseurs doivent apporter les modifications suivantes :

Figure 7. Modifications apportées au pilote du fournisseur.
- Copiez
libclcore.bc
dans la partition/vendor
. Cela permet de s'assurer quelibclcore.bc
,libLLVM.so
etlibbcc.so
sont synchronisés. - Modifiez le chemin d'accès à l'exécutable
bcc
en définissantRsdCpuScriptImpl::BCC_EXE_PATH
à partir de l'implémentation RS HAL.
Règle SELinux
La règle SELinux affecte à la fois les exécutables du pilote et du compilateur. Tous les modules de pilote doivent être étiquetés same_process_hal_file
dans le file_contexts
de l'appareil. Exemple :
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
L'exécutable du compilateur doit pouvoir être appelé par un processus d'application, tout comme la copie du fournisseur de bcc (/vendor/bin/bcc
). Par exemple :
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Anciens appareils
Les anciens appareils sont ceux qui remplissent les conditions suivantes :
- PRODUCT_SHIPPING_API_LEVEL est inférieur à 26.
- PRODUCT_FULL_TREBLE_OVERRIDE n'est pas défini.
Pour les anciens appareils, les restrictions ne sont pas appliquées lors de la mise à niveau vers Android 8.0 ou version ultérieure. Cela signifie que les pilotes peuvent continuer à établir un lien vers les bibliothèques dans /system/lib[64]
. Toutefois, en raison du changement d'architecture lié à OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
doit être installé dans la partition /vendor
. Si ce n'est pas le cas, l'environnement d'exécution RenderScript est forcé de revenir au chemin d'accès du processeur.
Pour en savoir plus sur les raisons de l'abandon de Renderscript, consultez le blog Android Developers : Android GPU Compute Going Forward. Les informations sur les ressources pour cet abandon incluent les éléments suivants :
- Migrer depuis RenderScript
- Exemple RenderScriptMigration
- README du kit de remplacement des fonctionnalités intrinsèques
- Intrinsics ReplacementToolkit.kt