RenderScript è un framework per l'esecuzione di attività computazionalmente intensive ad alte prestazioni su Android. È progettato per l'uso con il calcolo parallelo dei dati, sebbene anche i carichi di lavoro seriali possano trarne vantaggio. Il runtime RenderScript parallelizza il lavoro tra i processori disponibili su un dispositivo, come CPU e GPU multi-core, consentendo agli sviluppatori di concentrarsi sull'espressione di algoritmi piuttosto che sulla pianificazione del lavoro. RenderScript è particolarmente utile per le applicazioni che eseguono l'elaborazione delle immagini, la fotografia computazionale o la visione artificiale.
I dispositivi con Android 8.0 e versioni successive utilizzano il seguente framework RenderScript e gli HAL dei fornitori:
Le differenze rispetto a RenderScript in Android 7.x e versioni precedenti includono:
- Due istanze di librerie interne di RenderScript in un processo. Un set è per il percorso di fallback della CPU e proviene direttamente da
/system/lib
; l'altro set è per il percorso GPU e proviene da/system/lib/vndk-sp
. - Le librerie interne di RS in
/system/lib
sono create come parte della piattaforma e vengono aggiornate man mano chesystem.img
viene aggiornato. Tuttavia, le librerie in/system/lib/vndk-sp
sono create per il fornitore e non vengono aggiornate quandosystem.img
viene aggiornato (sebbene possano essere aggiornate per una correzione di sicurezza, il loro ABI rimane lo stesso). - Il codice del fornitore (RS HAL, driver RS e
bcc plugin
) è collegato alle librerie interne di RenderScript situate in/system/lib/vndk-sp
. Non possono collegarsi alle librerie in/system/lib
perché le librerie in quella directory sono costruite per la piattaforma e quindi potrebbero non essere compatibili con il codice del fornitore (cioè i simboli potrebbero essere rimossi). Ciò renderebbe impossibile un’OTA basata solo sul framework.
Progetto
Le sezioni seguenti descrivono in dettaglio la progettazione RenderScript in Android 8.0 e versioni successive.
Librerie RenderScript disponibili per i fornitori
Questa sezione elenca le librerie RenderScript (note come Vendor NDK per HAL Same-Process o VNDK-SP) disponibili per il codice del fornitore e a cui è possibile collegare. Fornisce inoltre dettagli sulle librerie aggiuntive che non sono correlate a RenderScript ma che vengono fornite anche al codice del fornitore.
Sebbene il seguente elenco di librerie possa differire tra le versioni Android, è immutabile per una specifica versione Android; per un elenco aggiornato delle librerie disponibili, fare riferimento a /system/etc/ld.config.txt
.
Librerie RenderScript | Librerie non RenderScript |
---|---|
|
|
Configurazione dello spazio dei nomi del linker
La restrizione di collegamento che impedisce alle librerie non presenti in VNDK-SP di essere utilizzate dal codice del fornitore viene applicata in fase di esecuzione utilizzando lo spazio dei nomi del linker. (Per i dettagli, fare riferimento alla presentazione VNDK Design .)
Su un dispositivo che esegue Android 8.0 e versioni successive, tutti gli HAL Same-Process (SP-HAL) tranne RenderScript vengono caricati all'interno dello spazio dei nomi del linker sphal
. RenderScript viene caricato nello spazio dei nomi specifico di RenderScript rs
, una posizione che consente un'applicazione leggermente più flessibile per le librerie RenderScript. Poiché l'implementazione RS deve caricare il codice bit compilato, /data/*/*.so
viene aggiunto al percorso dello spazio dei nomi rs
(ad altri SP-HAL non è consentito caricare librerie dalla partizione dati).
Inoltre, lo spazio dei nomi rs
consente più librerie di quelle fornite da altri spazi dei nomi. libmediandk.so
e libft2.so
sono esposti allo spazio dei nomi rs
perché libRS_internal.so
ha una dipendenza interna da queste librerie.
Caricamento dei driver
Percorso di fallback della CPU
A seconda dell'esistenza del bit RS_CONTEXT_LOW_LATENCY
durante la creazione di un contesto RS, viene selezionato il percorso CPU o GPU. Quando viene selezionato il percorso della CPU, libRS_internal.so
(l'implementazione principale del framework RS) viene dlopen
direttamente dallo spazio dei nomi del linker predefinito in cui viene fornita la versione della piattaforma delle librerie RS.
L'implementazione RS HAL del fornitore non viene utilizzata affatto quando viene utilizzato il percorso di fallback della CPU e viene creato un oggetto RsContext
con null mVendorDriverName
. libRSDriver.so
è (per impostazione predefinita) dlopen
ed e la lib del driver viene caricata dallo spazio dei nomi default
perché anche il chiamante ( libRS_internal.so
) è caricato nello spazio dei nomi default
.
Percorso GPU
Per il percorso GPU, libRS_internal.so
viene caricato in modo diverso. Innanzitutto, libRS.so
utilizza android.hardware.renderscript@1.0.so
(e il suo sottostante libhidltransport.so
) per caricare android.hardware.renderscript@1.0-impl.so
(un'implementazione del fornitore di RS HAL) in uno spazio dei nomi del linker diverso chiamato sphal
. L'HAL RS quindi dlopen
libRS_internal.so
in un altro spazio dei nomi del linker chiamato rs
.
I fornitori possono fornire il proprio driver RS impostando il flag del tempo di compilazione OVERRIDE_RS_DRIVER
, che è incorporato nell'implementazione RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp
). Questo nome di driver viene quindi dlopen
per il contesto RS per il percorso GPU.
La creazione dell'oggetto RsContext
è delegata all'implementazione RS HAL. L'HAL richiama il framework RS utilizzando la funzione rsContextCreateVendor()
con il nome del driver da utilizzare come argomento. Il framework RS carica quindi il driver specificato quando viene inizializzato RsContext
. In questo caso, la libreria dei driver viene caricata nello spazio dei nomi rs
perché l'oggetto RsContext
viene creato all'interno dello spazio dei nomi rs
e /vendor/lib
si trova nel percorso di ricerca dello spazio dei nomi.
Durante la transizione dallo spazio dei nomi default
allo spazio dei nomi sphal
, libhidltransport.so
utilizza la funzione android_load_sphal_library()
per ordinare esplicitamente al linker dinamico di caricare la libreria -impl.so
dallo spazio dei nomi sphal
.
Durante la transizione dallo spazio dei nomi sphal
allo spazio dei nomi rs
, il caricamento viene eseguito indirettamente dalla seguente riga in /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Questa riga specifica che il linker dinamico dovrebbe caricare libRS_internal.so
dallo spazio dei nomi rs
quando la lib non può essere trovata/caricata dallo spazio dei nomi sphal
(che è sempre così perché lo spazio dei nomi sphal
non cerca /system/lib/vndk-sp
dove risiede libRS_internal.so
). Con questa configurazione, una semplice chiamata dlopen()
a libRS_internal.so
è sufficiente per effettuare la transizione dello spazio dei nomi.
Caricamento del plugin Ccn
bcc plugin
è una libreria fornita dal fornitore caricata nel compilatore bcc
. Poiché bcc
è un processo di sistema nella directory /system/bin
, la libreria bcc plugin
può essere considerata un SP-HAL (ovvero un HAL del fornitore che può essere caricato direttamente nel processo di sistema senza essere binderizzato). Come SP-HAL, la libreria bcc-plugin
:
- Impossibile collegarsi a librerie solo framework come
libLLVM.so
. - Può collegarsi solo alle librerie VNDK-SP disponibili per il fornitore.
Questa restrizione viene applicata caricando il bcc plugin
nello spazio dei nomi sphal
utilizzando la funzione android_sphal_load_library()
. Nelle versioni precedenti di Android, il nome del plugin veniva specificato utilizzando l'opzione -load
e la lib veniva caricata utilizzando il semplice dlopen()
di libLLVM.so
. In Android 8.0 e versioni successive, questo è specificato nell'opzione -plugin
e la lib viene caricata direttamente dal bcc
stesso. Questa opzione abilita un percorso non specifico per Android al progetto LLVM open source.
Percorsi di ricerca per ld.mc
Quando si esegue ld.mc
, alcune librerie di runtime RS vengono fornite come input al linker. Il codice bit RS dell'app è collegato alle librerie di runtime e quando il codice bit convertito viene caricato in un processo dell'app, le librerie di runtime vengono nuovamente collegate dinamicamente dal codice bit convertito.
Le librerie di runtime includono:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- Driver RS (
libRSDriver.so
oOVERRIDE_RS_DRIVER
)
Quando carichi il codice bit compilato nel processo dell'app, fornisci esattamente la stessa libreria utilizzata da ld.mc
. In caso contrario, il codice bit compilato potrebbe non trovare un simbolo disponibile al momento del collegamento.
Per fare ciò, il framework RS utilizza diversi percorsi di ricerca per le librerie di runtime durante l'esecuzione ld.mc
, a seconda che il framework RS stesso venga caricato da /system/lib
o da /system/lib/vndk-sp
. Questo può essere determinato leggendo l'indirizzo di un simbolo arbitrario di una libreria del framework RS e utilizzando dladdr()
per ottenere il percorso del file mappato all'indirizzo.
Politica SELinux
Come risultato delle modifiche alla policy SELinux in Android 8.0 e versioni successive, è necessario seguire regole specifiche (applicate tramite neverallows
) quando si etichettano file aggiuntivi nella partizione vendor
:
-
vendor_file
deve essere l'etichetta predefinita per tutti i file nella partizionevendor
. La policy della piattaforma lo richiede per accedere alle implementazioni HAL passthrough. - Tutti i nuovi
exec_types
aggiunti nella partizionevendor
tramite SEPolicy del fornitore devono avere l'attributovendor_file_type
. Questo viene applicato tramiteneverallows
. - Per evitare conflitti con futuri aggiornamenti della piattaforma/framework, evitare di etichettare file diversi da
exec_types
nella partizionevendor
. - Tutte le dipendenze della libreria per gli HAL dello stesso processo identificati da AOSP devono essere etichettati come
same_process_hal_file
.
Per dettagli sulla policy SELinux, vedere Linux con sicurezza avanzata in Android .
Compatibilità ABI per bitcode
Se non vengono aggiunte nuove API, il che significa che non viene apportata alcuna modifica alla versione HAL, i framework RS continueranno a utilizzare il driver GPU esistente (HAL 1.0).
Per modifiche minori all'HAL (HAL 1.1) che non influiscono sul bitcode, i framework dovrebbero eseguire il fallback sulla CPU per queste API appena aggiunte e continuare a utilizzare il driver GPU (HAL 1.0) altrove.
Per le principali modifiche HAL (HAL 2.0) che influiscono sulla compilazione/collegamento del codice bit, i framework RS dovrebbero scegliere di non caricare i driver GPU forniti dal fornitore e utilizzare invece il percorso CPU o Vulkan per l'accelerazione.
Il consumo del codice bit RenderScript avviene in tre fasi:
Palcoscenico | Dettagli |
---|---|
Compilare |
|
Collegamento |
|
Carico |
|
Oltre all'HAL, anche le API runtime e i simboli esportati sono interfacce. Nessuna delle due interfacce è cambiata da Android 7.0 (API 24) e non ci sono piani immediati per cambiarla in Android 8.0 e versioni successive. Tuttavia, se l'interfaccia cambia, aumenterà anche la versione dell'HAL.
Implementazioni del fornitore
Android 8.0 e versioni successive richiedono alcune modifiche al driver GPU affinché il driver GPU funzioni correttamente.
Moduli driver
- I moduli driver non devono dipendere da librerie di sistema non presenti nell'elenco .
- Il driver deve fornire il proprio
android.hardware.renderscript@1.0-impl_{NAME}
o dichiarare l'implementazione predefinitaandroid.hardware.renderscript@1.0-impl
come dipendenza. - L'implementazione della CPU
libRSDriver.so
è un buon esempio di come rimuovere le dipendenze non VNDK-SP.
Compilatore di codici bit
È possibile compilare il codice bit RenderScript per il driver del fornitore in due modi:
- Richiama il compilatore RenderScript specifico del fornitore in
/vendor/bin/
(metodo preferito di compilazione GPU). Similmente ad altri moduli driver, il binario del compilatore del fornitore non può dipendere da alcuna libreria di sistema che non sia nell'elenco delle librerie RenderScript disponibili ai fornitori . - Richiama system bcc:
/system/bin/bcc
con unbcc plugin
fornito dal fornitore; questo plugin non può dipendere da alcuna libreria di sistema che non sia nell'elenco delle librerie RenderScript disponibili per i fornitori .
Se il bcc plugin
del fornitore deve interferire con la compilazione della CPU e la sua dipendenza da libLLVM.so
non può essere rimossa facilmente, il fornitore dovrebbe copiare bcc
(e tutte le dipendenze non LL-NDK, incluse libLLVM.so
, libbcc.so
) in /vendor
.
Inoltre, i fornitori devono apportare le seguenti modifiche:
- Copia
libclcore.bc
nella partizione/vendor
. Ciò garantiscelibclcore.bc
,libLLVM.so
elibbcc.so
siano sincronizzati. - Modificare il percorso dell'eseguibile
bcc
impostandoRsdCpuScriptImpl::BCC_EXE_PATH
dall'implementazione RS HAL.
Politica SELinux
La politica di SELinux influenza sia il driver che gli eseguibili del compilatore. Tutti i moduli driver devono essere etichettati same_process_hal_file
nel file_contexts
del dispositivo. Per esempio:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
L'eseguibile del compilatore deve poter essere richiamato da un processo dell'app, così come la copia del fornitore di bcc ( /vendor/bin/bcc
). Per esempio:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Dispositivi legacy
I dispositivi legacy sono quelli che soddisfano le seguenti condizioni:
- PRODUCT_SHIPPING_API_LEVEL è inferiore a 26.
- PRODUCT_FULL_TREBLE_OVERRIDE non è definito.
Per i dispositivi legacy, le restrizioni non vengono applicate durante l'aggiornamento ad Android 8.0 e versioni successive, il che significa che i driver possono continuare a collegarsi alle librerie in /system/lib[64]
. Tuttavia, a causa della modifica dell'architettura relativa a OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
deve essere installato nella partizione /vendor
; in caso contrario, si forza il fallback del runtime RenderScript sul percorso della CPU.
Per informazioni sulla motivazione della deprecazione di Renderscript, vedere il blog degli sviluppatori Android: Android GPU Compute Going Forward . Le informazioni sulle risorse per questa deprecazione includono quanto segue:
- Migrazione da Renderscript
- Esempio di RenderScriptMigration
- README del kit di strumenti per la sostituzione degli intrinseci
- Sostituzione degli intrinseci Toolkit.kt