1 pontos por GN⁺ 2024-01-30 | 1 comentários | Compartilhar no WhatsApp
  • A base de renderização do GTK foi reorganizada em ngl para GL e vulkan para Vulkan, e os dois renderizadores têm uma estrutura unificada compilada a partir do mesmo código-fonte
  • A implementação compartilhada toma o fluxo da API Vulkan como referência e abstrai as diferenças entre GL 3.3+ e GLES 3.0+, permitindo reutilizar a mesma infraestrutura de renderização para travessia do grafo de cena e cache
  • Os novos renderizadores priorizam correção e facilidade de manutenção acima da velocidade imediata, além de melhorar antialiasing, escalonamento fracionário, pontos de parada de gradiente ilimitados e suporte a dmabuf
  • Desenvolvedores de apps devem verificar a falta de suporte a nós glshader, mudanças no tratamento de posições fracionárias e possíveis problemas de driver; mesmo que pareça um problema do driver, é melhor reportá-lo ao GTK
  • No snapshot GTK 4.13.6, o ngl passou a ser o novo padrão, mas ainda está em fase de testes; se surgirem problemas sérios, o GTK 4.14 pode voltar ao renderizador gl antigo

Renderizador unificado para GL e Vulkan

  • O GTK adicionou o novo renderizador ngl para GL e o novo renderizador vulkan para Vulkan
  • Os dois renderizadores são compilados a partir do mesmo código-fonte, por isso são chamados de renderizador unificado
  • O modelo de implementação segue a API Vulkan e inclui abstrações para lidar com as diferenças entre GL 3.3+ e GLES 3.0+
  • Graças a essa estrutura, é possível compartilhar o trabalho de base que antes era mantido separadamente para cada renderizador
    • travessia do grafo de cena
    • manutenção de transformações e outros estados
    • cache de texturas e glifos
    • trabalho para manter os dois renderizadores alinhados e atualizados

Condições para expandir para Metal e DirectX

  • Existe a possibilidade de estender a mesma abordagem para um renderizador baseado em Metal no macOS ou em DirectX no Windows
  • Vulkan e GL levam vantagem por compartilharem essencialmente a mesma linguagem de shaders, o GLSL
  • Essa mesma condição não se aplica a Metal ou DirectX, então seria necessário duplicar shaders ou usar ferramentas de conversão como SPIRV-Cross
  • Contribuidores interessados nesse trabalho são bem-vindos

Modo de implementação e ubershader

  • O renderizador GL antigo usa shaders simples para cada tipo de rendernode e, em conteúdo complexo, depende com frequência de renderização offscreen
  • O renderizador unificado também tem shaders por nó mais poderosos, mas usa junto shaders complexos que interpretam dados de buffer em vez de depender de offscreen
  • Em programação de jogos, essa abordagem é chamada de ubershader
  • A nova implementação é menos otimizada que o renderizador GL antigo, mas prioriza correção e manutenção, conseguindo tratar corretamente uma variedade maior de árvores de rendernode

Qualidade de renderização e novos recursos

  • Antialiasing

    • O renderizador GL antigo podia perder detalhes pequenos o bastante para caber entre os limites de uma única linha de pixels
    • Esse problema podia afetar até sublinhados como os de mnemonics
    • O renderizador unificado preserva melhor esses detalhes pequenos e também reduz o efeito de serrilhado nos contornos das primitivas
  • Escalonamento fracionário

    • O antialiasing é a base para tratar corretamente escala fracionária
    • Ao escalar uma janela de 1200×800 em 125%, o renderizador unificado usa um framebuffer de 1500×1000
    • Isso processa muito menos pixels e gera uma imagem mais nítida do que deixar o compositor reduzir uma imagem de 2400×1600
  • Gradientes arbitrários

    • O renderizador GL antigo lidava com no máximo 6 pontos de parada de cor em gradientes lineares, radiais e cônicos
    • O renderizador unificado permite uma quantidade ilimitada de pontos de parada de cor
    • Ele também aplica antialiasing aos gradientes, criando linhas suaves em bordas nítidas
  • dmabuf

    • No outono passado, o GTK trabalhou em suporte a dmabuf e offloading gráfico
    • O novo renderizador oferece suporte a isso e expande a API render_texture para poder criar dmabuf quando recebe uma solicitação de criação de textura
    • No momento, essa extensão se aplica apenas ao renderizador Vulkan

Pontos que desenvolvedores de apps devem verificar

  • Falta de suporte a nós glshader

    • Os nós glshader eram úteis nas demos do GTK 4.0, mas estão fortemente acoplados ao renderizador GL antigo
    • Esses nós pressupõem a API GLSL exposta pelo renderizador antigo
    • O novo renderizador não oferece suporte a nós glshader
    • A documentação do GTK orienta a validar antes de depender de shaders e, em caso de falha, usar um shader mais simples ou um caminho alternativo sem shader
    • Desde o GTK 4.0, recursos como nós mask e suporte a texturas straight-alpha foram adicionados, então muitos casos de uso de nós glshader já não são mais necessários
  • Posições fracionárias

    • O renderizador GL antigo arredondava posições, então passar posições fracionárias podia não revelar problemas
    • O novo renderizador posiciona exatamente no local especificado
    • Essa diferença pode produzir resultados indesejados, então é preciso verificar se a posição é realmente a desejada
    • É preciso atenção especial a desenhos no estilo cairo, em que uma linha é colocada em meia posição de pixel para preencher exatamente uma linha de pixels
  • Problemas de driver

    • O novo renderizador usa os drivers gráficos de formas novas e diferentes, então pode acabar provocando problemas no lado do driver
    • Mesmo que o problema pareça ser do driver, é melhor reportá-lo ao GTK
    • Isso ajuda a entender o quão bem o novo código funciona em diferentes drivers e hardwares

Estado atual de desempenho

  • O novo renderizador ainda não é mais rápido que o renderizador antigo
  • O renderizador GL antigo foi fortemente otimizado para velocidade, usa shaders mais simples e não faz os cálculos necessários para recursos como antialiasing
  • O objetivo final é tornar o novo renderizador mais rápido, mas no momento os maiores avanços estão em novos recursos e correção
  • Todos os renderizadores atuais baseados em GPU são rápidos o bastante para renderizar apps GTK a 60fps ou 144fps
  • Em benchmarks não científicos, o renderizador Vulkan chega perto de igualar o renderizador GL antigo ou até superá-lo em alguns casos
  • O motivo de o novo renderizador GL ser mais lento ainda não foi rastreado

Mudança de padrão e exceções

  • No recém-lançado snapshot GTK 4.13.6, o renderizador ngl passou a ser o novo padrão
  • Essa mudança é experimental e precisa de testes mais amplos em vários apps para confirmar se está pronta para produção
  • Se aparecerem problemas sérios, o GTK 4.14 pode voltar ao renderizador gl antigo
  • O renderizador Vulkan ainda não é o padrão
    • A porta GTK4 do WebKit funciona com GL, mas não com Vulkan
    • GtkGLArea e GtkMediaStream atualmente criam texturas GL, e o renderizador Vulkan não consegue importá-las diretamente
    • Se esses problemas forem resolvidos em breve, a decisão sobre o renderizador padrão será reavaliada
  • Em hardwares muito antigos, o renderizador GL antigo pode ser a melhor opção
    • O renderizador GL antigo exige menos da GPU
    • É possível sobrescrever a escolha do renderizador com a variável de ambiente GSK_RENDERER
    • Exemplo: GSK_RENDERER=gl

Possíveis trabalhos futuros

  • O novo renderizador serve de base para implementar recursos desejados há muito tempo
  • Entre os trabalhos possíveis daqui para frente estão
    • tratamento correto de cores, incluindo HDR
    • renderização de caminhos na GPU
    • possível inclusão de renderização de glifos
    • renderização fora da thread principal
    • melhoria de desempenho em dispositivos antigos e menos potentes
  • Alguns desses itens devem se tornar foco de trabalho no curto e médio prazo
  • Mais recursos ainda estão planejados para o novo renderizador, e os usuários podem testá-lo por conta própria e informar como ele se comporta

1 comentários

 
GN⁺ 2024-01-30
Comentários no Hacker News
  • Há muito tempo, talvez por volta de 2010, acho que existia um renderizador HTML experimental que abria apps GTK dentro do navegador e montava a UI com HTML+CSS comum
    Na época isso foi realmente chocante, e acho que foi antes do Atom, VS Code, Electron e talvez até do NodeJS
    Não sei se esse renderizador ainda existe

    • Você está falando do Broadway?
      https://docs.gtk.org/gtk4/broadway.html
      https://www.phoronix.com/news/GTK4-Broadway-Being-Used
      Eu não achava que fosse um backend principal/oficial, mas ele ainda existe e também foi portado para GTK4
    • Embora use mais HTML e CSS do que coisas parecidas, acho difícil chamá-lo de HTML+CSS comum
      Isso porque seu comportamento parece mais próximo de uma abordagem de canvas puro que descarta quase tudo que o navegador oferece e refaz tudo do zero
      Os critérios para julgar um comportamento correto geralmente são (a) usar a rolagem do navegador, (b) usar a renderização de texto do navegador e (c) tratar links como elementos reais, e o Broadway falha nos três
      Ele reimplementa a rolagem, renderiza o texto no servidor e o envia como imagem, e parece realmente travar quando se tenta clicar em links
      Além disso, a entrada de texto parece usar apenas eventos de tecla, então a composição por IME fica completamente quebrada, e a navegação por teclado provavelmente fica do lado do GTK, não é nativa
      Ele também não consegue fornecer uma árvore de acessibilidade de forma significativa
      Serve para demos técnicas ou uso pessoal aceitando limitações, mas é inadequado para distribuição pública e, na prática, fica mais próximo de algo do tipo RDP/VNC com um pouco de DOM misturado
      Também é preciso lembrar que todo o código roda no servidor
    • Pelo menos no GTK3, chamar isso de renderizador HTML é um pouco exagerado
      Na prática, ele transmite dados de pixels para um elemento canvas, então é quase igual a um VNC com um visualizador web acoplado
      https://imgur.com/a/2EDZ2Ti
    • O nome é Broadway: https://docs.gtk.org/gtk4/broadway.html
    • Há algum tempo fiz uma pequena prova de conceito rodando dentro do Docker com broadway, e funcionou bem
      https://github.com/moondev/gtk3-docker
      Meu caso de uso era executar um navegador dentro do navegador, para interagir facilmente com serviços Kubernetes clusterip sem encaminhamento de porta nem proxy
      Outro exemplo bacana é abrir o virt-manager, executar uma VM com o gtk virt-viewer e controlá-la pelo navegador
      https://github.com/m-bers/docker-virt-manager
  • Espero que o GTK não siga a tendência de colocar widgets na barra de título
    Algumas coisas podem ser arrastadas e outras não, e também diminui o espaço para mostrar o nome do app e o nome do arquivo
    Essa não é uma reclamação só do GTK

    • Essa tendência não foi criada pelo gtk/gnome?
    • Já é ruim o bastante que isso aconteça no GNOME; espero que o GTK não cometa outro erro grave
  • Escalonamento fracionário preciso em nível de pixel, ótimo, uhu!

    • Por mais de 10 anos o GTK insistiu que escalonamento fracionário era “impossível”, e desenvolvedores do GTK impediram o escalonamento fracionário no protocolo Wayland, mas finalmente alcançaram paridade de recursos com o Qt nessa área
      Agora, se isso for devidamente suportado no Wayland, todos os principais ambientes de desktop Linux poderão ter suporte a HiDPI
    • A explicação do post do blog é meio confusa
      Ele diz que, ao escalar uma janela de 1200×800 para 125%, o renderizador unificado usa um framebuffer de 1500×1000 em vez de deixar o compositor reduzir uma imagem de 2400×1600
      Pelo que entendi, isso significa que, por causa da escala de 125%, uma janela que deve ser desenhada na tela como 1500×1000 pixels é 1200×800 em pixels da aplicação
      Como OpenGL e Vulkan renderizam com ponto flutuante, a ideia deve ser desenhar diretamente em um buffer que possa ser renderizado 1:1 na tela por meio de uma transformação de coordenadas
      Se for isso mesmo, finalmente parece uma abordagem sensata
  • Existe alguém que entenda direito como os ambientes de desktop funcionam no Linux? Eu não entendo bem
    A sensação é de que está ficando cada vez mais complexo e remendado

    • O X Window System foi uma aposta fundamentalmente errada sobre como GUIs e hardware de computador evoluiriam
      A arquitetura cliente/servidor acabou sendo o oposto do modelo de processamento gráfico altamente integrado a que chegamos
      Em vez de abandonar cedo o X11 e cortar as perdas, tanto os fornecedores Unix quanto o open source passaram tempo demais tentando fazer limonada com um caminhão de limões estragados
      É por isso que a GUI no Linux ficou tão atrasada
      A Apple conseguiu fazer a GUI Unix avançar rapidamente porque não ficou presa ao X11 e adotou um modelo integrado, e chama a atenção que agora ela até projeta suas próprias GPUs
    • Nesse campo, o GNOME é algo próximo de líder
      Fico curioso para saber quão grande será o impacto da arquitetura Wayland e se apps exclusivos do GNOME de fato surgirão
  • Seria bom ter um renderizador de texto ANSI
    Para eu poder executar programas GTK dentro do meu xterm, opcionalmente com um pouco de sixel junto

    • Hoje em dia, a maioria dos apps GTK tem uma aparência bem parecida
      Barra lateral, algumas ações na barra de título e uma estrutura de visualização de detalhes
      Apps de Mac, apps “modernos” do Windows e apps móveis também são parecidos
      Fico curioso se um toolkit de UX poderia ser totalmente declarativo e semântico
      Algo que, em alto nível, diga “visualização mestre/detalhe, uma lista com estes campos, algumas ações necessárias”, sem fornecer posição nem estilo, e que use automaticamente os widgets adequados do sistema
      Por cima disso, poderia haver um pouco de CSS ou uma saída de emergência para widgets nativos
      Quase todo app que não seja navegador, editor WYSIWYG ou visualizador de mídia parece se encaixar nesse modelo, e o ponto principal é que, a partir de uma descrição assim, seria fácil gerar uma TUI
    • Combinar o broadway mencionado em outro comentário com o carbonyl chega a algo mais ou menos parecido
      https://github.com/fathyb/carbonyl
      https://i.imgur.com/pIQ4K7Q.png
  • Se tivessem usado https://wgpu.rs/, teriam ganhado DirectX e Metal de graça :)

  • Esse trabalho parece realmente divertido
    Ao ler a parte sobre antialiasing, pensei que campos de distância com sinal, como em engines de jogos, também poderiam funcionar bem para renderização de fontes em escala arbitrária
    A Valve já publicou um bom artigo sobre esse tema
    Há muitas técnicas interessantes no código de UI de renderizadores de jogos ou na renderização de decalques que também poderiam ser úteis em código de GUI

  • Não entendo por que a queda de desempenho é aceitável
    Faço a maior parte do meu trabalho em hardware antigo, e, se puder desativar esses recursos, eu gostaria de fazê-lo; talvez eles nem sejam compatíveis com a minha GPU

    • Em “não, o novo renderizador ainda não é mais rápido”, a palavra importante, para mim, é ainda
      Se houver uma queda de desempenho perceptível, dá para usar GSK_RENDERER=gl
      Microsoft, Apple e Google provavelmente nem teriam discutido isso
      Talvez a Microsoft dissesse “esqueça a API antiga, aqui está a nova API”; a Apple, “obrigatório a partir de ${WEIRD_NAME}”; e o Google, “você não vai receber essa atualização”
    • No GL, se você por acaso perde o caminho rápido, é fácil ficar surpreendentemente lento; por outro lado, se você segue esse caminho, também pode ser surpreendentemente rápido
      Mas o decepcionante é que o renderizador Vulkan só chega a um desempenho quase igual ao do renderizador GL existente
      Isso parece um sinal de que o problema está mais no lado de quem chama do que na API 3D em si
      O desempenho deveria ter sido acompanhado e melhorado iterativamente durante toda a implementação; confiar em “pureza arquitetural” provavelmente não foi uma boa ideia
    • O único caso em que eu tolero uma regressão de desempenho é quando a implementação anterior era realmente incorreta, não apenas antiga ou algo que precisasse ser reescrito com um framework/tecnologia da moda
    • Esses renderizadores não são o padrão e provavelmente também não se tornarão o padrão no futuro
      Nunca vi uma API de renderização de modo imediato ficar mais rápida ao ser convertida para modo retido
      De alguma forma deve ser possível, mas exigiria um trabalho enorme, e corrigir casos patológicos também exigiria mudanças do lado dos clientes da API
    • A equipe de desenvolvimento do GNOME e, de forma mais ampla, o pessoal do GTK parecem não se importar muito
      Pelo que lembro, como a maioria usa MacBooks caros, muitos problemas são ignorados com um “funciona na minha máquina”
      Por exemplo, há vários problemas de renderização de fontes que não afetam telas Retina
  • Espero que isso não soe amargo, mas a maioria dos bons desenvolvedores de engines gráficas já vem criando renderizadores várias gerações à frente dos renderizadores de toolkits GUI open source
    Entre nós, há várias pessoas que poderiam trazer renderização realmente de próxima geração para o desktop open source, mas trabalham em empresas de desenvolvimento de jogos, e é isso que paga as contas
    Não têm tempo para contribuir com a stack open source
    Se a comunidade conseguisse organizar um orçamento para pagar regularmente esses desenvolvedores, as atualizações de renderizadores e toolkits mudariam bastante
    O mesmo vale para outros apps open source

    • No passado, implementei algumas vezes renderizadores de GUI voltados para GPU; por exemplo, este aqui: https://github.com/Const-me/Vrmac?tab=readme-ov-file#vector-graphics-engine https://github.com/Const-me/Vrmac/blob/master/Vrmac/Draw/VAA.md
      Gráficos 2D têm muito pouco em comum com engines de jogos
      Em 2D, a entrada normalmente vem como Béziers e outras splines, há muito overdraw, e o gerenciamento de memória da VRAM fica complicado por causa de texturas fornecidas pelo usuário
      Em contrapartida, engines de jogos resolvem problemas difíceis que não têm relação com renderizadores 2D, como iluminação dinâmica, efeitos volumétricos e ambientes dinâmicos
    • Sou um pouco cético quanto a essa afirmação
      Sinto que toolkits de UI para jogos e frameworks de GUI de desktop vivem em mundos separados, com expectativas diferentes
      Pela minha experiência usando ambos na carreira, GTK/Qt normalmente são bons ou muito bons em lidar com recursos como integração com o sistema operacional, acessibilidade, navegação por teclado e copiar/colar
      Toolkits de UI para jogos muitas vezes não precisam dessas coisas e as abandonam completamente; em vez disso, focam em desempenho, temas e integração com a engine do jogo
      Em teoria, o renderizador poderia ser independente dessas partes, mas na prática não é totalmente assim
      Quando o orçamento é limitado, também muda em quais recursos se gasta tempo
      Um renderizador extremamente rápido e preciso não é tão importante em um framework de GUI de desktop quanto é em um toolkit de UI para jogos
    • Quantas dessas engines de jogos têm um nível de abstração suficiente para poder trocar o backend por PDF ou SVG?
      Quantas dão suporte a CMYK e unidades de impressão?
      Isso é só arranhar a superfície das coisas necessárias em um renderizador de GUI, mas não em uma engine de jogos
      Sou muito cético quanto à ideia de que desenvolvedores de jogos reunidos conseguiriam simplesmente criar algo muito mais rápido que o Skia sem sacrificar muitos recursos
    • A comunidade de que se fala aqui, no fim das contas, são pessoas como você
      Pessoas que precisam se sustentar, mas contribuem na medida do possível usando o software e, às vezes, contribuindo com código
      Claro que seria ótimo se a comunidade conseguisse arrecadar fundos, mas o próprio trabalho de coordenação também acaba sendo algo que não paga as contas de alguém
      Eu gosto de software open source/livre, sou grato por ele existir e contribuo quando posso, mas há muito tempo penso que isso é uma busca de pessoas privilegiadas
      É preciso ter tempo livre, poder usar esse tempo livre em algo que não aumenta seu padrão de vida e conseguir manter isso de forma constante
    • Sou bastante cético quanto a isso
      Trabalho na indústria de jogos e, embora os renderizadores 3D sejam muito bons, nunca vi um renderizador de UI 2D que eu considerasse competitivo
      O que estão usando para renderização de paths e padrões?