RenderScript

O RenderScript é um framework para execução de computação intensiva tarefas com alto desempenho no Android. Ele foi projetado para ser usado computação paralela de dados, embora cargas de trabalho seriais também possam se beneficiar. A O tempo de execução do RenderScript carrega em paralelo entre processadores disponíveis em uma como CPUs e GPUs com vários núcleos, permitindo que os desenvolvedores se concentrem expressar algoritmos em vez de agendar trabalhos. O RenderScript é especialmente útil para aplicativos que executam processamento de imagens, fotografia ou visão computacional.

Dispositivos com o Android 8.0 e versões mais recentes usam o seguinte RenderScript HALs de fornecedor e framework:

Figura 1. Link do código do fornecedor para bibliotecas internas.

As diferenças do RenderScript no Android 7.x e 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 definido é para o caminho da GPU e é de /system/lib/vndk-sp.
  • As bibliotecas internas de RS em /system/lib são criadas como parte da plataforma e são atualizados à medida que o system.img é atualizado. No entanto, as libs em /system/lib/vndk-sp são criados para o fornecedor e não são atualizados quando o system.img é atualizado (enquanto podem ser atualizados) para uma correção de segurança, a ABI dele permanece a mesma).
  • O código do fornecedor (HAL RS, driver RS e bcc plugin) é vinculado às bibliotecas internas do RenderScript localizadas em /system/lib/vndk-sp. Eles não podem vincular a bibliotecas em /system/lib porque as bibliotecas nesse diretório são criadas para o plataforma e, portanto, podem não ser compatíveis com o código do fornecedor (ou seja, símbolos pode ser removido). Isso tornaria impossível uma OTA somente na estrutura.

Design

As seções abaixo 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 Same-Process) HALs ou VNDK-SP) que estão disponíveis para o código do fornecedor e que podem ser vinculados contra. Ele também detalha bibliotecas adicionais não relacionadas a RenderScript, mas que também são fornecidos ao código do fornecedor.

Embora a lista de bibliotecas a seguir possa ser diferente entre as versões do Android, é imutável para uma versão específica do Android. para uma lista atualizada de bibliotecas disponíveis, consulte /system/etc/ld.config.txt.

Bibliotecas do RenderScript Bibliotecas não-RenderScript
  • android.hardware.graphics.renderscript@1.0.so
  • libRS_internal.so
  • libRSCpuRef.so
  • libblas.so
  • libbcinfo.so
  • libcompiler_rt.so
  • libRSDriver.so
  • libc.so
  • libm.so
  • libdl.so
  • libstdc++.so
  • liblog.so
  • libnativewindow.so
  • libsync.so
  • libvndksupport.so
  • libbase.so
  • libc++.so
  • libcutils.so
  • libutils.so
  • libhardware.so
  • libhidlbase.so
  • libhidltransport.so
  • libhwbinder.so
  • liblzma.so
  • libz.so
  • libEGL.so
  • libGLESv1_CM.so
  • libGLESv2.so

Configuração de namespace do vinculador

A restrição de vinculação que impede que as bibliotecas não presentes no VNDK-SP sejam usadas por o código do fornecedor é aplicado no ambiente de execução usando o namespace do vinculador. Para mais detalhes, consulte o Design do VNDK apresentação.

Em um dispositivo com o Android 8.0 e versões mais recentes, todas as HALs de mesmo processo (SP-HALs) exceto o RenderScript é carregado dentro do namespace do vinculador. sphal O RenderScript é carregado na interface específica do RenderScript o namespace rs, um local que permite um ambiente um pouco mais flexível aplicação para bibliotecas do RenderScript. Como a implementação de RS precisa carregar o bitcode compilado, /data/*/*.so é adicionado ao caminho do Namespace rs (outros SP-HALs não têm permissão para carregar bibliotecas da (ou partição de dados).

Além disso, o namespace rs permite mais bibliotecas do que as fornecidas para por outros namespaces. libmediandk.so e libft2.so foram expostos ao namespace rs porque libRS_internal.so tem uma dependência interna para essas 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 de RS, o caminho da CPU ou da GPU é selecionado. Quando o O caminho da CPU está selecionado, libRS_internal.so (a implementação principal da estrutura RS) é diretamente dlopen pelo vinculador padrão namespace em que a versão da plataforma das bibliotecas RS é fornecida.

A implementação de HAL de RS do fornecedor não é usada quando o caminho substituto e um objeto RsContext é criado com mVendorDriverName nulo. libRSDriver.so é (por padrão) dlopen e a biblioteca do driver é carregada da Namespace default porque o autor da chamada (libRS_internal.so) também é carregado no arquivo default .

Figura 3. caminho substituto da CPU.

Caminho da GPU

Para o caminho da GPU, o libRS_internal.so é carregado de maneira diferente. Primeiro, o libRS.so usa android.hardware.renderscript@1.0.so (e os libhidltransport.so) para carregar android.hardware.renderscript@1.0-impl.so (um fornecedor implementação de HAL de RS) em um namespace do vinculador diferente, chamado sphal. O Usuário em ascensão A HAL depois dlopens e 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, incorporado à HAL de RS implementação hardware/interfaces/renderscript/1.0/default/Context.cpp). Isso O nome do driver recebe dlopen para o contexto RS do caminho da GPU.

A criação do objeto RsContext é delegada à HAL de RS implementação. A HAL chama o framework de RS usando rsContextCreateVendor() com o nome do motorista do como argumento. O framework RS carrega o driver especificado quando o RsContext foi inicializado. Nesse caso, a biblioteca de drivers carregados no namespace rs porque o 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 o namespace sphal, libhidltransport.so usa o android_load_sphal_library() para ordenar explicitamente vinculador dinâmico para carregar a biblioteca -impl.so da 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

Esta linha especifica que o vinculador dinâmico deve carregar libRS_internal.so do namespace rs quando a biblioteca e não podem ser encontrados/carregados a partir do namespace sphal (que é sempre o caso porque o namespace sphal não pesquisa /system/lib/vndk-sp em que libRS_internal.so reside). Com essa configuração, uma simples chamada dlopen() para libRS_internal.so é suficiente para fazer a transição do namespace.

Carregar plug-in Cco

bcc plugin é uma biblioteca fornecida pelo fornecedor carregada no Compiler bcc. Como bcc é um processo do sistema na diretório /system/bin, a biblioteca bcc plugin pode ser considerada uma SP-HAL (ou seja, uma HAL de fornecedor que pode ser carregada diretamente no no processo do sistema sem vinculação). Como uma SP-HAL, a Biblioteca bcc-plugin:

  • Não é possível vincular a bibliotecas somente de framework, como libLLVM.so:
  • Pode ser vinculado apenas às bibliotecas VNDK-SP disponíveis para o fornecedor.

Essa restrição é aplicada carregando o bcc plugin no sphal usando o função android_sphal_load_library(). Nas versões anteriores do Android, o nome do plug-in foi especificado usando a opção -load; a biblioteca foi carregada usando dlopen() simples libLLVM.so No Android 8.0 e versões posteriores, isso é especificado na a opção -plugin, e a lib é carregada diretamente pelo bcc. Essa opção ativa um caminho não específico do Android para no projeto LLVM de código aberto.

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



Figura 6. Carregando plug-in Cco, Android 8.0 e mais recentes.

Pesquisar caminhos para ld.mc

Ao executar ld.mc, algumas bibliotecas de ambiente de execução RS são fornecidas como entradas. ao vinculador. O bitcode RS do app está vinculado às bibliotecas do ambiente de execução e quando o bitcode convertido é carregado em um processo de aplicativo, as bibliotecas de tempo de execução são novamente vinculados dinamicamente ao bitcode convertido.

As bibliotecas de ambiente de execução incluem:

  • libcompiler_rt.so
  • libm.so
  • libc.so
  • Driver RS (libRSDriver.so ou OVERRIDE_RS_DRIVER)

Ao carregar o bitcode compilado no processo do app, forneça as mesmas informações de biblioteca que foi usada por 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 de RS usa caminhos de pesquisa diferentes para as bibliotecas de ambiente de execução quando executar ld.mc, dependendo se o próprio framework de RS está 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 um RS framework lib e usar dladdr() para mapear o caminho do arquivo 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) quando rotulando arquivos adicionais na partição vendor:

  • vendor_file precisa ser o marcador padrão para todos os arquivos em vendor. A política da plataforma exige isso para acessar as implementações de HAL de passagem.
  • Todos os novos exec_types foram adicionados à partição vendor pelo fornecedor SEPolicy, precisam ter o atributo vendor_file_type. Isso é aplicado pela neverallows.
  • Para evitar conflitos com futuras atualizações de plataforma/framework, evite rotular arquivos diferentes de exec_types na partição vendor.
  • Todas as dependências de biblioteca para HALs do mesmo processo identificadas pelo AOSP precisam ser marcado como same_process_hal_file.

Para conferir detalhes sobre a política do SELinux, consulte Linux com segurança avançada no Android.

Compatibilidade com ABI para bitcode

Se nenhuma API nova for adicionada, ou seja, sem promoção de versão da HAL, as estruturas de RS vai continuar usando o driver da GPU (HAL 1.0).

Para pequenas alterações na HAL (HAL 1.1) que não afetam o bitcode, as estruturas devem substituto para a CPU para essas APIs recém-adicionadas e continue usando o driver da GPU (HAL 1.0) em outro lugar.

Para as principais alterações de HAL (HAL 2.0) que afetam a compilação/vinculação de bitcode, o RS em vez de carregar drivers de GPU fornecidos pelo fornecedor e, em vez usar o caminho da CPU ou do Vulkan para aceleração.

O consumo de bitcode do RenderScript ocorre em três etapas:

Etapa Detalhes
Compilar
  • O bitcode de entrada (.bc) para bcc precisa estar em O formato de bitcode LLVM 3.2 e bcc precisam estar inversos compatíveis com os apps legados.
  • No entanto, os metadados em .bc podem mudar (pode haver novos funções, como Configuradores de alocação ∓ getters, funções matemáticas etc.). Parte das funções de ambiente de execução ficam em libclcore.bc, parte delas resida no LibRSDriver ou equivalente no fornecedor.
  • Novas funções de ambiente de execução ou alterações interruptivas nos metadados exigem incremento o nível da API de bitcode. Como os motoristas do fornecedor não poderão consumir o produto, a versão da HAL também precisa ser incrementada.
  • Os fornecedores podem ter seus próprios compiladores, mas as conclusões/requisitos para bcc também se aplicam a esses compiladores.
Link
  • O arquivo .o compilado será vinculado ao driver do fornecedor, por exemplo, libRSDriver_foo.so e libcompiler_rt.so. A CPU o caminho será vinculado a libRSDriver.so.
  • Se o arquivo .o exigir uma nova API de execução de libRSDriver_foo, o driver do fornecedor precisa ser atualizado para ser compatível.
  • Certos fornecedores podem ter seus próprios vinculadores, mas o argumento para ld.mc também se aplicam a eles.
Carregamento
  • libRSCpuRef carrega o objeto compartilhado. Se houver alterações nessa interface, é necessária uma promoção de versão da HAL.
  • Os fornecedores dependeriam do libRSCpuRef para carregar os arquivos objeto ou implementar um próprio.

Além da HAL, as APIs de ambiente de execução e os símbolos exportados também são do Google Cloud. Nenhuma das interfaces mudou desde o Android 7.0 (API 24) e, não há planos imediatos para mudá-lo no Android 8.0 e em versões posteriores. No entanto, se o interface mudar, a versão da HAL também será incrementada.

Implementações do fornecedor

O Android 8.0 e versões mais recentes exigem algumas mudanças no driver da GPU para funcionam corretamente.

Módulos de driver

  • Os módulos do driver não podem depender de bibliotecas do sistema que não estejam no na lista.
  • O motorista precisa fornecer android.hardware.renderscript@1.0-impl_{NAME} ou declare o implementação padrão android.hardware.renderscript@1.0-impl, como a dependência dele.
  • A implementação de CPU libRSDriver.so é um bom exemplo de como Remova as dependências não VNDK-SP.

Compilador de bitcode

Você pode compilar bitcode do RenderScript para o driver do fornecedor de duas maneiras:

  1. Invocar o compilador do RenderScript específico do fornecedor em /vendor/bin/ (método preferido de compilação de GPU). Semelhante a outros módulos de driver, o O binário do compilador do fornecedor não pode depender de nenhuma biblioteca do sistema que não esteja na lista de bibliotecas RenderScript disponíveis para os fornecedores.
  2. Invocar Cco do sistema: /system/bin/bcc com um endereço fornecido pelo fornecedor bcc plugin este plug-in não pode depender de nenhuma biblioteca do sistema não está na lista de Bibliotecas RenderScript disponíveis aos fornecedores.

Se o fornecedor bcc plugin precisar interferir na CPU a compilação e sua dependência de libLLVM.so não podem ser facilmente removido, o fornecedor deve copiar bcc (e todos os arquivos dependências, incluindo libLLVM.so, libbcc.so) em /vendor.

Além disso, os fornecedores precisam fazer as seguintes alterações:

Figura 7. Alterações no driver do fornecedor.

  1. Copie libclcore.bc para a partição /vendor. Isso garante que libclcore.bc, libLLVM.so e libbcc.so estão sincronizadas.
  2. Defina o caminho para o executável bcc. RsdCpuScriptImpl::BCC_EXE_PATH da implementação de HAL de RS.
.

Política do SELinux

A política do SELinux afeta os executáveis do driver e do compilador. Todos módulos do driver precisam ser rotulados como same_process_hal_file na 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 ser capaz de ser invocado por um processo do app, assim como a cópia do fornecedor em Cco (/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

Dispositivos legados são aqueles que atendem às seguintes condições:

  1. PRODUCT_SHIPPING_API_LEVEL é inferior a 26.
  2. PRODUCT_FULL_TREBLE_OVERRIDE não está definido.

Para dispositivos legados, as restrições não são aplicadas ao fazer upgrade para Android 8.0 e versões mais recentes, o que significa que os drivers podem continuar a vincular a bibliotecas em /system/lib[64]. No entanto, devido à mudança na arquitetura, relacionadas a OVERRIDE_RS_DRIVER, android.hardware.renderscript@1.0-impl deve ser instalado em partição /vendor; Se isso não for feito, o tempo de execução do RenderScript será forçado substituto para o caminho da CPU.

Para mais informações sobre o motivo da descontinuação do Renderscript, consulte a documentação Blog: O futuro da computação de GPU no Android (em inglês). As informações de recursos para esta suspensão de uso incluem o seguinte: