RenderScript ist ein Framework zum Ausführen rechenintensiver Aufgaben mit hoher Leistung auf Android-Geräten. Sie wurde für die Verwendung mit datenparrallel arbeitenden Berechnungen entwickelt, kann aber auch für serielle Arbeitslasten genutzt werden. Die RenderScript-Laufzeit parallelisiert die Arbeit auf allen auf einem Gerät verfügbaren Prozessoren, z. B. auf Mehrkern-CPUs und GPUs. So können sich Entwickler darauf konzentrieren, Algorithmen zu erstellen, anstatt Aufgaben zu planen. RenderScript ist besonders nützlich für Apps, die Bildverarbeitung, Computerfotografie oder Computer Vision nutzen.
Auf Geräten mit Android 8.0 und höher werden das folgende RenderScript-Framework und die folgenden HALs von Anbietern verwendet:

Abbildung 1: Anbietercode, der mit internen libs verknüpft ist.
Zu den Unterschieden zu RenderScript in Android 7.x und niedriger gehören:
- Zwei Instanzen von internen RenderScript-Bibliotheken in einem Prozess. Eine Gruppe ist für den CPU-Fallbackpfad und beginnt direkt bei
/system/lib
. Die andere Gruppe ist für den GPU-Pfad und beginnt bei/system/lib/vndk-sp
. - Interne RS-Bibliotheken in
/system/lib
werden als Teil der Plattform erstellt und bei der Umstellung vonsystem.img
aktualisiert. Die/system/lib/vndk-sp
-Bibliotheken werden jedoch für den Anbieter erstellt und nicht aktualisiert, wennsystem.img
aktualisiert wird. Sie können zwar für eine Sicherheitskorrektur aktualisiert werden, ihr ABI bleibt jedoch gleich. - Der Anbietercode (RS HAL, RS-Treiber und
bcc plugin
) ist mit den internen RenderScript-Bibliotheken unter/system/lib/vndk-sp
verknüpft. Sie können nicht mit Bibliotheken in/system/lib
verknüpft werden, da Bibliotheken in diesem Verzeichnis für die Plattform erstellt werden und daher möglicherweise nicht mit dem Anbietercode kompatibel sind (d.h. Symbole werden möglicherweise entfernt). Andernfalls wäre eine OTA-Aktualisierung nur über das Framework nicht möglich.
Design
In den folgenden Abschnitten wird das RenderScript-Design in Android 8.0 und höher beschrieben.
RenderScript-Bibliotheken für Anbieter verfügbar
In diesem Abschnitt sind die RenderScript-Bibliotheken (Vendor NDK for Same-Process HALs oder VNDK-SP) aufgeführt, die für Anbietercode verfügbar sind und mit denen eine Verknüpfung hergestellt werden kann. Außerdem werden zusätzliche Bibliotheken aufgeführt, die nichts mit RenderScript zu tun haben, aber auch für Anbietercode bereitgestellt werden.
Die folgende Liste der Bibliotheken kann sich zwischen Android-Releases unterscheiden, ist aber für einen bestimmten Android-Release unveränderlich. Eine aktuelle Liste der verfügbaren Bibliotheken finden Sie unter /system/etc/ld.config.txt
.
RenderScript-Bibliotheken | Nicht RenderScript-Bibliotheken |
---|---|
|
|
Konfiguration des Linker-Namespaces
Die Verknüpfungsbeschränkung, die verhindert, dass ‑Libs, die nicht in VNDK-SP enthalten sind, von Anbietercode verwendet werden, wird zur Laufzeit mithilfe des Linker-Namespace erzwungen. Weitere Informationen finden Sie in der Präsentation VNDK Design.
Auf einem Gerät mit Android 8.0 oder höher werden alle SP-HALs (Same-Process HALs, HALs mit demselben Prozess) mit Ausnahme von RenderScript im Linker-Namespace sphal
geladen. RenderScript wird in den RenderScript-spezifischen Namespace rs
geladen. An diesem Speicherort ist die Durchsetzung für RenderScript-Bibliotheken etwas lockerer. Da die RS-Implementierung den kompilierten Bitcode laden muss, wird /data/*/*.so
dem Pfad des rs
-Namespace hinzugefügt. Andere SP-HALs dürfen keine Bibliothken aus der Datenpartition laden.
Außerdem sind im rs
-Namespace mehr Bibliotheken zulässig als in anderen Namespaces. libmediandk.so
und libft2.so
sind für den rs
-Namespace verfügbar, da libRS_internal.so
eine interne Abhängigkeit von diesen Bibliotheken hat.

Abbildung 2: Namespace-Konfiguration für den Linker.
Treiber laden
CPU-Fallback-Pfad
Je nachdem, ob das RS_CONTEXT_LOW_LATENCY
-Bit beim Erstellen eines RS-Kontexts vorhanden ist, wird entweder der CPU- oder der GPU-Pfad ausgewählt. Wenn der CPU-Pfad ausgewählt ist, wird libRS_internal.so
(die Hauptimplementierung des RS-Frameworks) direkt aus dem Standardlinker-Namespace dlopen
ed, in dem die Plattformversion der RS-Bibliotheken bereitgestellt wird.
Die RS HAL-Implementierung des Anbieters wird nicht verwendet, wenn der CPU-Fallbackpfad verwendet wird, und ein RsContext
-Objekt wird mit null mVendorDriverName
erstellt. libRSDriver.so
wird standardmäßig dlopen
ed und die Treiberbibliothek wird aus dem Namespace default
geladen, da auch der Aufrufer (libRS_internal.so
) im Namespace default
geladen wird.

Abbildung 3: CPU-Fallback-Pfad.
GPU-Pfad
Für den GPU-Pfad wird die libRS_internal.so
anders geladen.
Zuerst verwendet libRS.so
android.hardware.renderscript@1.0.so
(und die zugrunde liegende libhidltransport.so
), um android.hardware.renderscript@1.0-impl.so
(eine Anbieterimplementierung der RS HAL) in einen anderen Linker-Namespace namens sphal
zu laden. Die RS-HAL dlopen
s libRS_internal.so
dann in einem anderen Linker-Namespace namens rs
.
Anbieter können ihren eigenen RS-Treiber bereitstellen, indem sie das Buildzeit-Flag OVERRIDE_RS_DRIVER
festlegen, das in die RS HAL-Implementierung (hardware/interfaces/renderscript/1.0/default/Context.cpp
) eingebettet ist. Dieser Treibername wird dann für den RS-Kontext für den GPU-Pfad dlopen
ed.
Die Erstellung des RsContext
-Objekts wird an die RS HAL-Implementierung delegiert. Die HAL ruft das RS-Framework mit der Funktion rsContextCreateVendor()
auf und übergibt den Namen des Treibers als Argument. Das RS-Framework lädt dann den angegebenen Treiber, wenn RsContext
initialisiert wird. In diesem Fall wird die Treiberbibliothek in den Namespace rs
geladen, da das RsContext
-Objekt im Namespace rs
erstellt wird und /vendor/lib
sich im Suchpfad des Namespace befindet.

Abbildung 4: GPU-Fallback-Pfad.
Bei der Umstellung vom Namespace default
auf den Namespace sphal
weist libhidltransport.so
den dynamischen Linker über die Funktion android_load_sphal_library()
ausdrücklich an, die -impl.so
-Bibliothek aus dem Namespace sphal
zu laden.
Beim Übergang vom Namespace sphal
zum Namespace rs
erfolgt das Laden indirekt über die folgende Zeile in /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
In dieser Zeile wird angegeben, dass der dynamische Linker libRS_internal.so
aus dem Namespace rs
laden soll, wenn die Bibliothek nicht im Namespace sphal
gefunden oder geladen werden kann. Das ist immer der Fall, da im Namespace sphal
nicht nach /system/lib/vndk-sp
gesucht wird, wo sich libRS_internal.so
befindet. Bei dieser Konfiguration reicht ein einfacher dlopen()
-Aufruf an libRS_internal.so
aus, um den Namespace zu wechseln.
Bcc-Plug-in laden
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 (d.h. als HAL eines Anbieters, die direkt in den Systemprozess geladen werden kann, ohne verbunden zu werden) betrachtet werden. Als SP-HAL bietet die bcc-plugin
-Bibliothek folgende Vorteile:
- Es ist keine Verknüpfung mit Bibliotheken möglich, die nur für das Framework bestimmt sind, z. B.
libLLVM.so
. - Es kann nur mit den VNDK-SP-Bibliotheken verknüpft werden, die dem Anbieter zur Verfügung stehen.
Diese Einschränkung wird erzwungen, indem bcc plugin
mit der Funktion android_sphal_load_library()
in den Namespace sphal
geladen wird. In früheren Versionen von Android wurde der Plug-in-Name mit der Option -load
angegeben und die Lib wurde mit dem einfachen dlopen()
von libLLVM.so
geladen. Unter Android 8.0 und höher wird dies in der Option -plugin
angegeben und die Lib wird direkt von bcc
geladen. Mit dieser Option wird ein nicht Android-spezifischer Pfad zum Open-Source-LLVM-Projekt aktiviert.

Abbildung 5: bcc-Plug-in wird geladen, Android 7.x und niedriger

Abbildung 6 Laden des BCC-Plug-ins, Android 8.0 und höher
Suchpfade für ld.mc
Bei der Ausführung 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. Wenn der konvertierte Bitcode in einen App-Prozess geladen wird, werden die Laufzeitbibliotheken wieder dynamisch über den konvertierten Bitcode verknüpft.
Zu den Laufzeitbibliotheken gehören:
libcompiler_rt.so
libm.so
libc.so
- RS-Treiber (
libRSDriver.so
oderOVERRIDE_RS_DRIVER
)
Wenn Sie den kompilierten Bitcode in den App-Prozess laden, müssen Sie genau dieselbe Bibliothek angeben, die von ld.mc
verwendet wurde. Andernfalls wird im kompilierten Bitcode möglicherweise kein Symbol gefunden, das bei der Verknüpfung verfügbar war.
Dazu verwendet das RS-Framework beim Ausführen von 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.
Dazu wird die Adresse eines beliebigen Symbols einer RS-Framework-Bibliothek gelesen und mit dladdr()
der Dateipfad abgerufen, der der Adresse zugeordnet ist.
SELinux-Richtlinie
Aufgrund der Änderungen an den SELinux-Richtlinien in Android 8.0 und höher müssen Sie beim Beschriften zusätzlicher Dateien in der vendor
-Partition bestimmte Regeln einhalten, die über neverallows
erzwungen werden:
vendor_file
muss das Standardlabel für alle Dateien in dervendor
-Partition sein. Gemäß der Plattformrichtlinie ist dies für den Zugriff auf Passthrough-HAL-Implementierungen erforderlich.- Alle neuen
exec_types
, die über die SEPolicy des Anbieters dervendor
-Partition hinzugefügt werden, müssen das Attributvendor_file_type
haben. Dies wird überneverallows
erzwungen. - Um Konflikte mit zukünftigen Plattform-/Framework-Updates zu vermeiden, sollten Sie in der Partition
vendor
keine anderen Dateien alsexec_types
kennzeichnen. - Alle Bibliotheksabhängigkeiten für von AOSP identifizierte HALs für denselben Prozess müssen als
same_process_hal_file
gekennzeichnet sein.
Weitere Informationen zu SELinux-Richtlinien finden Sie unter Security-Enhanced Linux in Android.
ABI-Kompatibilität für Bitcode
Wenn keine neuen APIs hinzugefügt werden, d. h. keine HAL-Version erhöht wird, 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 den GPU-Treiber (HAL 1.0) an anderer Stelle weiter verwenden.
Bei größeren HAL-Änderungen (HAL 2.0), die sich auf die Bitcode-Kompilierung/-Verknüpfung auswirken, sollten RS-Frameworks keine vom Anbieter bereitgestellten GPU-Treiber laden, sondern stattdessen den CPU- oder Vulkan-Pfad für die Beschleunigung verwenden.
Die Verwendung von RenderScript-Bitcode erfolgt in drei Phasen:
Bühne | Details |
---|---|
Kompilieren |
|
Link |
|
Laden |
|
Neben der HAL sind auch die Laufzeit-APIs und die exportierten Symbole Schnittstellen. Die Benutzeroberfläche hat sich seit Android 7.0 (API 24) nicht geändert und es gibt keine unmittelbaren Pläne, sie in Android 8.0 und höher zu ändern. Wenn sich die Benutzeroberfläche jedoch ändert, wird auch die HAL-Version erhöht.
Anbieterimplementierungen
Unter Android 8.0 und höher sind einige Änderungen am GPU-Treiber erforderlich, damit er ordnungsgemäß funktioniert.
Treibermodule
- Treibermodule dürfen nicht von Systembibliotheken abhängen, die nicht in der Liste enthalten sind.
- Der Treiber muss eine eigene
android.hardware.renderscript@1.0-impl_{NAME}
bereitstellen oder die Standardimplementierungandroid.hardware.renderscript@1.0-impl
als Abhängigkeit deklarieren. - Die CPU-Implementierung
libRSDriver.so
ist ein gutes Beispiel dafür, wie Sie Abhängigkeiten, die nicht zu VNDK-SP gehören, entfernen.
Bitcode-Compiler
Sie haben zwei Möglichkeiten, RenderScript-Bitcode für den Anbietertreiber zu kompilieren:
- Anbieterspezifischen RenderScript-Compiler in
/vendor/bin/
aufrufen (bevorzugte Methode der GPU-Kompilierung) Ähnlich wie bei anderen Treibermodulen darf das Binärprogramm des Anbietercompilers nicht von einer Systembibliothek abhängen, die nicht in der Liste der für Anbieter verfügbaren RenderScript-Bibliotheken enthalten ist. - System-bcc:
/system/bin/bcc
mit einer vom Anbieter bereitgestelltenbcc plugin
aufrufen; dieses Plug-in darf nicht von einer Systembibliothek abhängen, die nicht in der Liste der für Anbieter verfügbaren RenderScript-Bibliotheken enthalten ist.
Wenn der Anbieter bcc plugin
in die CPU-Kompilierung eingreifen muss und seine Abhängigkeit von libLLVM.so
nicht einfach entfernt werden kann, sollte er bcc
(und alle nicht LL-NDK-Abhängigkeiten, einschließlich libLLVM.so
, libbcc.so
) in die Partition /vendor
kopieren.
Außerdem müssen Anbieter die folgenden Änderungen vornehmen:

Abbildung 7. Änderungen am Anbietertreiber.
- Kopieren Sie
libclcore.bc
in die Partition/vendor
. So sindlibclcore.bc
,libLLVM.so
undlibbcc.so
immer synchron. - Ändern Sie den Pfad zur ausführbaren Datei
bcc
, 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 Compiler aus. Alle Treibermodule müssen im file_contexts
des Geräts als same_process_hal_file
gekennzeichnet sein. 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 Anbieterkopie von bcc (/vendor/bin/bcc
). Beispiel:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Ältere Geräte
Zu den Legacy-Geräten gehören Geräte, die die folgenden Bedingungen erfüllen:
- PRODUCT_SHIPPING_API_LEVEL ist kleiner 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. Das bedeutet, dass die Treiber weiterhin mit Bibliotheken in /system/lib[64]
verknüpft werden können. Aufgrund der Architekturänderung im Zusammenhang mit OVERRIDE_RS_DRIVER
muss android.hardware.renderscript@1.0-impl
jedoch in der Partition /vendor
installiert werden. Andernfalls wird die RenderScript-Laufzeit auf den CPU-Pfad zurückgesetzt.
Informationen zu den Gründen 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 Sample
- README für das Intrinsics Replacement Toolkit
- Ersatz für Intrinsics:Toolkit.kt