O RenderScript é um framework para executar tarefas intensivas em termos de computação com alto desempenho no Android. Ele foi projetado para uso com computação paralela de dados, embora cargas de trabalho seriais também possam se beneficiar. O tempo de execução do RenderScript carrega em paralelo todos os processadores disponíveis em um dispositivo, como CPUs e GPUs com vários núcleos, permitindo que os desenvolvedores se concentrem em expressar algoritmos em vez de programar trabalho. O RenderScript é especialmente útil para apps que realizam processamento de imagens, fotografia computacional ou visão computacional.
Dispositivos com o Android 8.0 e versões mais recentes usam as seguintes estruturas do RenderScript e HALs do fornecedor:

Figura 1. Vinculação de código do fornecedor a bibliotecas internas.
As diferenças do RenderScript no Android 7.x e em versões anteriores incluem:
- Duas instâncias de bibliotecas internas do RenderScript em um processo. Um conjunto é para
o caminho de substituição da CPU e vem diretamente de
/system/lib
. O outro conjunto é para o caminho da GPU e vem de/system/lib/vndk-sp
. - As bibliotecas internas do RS em
/system/lib
são criadas como parte da plataforma e atualizadas quando osystem.img
é atualizado. No entanto, as bibliotecas em/system/lib/vndk-sp
são criadas para o fornecedor e não são atualizadas quando osystem.img
é atualizado (embora possam ser atualizadas para uma correção de segurança, a ABI permanece a mesma). - O código do fornecedor (RS HAL, driver RS e
bcc plugin
) é vinculado às bibliotecas internas do RenderScript localizadas em/system/lib/vndk-sp
. Não é possível vincular a bibliotecas em/system/lib
porque as bibliotecas nesse diretório são criadas para a plataforma e, portanto, podem não ser compatíveis com o código do fornecedor (ou seja, os símbolos podem ser removidos). Isso impossibilitaria uma OTA somente de framework.
Design
As seções a seguir detalham o design do RenderScript no Android 8.0 e versões mais recentes.
Bibliotecas do RenderScript disponíveis para fornecedores
Esta seção lista as bibliotecas do RenderScript (conhecidas como NDK do fornecedor para HALs de mesmo processo ou VNDK-SP) disponíveis para o código do fornecedor e que podem ser vinculadas a ele. Ele também detalha outras bibliotecas que não estão relacionadas ao RenderScript, mas que também são fornecidas ao código do fornecedor.
Embora a lista de bibliotecas a seguir possa variar entre as versões do Android, ela é imutável para uma versão específica. Para conferir uma lista atualizada de bibliotecas disponíveis, consulte /system/etc/ld.config.txt
.
Bibliotecas do RenderScript | Bibliotecas não RenderScript |
---|---|
|
|
Configuração do namespace do vinculador
A restrição de vinculação que impede que bibliotecas que não estão no VNDK-SP sejam usadas pelo código do fornecedor é aplicada em tempo de execução usando o namespace do vinculador. Para mais detalhes, consulte a apresentação Design do VNDK.
Em um dispositivo com Android 8.0 e versões mais recentes, todas as HALs do mesmo processo (SP-HALs), exceto o RenderScript, são carregadas no namespace do vinculador sphal
. O RenderScript é carregado no namespace específico do RenderScript
rs
, um local que permite uma aplicação um pouco mais flexível
para bibliotecas do RenderScript. Como a implementação do RS precisa carregar
o bitcode compilado, /data/*/*.so
é adicionado ao caminho do namespace
rs
. Outras SP-HALs não podem carregar bibliotecas da
partição de dados.
Além disso, o namespace rs
permite mais bibliotecas do que outros namespaces. libmediandk.so
e libft2.so
são expostos ao namespace rs
porque
libRS_internal.so
tem uma dependência interna dessas bibliotecas.

Figura 2. Configuração de namespace para o vinculador.
Carregar drivers
Caminho de substituição da CPU
Dependendo da existência do bit RS_CONTEXT_LOW_LATENCY
ao criar um contexto do RS, o caminho da CPU ou da GPU é selecionado. Quando o
caminho da CPU é selecionado, libRS_internal.so
(a principal implementação
do framework RS) é diretamente dlopen
ed do namespace
padrão do vinculador, em que a versão da plataforma das bibliotecas RS é fornecida.
A implementação do HAL do RS do fornecedor não é usada quando o caminho de
fallback da CPU é adotado, e um objeto RsContext
é criado com
mVendorDriverName
nulo. libRSDriver.so
é (por
padrão) dlopen
ed, e a biblioteca de driver é carregada do namespace
default
porque o caller
(libRS_internal.so
) também é carregado no namespace
default
.

Figura 3. Caminho de substituição da CPU.
Caminho da GPU
No caminho da GPU, o libRS_internal.so
é carregado de maneira diferente.
Primeiro, libRS.so
usa
android.hardware.renderscript@1.0.so
(e o
libhidltransport.so
subjacente) para carregar
android.hardware.renderscript@1.0-impl.so
(uma implementação
do fornecedor do RS HAL) em um namespace de vinculador diferente chamado
sphal
. O HAL do RS dlopen
libRS_internal.so
em outro namespace do vinculador chamado rs
.
Os fornecedores podem fornecer o próprio driver RS definindo a flag de tempo de build
OVERRIDE_RS_DRIVER
, que é incorporada à implementação da HAL RS
(hardware/interfaces/renderscript/1.0/default/Context.cpp
). Esse
nome de driver é dlopen
ed para o contexto RS do caminho da GPU.
A criação do objeto RsContext
é delegada à implementação da HAL
do RS. A HAL faz uma chamada de volta para o framework RS usando a função rsContextCreateVendor()
com o nome do driver a ser usado como argumento. Em seguida, o framework RS carrega o driver especificado quando o
RsContext
é inicializado. Nesse caso, a biblioteca de driver é
carregada no namespace rs
porque o objeto RsContext
é criado dentro do namespace rs
e
/vendor/lib
está no caminho de pesquisa do namespace.

Figura 4. Caminho de substituição da GPU.
Ao fazer a transição do namespace default
para o
sphal
, o libhidltransport.so
usa a função
android_load_sphal_library()
para ordenar explicitamente o
vinculador dinâmico a carregar a biblioteca -impl.so
do namespace
sphal
.
Ao fazer a transição do namespace sphal
para o
rs
, o carregamento é feito indiretamente pela seguinte linha em
/system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Essa linha especifica que o vinculador dinâmico precisa carregar
libRS_internal.so
do namespace rs
quando a biblioteca
não pode ser encontrada/carregada do namespace sphal
(o que sempre
acontece porque o namespace sphal
não pesquisa
/system/lib/vndk-sp
onde libRS_internal.so
está). Com essa configuração, uma simples chamada dlopen()
para
libRS_internal.so
é suficiente para fazer a transição do namespace.
Carregar plug-in de Cco
bcc plugin
é uma biblioteca fornecida pelo fornecedor e carregada no compilador
bcc
. Como bcc
é um processo do sistema no diretório /system/bin
, a biblioteca bcc plugin
pode ser considerada uma SP-HAL (ou seja, uma HAL do fornecedor que pode ser carregada diretamente no processo do sistema sem ser vinculada). Como uma SP-HAL, a biblioteca
bcc-plugin
:
- Não é possível vincular a bibliotecas somente de framework, como
libLLVM.so
. - Só pode ser vinculado às bibliotecas VNDK-SP disponíveis para o fornecedor.
Essa restrição é aplicada carregando o bcc plugin
no namespace sphal
usando a função android_sphal_load_library()
. Em versões anteriores do
Android, o nome do plug-in era especificado usando a opção -load
e
a biblioteca era carregada usando o simples dlopen()
por
libLLVM.so
. No Android 8.0 e versões mais recentes, isso é especificado na opção
-plugin
, e a biblioteca é carregada diretamente pelo
próprio bcc
. Essa opção permite um caminho não específico do Android para o projeto de código aberto LLVM.

Figura 5. Carregando o plug-in bcc, Android 7.x e versões anteriores.

Figura 6. Carregando o plug-in bcc, Android 8.0 e versões mais recentes.
Caminhos de pesquisa para ld.mc
Ao executar ld.mc
, algumas bibliotecas de tempo de execução do RS são fornecidas como entradas
para o vinculador. O bitcode do RS do app é vinculado às bibliotecas de tempo de execução
e, quando o bitcode convertido é carregado em um processo de app, as bibliotecas de tempo de execução
são novamente vinculadas dinamicamente do bitcode convertido.
As bibliotecas de execução incluem:
libcompiler_rt.so
libm.so
libc.so
- Driver RS (
libRSDriver.so
ouOVERRIDE_RS_DRIVER
)
Ao carregar o bitcode compilado no processo do app, forneça exatamente a mesma biblioteca usada pelo ld.mc
. Caso contrário, o bitcode compilado
pode não encontrar um símbolo que estava disponível quando foi vinculado.
Para isso, o framework RS usa diferentes caminhos de pesquisa para as bibliotecas de tempo de execução ao
executar ld.mc
, dependendo se o próprio framework RS é
carregado de /system/lib
ou de /system/lib/vndk-sp
.
Isso pode ser determinado lendo o endereço de um símbolo arbitrário de uma biblioteca de framework RS e usando dladdr()
para receber o caminho do arquivo mapeado para o endereço.
Política do SELinux
Como resultado das mudanças na política do SELinux no Android 8.0 e versões mais recentes, é necessário seguir regras específicas (aplicadas por neverallows
) ao rotular arquivos adicionais na partição vendor
:
vendor_file
precisa ser o marcador padrão para todos os arquivos na partiçãovendor
. A política da plataforma exige isso para acessar implementações de HAL de passagem.- Todos os novos
exec_types
adicionados na partiçãovendor
pela SEPolicy do fornecedor precisam ter o atributovendor_file_type
. Isso é aplicado porneverallows
. - Para evitar conflitos com atualizações futuras de plataforma/framework, evite rotular arquivos que não sejam
exec_types
na partiçãovendor
. - Todas as dependências de biblioteca para HALs de mesmo processo identificados pelo AOSP precisam ser
rotuladas como
same_process_hal_file
.
Para mais detalhes sobre a política do SELinux, consulte Security-Enhanced Linux no Android.
Compatibilidade com ABI para bitcode
Se nenhuma API nova for adicionada, o que significa que não haverá aumento na versão da HAL, os frameworks do RS vão continuar usando o driver da GPU atual (HAL 1.0).
Para pequenas mudanças na HAL (HAL 1.1) que não afetam o bitcode, os frameworks precisam recorrer à CPU para essas APIs recém-adicionadas e continuar usando o driver da GPU (HAL 1.0) em outros lugares.
Para mudanças importantes na HAL (HAL 2.0) que afetam a compilação/vinculação de bitcode, as estruturas do RS não devem carregar drivers de GPU fornecidos pelo fornecedor e, em vez disso, usar o caminho da CPU ou do Vulkan para aceleração.
O consumo de bitcode do RenderScript ocorre em três etapas:
Estágio | Detalhes |
---|---|
Compilar |
|
Link |
|
Carregar |
|
Além da HAL, as APIs de tempo de execução e os símbolos exportados também são interfaces. Nenhuma das interfaces mudou desde o Android 7.0 (API 24), e não há planos imediatos para mudar no Android 8.0 e versões mais recentes. No entanto, se a interface mudar, a versão da HAL também será incrementada.
Implementações de fornecedores
O Android 8.0 e versões mais recentes exigem algumas mudanças no driver da GPU para que ele funcione corretamente.
Módulos de driver
- Os módulos de driver não podem depender de bibliotecas do sistema que não estejam na lista.
- O driver precisa fornecer o próprio
android.hardware.renderscript@1.0-impl_{NAME}
ou declarar a implementação padrãoandroid.hardware.renderscript@1.0-impl
como dependência. - A implementação da CPU
libRSDriver.so
é um bom exemplo de como remover dependências não VNDK-SP.
Compilador de bitcode
É possível compilar o bitcode do RenderScript para o driver do fornecedor de duas maneiras:
- Invocar o compilador RenderScript específico do fornecedor em
/vendor/bin/
(método preferencial de compilação de GPU). Assim como outros módulos de driver, o binário do compilador do fornecedor não pode depender de nenhuma biblioteca do sistema que não esteja na lista de bibliotecas do RenderScript disponíveis para fornecedores. - Invoque o bcc do sistema:
/system/bin/bcc
com umbcc plugin
fornecido pelo fornecedor. Esse plug-in não pode depender de nenhuma biblioteca do sistema que não esteja na lista de bibliotecas do RenderScript disponíveis para fornecedores.
Se o fornecedor bcc plugin
precisar interferir na compilação da CPU e a dependência dela em libLLVM.so
não puder ser removida facilmente, o fornecedor deverá copiar bcc
(e todas as dependências não LL-NDK, incluindo libLLVM.so
, libbcc.so
) para a partição /vendor
.
Além disso, os fornecedores precisam fazer as seguintes mudanças:

Figura 7. Mudanças no driver do fornecedor.
- Copie
libclcore.bc
para a partição/vendor
. Isso garante quelibclcore.bc
,libLLVM.so
elibbcc.so
estejam sincronizados. - Mude o caminho para o executável
bcc
definindoRsdCpuScriptImpl::BCC_EXE_PATH
na implementação da HAL do RS.
Política do SELinux
A política do SELinux afeta os executáveis do driver e do compilador. Todos os módulos de driver precisam ser rotulados como same_process_hal_file
no file_contexts
do dispositivo. Exemplo:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
O executável do compilador precisa poder ser invocado por um processo de app, assim como
a cópia do fornecedor de bcc (/vendor/bin/bcc
). Por exemplo:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Dispositivos legados
Os dispositivos legados são aqueles que atendem às seguintes condições:
- PRODUCT_SHIPPING_API_LEVEL é menor que 26.
- PRODUCT_FULL_TREBLE_OVERRIDE não está definido.
Em dispositivos legados, as restrições não são aplicadas ao fazer upgrade para
o Android 8.0 ou versões mais recentes. Isso significa que os drivers podem continuar vinculando bibliotecas
em /system/lib[64]
. No entanto, devido à mudança de arquitetura
relacionada a OVERRIDE_RS_DRIVER
,
android.hardware.renderscript@1.0-impl
precisa ser instalado na
partição /vendor
. Caso contrário, o tempo de execução do RenderScript
vai usar o caminho da CPU.
Para informações sobre a motivação da descontinuação do RenderScript, consulte o blog de desenvolvedores do Android: Android GPU Compute Going Forward (em inglês). As informações de recursos para essa suspensão de uso incluem o seguinte:
- Migrar do RenderScript
- Exemplo de migração do RenderScript
- README do kit de ferramentas de substituição de intrínsecos
- Intrinsics ReplacementToolkit.kt