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:
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.
Ł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.
Ś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.
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.
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:
- 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