RenderScript to framework do wykonywania zadań wymagających dużej mocy obliczeniowej z dużą wydajnością na Androidzie. Jest przeznaczony do stosowania w obliczeniach równoległych do danych, chociaż obciążenia szeregowe również mogą na tym skorzystać. Środowisko wykonawcze RenderScript umożliwia równoległą pracę procesorów dostępnych na urządzeniu, takich jak wielordzeniowe procesory CPU i procesory graficzne, umożliwiając programistom skupienie się na wyrażaniu algorytmów zamiast na planowaniu pracy. RenderScript jest szczególnie przydatny w aplikacjach przetwarzających obrazy, fotografię obliczeniową lub wizję komputerową.
Urządzenia z systemem Android 8.0 i nowszym korzystają z następującej platformy RenderScript i warstw HAL dostawców:
![](https://source.android.com/docs/core/architecture/images/treble_rs_linking.png?authuser=5&hl=pl)
Różnice w stosunku do RenderScript w systemie Android 7.x i starszych obejmują:
- Dwie instancje wewnętrznych bibliotek RenderScript w procesie. Jeden zestaw dotyczy ścieżki awaryjnej procesora i pochodzi bezpośrednio z
/system/lib
; drugi zestaw dotyczy ścieżki GPU i pochodzi z/system/lib/vndk-sp
. - Wewnętrzne biblioteki RS w
/system/lib
są budowane jako część platformy i są aktualizowane w miarę aktualizacjisystem.img
. Jednakże biblioteki w/system/lib/vndk-sp
są zbudowane dla dostawcy i nie są aktualizowane podczas aktualizacjisystem.img
(chociaż można je zaktualizować w celu poprawy bezpieczeństwa, ich ABI pozostaje takie samo). - Kod dostawcy (RS HAL, sterownik RS i
bcc plugin
) są powiązane z wewnętrznymi bibliotekami RenderScript znajdującymi się w/system/lib/vndk-sp
. Nie mogą łączyć się z bibliotekami w/system/lib
, ponieważ biblioteki w tym katalogu są zbudowane dla danej platformy i dlatego mogą nie być kompatybilne z kodem dostawcy (tj. symbole mogą zostać usunięte). Takie postępowanie uniemożliwiłoby OTA oparte wyłącznie na frameworku.
Projekt
W poniższych sekcjach szczegółowo opisano projekt RenderScript w systemie Android 8.0 i nowszych wersjach.
Biblioteki RenderScript dostępne dla dostawców
W tej sekcji wymieniono biblioteki RenderScript (znane jako Vendor NDK dla HAL tego samego procesu lub VNDK-SP), które są dostępne dla kodu dostawcy i z którymi można powiązać. Zawiera także szczegółowe informacje na temat dodatkowych bibliotek, które nie są powiązane z RenderScript, ale które są również dostarczane do kodu dostawcy.
Chociaż poniższa lista bibliotek może się różnić w zależności od wersji Androida, jest ona niezmienna w przypadku konkretnej wersji Androida; aktualna lista dostępnych bibliotek znajduje się w /system/etc/ld.config.txt
.
Biblioteki RenderScript | Biblioteki inne niż RenderScript |
---|---|
|
|
Konfiguracja przestrzeni nazw linkera
Ograniczenie łączenia, które zapobiega używaniu przez kod dostawcy bibliotek spoza VNDK-SP, jest wymuszane w czasie wykonywania przy użyciu przestrzeni nazw konsolidatora. (Szczegółowe informacje można znaleźć w prezentacji VNDK Design .)
Na urządzeniu z systemem Android 8.0 i nowszym wszystkie warstwy HAL tego samego procesu (SP-HAL) z wyjątkiem RenderScript są ładowane w przestrzeni nazw konsolidatora sphal
. RenderScript jest ładowany do specyficznej dla RenderScript przestrzeni nazw rs
, lokalizacji, która umożliwia nieco luźniejsze egzekwowanie bibliotek RenderScript. Ponieważ implementacja RS musi załadować skompilowany kod bitowy, /data/*/*.so
jest dodawany do ścieżki przestrzeni nazw rs
(inne SP-HAL nie mogą ładować bibliotek z partycji danych).
Ponadto przestrzeń nazw rs
umożliwia korzystanie z większej liczby bibliotek, niż jest to przewidziane w innych przestrzeniach nazw. libmediandk.so
i libft2.so
są dostępne w przestrzeni nazw rs
, ponieważ libRS_internal.so
ma wewnętrzną zależność od tych bibliotek.
![](https://source.android.com/docs/core/architecture/images/treble_rs_namespace.png?authuser=5&hl=pl)
Ładowanie sterowników
Ścieżka zastępcza procesora
W zależności od obecności bitu RS_CONTEXT_LOW_LATENCY
podczas tworzenia kontekstu RS wybierana jest ścieżka procesora lub procesora graficznego. Kiedy wybrana jest ścieżka procesora, libRS_internal.so
(główna implementacja frameworka RS) jest bezpośrednio dlopen
z domyślnej przestrzeni nazw linkera, w której dostępna jest platforma bibliotek RS.
Implementacja RS HAL od dostawcy nie jest w ogóle używana, gdy używana jest ścieżka zastępcza procesora i tworzony jest obiekt RsContext
z wartością null mVendorDriverName
. libRSDriver.so
jest (domyślnie) dlopen
, a biblioteka sterownika jest ładowana z default
przestrzeni nazw, ponieważ obiekt wywołujący ( libRS_internal.so
) jest również ładowany w default
przestrzeni nazw.
![](https://source.android.com/docs/core/architecture/images/treble_rs_cpu_fallback.png?authuser=5&hl=pl)
Ścieżka GPU
W przypadku ścieżki GPU plik libRS_internal.so
jest ładowany inaczej. Po pierwsze, libRS.so
używa android.hardware.renderscript@1.0.so
(i bazowej libhidltransport.so
) do załadowania android.hardware.renderscript@1.0-impl.so
(implementacja RS HAL dostawcy) do innej przestrzeni nazw linkera zwanej sphal
. Następnie RS HAL dlopen
s libRS_internal.so
w innej przestrzeni nazw linkera o nazwie rs
.
Dostawcy mogą zapewnić własny sterownik RS, ustawiając flagę czasu kompilacji OVERRIDE_RS_DRIVER
, która jest osadzona w implementacji RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp
). Ta nazwa sterownika jest następnie dlopen
w kontekście RS dla ścieżki GPU.
Tworzenie obiektu RsContext
jest delegowane do implementacji RS HAL. HAL odwołuje się do struktury RS przy użyciu funkcji rsContextCreateVendor()
z nazwą sterownika, która ma być używana jako argument. Struktura RS następnie ładuje określony sterownik po zainicjowaniu RsContext
. W tym przypadku biblioteka sterowników jest ładowana do przestrzeni rs
, ponieważ obiekt RsContext
jest tworzony w przestrzeni rs
, a /vendor/lib
znajduje się w ścieżce wyszukiwania tej przestrzeni nazw.
![](https://source.android.com/docs/core/architecture/images/treble_rs_gpu_fallback.png?authuser=5&hl=pl)
Podczas przejścia z default
przestrzeni nazw do przestrzeni nazw sphal
, libhidltransport.so
używa funkcji android_load_sphal_library()
, aby jawnie nakazać dynamicznemu linkerowi załadowanie biblioteki -impl.so
z przestrzeni nazw sphal
.
Podczas przejścia z przestrzeni nazw sphal
do przestrzeni nazw rs
ładowanie odbywa się pośrednio za pomocą następującego wiersza w /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Ta linia określa, że dynamiczny linker powinien załadować libRS_internal.so
z przestrzeni nazw rs
, gdy nie można znaleźć/załadować biblioteki z przestrzeni nazw sphal
(co zawsze ma miejsce, ponieważ przestrzeń nazw sphal
nie przeszukuje /system/lib/vndk-sp
gdzie znajduje się libRS_internal.so
). W tej konfiguracji proste wywołanie dlopen()
do libRS_internal.so
wystarczy, aby dokonać przejścia przestrzeni nazw.
Ładowanie wtyczki bcc
bcc plugin
to biblioteka dostarczona przez dostawcę, załadowana do kompilatora bcc
. Ponieważ bcc
jest procesem systemowym w katalogu /system/bin
, bibliotekę bcc plugin
można uznać za SP-HAL (tj. warstwę HAL dostawcy, którą można bezpośrednio załadować do procesu systemowego bez tworzenia powiązania). Jako SP-HAL, biblioteka bcc-plugin
:
- Nie można połączyć się z bibliotekami przeznaczonymi wyłącznie dla platformy, takimi jak
libLLVM.so
. - Można łączyć tylko z bibliotekami VNDK-SP dostępnymi dla dostawcy.
To ograniczenie jest wymuszane poprzez załadowanie bcc plugin
do przestrzeni nazw sphal
przy użyciu funkcji android_sphal_load_library()
. W poprzednich wersjach Androida nazwa wtyczki była określana za pomocą opcji -load
, a biblioteka była ładowana za pomocą prostej dlopen()
przez libLLVM.so
. W Androidzie 8.0 i nowszych jest to określone w opcji -plugin
, a biblioteka jest ładowana bezpośrednio przez sam bcc
. Ta opcja włącza ścieżkę inną niż Android do projektu LLVM typu open source.
![](https://source.android.com/docs/core/architecture/images/treble_rs_bcc_plugin_old.png?authuser=5&hl=pl)
![](https://source.android.com/docs/core/architecture/images/treble_rs_bcc_plugin_new.png?authuser=5&hl=pl)
Wyszukaj ścieżki dla ld.mc
Podczas wykonywania ld.mc
niektóre biblioteki wykonawcze RS są podawane jako dane wejściowe do linkera. Kod bitowy RS z aplikacji jest łączony z bibliotekami wykonawczymi, a gdy przekonwertowany kod bitowy jest ładowany do procesu aplikacji, biblioteki wykonawcze są ponownie dynamicznie łączone z przekonwertowanego kodu bitowego.
Biblioteki wykonawcze obejmują:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- Sterownik RS (
libRSDriver.so
lubOVERRIDE_RS_DRIVER
)
Ładując skompilowany kod bitowy do procesu aplikacji, podaj dokładnie tę samą bibliotekę, która była używana przez ld.mc
. W przeciwnym razie skompilowany kod bitowy może nie znaleźć symbolu, który był dostępny w momencie łączenia.
Aby to zrobić, framework RS używa różnych ścieżek wyszukiwania bibliotek wykonawczych podczas wykonywania ld.mc
, w zależności od tego, czy sam framework RS jest ładowany z /system/lib
czy z /system/lib/vndk-sp
. Można to ustalić, czytając adres dowolnego symbolu biblioteki frameworka RS i używając dladdr()
, aby uzyskać odwzorowanie ścieżki pliku na adres.
Polityka SELinuksa
W wyniku zmian zasad SELinux w systemie Android 8.0 i nowszych, musisz przestrzegać określonych zasad (wymuszanych przez neverallows
) podczas oznaczania dodatkowych plików na partycji vendor
:
-
vendor_file
musi być domyślną etykietą dla wszystkich plików w partycjivendor
. Zasady platformy wymagają tego, aby uzyskać dostęp do implementacji warstwy HAL z przekazywaniem. - Wszystkie nowe
exec_types
dodane do partycjivendor
za pośrednictwem SEPolicy dostawcy muszą mieć atrybutvendor_file_type
. Jest to wymuszane poprzezneverallows
. - Aby uniknąć konfliktów z przyszłymi aktualizacjami platformy/frameworka, unikaj etykietowania plików innych niż
exec_types
na partycjivendor
. - Wszystkie zależności bibliotek dla warstw HAL tego samego procesu zidentyfikowanych przez AOSP muszą być oznaczone etykietą
same_process_hal_file
.
Aby uzyskać szczegółowe informacje na temat zasad SELinux, zobacz Linux o zwiększonych zabezpieczeniach w systemie Android .
Zgodność ABI z kodem bitowym
Jeśli nie zostaną dodane żadne nowe interfejsy API, co oznacza brak zmiany wersji HAL, frameworki RS będą nadal korzystać z istniejącego sterownika GPU (HAL 1.0).
W przypadku drobnych zmian HAL (HAL 1.1), które nie wpływają na kod bitowy, frameworki powinny powrócić do procesora dla nowo dodanych interfejsów API i nadal używać sterownika GPU (HAL 1.0) w innym miejscu.
W przypadku głównych zmian HAL (HAL 2.0) wpływających na kompilację/łączenie kodu bitowego, platformy RS powinny zdecydować się nie ładować sterowników GPU dostarczonych przez dostawcę i zamiast tego używać ścieżki CPU lub Vulkan do przyspieszania.
Zużywanie kodu bitowego RenderScript odbywa się w trzech etapach:
Scena | Detale |
---|---|
Skompilować |
|
Połączyć |
|
Obciążenie |
|
Oprócz warstwy HAL interfejsami są także interfejsy API środowiska wykonawczego i eksportowane symbole. Żaden z interfejsów nie uległ zmianie od czasu Androida 7.0 (API 24) i nie ma bezpośrednich planów jego zmiany w Androidzie 8.0 i nowszych wersjach. Jeśli jednak interfejs ulegnie zmianie, wersja HAL również ulegnie zmianie.
Wdrożenia dostawców
Android 8.0 i nowsze wymagają pewnych zmian w sterowniku GPU, aby sterownik GPU działał poprawnie.
Moduły sterowników
- Moduły sterowników nie mogą zależeć od żadnych bibliotek systemowych, których nie ma na liście .
- Sterownik musi dostarczyć własny
android.hardware.renderscript@1.0-impl_{NAME}
lub zadeklarować domyślną implementacjęandroid.hardware.renderscript@1.0-impl
jako swoją zależność. - Implementacja procesora
libRSDriver.so
jest dobrym przykładem usuwania zależności innych niż VNDK-SP.
Kompilator kodu bitowego
Kod bitowy RenderScript dla sterownika dostawcy można skompilować na dwa sposoby:
- Wywołaj kompilator RenderScript specyficzny dla dostawcy w
/vendor/bin/
(preferowana metoda kompilacji GPU). Podobnie jak inne moduły sterowników, plik binarny kompilatora dostawcy nie może zależeć od żadnej biblioteki systemowej, której nie ma na liście bibliotek RenderScript dostępnych dla dostawców . - Wywołaj system bcc:
/system/bin/bcc
za pomocąbcc plugin
dostarczonej przez dostawcę; ta wtyczka nie może zależeć od żadnej biblioteki systemowej, której nie ma na liście bibliotek RenderScript dostępnych dla dostawców .
Jeśli bcc plugin
dostawcy musi zakłócać kompilację procesora i nie można łatwo usunąć jej zależności od libLLVM.so
, sprzedawca powinien skopiować bcc
(i wszystkie zależności inne niż LL-NDK, w tym libLLVM.so
, libbcc.so
) do partycja /vendor
.
Ponadto dostawcy muszą wprowadzić następujące zmiany:
![](https://source.android.com/docs/core/architecture/images/treble_rs_vendor_driver.png?authuser=5&hl=pl)
- Skopiuj
libclcore.bc
na partycję/vendor
. Zapewnia to synchronizacjęlibclcore.bc
,libLLVM.so
ilibbcc.so
. - Zmień ścieżkę do pliku wykonywalnego
bcc
, ustawiającRsdCpuScriptImpl::BCC_EXE_PATH
z implementacji RS HAL.
Polityka SELinuksa
Polityka SELinux dotyczy zarówno sterownika, jak i plików wykonywalnych kompilatora. Wszystkie moduły sterowników muszą być oznaczone etykietą same_process_hal_file
w file_contexts
urządzenia. Na przykład:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
Plik wykonywalny kompilatora musi umożliwiać wywołanie procesu aplikacji, podobnie jak kopia bcc dostawcy ( /vendor/bin/bcc
). Na przykład:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Starsze urządzenia
Starsze urządzenia to takie, które spełniają następujące warunki:
- PRODUCT_SHIPPING_API_LEVEL jest niższy niż 26.
- PRODUCT_FULL_TREBLE_OVERRIDE nie jest zdefiniowany.
W przypadku starszych urządzeń ograniczenia nie są egzekwowane podczas aktualizacji do Androida 8.0 i nowszych wersji, co oznacza, że sterowniki mogą nadal łączyć się z bibliotekami w /system/lib[64]
. Jednakże ze względu na zmianę architektury związaną z OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
musi być zainstalowany na partycji /vendor
; w przeciwnym razie zmusza środowisko wykonawcze RenderScript do powrotu do ścieżki procesora.
Informacje na temat powodów wycofania skryptu Renderscript można znaleźć na blogu deweloperów systemu Android: Android GPU Compute Going Forward . Informacje o zasobach dotyczące tego wycofania obejmują:
- Przeprowadź migrację z Renderscriptu
- Przykład migracji RenderScript
- Zestaw narzędzi do wymiany elementów wewnętrznych — plik README
- Zestaw narzędzi do wymiany elementów wewnętrznych.kt