RenderScript ist ein Framework zum Ausführen rechenintensiver Aufgaben mit hoher Leistung auf Android. Es ist für die Verwendung mit datenparalleler Berechnung konzipiert, obwohl auch serielle Workloads davon profitieren können. Die RenderScript-Laufzeitumgebung parallelisiert die Arbeit aller auf einem Gerät verfügbaren Prozessoren, wie z. B. Multi-Core-CPUs und GPUs, sodass sich Entwickler auf das Ausdrücken von Algorithmen statt auf die Planung von Arbeiten konzentrieren können. RenderScript ist besonders nützlich für Anwendungen zur Bildverarbeitung, Computerfotografie oder Computer Vision.
Geräte mit Android 8.0 und höher verwenden das folgende RenderScript-Framework und die folgenden Anbieter-HALs:
![](https://source.android.com/docs/core/architecture/images/treble_rs_linking.png?authuser=6&hl=de)
Zu den Unterschieden zu RenderScript in Android 7.x und niedriger gehören:
- Zwei Instanzen interner RenderScript-Bibliotheken in einem Prozess. Ein Satz ist für den CPU-Fallback-Pfad und stammt direkt von
/system/lib
; Der andere Satz ist für den GPU-Pfad und stammt aus/system/lib/vndk-sp
. - Interne RS-Bibliotheken in
/system/lib
werden als Teil der Plattform erstellt und aktualisiert, wennsystem.img
aktualisiert wird. Allerdings werden Bibliotheken in/system/lib/vndk-sp
für den Anbieter erstellt und nicht aktualisiert, wennsystem.img
aktualisiert wird (sie können zwar für einen Sicherheitsupdate aktualisiert werden, ihr ABI bleibt jedoch gleich). - Herstellercode (RS HAL, RS-Treiber und das
bcc plugin
) sind mit den internen RenderScript-Bibliotheken verknüpft, die sich unter/system/lib/vndk-sp
befinden. Sie können keine Verknüpfung mit Bibliotheken in/system/lib
herstellen, da Bibliotheken in diesem Verzeichnis für die Plattform erstellt wurden und daher möglicherweise nicht mit dem Herstellercode kompatibel sind (dh Symbole werden möglicherweise entfernt). Dies würde eine reine Framework-OTA unmöglich machen.
Design
In den folgenden Abschnitten wird das RenderScript-Design in Android 8.0 und höher detailliert beschrieben.
Für Anbieter verfügbare RenderScript-Bibliotheken
In diesem Abschnitt werden die RenderScript-Bibliotheken (bekannt als Vendor NDK für Same-Process HALs oder VNDK-SP) aufgeführt, die für Anbietercode verfügbar sind und mit denen verknüpft werden können. Außerdem werden zusätzliche Bibliotheken beschrieben, die nichts mit RenderScript zu tun haben, aber auch dem Code des Anbieters zur Verfügung gestellt werden.
Während sich die folgende Liste der Bibliotheken je nach Android-Version unterscheiden kann, ist sie für eine bestimmte Android-Version unveränderlich. Eine aktuelle Liste der verfügbaren Bibliotheken finden Sie unter /system/etc/ld.config.txt
.
RenderScript-Bibliotheken | Nicht-RenderScript-Bibliotheken |
---|---|
|
|
Linker-Namespace-Konfiguration
Die Verknüpfungseinschränkung, die verhindert, dass Bibliotheken, die nicht in VNDK-SP enthalten sind, vom Herstellercode verwendet werden, wird zur Laufzeit mithilfe des Linker-Namespace erzwungen. (Einzelheiten finden Sie in der VNDK Design- Präsentation.)
Auf einem Gerät mit Android 8.0 und höher werden alle Same-Process HALs (SP-HALs) außer RenderScript in den Linker-Namespace sphal
geladen. RenderScript wird in den RenderScript-spezifischen Namespace rs
geladen, einen Speicherort, der eine etwas lockerere Durchsetzung für RenderScript-Bibliotheken ermöglicht. Da die RS-Implementierung den kompilierten Bitcode laden muss, wird /data/*/*.so
zum Pfad des rs
Namespace hinzugefügt (andere SP-HALs dürfen keine Bibliotheken aus der Datenpartition laden).
Darüber hinaus erlaubt der rs
Namespace mehr Bibliotheken als andere Namespaces bieten. libmediandk.so
und libft2.so
sind dem rs
Namespace ausgesetzt, da libRS_internal.so
eine interne Abhängigkeit zu diesen Bibliotheken aufweist.
![](https://source.android.com/docs/core/architecture/images/treble_rs_namespace.png?authuser=6&hl=de)
Treiber werden geladen
CPU-Fallback-Pfad
Abhängig vom Vorhandensein des Bits RS_CONTEXT_LOW_LATENCY
beim Erstellen eines RS-Kontexts wird entweder der CPU- oder der GPU-Pfad ausgewählt. Wenn der CPU-Pfad ausgewählt wird, wird libRS_internal.so
(die Hauptimplementierung des RS-Frameworks) direkt aus dem Standard-Linker-Namensraum dlopen
, in dem die Plattformversion der RS-Bibliotheken bereitgestellt wird.
Die RS-HAL-Implementierung des Anbieters wird überhaupt nicht verwendet, wenn der CPU-Fallback-Pfad verwendet wird, und ein RsContext
Objekt mit null mVendorDriverName
erstellt wird. libRSDriver.so
ist (standardmäßig) dlopen
und die Treiberbibliothek wird aus dem default
Namespace geladen, da der Aufrufer ( libRS_internal.so
) auch im default
Namespace geladen wird.
![](https://source.android.com/docs/core/architecture/images/treble_rs_cpu_fallback.png?authuser=6&hl=de)
GPU-Pfad
Für den GPU-Pfad wird libRS_internal.so
anders geladen. Erstens verwendet libRS.so
android.hardware.renderscript@1.0.so
(und das zugrunde liegende libhidltransport.so
), um android.hardware.renderscript@1.0-impl.so
(eine Herstellerimplementierung von RS HAL) in einen anderen Linker-Namespace namens zu laden sphal
. Die RS-HAL dlopen
dann libRS_internal.so
in einem anderen Linker-Namespace namens rs
.
Anbieter können ihren eigenen RS-Treiber bereitstellen, indem sie das Build-Time-Flag OVERRIDE_RS_DRIVER
setzen, das in die RS-HAL-Implementierung eingebettet ist ( hardware/interfaces/renderscript/1.0/default/Context.cpp
). Dieser Treibername wird dann für den RS-Kontext für den GPU-Pfad dlopen
.
Die Erstellung des RsContext
Objekts wird an die RS-HAL-Implementierung delegiert. Der HAL ruft mit der Funktion rsContextCreateVendor()
mit dem Namen des zu verwendenden Treibers als Argument an das RS-Framework zurück. Das RS-Framework lädt dann den angegebenen Treiber, wenn der RsContext
initialisiert wird. In diesem Fall wird die Treiberbibliothek in den rs
Namespace geladen, da das RsContext
Objekt innerhalb des rs
Namespace erstellt wird und sich /vendor/lib
im Suchpfad des Namespace befindet.
![](https://source.android.com/docs/core/architecture/images/treble_rs_gpu_fallback.png?authuser=6&hl=de)
Beim Übergang vom default
Namespace zum sphal
Namespace verwendet libhidltransport.so
die Funktion android_load_sphal_library()
, um den dynamischen Linker explizit anzuweisen, die Bibliothek -impl.so
aus dem sphal
Namespace zu laden.
Beim Übergang vom sphal
Namespace zum rs
Namespace erfolgt das Laden indirekt über die folgende Zeile in /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Diese Zeile gibt an, dass der dynamische Linker libRS_internal.so
aus dem rs
-Namespace laden soll, wenn die Bibliothek nicht im sphal
Namespace gefunden/geladen werden kann (was immer der Fall ist, da sphal
Namespace nicht nach /system/lib/vndk-sp
sucht libRS_internal.so
liegt). Bei dieser Konfiguration reicht ein einfacher dlopen()
-Aufruf an libRS_internal.so
aus, um den Namespace-Übergang durchzuführen.
Bcc-Plugin wird geladen
bcc plugin
ist eine vom Anbieter bereitgestellte Bibliothek, die in den bcc
Compiler geladen wird. Da bcc
ein Systemprozess im Verzeichnis /system/bin
ist, kann die bcc plugin
Bibliothek als SP-HAL betrachtet werden (d. h. als Anbieter-HAL, der direkt in den Systemprozess geladen werden kann, ohne gebunden zu werden). Als SP-HAL ist die bcc-plugin
Bibliothek:
- Eine Verknüpfung mit reinen Framework-Bibliotheken wie
libLLVM.so
ist nicht möglich. - Kann nur mit den VNDK-SP-Bibliotheken verknüpft werden, die dem Anbieter zur Verfügung stehen.
Diese Einschränkung wird erzwungen, indem das bcc plugin
mithilfe der Funktion android_sphal_load_library()
in den sphal
Namespace geladen wird. In früheren Android-Versionen wurde der Plugin-Name mit der Option -load
angegeben und die Bibliothek wurde mit dem einfachen dlopen()
von libLLVM.so
geladen. In Android 8.0 und höher wird dies in der Option -plugin
angegeben und die Bibliothek wird direkt vom bcc
selbst geladen. Diese Option ermöglicht einen nicht Android-spezifischen Pfad zum Open-Source-LLVM-Projekt.
![](https://source.android.com/docs/core/architecture/images/treble_rs_bcc_plugin_old.png?authuser=6&hl=de)
![](https://source.android.com/docs/core/architecture/images/treble_rs_bcc_plugin_new.png?authuser=6&hl=de)
Suchpfade für ld.mc
Beim Ausführen von ld.mc
werden einige RS-Laufzeitbibliotheken als Eingaben an den Linker übergeben. Der RS-Bitcode aus der App wird mit den Laufzeitbibliotheken verknüpft und wenn der konvertierte Bitcode in einen App-Prozess geladen wird, werden die Laufzeitbibliotheken erneut dynamisch aus dem konvertierten Bitcode verknüpft.
Zu den Laufzeitbibliotheken gehören:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- RS-Treiber (entweder
libRSDriver.so
oderOVERRIDE_RS_DRIVER
)
Stellen Sie beim Laden des kompilierten Bitcodes in den App-Prozess genau dieselbe Bibliothek bereit, die von ld.mc
verwendet wurde. Andernfalls findet der kompilierte Bitcode möglicherweise kein Symbol, das zum Zeitpunkt der Verknüpfung verfügbar war.
Zu diesem Zweck verwendet das RS-Framework beim Ausführen ld.mc
unterschiedliche Suchpfade für die Laufzeitbibliotheken, je nachdem, ob das RS-Framework selbst von /system/lib
oder von /system/lib/vndk-sp
geladen wird. Dies kann ermittelt werden, indem die Adresse eines beliebigen Symbols einer RS-Framework-Bibliothek gelesen und dladdr()
verwendet wird, um den der Adresse zugeordneten Dateipfad abzurufen.
SELinux-Richtlinie
Aufgrund der SELinux-Richtlinienänderungen in Android 8.0 und höher müssen Sie beim Kennzeichnen zusätzlicher Dateien in vendor
bestimmte Regeln befolgen (durchgesetzt durch neverallows
):
-
vendor_file
muss die Standardbezeichnung für alle Dateien invendor
Partition sein. Die Plattformrichtlinie erfordert dies, um auf Passthrough-HAL-Implementierungen zuzugreifen. - Alle neuen
exec_types
, die über die Vendor-SEPolicy in dervendor
Partition hinzugefügt werden, müssen über das Attributvendor_file_type
verfügen. Dies wird durchneverallows
erzwungen. - Um Konflikte mit zukünftigen Plattform-/Framework-Updates zu vermeiden, vermeiden Sie die Kennzeichnung anderer Dateien als
exec_types
in dervendor
. - Alle Bibliotheksabhängigkeiten für AOSP-identifizierte HALs desselben Prozesses müssen als
same_process_hal_file
gekennzeichnet sein.
Einzelheiten zur SELinux-Richtlinie finden Sie unter Security-Enhanced Linux in Android .
ABI-Kompatibilität für Bitcode
Wenn keine neuen APIs hinzugefügt werden, was bedeutet, dass es keinen HAL-Versionssprung gibt, verwenden die RS-Frameworks weiterhin den vorhandenen GPU-Treiber (HAL 1.0).
Bei geringfügigen HAL-Änderungen (HAL 1.1), die sich nicht auf den Bitcode auswirken, sollten die Frameworks für diese neu hinzugefügten APIs auf die CPU zurückgreifen und an anderer Stelle weiterhin den GPU-Treiber (HAL 1.0) verwenden.
Bei größeren HAL-Änderungen (HAL 2.0), die sich auf die Bitcode-Kompilierung/-Verknüpfung auswirken, sollten sich RS-Frameworks dafür entscheiden, keine vom Hersteller bereitgestellten GPU-Treiber zu laden und stattdessen den CPU- oder Vulkan-Pfad zur Beschleunigung zu verwenden.
Der Konsum von RenderScript-Bitcode erfolgt in drei Phasen:
Bühne | Einzelheiten |
---|---|
Kompilieren |
|
Verknüpfung |
|
Belastung |
|
Neben der HAL sind auch Laufzeit-APIs und die exportierten Symbole Schnittstellen. Keine der Schnittstellen hat sich seit Android 7.0 (API 24) geändert und es gibt keine unmittelbaren Pläne, sie in Android 8.0 und höher zu ändern. Wenn sich jedoch die Schnittstelle ändert, wird auch die HAL-Version erhöht.
Anbieterimplementierungen
Android 8.0 und höher erfordert einige GPU-Treiberänderungen, damit der GPU-Treiber ordnungsgemäß funktioniert.
Treibermodule
- Treibermodule dürfen nicht von Systembibliotheken abhängen, die nicht in der Liste aufgeführt sind.
- Der Treiber muss sein eigenes
android.hardware.renderscript@1.0-impl_{NAME}
bereitstellen oder die Standardimplementierungandroid.hardware.renderscript@1.0-impl
als seine Abhängigkeit deklarieren. - Die CPU-Implementierung
libRSDriver.so
ist ein gutes Beispiel dafür, wie Nicht-VNDK-SP-Abhängigkeiten entfernt werden können.
Bitcode-Compiler
Sie können RenderScript-Bitcode für den Herstellertreiber auf zwei Arten kompilieren:
- Rufen Sie den herstellerspezifischen RenderScript-Compiler in
/vendor/bin/
auf (bevorzugte Methode der GPU-Kompilierung). Ähnlich wie bei anderen Treibermodulen kann die Compiler-Binärdatei des Anbieters nicht von einer Systembibliothek abhängen, die nicht in der Liste der für Anbieter verfügbaren RenderScript-Bibliotheken enthalten ist. - Rufen Sie System bcc auf:
/system/bin/bcc
mit einem vom Anbieter bereitgestelltenbcc plugin
. Dieses Plugin kann nicht von einer Systembibliothek abhängen, die nicht in der Liste der für Anbieter verfügbaren RenderScript-Bibliotheken aufgeführt ist.
Wenn das bcc plugin
des Anbieters die CPU-Kompilierung beeinträchtigen muss und seine Abhängigkeit von libLLVM.so
nicht einfach entfernt werden kann, sollte der Anbieter bcc
(und alle Nicht-LL-NDK-Abhängigkeiten, einschließlich libLLVM.so
und libbcc.so
) kopieren /vendor
Partition.
Darüber hinaus müssen Anbieter folgende Änderungen vornehmen:
![](https://source.android.com/docs/core/architecture/images/treble_rs_vendor_driver.png?authuser=6&hl=de)
- Kopieren Sie
libclcore.bc
in die/vendor
Partition. Dadurch wird sichergestellt, dasslibclcore.bc
,libLLVM.so
undlibbcc.so
synchron sind. - Ändern Sie den Pfad zur ausführbaren
bcc
Datei, indem SieRsdCpuScriptImpl::BCC_EXE_PATH
aus der RS HAL-Implementierung festlegen.
SELinux-Richtlinie
Die SELinux-Richtlinie wirkt sich sowohl auf den Treiber als auch auf die ausführbaren Dateien des Compilers aus. Alle Treibermodule müssen im file_contexts
des Geräts same_process_hal_file
gekennzeichnet sein. Zum Beispiel:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
Die ausführbare Compilerdatei muss von einem App-Prozess aufgerufen werden können, ebenso wie die Herstellerkopie von bcc ( /vendor/bin/bcc
). Zum Beispiel:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Ältere Geräte
Legacy-Geräte sind solche, die die folgenden Bedingungen erfüllen:
- PRODUCT_SHIPPING_API_LEVEL ist niedriger als 26.
- PRODUCT_FULL_TREBLE_OVERRIDE ist nicht definiert.
Bei älteren Geräten werden die Einschränkungen beim Upgrade auf Android 8.0 und höher nicht erzwungen, was bedeutet, dass die Treiber weiterhin auf Bibliotheken in /system/lib[64]
verlinken können. Aufgrund der Architekturänderung im Zusammenhang mit OVERRIDE_RS_DRIVER
muss jedoch android.hardware.renderscript@1.0-impl
auf der Partition /vendor
installiert werden; Andernfalls wird ein RenderScript-Laufzeit-Fallback auf den CPU-Pfad erzwungen.
Informationen zur Motivation für die Einstellung von Renderscript finden Sie im Android Developers Blog: Android GPU Compute Going Forward . Zu den Ressourceninformationen für diese Einstellung gehören:
- Von Renderscript migrieren
- RenderScriptMigration-Beispiel
- Intrinsics Replacement Toolkit README
- Intrinsics Replacement Toolkit.kt