RenderScript to framework do wykonywania zadań wymagających dużej mocy obliczeniowej na urządzeniach z Androidem. Jest on przeznaczony do korzystania z obliczeń równoległych z danymi, ale może też przynieść korzyści w przypadku zadań sekwencyjnych. Środowisko wykonawcze RenderScript równolegle wykonuje zadania na różnych procesorach dostępnych na urządzeniu, takich jak procesory wielordzeniowe i procesory graficzne, co pozwala deweloperom skupić się na wyrażaniu algorytmów zamiast na planowaniu pracy. RenderScript jest szczególnie przydatny w przypadku aplikacji wykonujących przetwarzanie obrazu, fotografię obliczeniową lub widzenie komputerowe.
Urządzenia z Androidem 8.0 lub nowszym korzystają z następujących frameworków RenderScript i interfejsów HAL:

Rysunek 1. Kod dostawcy łączący się z bibliotekami wewnętrznymi.
Różnice między RenderScript w Androidzie 7.x i starszych wersjach:
- 2 instancje bibliotek wewnętrznych RenderScript w procesie. Jeden zestaw jest przeznaczony do ścieżki awaryjnej procesora i jest bezpośrednio z
/system/lib
; drugi zestaw jest przeznaczony do ścieżki GPU i jest z/system/lib/vndk-sp
. - Biblioteki wewnętrzne RS w
/system/lib
są tworzone w ramach platformy i aktualizowane wraz z uaktualnieniemsystem.img
. Jednak biblioteki w/system/lib/vndk-sp
są tworzone dla dostawcy i nie są aktualizowane, gdysystem.img
jest aktualizowana (chociaż można je aktualizować w celu wprowadzenia poprawki zabezpieczeń, ich ABI pozostaje taki sam). - Kod dostawcy (RS HAL, sterownik RS i
bcc plugin
) jest powiązany z bibliotekami wewnętrznymi RenderScript znajdującymi się w katalogu/system/lib/vndk-sp
. Nie można ich łączyć z bibliotekami w katalogu/system/lib
, ponieważ są one tworzone na potrzeby danej platformy i mogą nie być zgodne z kodem dostawcy (np. symbole mogą zostać usunięte). Uniemożliwiłoby to OTA tylko dla frameworka.
Projektowanie
W następnych sekcjach znajdziesz szczegółowe informacje o projektowaniu RenderScript w Androidzie 8.0 i nowszych wersjach.
Biblioteki RenderScript dostępne dla dostawców
Ta sekcja zawiera listę bibliotek RenderScript (znanych jako NDK dostawcy dla interfejsów HAL w tym samym procesie lub VNDK-SP), które są dostępne dla kodu dostawcy i z którymi można utworzyć link. Zawiera on też informacje o dodatkowych bibliotekach, które nie są powiązane z RenderScript, ale są również udostępniane w kodzie dostawcy.
Poniższa lista bibliotek może się różnić w zależności od wersji Androida, ale jest niezmienna w przypadku konkretnej wersji Androida. Aktualną listę dostępnych bibliotek znajdziesz na stronie /system/etc/ld.config.txt
.
Biblioteki RenderScript | Biblioteki inne niż RenderScript |
---|---|
|
|
Konfiguracja przestrzeni nazw linkera
Ograniczenie łączenia, które uniemożliwia korzystanie z bibliotek nieznajdujących się w VNDK-SP przez kod dostawcy, jest egzekwowane w czasie wykonywania za pomocą przestrzeni nazw linkera. (szczegółowe informacje znajdziesz w prezentacji VNDK Design).
Na urządzeniu z Androidem 8.0 lub nowszym wszystkie interfejsy HAL w ramach tego samego procesu (SP-HAL) z wyjątkiem RenderScript są ładowane w przestrzeni nazw linkera sphal
. RenderScript jest ładowany do specyficznej dla niego przestrzeni nazw rs
, która umożliwia nieco luźniejszą kontrolę bibliotek RenderScript. Implementacja RS musi wczytać skompilowany kod bitowy, dlatego /data/*/*.so
jest dodawany do ścieżki przestrzeni nazw rs
(inne SP-HAL nie mogą wczytywać bibliotek z partycji danych).
Ponadto przestrzeń nazw rs
umożliwia stosowanie większej liczby bibliotek niż inne przestrzenie 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.

Rysunek 2. Konfiguracja przestrzeni nazw dla linkera.
Czynniki obciążenia
Ścieżka awaryjnego korzystania z procesora
Podczas tworzenia kontekstu RS w zależności od obecności bitu RS_CONTEXT_LOW_LATENCY
wybierana jest ścieżka procesora lub karty graficznej. Gdy wybrana jest ścieżka CPU, libRS_internal.so
(główna implementacja
frameworku RS) jest bezpośrednio dlopen
z domyślnego przedrostka linkera, w którym dostępne są biblioteki RS dla danej platformy.
Implementacja RS HAL od dostawcy nie jest w ogóle używana, gdy wybrano ścieżkę awaryjnego korzystania z procesora. Tworzony jest obiekt RsContext
z wartością null mVendorDriverName
. libRSDriver.so
jest (domyślnie) dlopen
ed i sterownik lib jest wczytany z default
przestrzeni nazw, ponieważ wywołujący (libRS_internal.so
) jest też wczytywany w przestrzeni nazw default
.

Rysunek 3. Ścieżka awaryjna procesora.
Ścieżka GPU
W przypadku ścieżki GPU element libRS_internal.so
jest wczytywany inaczej.
Po pierwsze, libRS.so
używa android.hardware.renderscript@1.0.so
(i podległych mu libhidltransport.so
), aby wczytać android.hardware.renderscript@1.0-impl.so
(implementację interfejsu RS HAL przez dostawcę) do innej przestrzeni nazw linkera o nazwie sphal
. RS
HAL następnie dlopen
s libRS_internal.so
w innej
przestrzeni nazw linkera o nazwie rs
.
Dostawcy mogą udostępnić własny sterownik RS, ustawiając flagę OVERRIDE_RS_DRIVER
, która jest umieszczana w implementacji interfejsu API RS (hardware/interfaces/renderscript/1.0/default/Context.cpp
). Następnie nazwa tego sterownika jest dlopen
w kontekście RS na potrzeby ścieżki GPU.
Tworzenie obiektu RsContext
jest delegowane do implementacji RS HAL. HAL wywołuje ponownie mechanizm RS za pomocą funkcji rsContextCreateVendor()
z nazwą sterownika do użycia jako argumentu. Następnie framework RS wczytuje określony sterownik po zainicjowaniu interfejsu RsContext
. W tym przypadku biblioteka sterownika jest wczytana do przestrzeni nazw rs
, ponieważ obiekt RsContext
jest tworzony w ramach tej przestrzeni, a obiekt /vendor/lib
znajduje się na ścieżce wyszukiwania tej przestrzeni.rs

Rysunek 4. Ścieżka awaryjnego korzystania z GPU.
Podczas przechodzenia z przestrzeni nazw default
do przestrzeni nazw sphal
funkcja libhidltransport.so
używa funkcji android_load_sphal_library()
, aby wyraźnie zlecić linkerowi dynamicznemu załadowanie biblioteki -impl.so
z przestrzeni nazw sphal
.
Podczas przechodzenia z przestrzeni nazw sphal
do rs
wczytywanie odbywa się pośrednio za pomocą tego wiersza w pliku /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Ten wiersz określa, że dynamiczny linker powinien wczytać libRS_internal.so
z przestrzeni nazw rs
, gdy nie można znaleźć lub wczytać biblioteki z przestrzeni nazw sphal
(co zawsze ma miejsce, ponieważ przestrzeń nazw sphal
nie przeszukuje przestrzeni nazw /system/lib/vndk-sp
, w której znajduje się libRS_internal.so
). W tej konfiguracji wystarczy wywołanie funkcji dlopen()
w funkcji libRS_internal.so
, aby przejść do nowej przestrzeni nazw.
Ładowanie wtyczki UDW
bcc plugin
to biblioteka dostarczona przez dostawcę i wczytana do kompilatora bcc
. Ponieważ bcc
to proces systemowy w katalogu /system/bin
, biblioteka bcc plugin
może być uważana za SP-HAL (czyli interfejs HAL dostawcy, który można wczytać bezpośrednio do procesu systemowego bez korzystania z bindera). Jako SP-HAL biblioteka bcc-plugin
:
- Nie można tworzyć linków do bibliotek tylko do frameworku, takich jak
libLLVM.so
. - Może zawierać linki tylko do bibliotek VNDK-SP dostępnych dla dostawcy.
To ograniczenie jest egzekwowane przez załadowanie bcc plugin
do przestrzeni nazw sphal
za pomocą funkcji android_sphal_load_library()
. We wcześniejszych wersjach Androida nazwa wtyczki była określana za pomocą opcji -load
, a biblioteka była wczytywana za pomocą prostego polecenia dlopen()
przez libLLVM.so
. W Androidzie 8.0 i nowszych ta opcja jest określona w opcji -plugin
, a biblioteka jest wczytana bezpośrednio przez bcc
. Ta opcja umożliwia dostęp do projektu open source LLVM inny niż Android.

Rysunek 5. Ładowanie wtyczki bcc na Androidzie 7.x i starszych.

Rysunek 6. Ładowanie wtyczki bcc, Android 8.0 lub nowszy.
Ścieżki wyszukiwania pliku ld.mc
Podczas wykonywania ld.mc
niektóre biblioteki RS są przekazywane jako dane wejściowe do linkera. Kod bitowy RS z aplikacji jest powiązany z bibliotekami środowiska wykonawczego. Gdy skompresowany kod bitowy jest ładowany do procesu aplikacji, biblioteki środowiska wykonawczego są ponownie powiązane dynamicznie z kompresowanego kodu bitowego.
Biblioteki środowiska wykonawczego:
libcompiler_rt.so
libm.so
libc.so
- Sterownik RS (
libRSDriver.so
lubOVERRIDE_RS_DRIVER
)
Podczas wczytywania skompilowanego kodu bitowego do procesu aplikacji podaj dokładnie tę samą bibliotekę, której używała ld.mc
. W przeciwnym razie skompilowany kod bitowy może nie znaleźć symbolu, który był dostępny w momencie połączenia.
Aby to zrobić, framework RS używa różnych ścieżek wyszukiwania dla bibliotek runtime podczas wykonywania funkcji ld.mc
w zależności od tego, czy sam framework RS jest wczytywany z /system/lib
czy z /system/lib/vndk-sp
.
Można to określić, odczytując adres dowolnego symbolu biblioteki RS framework i używanie dladdr()
do mapowania ścieżki pliku do adresu.
Zasady SELinux
W Androidzie 8.0 i nowszych ze względu na zmiany w zasadach SELinux musisz przestrzegać określonych zasad (wykonywanych przez neverallows
) podczas etykietowania dodatkowych plików na partycji vendor
:
vendor_file
musi być domyślną etykietą dla wszystkich plików na partycjivendor
. Zasady platformy wymagają tego, aby uzyskać dostęp do implementacji interfejsu HAL typu passthrough.- Wszystkie nowe
exec_types
dodane w partycjivendor
za pomocą SEPolicy dostawcy muszą mieć atrybutvendor_file_type
. Jest to egzekwowane za pomocąneverallows
. - Aby uniknąć konfliktów z przyszłymi aktualizacjami platformy lub frameworka, nie etykietuj plików innymi niż
exec_types
w partycjivendor
. - Wszystkie zależności bibliotek dla identyfikatorów HAL identyfikowanych przez AOSP w ramach tego samego procesu muszą być oznaczone jako
same_process_hal_file
.
Szczegółowe informacje o zasadach SELinux znajdziesz w artykule SELinux w Androidzie.
Zgodność kodu bitowego z interfejsem ABI
Jeśli nie zostaną dodane żadne nowe interfejsy API, co oznacza, że nie nastąpi zmiana wersji HAL, frameworki RS będą nadal używać dotychczasowego sterownika GPU (HAL 1.0).
W przypadku drobnych zmian w interfejsie HAL (HAL 1.1), które nie mają wpływu na kod bitowy, frameworki powinny stosować w przypadku nowo dodanych interfejsów API procesor CPU, a w pozostałych miejscach – sterownik GPU (HAL 1.0).
W przypadku istotnych zmian w interfejsie HAL (HAL 2.0), które mają wpływ na kompilację i linkowanie kodu bitowego, frameworki RS powinny zrezygnować z ładowania sterowników GPU dostarczanych przez dostawcę i zamiast tego używać procesora lub ścieżki Vulkan do przyspieszania.
Przetwarzanie kodu bajtowego RenderScript odbywa się w 3 etapach:
Etap | Szczegóły |
---|---|
Kompilowanie |
|
Link |
|
Wczytaj |
|
Oprócz HAL interfejsami są też interfejsy API czasu wykonywania i wyeksportowane symbole. Żaden z tych interfejsów nie zmienił się od wersji Androida 7.0 (interfejs API 24) i nie planujemy wprowadzać zmian w Androidzie 8.0 ani nowszych wersjach. Jeśli jednak interfejs ulegnie zmianie, wersja HAL również wzrośnie.
Implementacje dostawców
Aby sterownik GPU działał prawidłowo, Android 8.0 i nowsze wymaga wprowadzenia pewnych zmian.
Moduły sterujące
- Moduł sterownika nie może być zależny od żadnych bibliotek systemowych, które nie znajdują się na liście.
- Sterownik musi zawierać własne
android.hardware.renderscript@1.0-impl_{NAME}
lub zadeklarować domyślną implementacjęandroid.hardware.renderscript@1.0-impl
jako swoją zależność. - Implementacja na procesorze CPU
libRSDriver.so
to dobry przykład usuwania zależności innych niż VNDK-SP.
Kompilator kodu bitowego
Kod bitowy RenderScript dla sterownika dostawcy możesz skompilować na 2 sposoby:
- Wywołaj kompilator RenderScript konkretnego dostawcy w
/vendor/bin/
(preferowana metoda kompilacji na GPU). Podobnie jak inne moduły sterownika, binarny kompilator dostawcy nie może zależeć od żadnej biblioteki systemowej, która nie znajduje się na liście bibliotek RenderScript dostępnych dla dostawców. - Wywołanie systemu bcc:
/system/bin/bcc
z użyciem biblioteki dostarczonej przez dostawcębcc plugin
; ten wtyczka nie może zależeć od żadnej biblioteki systemowej, która nie znajduje się na liście bibliotek RenderScript dostępnych dla dostawców.
Jeśli dostawca bcc plugin
musi ingerować w kompilację procesora, a zależność od libLLVM.so
nie może być łatwo usunięta, dostawca powinien skopiować bcc
(oraz wszystkie zależności inne niż LL-NDK, w tym libLLVM.so
i libbcc.so
) do partycji /vendor
.
Dostawcy muszą też wprowadzić te zmiany:

Rysunek 7. Zmiany w komponencie dostawcy.
- Skopiuj
libclcore.bc
do partycji/vendor
. Dzięki temulibclcore.bc
,libLLVM.so
ilibbcc.so
są zsynchronizowane. - Zmień ścieżkę do pliku wykonywalnego
bcc
, ustawiając parametrRsdCpuScriptImpl::BCC_EXE_PATH
w implementacji RS HAL.
Zasady SELinux
Zasady SELinux wpływają zarówno na sterownik, jak i pliki wykonywalne kompilatora. Wszystkie moduły sterownika muszą mieć etykietę same_process_hal_file
w file_contexts
urządzenia. Przykład:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
Kompilator musi być uruchamiany przez proces aplikacji, tak samo jak kopia bcc (/vendor/bin/bcc
) dostawcy. Przykład:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Starsze urządzenia
Urządzenia starsze to te, które spełniają te warunki:
- Wartość parametru PRODUCT_SHIPPING_API_LEVEL jest mniejsza niż 26.
- Parametr PRODUCT_FULL_TREBLE_OVERRIDE nie jest zdefiniowany.
W przypadku starszych urządzeń ograniczenia nie są wymuszane podczas aktualizacji do Androida 8.0 lub nowszego, co oznacza, że sterowniki mogą nadal łączyć się z bibliotekami w /system/lib[64]
. Jednak ze względu na zmianę architektury związaną z OVERRIDE_RS_DRIVER
aplikacja android.hardware.renderscript@1.0-impl
musi być zainstalowana w partycji /vendor
. Jeśli tego nie zrobisz, środowisko uruchomieniowe RenderScript użyje ścieżki procesora.
Informacje o motywacjach do wycofania Renderscript znajdziesz na blogu dla deweloperów aplikacji na Androida: Proces obliczeniowy na procesorze graficznym Androida w przyszłości. Informacje o wycofanych zasobach:
- Migracja z Renderscript
- Przykład RenderScriptMigration
- README dotyczący pakietu narzędzi do zastępowania informacji wewnętrznych
- Zamiennik pliku Toolkit.kt