Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

O pipeline de renderização

Entender como o desenho vira pixels explica várias regras de performance do framework.

Paint
fachada de alto nível
(rect, text, line, image)
coords locais + clip

gl / Renderers
um renderizador por primitiva
(cada um é um shader)

OpenGL

As camadas do desenho

  • Paint é a fachada com que você desenha em onPaint(...). Ela pensa em coordenadas locais, clip e translação — e nada sabe de shaders ou OpenGL. Você diz “desenhe este retângulo aqui”; como isso vira triângulos e chamadas de GPU não é problema seu.
  • gl / renderizadores — há um renderizador especializado por primitiva (retângulo, retângulo arredondado, linha, texto, imagem…), cada um essencialmente um shader. O Paint delega para o renderizador certo.
  • OpenGL — as draw calls finais.

O conceito central: batching

Renderizadores agrupam desenhos do mesmo tipo em lote (batch) para reduzir chamadas de GPU. A regra que decorre disso:

Trocar de tipo de primitiva “fecha” o batch anterior. A ordem de desenho é sempre preservada, mas alternar tipos (retângulo → texto → retângulo → texto) força vários flushes; agrupar chamadas do mesmo tipo é o que dá desempenho.

Na prática, em desenho custom pesado, desenhar todos os retângulos juntos e depois todos os textos rende mais que intercalar.

Render sob demanda + repintura de árvore inteira

Duas propriedades do modelo de render que afetam como você escreve onPaint:

  • Sob demanda: a tela só redesenha quando alguém pede (repaint() → requestRendering()). Sem pedido, nenhum frame novo é gerado — economiza bateria. (O ângulo de threading disso está em A paint thread.)
  • Sem dirty rectangles: quando um frame acontece, toda a árvore visível é repintada, não só a parte que mudou. Não há repintura parcial.

A consequência prática é um princípio:

Mantenha onPaint barato. Ele roda para a árvore inteira a cada frame renderizado — nada de alocar objetos, carregar recursos ou fazer cálculo caro dentro dele.

Como o frame é montado (visão de alto nível)

A cada frame renderizado, o EventsProcessor pinta a pilha de janelas (via paintWindows(...)): a janela do topo por cima, as de baixo atrás (popups deixam a anterior visível). Cada componente visível recebe seu onPaint(Paint).

// onPaint mínimo e barato: reaproveite temporários, desenhe em coords locais (0,0 = topo-esquerda)
@Override public void onPaint(Paint paint) throws Exception {
   paint.rect(scratch.bounds(0, 0, width, height).fill(bg));   // 'scratch' é um GRect reutilizado
}

Veja também

Esta página foi útil?