RenderScript est un framework permettant d'exécuter des tâches gourmandes en calcul à hautes performances sur Android. Il est conçu pour être utilisé avec le calcul parallèle aux données, bien que les charges de travail en série puissent également en bénéficier. Le runtime RenderScript parallélise le travail sur les processeurs disponibles sur un appareil, tels que les processeurs multicœurs et les GPU, permettant aux développeurs de se concentrer sur l'expression des algorithmes plutôt que sur la planification du travail. RenderScript est particulièrement utile pour les applications effectuant du traitement d'images, de la photographie informatique ou de la vision par ordinateur.
Les appareils exécutant Android 8.0 et versions ultérieures utilisent le framework RenderScript et les HAL des fournisseurs suivants :
Les différences par rapport à RenderScript dans Android 7.x et versions antérieures incluent :
- 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 concerne le chemin du GPU et provient de/system/lib/vndk-sp
. - Les bibliothèques internes RS dans
/system/lib
sont construites dans le cadre de la plate-forme et sont mises à jour à mesure quesystem.img
est mis à niveau. Cependant, les bibliothèques dans/system/lib/vndk-sp
sont créées pour le fournisseur et ne sont pas mises à jour lorsquesystem.img
est mis à niveau (bien qu'elles puissent être mises à jour pour un correctif de sécurité, leur ABI reste le même). - Le code du fournisseur (RS HAL, le pilote RS et le
bcc plugin
) sont liés aux bibliothèques internes RenderScript situées dans/system/lib/vndk-sp
. Ils ne peuvent pas établir de lien avec les bibliothèques de/system/lib
car les bibliothèques de ce répertoire sont construites pour la plate-forme et peuvent donc ne pas être compatibles avec le code du fournisseur (c'est-à-dire que les symboles peuvent être supprimés). Cela rendrait impossible une OTA uniquement basée sur un cadre.
Conception
Les sections suivantes détaillent la conception de RenderScript dans Android 8.0 et versions ultérieures.
Bibliothèques RenderScript disponibles pour les fournisseurs
Cette section répertorie les bibliothèques RenderScript (appelées Vendor NDK pour Same-Process HAL ou VNDK-SP) qui sont disponibles pour le code du fournisseur et qui peuvent être liées. Il détaille également des 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 différer d'une version d'Android à l'autre, elle est immuable pour une version d'Android spécifique ; pour une liste à jour des bibliothèques disponibles, reportez-vous à /system/etc/ld.config.txt
.
Bibliothèques RenderScript | Bibliothèques non RenderScript |
---|---|
|
|
Configuration de l'espace de noms de l'éditeur de liens
La restriction de liaison qui empêche les bibliothèques ne figurant pas dans VNDK-SP d'être utilisées par le code du fournisseur est appliquée au moment de l'exécution à l'aide de l'espace de noms de l'éditeur de liens. (Pour plus de détails, reportez-vous à la présentation VNDK Design .)
Sur un appareil exécutant Android 8.0 et versions ultérieures, tous les HAL de même processus (SP-HAL), à l'exception de RenderScript, sont chargés dans l'espace de noms de l'éditeur de liens sphal
. RenderScript est chargé dans l'espace de noms spécifique à RenderScript rs
, un emplacement qui permet une application légèrement plus souple pour les bibliothèques RenderScript. Étant donné que l'implémentation RS doit charger le bitcode compilé, /data/*/*.so
est ajouté au chemin 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 celles fournies par 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 envers ces bibliothèques.
Chargement des pilotes
Chemin de secours du processeur
En fonction de l'existence du bit RS_CONTEXT_LOW_LATENCY
lors de la création d'un contexte RS, soit le chemin CPU soit le chemin GPU est sélectionné. Lorsque le chemin CPU est sélectionné, libRS_internal.so
(l'implémentation principale du framework RS) est directement dlopen
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 utilisée du tout lorsque le chemin de secours du processeur est emprunté et qu'un objet RsContext
est créé avec null mVendorDriverName
. libRSDriver.so
est (par défaut) dlopen
et la bibliothèque du pilote 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
.
Chemin du GPU
Pour le chemin GPU, libRS_internal.so
est chargé différemment. Tout d'abord, libRS.so
utilise android.hardware.renderscript@1.0.so
(et son sous-jacent libhidltransport.so
) pour charger android.hardware.renderscript@1.0-impl.so
(une implémentation fournisseur de RS HAL) dans un espace de noms d'éditeur de liens différent appelé sphal
. Le RS HAL 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 temps de construction OVERRIDE_RS_DRIVER
, qui est intégré dans 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 GPU.
La création de l'objet RsContext
est déléguée à l'implémentation RS HAL. Le HAL rappelle le framework RS en utilisant la fonction rsContextCreateVendor()
avec le nom du pilote à utiliser comme argument. Le framework RS charge ensuite le pilote spécifié lorsque le RsContext
est initialisé. 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.
Lors de la transition de l'espace de noms default
à l'espace de noms sphal
, libhidltransport.so
utilise la fonction android_load_sphal_library()
pour ordonner explicitement à l'éditeur de liens dynamique de charger la bibliothèque -impl.so
à partir de l'espace de noms sphal
.
Lors de la transition de l'espace de noms sphal
vers l'espace de noms rs
, le chargement se fait indirectement par la ligne suivante dans /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Cette ligne spécifie que l'éditeur de liens dynamique doit charger libRS_internal.so
à partir de l'espace de noms rs
lorsque la bibliothèque ne peut pas être trouvée/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ù libRS_internal.so
réside). Avec cette configuration, un simple appel dlopen()
à libRS_internal.so
suffit pour effectuer la transition d'espace de noms.
Chargement du plugin Cci
bcc plugin
est une bibliothèque fournie par le fournisseur chargée dans le compilateur bcc
. Parce que bcc
est un processus système dans le répertoire /system/bin
, la bibliothèque bcc plugin
peut être considérée comme un SP-HAL (c'est-à-dire un HAL du fournisseur qui peut être directement chargé dans le processus système sans être lié). En tant que SP-HAL, la bibliothèque bcc-plugin
:
- Impossible de créer un lien avec des bibliothèques uniquement framework telles que
libLLVM.so
. - Peut être lié uniquement aux bibliothèques VNDK-SP disponibles pour le fournisseur.
Cette restriction est appliquée en chargeant le 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 plugin était spécifié à l'aide de l'option -load
et la bibliothèque était chargée à l'aide du simple dlopen()
par libLLVM.so
. Sous Android 8.0 et versions ultérieures, cela est spécifié dans l'option -plugin
et la bibliothèque est directement chargée par le bcc
lui-même. Cette option active un chemin non spécifique à Android vers le projet open source LLVM.
Chemins de recherche pour ld.mc
Lors de l'exécution ld.mc
, certaines bibliothèques d'exécution RS sont fournies comme entrées à l'éditeur de liens. Le bitcode RS de l'application est lié aux bibliothèques d'exécution et 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 (soit
libRSDriver.so
ouOVERRIDE_RS_DRIVER
)
Lors du chargement du bitcode compilé dans le processus d'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 ld.mc
, selon que le framework RS lui-même est chargé depuis /system/lib
ou depuis /system/lib/vndk-sp
. Cela peut être déterminé en lisant l'adresse d'un symbole arbitraire d'une bibliothèque de framework RS et en utilisant dladdr()
pour obtenir le chemin du fichier mappé à l'adresse.
Politique SELinux
En raison des changements de politique SELinux dans Android 8.0 et versions ultérieures, vous devez suivre des règles spécifiques (appliquées via neverallows
) lors de l'étiquetage de fichiers supplémentaires dans la partition vendor
:
-
vendor_file
doit être l'étiquette par défaut pour tous les fichiers de la partitionvendor
. La politique de la plate-forme l’exige pour accéder aux implémentations passthrough HAL. - Tous les nouveaux
exec_types
ajoutés dans la partitionvendor
via SEPolicy du fournisseur doivent avoir l'attributvendor_file_type
. Ceci est appliqué vianeverallows
. - Pour éviter les conflits avec les futures mises à jour de la plate-forme/du framework, évitez d'étiqueter 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 AOSP doivent être étiquetées comme
same_process_hal_file
.
Pour plus de détails sur la politique SELinux, consultez Linux à sécurité améliorée sous Android .
Compatibilité ABI pour le bitcode
Si aucune nouvelle API n'est ajoutée, ce qui signifie qu'il n'y a pas de changement de version HAL, les frameworks RS continueront à 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 recourir au CPU 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/liaison de bitcode, les frameworks RS doivent choisir de ne pas charger les pilotes GPU fournis par le fournisseur et d'utiliser à la place le chemin CPU ou Vulkan pour l'accélération.
La consommation du bitcode RenderScript se déroule en trois étapes :
Scène | Détails |
---|---|
Compiler |
|
Lien |
|
Charger |
|
En plus du 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 dans l'immédiat de la modifier dans Android 8.0 et au-delà. Cependant, si l'interface change, la version HAL augmentera également.
Implémentations des fournisseurs
Android 8.0 et versions ultérieures nécessitent certaines modifications du pilote GPU pour que le pilote GPU fonctionne correctement.
Modules pilotes
- Les modules 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 de codes binaires
Vous pouvez compiler le bitcode RenderScript pour le pilote du fournisseur de deux manières :
- Appelez le compilateur RenderScript spécifique au fournisseur dans
/vendor/bin/
(méthode préférée de compilation GPU). Semblable à d'autres modules de pilotes, 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 bcc :
/system/bin/bcc
avec unbcc plugin
fourni par le fournisseur ; ce plugin 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 bcc plugin
du fournisseur doit interférer avec la compilation du processeur et que sa dépendance sur libLLVM.so
ne peut pas être facilement supprimée, le fournisseur doit copier bcc
(et toutes les dépendances non LL-NDK, y compris libLLVM.so
, libbcc.so
) dans /vendor
.
De plus, les fournisseurs doivent apporter les modifications suivantes :
- Copiez
libclcore.bc
sur la partition/vendor
. Cela garantit 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.
Politique SELinux
La politique 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
du périphérique. Par exemple:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
L'exécutable du compilateur doit pouvoir être invoqué 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
Appareils hérités
Les appareils existants sont ceux qui satisfont aux conditions suivantes :
- PRODUCT_SHIPPING_API_LEVEL est inférieur à 26.
- PRODUCT_FULL_TREBLE_OVERRIDE n'est pas défini.
Pour les appareils existants, les restrictions ne sont pas appliquées lors de la mise à niveau vers Android 8.0 et versions ultérieures, ce qui signifie que les pilotes peuvent continuer à être liés aux bibliothèques dans /system/lib[64]
. Cependant, en raison du changement d'architecture lié à OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
doit être installé sur la partition /vendor
; à défaut de le faire, le temps d'exécution de RenderScript se replie sur le chemin du processeur.
Pour plus d'informations sur la motivation de l'abandon de Renderscript, consultez le blog des développeurs Android : Android GPU Compute Going Forward . Les informations sur les ressources pour cette dépréciation incluent les éléments suivants :
- Migrer depuis Renderscript
- Exemple de migration RenderScript
- Boîte à outils de remplacement intrinsèque README
- Toolkit de remplacement intrinsèque.kt