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 elementos essenciais da arquitetura de gráficos no nível do sistema Android e como eles são usados pelo framework de apps 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 SurfaceView e TextureView se comportam da maneira como fazem ou como as superfícies e o EGLSurface interagem, você está no lugar certo.

É necessário ter alguma familiaridade com dispositivos Android e desenvolvimento de apps. Não é necessário ter 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 significativos envolvidos na renderização de um frame para saída e ajudar você a tomar decisões informadas ao projetar um app. Para isso, este documento funciona de baixo para cima, descrevendo como as classes de UI funcionam em vez de como podem ser usadas.

Esta seção inclui várias páginas que abordam desde material de apoio 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 superior que fornecem dados ao compositor. Recomendamos ler as páginas na ordem a seguir 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 posterior (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 Hardware Composer HAL (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 buffers 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 para aceleração de hardware) para desenhar diretamente em uma superfície (alternativa de baixo nível ao OpenGL ES). Tudo o que tem 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 de gráficos projetada para ser combinada com o EGL, uma biblioteca que pode criar e acessar janelas pelo sistema operacional (para desenhar polígonos texturizados, 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 com 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 para apps. As vantagens do Vulkan incluem reduções na sobrecarga da CPU e suporte para a linguagem intermediária binária SPIR-V.

Componentes de alto nível

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