As camadas compostas HAL do Hardware Composer (HWC) recebidas SurfaceFlinger, reduzindo a quantidade de composição OpenGL ES (GLES) e o desempenho da GPU.
O HWC abstrai objetos, como sobreposições e blitters 2D, para compor superfícies e se comunica com hardware de composição de janela especializado para janelas compostas. Use o HWC para compor janelas em vez de ter composição do SurfaceFlinger com a GPU. A maioria das GPUs não é otimizada composição e quando a GPU compõe camadas SurfaceFlinger, os apps não podem usar a GPU para a própria renderização.
As implementações de HWC precisam oferecer suporte a:
- Pelo menos quatro sobreposições:
- Barra de status
- Barra do sistema
- App
- Plano de fundo/plano de fundo
- Camadas maiores que a tela (por exemplo, um plano de fundo)
- Mesclagem alfa pré-multiplicada simultânea por pixel e por plano mistura alfa
- Caminho de hardware para reprodução de vídeo protegida
- Ordem de empacotamento RGBA, formatos YUV, ladrilhos, swizzling e stride propriedades
Para implementar a HWC:
- Implementar uma HWC não operacional e enviar todo o trabalho de composição para GLES.
- Implementar um algoritmo para delegar a composição ao HWC gradualmente. Por exemplo, delegue apenas as três ou quatro primeiras superfícies à sobreposição hardware do HWC.
- Otimizar a HWC. Isso pode incluir:
- Selecionar superfícies que maximizam a carga retirada da GPU ao HWC.
- Detectando se a tela está sendo atualizada. Se não estiver, delegue para o GLES em vez da HWC para economizar energia. Quando a tela for atualizado novamente, continue a descarregar a composição no HWC.
- Preparar-se para casos de uso comuns, como:
- A tela inicial, que inclui a barra de status, a barra do sistema, o app janela e planos de fundo interativos,
- Jogos em tela cheia nos modos retrato e paisagem
- Vídeo em tela cheia com legendas e reprodução controle
- Reprodução de vídeos protegida
- Janela dividida em tela dividida
Primitivos de HWC
O HWC fornece dois primitivos, camadas e telas, para representam o trabalho de composição e a interação dele com o hardware de tela. O O HWC também oferece controle sobre VSYNC e um callback para o SurfaceFlinger para notificá-lo quando ocorrer um evento VSYNC.
Interface HIDL
O Android 8.0 e versões mais recentes usam
interface HIDL chamada HAL do Composer para
IPC vinculada entre o HWC e o SurfaceFlinger. A HAL do Composer substitui
interface hwcomposer2.h
legada. Se os fornecedores fornecerem uma HAL do Composer
implementação do HWC, a HAL do Composer aceita diretamente chamadas HIDL do
com o SurfaceFlinger. Se os fornecedores fornecerem uma implementação legada de HWC, o Composer
A HAL carrega ponteiros de função de hwcomposer2.h
.
encaminhar chamadas HIDL para chamadas de ponteiro de função.
O HWC oferece funções para determinar as propriedades de uma determinada tela. para alternar entre diferentes configurações de tela (como 4K ou 1080p resolução) e modos de cor (como cor nativa ou sRGB verdadeiro); e transformar a tela ligada, desligada ou em um modo de baixo consumo de energia, se compatível.
Ponteiros de função
Se os fornecedores implementarem a HAL do Composer diretamente, o SurfaceFlinger chamará as funções dele.
por meio do HIDL IPC. Por exemplo, para criar uma camada, o SurfaceFlinger chama
createLayer()
no HAL do Composer.
Se os fornecedores implementarem a interface hwcomposer2.h
, a HAL do Composer
chamadas em ponteiros de função hwcomposer2.h
. Em hwcomposer2.h
comentários,
As funções de interface HWC são
referenciados por nomes bottomCamelCase que não existem na interface
como campos nomeados. Quase todas as funções são carregadas ao solicitar um
ponteiro de função usando o getFunction
fornecido pelo
hwc2_device_t
. Por exemplo, a função createLayer
é um ponteiro de função do tipo HWC2_PFN_CREATE_LAYER
, que é
retornado quando o valor enumerado HWC2_FUNCTION_CREATE_LAYER
é
transmitido para getFunction
.
Para consultar a documentação detalhada sobre as funções HAL do Composer e passagem de funções HWC
funções, consulte composer
. Para acessar a documentação detalhada
ponteiros da função HWC, consulte a
hwcomposer2.h
Alças de camada e exibição
As camadas e telas são manipuladas por alças geradas pelo HWC. As alças são opacas para o SurfaceFlinger.
Quando o SurfaceFlinger cria uma nova camada, ele chama createLayer
,
que retorna do tipo Layer
para
ou hwc2_layer_t
para implementações de passagem. Quando
O SurfaceFlinger modifica uma propriedade dessa camada, e o SurfaceFlinger passa
o valor hwc2_layer_t
na função de modificação adequada
além de outras informações necessárias para fazer a modificação. O
O tipo hwc2_layer_t
é grande o suficiente para conter um ponteiro ou um
índice.
Telas físicas são criadas com a conexão por hotplug. Quando uma tela física é
conectado, o HWC cria um identificador e o transmite para o SurfaceFlinger
pelo callback do hotplug. Telas virtuais criadas pelo SurfaceFlinger
chamando createVirtualDisplay()
para solicitar uma exibição. Se o dispositivo HWC
oferece suporte à composição de exibição virtual, ele retorna um identificador. Em seguida, o SurfaceFlinger
delega a composição das telas para o HWC. Se a HWC não oferecer suporte a
composição de exibição, o SurfaceFlinger cria o identificador e compõe a tela.
Mostrar operações de composição
Uma vez por VSYNC, o SurfaceFlinger é ativado se tiver um novo conteúdo para compor. Esse novo conteúdo pode ser novos buffers de imagem de apps ou uma mudança nas propriedades de uma ou mais camadas. Quando o SurfaceFlinger acorda:
- Processa transações, se houver.
- Trava novos buffers gráficos, se presentes.
- Executa uma nova composição se a etapa 1 ou 2 resultar em uma mudança ao conteúdo de exibição.
Para realizar uma nova composição, o SurfaceFlinger cria e
destrói camadas ou modifica os estados das camadas, conforme aplicável. Ele também atualiza
camadas com seus conteúdos atuais, usando chamadas como
setLayerBuffer
ou setLayerColor
. Depois que todas as camadas são
atualizadas, o SurfaceFlinger chama validateDisplay
, que instrui
o HWC a examinar o estado das camadas e determinar como a composição vai
prosseguir. Por padrão, o SurfaceFlinger tenta configurar todas as camadas.
de forma que a camada seja composta pelo HWC; embora, em alguns
circunstâncias, o SurfaceFlinger compõe camadas usando o substituto da GPU.
Após a chamada para validateDisplay
, o SurfaceFlinger chama
getChangedCompositionTypes
para ver se o hardware
quiser que qualquer um dos tipos de composição da camada seja alterado antes de realizar a
composição. Para aceitar as mudanças, o SurfaceFlinger chama
acceptDisplayChanges
:
Se alguma camada estiver marcada para a composição do SurfaceFlinger, o SurfaceFlinger
e os compõe no buffer de destino. O SurfaceFlinger chama
setClientTarget
para fornecer o buffer à tela, para que o
buffer possa ser mostrado na tela ou composto com camadas que
não foram marcadas para a composição do SurfaceFlinger. Se nenhuma camada estiver marcada para
Composição do SurfaceFlinger, o SurfaceFlinger ignora a etapa de composição.
Por fim, o SurfaceFlinger chama presentDisplay
para informar
ao HWC que ele precisa concluir o processo de composição e mostrar o resultado final.
Várias telas
O Android 10 oferece suporte a várias telas físicas. Ao projetar uma implementação de HWC destinada ao uso no Android 7.0 e versões mais recentes, há algumas restrições que não estão presentes na definição de HWC:
- Suponha que haja exatamente uma tela interna. Os dados tela é aquela que o hotplug inicial informa durante inicialização. Depois que a tela interna é conectada, não é possível ser desconectados.
- Além da tela interna, qualquer número de monitores externos pode estar conectado por hotplug
durante a operação normal do dispositivo. O framework presume que todos
os hotplugs após a primeira tela interna são telas externas, portanto, se houver mais
telas internas forem adicionadas, elas serão categorizadas incorretamente como
Display.TYPE_HDMI
em vez deDisplay.TYPE_BUILT_IN
.
Enquanto as operações do SurfaceFlinger descritas acima são realizadas por tela, elas são realizadas sequencialmente para todas as telas ativas, mesmo que o conteúdo de apenas uma tela seja atualizado.
Por exemplo, se o monitor externo for atualizado, a sequência será:
// In Android 9 and lower: // Update state for internal display // Update state for external display validateDisplay(<internal display>) validateDisplay(<external display>) presentDisplay(<internal display>) presentDisplay(<external display>) // In Android 10 and higher: // Update state for internal display // Update state for external display validateInternal(<internal display>) presentInternal(<internal display>) validateExternal(<external display>) presentExternal(<external display>)
Composição de tela virtual
A composição da tela virtual é semelhante à da tela externa composição. A diferença entre a composição da tela virtual e as formas físicas composição da exibição é que as telas virtuais enviam saídas para um buffer Gralloc, e não na tela. O Hardware Composer (HWC) grava a saída em um buffer, fornece o limite de conclusão e envia o buffer para um consumidor (como o codificador de vídeo, GPU, CPU e assim por diante). Telas virtuais podem usar 2D/blitter ou se o pipeline de exibição fizer gravações na memória.
Modos
Cada frame está em um dos três modos depois que o SurfaceFlinger chama o
método HWC validateDisplay()
:
- GLES: a GPU compõe todas as camadas, gravando diretamente no buffer de saída. A HWC não está envolvida na composição.
- MIXED: a GPU compõe algumas camadas no framebuffer, e o HWC compõe o framebuffer e as camadas restantes, gravando diretamente no buffer de saída.
- HWC: HWC compõe todas as camadas e grava diretamente ao buffer de saída.
Formato de saída
Os formatos de saída do buffer de exibição virtual dependem do modo:
- Modo GLES: o driver EGL define o buffer de saída.
em
dequeueBuffer()
, normalmenteRGBA_8888
. O consumidor precisa ser capaz de aceitar o formato de saída definido pelo driver ou a e o buffer não pode ser lido. - Modos MIXED e HWC: se o consumidor precisar de CPU
acesso, o consumidor define o formato. Caso contrário, o formato será
IMPLEMENTATION_DEFINED
, e o Gralloc define o melhor formato com base as flags de uso. Por exemplo, Gralloc define um formato YCbCr se o consumidor o codificador de vídeo e o HWC possam gravar o formato de forma eficiente.
Limites de sincronização
As cercas de sincronização (sync) são um aspecto crucial do sistema gráfico do Android. Os limites permitem que o trabalho da CPU ocorra de maneira independente do trabalho simultâneo da GPU. o bloqueio de dados somente quando há uma dependência verdadeira.
Por exemplo, quando um app envia um buffer que está sendo produzido em a GPU também envia um objeto de limite de sincronização. Essa cerca sinaliza quando A GPU terminou de gravar no buffer.
O HWC exige que a GPU termine de gravar buffers antes que os buffers sejam exibidos. As cercas de sincronização são transmitidas pelo pipeline gráfico com buffers e sinalizam quando os buffers são gravados. Antes que um buffer seja mostrado, o HWC verifica se a cerca de sincronização sinalizou e, se sim, exibe o buffer.
Para mais informações sobre limites de sincronização, consulte Hardware Composer Integração.