Arquitetura gráfica

O que todo desenvolvedor precisa saber sobre superfícies, SurfaceHolder, EGLSurface, SurfaceView, GLSurfaceView, SurfaceTexture, TextureView, SurfaceFlinger e Vulkan.

Esta página descreve os elementos essenciais da arquitetura de gráficos do sistema Android e como eles são usados pelo framework do app e pelo sistema multimídia. O foco é em como os buffers de dados gráficos se movem pelo sistema. Se você já se perguntou por que a SurfaceView e a TextureView se comportam dessa maneira ou como as superfícies e a EGLSurface interagem, você está no lugar certo.

É necessário ter algum conhecimento sobre dispositivos Android e desenvolvimento de apps. Você não precisa de conhecimento detalhado do framework do app, e poucas chamadas de API são mencionadas, mas o material não se sobrepõe a outras documentações públicas. O objetivo é fornecer detalhes sobre os eventos importantes envolvidos na renderização de um frame para saída e ajudar você a fazer escolhas informadas ao projetar um app. Para isso, trabalhamos de baixo para cima, descrevendo como as classes da interface funcionam, e não como elas podem ser usadas.

Esta seção inclui várias páginas que abrangem tudo, desde material de segundo plano até detalhes de HAL e casos de uso. Ele começa com uma explicação dos buffers gráficos do Android, descreve o mecanismo de composição e exibição e, em seguida, passa para os mecanismos de nível mais alto que fornecem dados ao compositor. Recomendamos ler as páginas na ordem listada abaixo em vez de pular para um tópico que pareça interessante.

Componentes de baixo nível

  • BufferQueue e gralloc. A BufferQueue conecta algo que gera buffers de dados gráficos (o produtor) a algo que aceita os dados para exibição ou processamento adicional (o consumidor). As alocações de buffer são realizadas pelo alocador de memória gralloc implementado por uma interface HAL específica do fornecedor.
  • SurfaceFlinger, Hardware Composer e telas virtuais. O SurfaceFlinger aceita buffers de dados de várias fontes, os compõe e os envia para a tela. O HAL do compositor de hardware (HWC) determina a maneira mais eficiente de compor buffers com o hardware disponível, e as telas virtuais disponibilizam a saída composta no sistema (gravando a tela ou enviando-a por uma rede).
  • Surface, canvas e SurfaceHolder. Uma superfície produz uma fila de buffer que geralmente é consumida pelo SurfaceFlinger. Ao renderizar em uma superfície, o resultado acaba em um buffer que é enviado ao consumidor. As APIs Canvas oferecem uma implementação de software (com suporte à aceleração de hardware) para desenhar diretamente em uma superfície (alternativa de baixo nível ao OpenGL ES). Qualquer coisa que tenha a ver com uma visualização envolve um SurfaceHolder, cujas APIs permitem receber e definir parâmetros de superfície, como tamanho e formato.
  • EGLSurface e OpenGL ES. O OpenGL ES (GLES) define uma API de renderização gráfica projetada para ser combinada com o EGL, uma biblioteca que pode criar e acessar janelas pelo sistema operacional. Para desenhar polígonos com textura, use chamadas GLES. Para colocar a renderização na tela, use chamadas EGL. Esta página também aborda ANativeWindow, o equivalente em C/C++ da classe Java Surface usada para criar uma superfície de janela EGL a partir do código nativo.
  • Vulkan. O Vulkan é uma API multiplataforma de baixa sobrecarga para gráficos 3D de alto desempenho. Assim como o OpenGL ES, o Vulkan oferece ferramentas para criar gráficos de alta qualidade em tempo real em apps. As vantagens do Vulkan incluem reduções na sobrecarga da CPU e suporte à linguagem SPIR-V Binary Intermediate (link em inglês).

Componentes de alto nível

  • SurfaceView e GLSurfaceView. O SurfaceView combina uma superfície e uma visualização. Os componentes de visualização da SurfaceView são compostos pelo SurfaceFlinger (e não pelo app), permitindo a renderização de uma linha de execução/processo separada e o isolamento da renderização da interface do app. A GLSurfaceView fornece classes auxiliares para gerenciar contextos EGL, comunicação intercorrente e interação com o ciclo de vida da atividade (mas não é necessário usar GLES).
  • SurfaceTexture. A SurfaceTexture combina uma superfície e uma textura GLES para criar uma BufferQueue para a qual o app é o consumidor. Quando um produtor enfileira um novo buffer, ele notificará seu app, que por sua vez libera o buffer mantido anteriormente, adquire o novo buffer da fila e faz chamadas EGL para disponibilizar o buffer para o GLES como uma textura externa. O Android 7.0 adicionou suporte à reprodução de vídeo de textura seguro, permitindo o pós-processamento de conteúdo de vídeo protegido pela GPU.
  • TextureView. A TextureView combina uma visualização com uma SurfaceTexture. O TextureView envolve uma SurfaceTexture e assume a responsabilidade de responder a callbacks e adquirir novos buffers. Ao renderizar, a TextureView usa o conteúdo do buffer mais recentemente recebido como fonte de dados, renderizando onde e como o estado da visualização indica. A composição de visualização é sempre realizada com GLES, o que significa que as atualizações de conteúdo podem fazer com que outros elementos de visualização sejam renderizados também.