3.3 Framebuffer

O framebuffer é uma área contígua da memória utilizada para armazenar a imagem que será mostrada no dispositivo de exibição. O controlador gráfico lê continuamente o conteúdo do framebuffer e atualiza o dispositivo de exibição, tipicamente a uma taxa de 60 Hz nos monitores de LCD.

Nos primeiros PCs e em sistemas gráficos mais antigos, o framebuffer fazia parte da memória padrão que poderia ser acessada diretamente pela CPU. Nos PCs do início da década de 1990, o framebuffer podia ser acessado com um simples ponteiro para o endereço 0xA000 no chamado “modo 13h” do controlador VGA (um modo gráfico de cores indexadas de 8 bits com resolução de 320x200). Atualmente, o framebuffer é acessado através da GPU e está localizado na mesma placa de circuito da GPU (figura 3.27).

Configuração do framebuffer em sistema gráfico com GPU dedicada.

Figura 3.27: Configuração do framebuffer em sistema gráfico com GPU dedicada.


Observação

Em hardware compatível com OpenGL (o que inclui todas as GPUs atuais), o framebuffer pode ser composto por vários buffers. Pelo menos um deles é um color buffer (buffer de cor) no qual cada pixel contém uma informação de cor, geralmente no formato RGB (24 bits) ou RGBA (32 bits).

Um framebuffer pode ter vários buffers de cor associados. Por exemplo, em implementações que suportam visão estereoscópica, dois buffers de cor podem ser utilizados: um para a tela da visão esquerda e outro para a tela da visão direita. Na técnica de backbuffering (descrita no fim da seção), também dois buffers de cor são utilizados: o backbuffer, que é um buffer off-screen (invisível) onde a imagem é renderizada antes de ser exibida na tela, e o frontbuffer, que recebe o conteúdo do backbuffer ao fim da renderização, para exibição na tela. Em renderização estéreo, cada lado esquerdo e direito tem o seu backbuffer e frontbuffer. Além dos buffers de cor, o framebuffer também pode incluir:

  • Um depth buffer (buffer de profundidade), no qual cada pixel contém uma informação de profundidade utilizada no teste de profundidade. O teste de profundidade faz parte da implementação da técnica de Z-buffering de determinação de superfícies visíveis. A informação de profundidade pode ser um inteiro ou ponto flutuante de 16, 24 ou 32 bits (geralmente 24 bits).
  • Um stencil buffer (buffer de estêncil), utilizado no teste de estêncil para operações de mascaramento e composição de imagens. No buffer estêncil, cada pixel contém um inteiro sem sinal, de 1, 4, 8 ou 16 bits (geralmente 8 bits).

Screen tearing

A taxa de atualização do dispositivo de exibição (chamada de vertical refresh rate) é controlada pelo controlador gráfico. Entretanto, a taxa em que o framebuffer é atualizado pode ser bem maior. Essa taxa é o número de quadros por segundo (FPS) que o processador gráfico consegue renderizar. Se o framebuffer for atualizado muito rapidamente, o controlador pode começar a atualizar o dispositivo de exibição com o conteúdo de um quadro e terminar com o conteúdo de outro, mais recente. Essa quebra entre os quadros de exibição gera um defeito na imagem conhecido como screen tearing ou simplesmente tearing (figura 3.28).


Screen tearing. ([fonte](https://commons.wikimedia.org/wiki/File:Tearing_(simulated).jpg)).

Figura 3.28: Screen tearing. (fonte).

Vsync

Para contornar o problema de screen tearing, a GPU pode sincronizar a atualização do framebuffer com a atualização do controlador gráfico, efetivamente limitando o número de FPS à frequência do monitor em Hz. Esse processo de sincronização é chamado de vertical synchronization, ou vsync. Em monitores mais recentes, compatíveis com as tecnologias G-SYNC da NVIDIA, e FreeSync da AMD, é possível fazer a sincronização na direção contrária: a frequência do monitor é ajustada pela GPU de acordo com a taxa de FPS.

Backbuffering

Defeitos de screen tearing também podem ocorrer quando a taxa de renderização é menor que a taxa de atualização do dispositivo de exibição. Nesse caso, o dispositivo de exibição pode mostrar o quadro de exibição antes da renderização ter sido finalizada. O resultado pode ser uma mistura de elementos do quadro atual com elementos do quadro anterior, ou a percepção de que o quadro está sendo desenhado.

Uma forma de reduzir o efeito de screen tearing é o uso de dois buffers de cor: o backbuffer e o frontbuffer. O processador renderiza os gráficos apenas no backbuffer. Após o fim da renderização, o conteúdo é transferido para o frontbuffer, que é então utilizado pelo controlador gráfico para atualizar o dispositivo de exibição. Dessa forma, o controlador sempre utiliza um buffer que já contém um quadro completo. Atualmente, essa técnica de backbuffering é implementada em hardware. O backbuffer e frontbuffer podem ser páginas de memória do framebuffer que são trocadas continuamente em um processo de page flipping, sem precisar realizar transferência de dados (figura 3.29).


Configuração do framebuffer com suporte a backbuffering.

Figura 3.29: Configuração do framebuffer com suporte a backbuffering.