Double Buffering: o que é e para que serve

4 min de leitura
Imagem de: Double Buffering: o que é e para que serve

Eis uma cena clássica: completamente envolvido com aquele seu jogo favorito, você parte em busca do chefão da máfia que — quem diria? — andava arquitetando todas as desgraças que acometeram o seu personagem ao longo da trama. Envolvimento e adrenalina não poderiam ser maiores... Quando surge uma surpresa: o seu carro é completamente destruído por um prédio que simplesmente não deveria estar ali.

Não, certamente não se trata de alguma forma de poder mediúnico daquele seu inimigo confesso. Há, entretanto, um belo exemplo do clássico “pop-in”, espécie de bug ocasionado por uma insuficiência gráfica — que resulta em uma releitura cômica da antiga teoria científica da “geração espontânea”. Em termos mais práticos, trata-se de um belo balde de água fria capaz de comprometer o clima da aventura que é exibida na tela.

Mas há um antídoto para situações assim. O nosso bom e velho “pop-in” nada mais é do que uma utilização insuficiente do que a arquitetura de computadores chama de “buffer”: um espaço que é alocado temporariamente para dados que, uma vez processados, serão exibidos na tela — sem efeitos indesejáveis como flicker (tremulações na imagem), tearing (cortes horizontais na tela) ou, é claro, o pop-in.

Dessa forma, o processo conhecido como double buffering surge como uma evolução natural: se modelos de processamento gráfico mais primitivos contavam com apenas um buffer (espaço de armazenamento) para preparar as  imagens que seriam exibidas, que tal, pois, adicionar um segundo espaço, a fim de manter o fluxo constante de dados?

Fonte: Techpubs.sgi.com
Ok, uma explicação teórica razoável. Mas há uma forma melhor de entender o que exatamente o double buffering faz — ou deixa de fazer — por você enquanto um blockbuster roda a todo o vapor na sua TV ou monitor. Basta pinçar um exemplo do “mundo real”.

Dois baldes são melhores do que apenas umO negócio é manter o fluxo constante

Digamos que, em uma tarde particularmente escaldante, você resolve desenrolar aquela sua velha piscina de 1000 litros, a fim de diminuir a penúria da situação. Mas há um inconveniente: a mangueira de jardim não pode ser encontrada em parte alguma. Isso significa que os 1000 litros terão que ser transportados em baldes.

Dessa forma, você então enche um balde (que bem poderia ser um buffer) por vez na sua torneira (que bem poderia ser um processador gráfico). Em seguida, resta caminhar até a piscina para esvaziar aquela água... E então repetir o processo. Com um porém, entretanto: a torneira, é claro, deverá ser fechada enquanto o primeiro balde é levado até o seu destino.

Img_normal

Mas... Por que não utilizar dois baldes? Dessa forma, enquanto um deles é levado até a piscina, o outro permanecerá enchendo, de forma que o fluxo de água (ou seria de dados?) permaneça constante.

A despeito da analogia escolhida, o princípio geral por trás da ideia de double buffering é rigorosamente o mesmo. Quando dois espaços de alocação temporária são utilizados pela GPU, o processamento de dados não precisa esperar até que a imagem já construída seja exibida na tela — consequentemente, esvaziando o buffer.

Sem escorregões gráficosEvitando flickers, tearings e afins

Voltando ao âmbito estrito da computação gráfica, o double buffering é uma técnica utilizada para, digamos, “homogeneizar” as imagens que são exibidas na tela, de forma que se evitem várias falhas gráficas — ou que, ao menos, elas sejam diminuídas ao máximo.

Uma implementação de double buffering usualmente estoca os resultados de cálculos que serão exibidos em uma estrutura denominada back buffer. Uma vez que todos os cálculos sejam concluídos, o resultado será remetido para o front buffer para, por fim, ser exibido na tela — ou enviado para outro dispositivo de saída qualquer.

Existe um motivo bastante claro para a necessidade de se manterem dois espaços temporários na memória. Basicamente, é difícil para um programa jogar uma nova imagem na tela de forma que apenas alguns poucos pixels sejam alterados durante o processo. Em outras palavras, é mais fácil para o processamento gráfico apagar toda a tela para em seguida reimprimi-la, do que alterar apenas os pixels que não são mantidos entre um e outro quadro.

Todavia, a imagem intermediária que resulta desse processo ocasionalmente será vista pelo usuário, ocasionando o famoso flickering, cujo exemplo mais típico é o brilho emitido por monitores de computador operando em taxas baixas de atualização (a rigor, menores que 60 quadros por segundo).

Por outro lado, há casos em que não há a sincronização entre os dados gráficos que deixam a GPU (unidade de processamento gráfico) e a taxa de atualização do monitor. Nessas situações, o que se tem é o tearing, espécie de corte horizontal — já que as atualizações de tela ocorrem sempre horizontalmente — que nada mais é do que duas imagens justapostas. O monitor simplesmente exibiu um momento intermediário entre imagens sucessivas — naturalmente, o problema pode ser evitado mediante a sincronização entre monitor e GPU.

De qualquer forma, vale lembrar que nem tudo aqui são flores “pixelizadas”. O double buffering ocupa uma quantia consideravelmente maior de memória de vídeo e  de tempo de processamento — se comparado com a utilização de apenas um buffer. Isso em razão da memória extra utilizada para alocar o back buffer, bem como do tempo necessário para as cópias sucessivas e para a sincronização entre os dispositivos de saída.

Você sabia que o TecMundo está no Facebook, Instagram, Telegram, TikTok, Twitter e no Whatsapp? Siga-nos por lá.