Uma introdução ao Renderscript

Este guia apresenta o Renderscript e explica como usar as APIs intrínsecas do Renderscript em um aplicativo Xamarin.Android destinado ao nível de API 17 ou superior.

Visão geral

Renderscript é um framework de programação criado pelo Google com o objetivo de melhorar o desempenho de aplicativos Android que exigem amplos recursos computacionais. É uma API de baixo nível e alto desempenho baseada em C99. Como é uma API de baixo nível que será executada em CPUs, GPUs ou DSPs, o Renderscript é adequado para aplicativos Android que talvez precisem executar qualquer um dos seguintes:

  • Elementos gráficos
  • Processamento de Imagem
  • Criptografia
  • Processamento de Sinais
  • Rotinas Matemáticas

O Renderscript usará clang e compilará os scripts para o código de bytes LLVM que é empacotado no APK. Quando o aplicativo for executado pela primeira vez, o código de byte LLVM será compilado em código de máquina para os processadores no dispositivo. Essa arquitetura permite que um aplicativo Android explore as vantagens do código de máquina sem que os próprios desenvolvedores tenham que escrevê-lo para cada processador no próprio dispositivo.

Há dois componentes em uma rotina de Renderscript:

  1. O tempo de execução do Renderscript – São as APIs nativas responsáveis pela execução do Renderscript. Isso inclui quaisquer Renderscripts escritos para o aplicativo.

  2. Managed Wrappers do Android Framework – Classes gerenciadas que permitem que um aplicativo Android controle e interaja com o tempo de execução e os scripts do Renderscript. Além das classes fornecidas pela estrutura para controlar o tempo de execução do Renderscript, o toolchain do Android examinará o código-fonte do Renderscript e gerará classes wrapper gerenciadas para uso pelo aplicativo Android.

O diagrama a seguir ilustra como esses componentes se relacionam:

Diagram illustrating how the Android Framework interacts with the Renderscript Runtime

Há três conceitos importantes para usar Renderscripts em um aplicativo Android:

  1. Um contexto – Uma API gerenciada fornecida pelo SDK do Android que aloca recursos para o Renderscript e permite que o aplicativo Android passe e receba dados do Renderscript.

  2. Um kernel de computação – Também conhecido como kernel raiz ou kernel, esta é uma rotina que faz o trabalho. O kernel é muito semelhante a uma função C; É uma rotina paralelizável que será executada sobre todos os dados na memória alocada.

  3. Memória alocada – Os dados são passados de e para um kernel através de uma alocação. Um kernel pode ter uma alocação de entrada e/ou uma saída.

O namespace Android.Renderscripts contém as classes para interagir com o tempo de execução do Renderscript. Em particular, a Renderscript classe gerenciará o ciclo de vida e os recursos do mecanismo Renderscript. O aplicativo Android deve inicializar um ou mais Android.Renderscripts.Allocation Objetos. Uma Alocação é uma API gerenciada responsável pela alocação e acesso à memória compartilhada entre o aplicativo Android e o tempo de execução do Renderscript. Normalmente, uma Alocação é criada para entrada e, opcionalmente, outra Alocação é criada para manter a saída do kernel. O mecanismo de tempo de execução Renderscript e as classes de wrapper gerenciadas associadas gerenciarão o acesso à memória mantida pelas Alocações, não há necessidade de um desenvolvedor de aplicativos Android fazer nenhum trabalho extra.

Uma Alocação conterá um ou mais Android.Renderscripts.Elements. Os elementos são um tipo especializado que descreve os dados em cada alocação. Os tipos de elemento da alocação de saída devem corresponder aos tipos do elemento de entrada. Ao executar, um Renderscript iterará sobre cada elemento na alocação de entrada em paralelo e gravará os resultados na alocação de saída. Existem dois tipos de Elementos:

  • tipo simples – Conceitualmente, isso é o mesmo que um tipo de dados C, float ou um chararquivo .

  • tipo complexo – Este tipo é semelhante a um C struct.

O mecanismo Renderscript executará uma verificação de tempo de execução para garantir que os Elementos em cada Alocação sejam compatíveis com o que é exigido pelo kernel. Se o tipo de dados dos elementos na alocação não corresponder ao tipo de dados que o kernel está esperando, uma exceção será lançada.

Todos os kernels Renderscript serão encapsulados por um tipo que é um descendente do classe Android.Renderscripts.Script. A Script classe é usada para definir parâmetros para um Renderscript, definir o apropriado Allocationse executar o Renderscript. Há duas Script subclasses no SDK do Android:

  • Android.Renderscripts.ScriptIntrinsic – Algumas das tarefas Renderscript mais comuns são empacotadas no SDK do Android e são acessíveis por uma subclasse da classe ScriptIntrinsic . Não há necessidade de um desenvolvedor tomar nenhuma etapa extra para usar esses scripts em seu aplicativo, pois eles já são fornecidos.

  • ScriptC_XXXXX – Também conhecidos como scripts de usuário, são scripts que são escritos por desenvolvedores e empacotados no APK. No momento da compilação, o conjunto de ferramentas do Android gerará classes de wrapper gerenciadas que permitirão que os scripts sejam usados no aplicativo Android. O nome dessas classes geradas é o nome do arquivo Renderscript, prefixado com ScriptC_. Escrever e incorporar scripts de usuário não é oficialmente suportado pelo Xamarin.Android e além do escopo deste guia.

Desses dois tipos, apenas o é suportado StringIntrinsic pelo Xamarin.Android. Este guia discutirá como usar scripts intrínsecos em um aplicativo Xamarin.Android.

Requisitos

Este guia destina-se a aplicativos Xamarin.Android destinados ao nível de API 17 ou superior. O uso de scripts de usuário não é abordado neste guia.

A Biblioteca de Suporte do Xamarin.Android V8 faz backports das APIs Renderscript instrinsic para aplicativos destinados a versões mais antigas do SDK do Android. Adicionar este pacote a um projeto Xamarin.Android deve permitir que os aplicativos destinados a versões mais antigas do SDK do Android aproveitem os scripts intrínsecos.

Usando renderscripts intrínsecos no Xamarin.Android

Os scripts intrínsecos são uma ótima maneira de executar tarefas de computação intensivas com uma quantidade mínima de código adicional. Eles foram ajustados manualmente para oferecer o desempenho ideal em uma grande seção transversal de dispositivos. Não é incomum que um script intrínseco seja executado 10x mais rápido do que o código gerenciado e 2-3x vezes depois de uma implementação C personalizada. Muitos dos cenários de processamento típicos são cobertos pelos scripts intrínsecos. Esta lista de scripts intrínsecos descreve os scripts atuais no Xamarin.Android:

Consulte a documentação da API para obter detalhes sobre cada um dos scripts intrínsecos.

As etapas básicas para usar o Renderscript em um aplicativo Android são descritas a seguir.

Criar um contexto Renderscript – O Renderscript class é um wrapper gerenciado em torno do contexto Renderscript e controlará a inicialização, o gerenciamento de recursos e a limpeza. O objeto Renderscript é criado usando o RenderScript.Create método factory, que usa um contexto Android (como uma atividade) como parâmetro. A linha de código a seguir demonstra como inicializar o contexto Renderscript:

Android.Renderscripts.RenderScript renderScript = RenderScript.Create(this);

Criar alocações – Dependendo do script intrínseco, pode ser necessário criar um ou dois Allocations. O Android.Renderscripts.Allocation class tem vários métodos de fábrica para ajudar a instanciar uma alocação para um intrínseco. Como exemplo, o trecho de código a seguir demonstra como criar alocação para bitmaps.

Android.Graphics.Bitmap originalBitmap;
Android.Renderscripts.Allocation inputAllocation = Allocation.CreateFromBitmap(renderScript,
                                                     originalBitmap,
                                                     Allocation.MipmapControl.MipmapFull,
                                                     AllocationUsage.Script);

Muitas vezes, será necessário criar um para armazenar os dados de saída de um Allocation script. Este trecho a seguir mostra como usar o auxiliar para instanciar um segundo Allocation do mesmo tipo que o Allocation.CreateTyped original:

Android.Renderscripts.Allocation outputAllocation = Allocation.CreateTyped(renderScript, inputAllocation.Type);

Instanciar o wrapper de script – Cada uma das classes de wrapper de script intrínseco deve ter métodos auxiliares (normalmente chamados Createde ) para instanciar um objeto wrapper para esse script. O trecho de código a seguir é um exemplo de como instanciar um ScriptIntrinsicBlur objeto blur. O Element.U8_4 método auxiliar criará um elemento que descreve um tipo de dados que é 4 campos de 8 bits, valores inteiros não assinados, adequados para armazenar os dados de um Bitmap objeto:

Android.Renderscripts.ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.Create(renderScript, Element.U8_4(renderScript));

Atribuir alocação(ões), Definir parâmetros, & Run Script – A Script classe fornece um ForEach método para realmente executar o Renderscript. Esse método iterará sobre cada Element um na Allocation retenção dos dados de entrada. Em alguns casos, pode ser necessário fornecer um Allocation que contenha a saída. ForEach substituirá o conteúdo da alocação de saída. Para continuar com os trechos de código das etapas anteriores, este exemplo mostra como atribuir uma alocação de entrada, definir um parâmetro e, finalmente, executar o script (copiando os resultados para a alocação de saída):

blurScript.SetInput(inputAllocation);
blurScript.SetRadius(25);  // Set a pamaeter
blurScript.ForEach(outputAllocation);

Você pode querer verificar a receita Blur an Image with Renderscript , é um exemplo completo de como usar um script intrínseco no Xamarin.Android.

Resumo

Este guia apresentou o Renderscript e como usá-lo em um aplicativo Xamarin.Android. Ele discutiu brevemente o que é Renderscript e como ele funciona em um aplicativo Android. Ele descreveu alguns dos principais componentes no Renderscript e a diferença entre scripts de usuário e scripts intrínsecos. Finalmente, este guia discutiu as etapas no uso de um script intrínseco em um aplicativo Xamarin.Android.