Gráficos

Ícone HAL de gráficos Android

A estrutura do Android oferece uma variedade de APIs de renderização gráfica para 2D e 3D que interagem com implementações de drivers gráficos do fabricante, por isso é importante ter um bom entendimento de como essas APIs funcionam em um nível superior. Esta página apresenta a camada de abstração de hardware gráfico (HAL) na qual esses drivers são criados. Antes de continuar com esta seção, familiarize-se com os seguintes termos:

canvas (termo genérico), Canvas (elemento API)
Uma tela é uma superfície de desenho que lida com a composição dos bits reais em um bitmap ou objeto Surface . Canvas possui métodos para desenho padrão de computador de bitmaps, linhas, círculos, retângulos, texto e assim por diante, e está vinculado a um bitmap ou superfície. Uma tela é a maneira mais simples e fácil de desenhar objetos 2D na tela. A classe base é Canvas .
desenhavel
Um drawable é um recurso visual compilado que pode ser usado como plano de fundo, título ou outra parte da tela. Um drawable normalmente é carregado em outro elemento da UI, por exemplo, como uma imagem de fundo. Um drawable não é capaz de receber eventos, mas atribui várias outras propriedades, como estado e agendamento, para habilitar subclasses, como objetos de animação ou bibliotecas de imagens. Muitos objetos desenháveis ​​são carregados de arquivos de recursos desenháveis ​​— arquivos XML ou bitmap que descrevem a imagem. Os recursos drawable são compilados em subclasses de android.graphics.drawable . Para obter mais informações sobre drawables e outros recursos, consulte Recursos .
recurso de layout
Um recurso de layout é um arquivo XML que descreve o layout de uma tela de atividade. Para obter mais informações, consulte Recurso de layout .
nove patches (9 patches, NinePatch)
Um nove patch é um recurso de bitmap redimensionável que pode ser usado para planos de fundo ou outras imagens no dispositivo. Para obter mais informações, consulte Nove patch .
OpenGL ES
OpenGL ES é uma API multiplataforma para renderização de gráficos 2D e 3D. O Android fornece bibliotecas OpenGL ES para renderização 3D acelerada por hardware. Para renderização 2D, uma tela é a opção mais simples. OpenGL ES está disponível no Android Native Development Kit (NDK) . Os pacotes android.opengl e javax.microedition.khronos.opengles expõem a funcionalidade do OpenGL ES.
superfície (termo genérico), Surface (elemento API)
Uma superfície representa um bloco de memória que é composto na tela. Uma superfície contém uma tela para desenho e fornece vários métodos auxiliares para desenhar camadas e redimensionar o objeto Surface . Use a classe SurfaceView em vez da classe Surface diretamente.
visualização de superfície (termo genérico), SurfaceView (elemento API)
Uma vista de superfície é um objeto View que envolve um objeto Surface para desenho e expõe métodos para especificar seu tamanho e formato dinamicamente. Uma visualização de superfície fornece uma maneira de desenhar independentemente do thread de UI para operações que consomem muitos recursos, como jogos ou visualizações de câmera, mas, como resultado, usa memória extra. Uma visualização de superfície oferece suporte a gráficos de tela e OpenGL ES. A classe base para um objeto SurfaceView é SurfaceView .
tema
Um tema é um conjunto de propriedades, como tamanho do texto e cor de fundo, agrupadas para definir várias configurações de exibição padrão. O Android fornece alguns temas padrão, listados em R.style e precedidos por Theme_ .
view (termo genérico), View (elemento API)
Uma visualização desenha uma área retangular na tela e controla cliques, pressionamentos de tecla e outros eventos de interação. A classe View é a classe base para a maioria dos componentes de layout de uma atividade ou tela de diálogo, como caixas de texto e janelas. Um objeto View recebe chamadas de seu objeto pai (consulte ViewGroup ) para desenhar a si mesmo e informa seu objeto pai sobre seu tamanho e localização preferidos, o que pode não ser respeitado pelo pai. Para obter mais informações, consulte View .
grupo de visualização (termo genérico), ViewGroup (elemento API)
Um grupo de visualizações agrupa um conjunto de visualizações filhas. O grupo de visualização é responsável por decidir onde as visualizações secundárias serão posicionadas e quão grandes elas podem ser, bem como por chamar cada uma para desenhar a si mesma quando apropriado. Alguns grupos de visualização são invisíveis e servem apenas para layout, enquanto outros possuem uma interface de usuário intrínseca, como uma caixa de listagem de rolagem. Os grupos de visualizações estão no pacote widget , mas estendem a classe ViewGroup .
ver hierarquia
Uma hierarquia de visualização é uma organização de objetos de visualização e de grupo de visualizações que define a interface do usuário para cada componente de um aplicativo. A hierarquia consiste em grupos de visualizações que contêm uma ou mais visualizações secundárias ou grupos de visualizações. Você pode obter uma representação visual de uma hierarquia de visualização para depuração e otimização usando o Hierarchy Viewer fornecido com o Android SDK.
Vulcano
Vulkan é uma API de plataforma cruzada de baixa sobrecarga para gráficos 3D de alto desempenho.
ferramenta
Um widget faz parte de um conjunto de subclasses de visualização totalmente implementadas que renderizam elementos de formulário e outros componentes de UI, como uma caixa de texto ou um menu pop-up. Como um widget é totalmente implementado, ele mede, desenha e responde a eventos de tela. Os widgets estão no pacote android.widget .
janela (termo genérico), Window (elemento API)
Em um aplicativo Android, uma janela é um objeto derivado da classe abstrata Window que especifica os elementos de uma janela genérica, como aparência, texto da barra de título e localização e conteúdo dos menus. Diálogos e atividades usam uma implementação da classe Window para renderizar um objeto Window . Você não precisa implementar a classe Window ou usar janelas em seu aplicativo.

Os desenvolvedores de aplicativos desenham imagens na tela de três maneiras: com Canvas , OpenGL ES ou Vulkan .

Componentes gráficos Android

Não importa qual API de renderização os desenvolvedores usem, tudo é renderizado em uma superfície. A superfície representa o lado produtor de uma fila de buffer que é frequentemente consumida pelo SurfaceFlinger. Cada janela criada na plataforma Android é apoiada por uma superfície. Todas as superfícies visíveis renderizadas são compostas na tela pelo SurfaceFlinger.

O diagrama a seguir mostra como os principais componentes funcionam juntos:

componentes de renderização de imagem

Figura 1. Como as superfícies são renderizadas.

Os principais componentes são descritos abaixo:

Produtores de fluxo de imagem

Um produtor de fluxo de imagens pode ser qualquer coisa que produza buffers gráficos para consumo. Os exemplos incluem OpenGL ES, Canvas 2D e decodificadores de vídeo mediaserver.

Consumidores de fluxo de imagem

O consumidor mais comum de fluxos de imagens é o SurfaceFlinger, o serviço do sistema que consome as superfícies atualmente visíveis e as compõe na tela usando informações fornecidas pelo Window Manager. SurfaceFlinger é o único serviço que pode modificar o conteúdo da exibição. SurfaceFlinger usa OpenGL e o Hardware Composer para compor um grupo de superfícies.

Outros aplicativos OpenGL ES também podem consumir fluxos de imagens, como o aplicativo de câmera que consome um fluxo de imagem de visualização da câmera. Aplicativos não GL também podem ser consumidores, por exemplo, a classe ImageReader.

Compositor de hardware

A abstração de hardware para o subsistema de exibição. SurfaceFlinger pode delegar determinado trabalho de composição ao Hardware Composer para descarregar o trabalho do OpenGL e da GPU. SurfaceFlinger atua apenas como mais um cliente OpenGL ES. Portanto, quando o SurfaceFlinger está compondo ativamente um ou dois buffers em um terceiro, por exemplo, ele está usando OpenGL ES. Isso torna a composição menos energética do que fazer com que a GPU conduza todos os cálculos.

O Hardware Composer HAL conduz a outra metade do trabalho e é o ponto central para toda a renderização gráfica do Android. O Hardware Composer deve suportar eventos, um dos quais é VSYNC (outro é hotplug para suporte HDMI plug-and-play).

Gralloc

O alocador de memória gráfica (Gralloc) é necessário para alocar a memória solicitada pelos produtores de imagens. Para obter detalhes, consulte Gralloc HAL .

Fluxo de dados

Consulte o diagrama a seguir para obter uma representação do pipeline gráfico do Android:

fluxo de dados gráficos

Figura 2. Fluxo de dados gráficos através do Android

Os objetos à esquerda são renderizadores que produzem buffers gráficos, como tela inicial, barra de status e interface do sistema. SurfaceFlinger é o compositor e Hardware Composer é o compositor.

BufferQueue

BufferQueues fornece a ligação entre os componentes gráficos do Android. Trata-se de um par de filas que medeiam o ciclo constante de buffers do produtor ao consumidor. Depois que os produtores entregam seus buffers, o SurfaceFlinger é responsável por compor tudo no display.

Consulte o diagrama a seguir para o processo de comunicação BufferQueue.

Processo de comunicação BufferQueue

Figura 3. Processo de comunicação BufferQueue

BufferQueue contém a lógica que une produtores e consumidores de fluxo de imagens. Alguns exemplos de produtores de imagens são as visualizações de câmera produzidas pelos jogos de câmera HAL ou OpenGL ES. Alguns exemplos de consumidores de imagem são SurfaceFlinger ou outro aplicativo que exibe um fluxo OpenGL ES, como o aplicativo de câmera que exibe o visor da câmera.

BufferQueue é uma estrutura de dados que combina um buffer pool com uma fila e usa Binder IPC para passar buffers entre processos. A interface do produtor, ou o que você passa para alguém que deseja gerar buffers gráficos, é IGraphicBufferProducer (parte de SurfaceTexture ). BufferQueue é frequentemente usado para renderizar em um Surface e consumir com um consumidor GL, entre outras tarefas.

BufferQueue pode operar em três modos diferentes:

Modo síncrono - BufferQueue por padrão opera em modo síncrono, no qual todo buffer que chega do produtor sai no consumidor. Nenhum buffer é descartado neste modo. E se o produtor for muito rápido e criar buffers mais rápido do que eles estão sendo drenados, ele bloqueará e aguardará buffers livres.

Modo sem bloqueio - BufferQueue também pode operar em modo sem bloqueio, onde gera um erro em vez de esperar por um buffer nesses casos. Nenhum buffer é descartado neste modo também. Isso é útil para evitar possíveis impasses no software aplicativo que pode não compreender as dependências complexas da estrutura gráfica.

Modo de descarte - Finalmente, BufferQueue pode ser configurado para descartar buffers antigos em vez de gerar erros ou esperar. Por exemplo, se estiver conduzindo a renderização GL para uma visualização de textura e desenhando o mais rápido possível, os buffers deverão ser descartados.

Para conduzir a maior parte deste trabalho, o SurfaceFlinger atua como apenas mais um cliente OpenGL ES. Portanto, quando o SurfaceFlinger está compondo ativamente um ou dois buffers em um terceiro, por exemplo, ele está usando OpenGL ES.

O Hardware Composer HAL conduz a outra metade do trabalho. Este HAL atua como ponto central para toda a renderização gráfica do Android.