1 puntos por GN⁺ 2024-01-30 | 1 comentarios | Compartir por WhatsApp
  • La base de renderizado de GTK se reorganiza con ngl para GL y vulkan para Vulkan, y ambos renderizadores tienen una estructura unificada que se compila desde la misma fuente
  • La implementación común se basa en el flujo de la API Vulkan y abstrae las diferencias entre GL 3.3+ y GLES 3.0+, compartiendo la infraestructura de renderizado como el recorrido del grafo de escena y las cachés
  • Los nuevos renderizadores priorizan por ahora la precisión y la mantenibilidad antes que la velocidad, y mejoran el antialiasing, el escalado fraccional, una cantidad ilimitada de puntos de parada de color en degradados y el soporte de dmabuf
  • Los desarrolladores de apps deben revisar la falta de soporte para nodos glshader, los cambios en el manejo de posiciones fraccionales y posibles problemas de drivers; incluso si parece un problema del driver, conviene reportarlo a GTK
  • En el snapshot GTK 4.13.6, ngl es el nuevo valor predeterminado, pero todavía está en fase de prueba; si aparecen problemas importantes, GTK 4.14 podría volver al renderizador gl anterior

Renderizadores unificados para GL y Vulkan

  • GTK agregó un nuevo renderizador ngl para GL y un nuevo renderizador vulkan para Vulkan
  • Ambos renderizadores se compilan desde la misma fuente, por eso se los llama renderizadores unificados
  • El modelo de implementación sigue la API Vulkan e incluye abstracciones para manejar las diferencias entre GL 3.3+ y GLES 3.0+
  • Gracias a esta estructura, se puede compartir el trabajo de base que antes se mantenía por separado para cada renderizador
    • Recorrido del grafo de escena
    • Transformaciones y mantenimiento de otros estados
    • Cachés de texturas y glifos
    • Trabajo para mantener ambos renderizadores actualizados y alineados

Condiciones para extenderlo a Metal y DirectX

  • Existe la posibilidad de extender el mismo enfoque a un renderizador basado en Metal para macOS o a uno basado en DirectX para Windows
  • Vulkan y GL tienen una ventaja: básicamente comparten el mismo lenguaje de shaders, GLSL
  • En Metal o DirectX no se dan las mismas condiciones, por lo que sería necesario duplicar los shaders o usar una herramienta de conversión como SPIRV-Cross
  • Se reciben con gusto contribuciones de quienes estén interesados en este trabajo

Forma de implementación y ubershaders

  • El renderizador GL anterior usa shaders simples para cada tipo de rendernode y, con contenido complejo, depende con frecuencia del renderizado offscreen
  • El renderizador unificado también tiene shaders por nodo más potentes, pero además usa shaders complejos que interpretan datos de búfer en lugar de recurrir al offscreen
  • En programación de videojuegos, este enfoque se conoce como ubershader
  • La nueva implementación está menos optimizada que el renderizador GL anterior, pero prioriza la precisión y la mantenibilidad, por lo que puede manejar correctamente una variedad más amplia de árboles de rendernode

Calidad de renderizado y nuevas funciones

  • Antialiasing

    • El renderizador GL anterior puede perder detalles lo bastante pequeños como para quedar entre los límites de una línea de píxeles
    • Este problema también puede afectar subrayados como los mnemónicos
    • El renderizador unificado conserva mejor los detalles pequeños y también reduce el efecto escalonado en los contornos de las primitivas
  • Escalado fraccional

    • El antialiasing es la base para manejar correctamente el escalado fraccional
    • Al escalar una ventana de 1200×800 al 125%, el renderizador unificado usa un framebuffer de 1500×1000
    • Esto procesa muchos menos píxeles y produce una imagen más nítida que dejar que el compositor reduzca una imagen de 2400×1600
  • Degradados arbitrarios

    • El renderizador GL anterior maneja como máximo 6 puntos de parada de color en degradados lineales, radiales y cónicos
    • El renderizador unificado permite una cantidad ilimitada de puntos de parada de color
    • También aplica antialiasing a los degradados, creando líneas suaves en bordes pronunciados
  • dmabuf

    • GTK trabajó el otoño pasado en soporte para dmabuf y en offloading gráfico
    • El nuevo renderizador lo soporta y extiende la API render_texture para poder crear dmabufs cuando se solicita la creación de una textura
    • Actualmente, esta extensión solo aplica al renderizador Vulkan

Aspectos que deben revisar los desarrolladores de apps

  • Sin soporte para nodos glshader

    • Los nodos glshader fueron útiles en la demo de GTK 4.0, pero están fuertemente ligados al renderizador GL anterior
    • Esos nodos asumen la API GLSL expuesta por el renderizador anterior
    • El nuevo renderizador no soporta nodos glshader
    • La documentación de GTK recomienda validar antes de depender de shaders y, si falla, usar un shader más simple o una ruta alternativa sin shaders
    • Desde GTK 4.0 se agregaron funciones como nodos mask y soporte de texturas straight-alpha, por lo que muchos casos de uso de nodos glshader ya no son necesarios
  • Posiciones fraccionales

    • Como el renderizador GL anterior redondeaba las posiciones, pasar posiciones fraccionales podía no revelar problemas
    • El nuevo renderizador coloca los elementos exactamente en la posición especificada
    • Esta diferencia puede producir resultados no deseados, por lo que hay que verificar que las posiciones sean las esperadas
    • Hay que prestar especial atención al dibujo estilo cairo, que coloca líneas en posiciones de medio píxel para llenar exactamente una fila de píxeles
  • Problemas de drivers

    • El nuevo renderizador usa los drivers gráficos de una forma nueva y distinta, por lo que puede activar problemas del lado del driver
    • Aunque el problema parezca ser del driver, conviene reportarlo a GTK
    • Eso ayuda a entender qué tan bien funciona el nuevo código en distintos drivers y hardware

Estado actual de rendimiento

  • Los nuevos renderizadores todavía no son más rápidos que los anteriores
  • El renderizador GL anterior está muy optimizado para velocidad, usa shaders más simples y no realiza cálculos necesarios para funciones como el antialiasing
  • El objetivo es que los nuevos renderizadores eventualmente sean más rápidos, pero por ahora las mejoras más importantes son las nuevas funciones y la precisión
  • Todos los renderizadores basados en GPU son actualmente lo bastante rápidos para renderizar apps GTK a 60 fps o 144 fps
  • En benchmarks no científicos, el renderizador Vulkan se acerca al nivel del renderizador GL anterior, igualándolo o superándolo en algunos casos
  • Todavía no se ha identificado por qué el nuevo renderizador GL es más lento

Cambio de valor predeterminado y excepciones

  • En el snapshot GTK 4.13.6 recién lanzado, el renderizador ngl pasó a ser el nuevo valor predeterminado
  • Este cambio es una prueba y debe validarse con pruebas más amplias en varias apps para confirmar si está listo para producción
  • Si aparecen problemas importantes, en GTK 4.14 se podría volver al renderizador gl anterior
  • El renderizador Vulkan todavía no es el predeterminado
    • El port GTK4 de WebKit funciona con GL, pero no con Vulkan
    • GtkGLArea y GtkMediaStream actualmente crean texturas GL, y el renderizador Vulkan no puede importarlas directamente
    • Si estos problemas se resuelven en el futuro cercano, se volverá a evaluar la decisión sobre el renderizador predeterminado
  • Si usas GTK en hardware muy antiguo, el renderizador GL anterior podría convenir más
    • El renderizador GL anterior exige menos a la GPU
    • Se puede sobrescribir la selección del renderizador con la variable de entorno GSK_RENDERER
    • Ejemplo: GSK_RENDERER=gl

Trabajo posible a futuro

  • Los nuevos renderizadores sientan las bases para implementar funciones deseadas desde hace mucho tiempo
  • Entre los trabajos posibles a futuro se incluyen:
    • Manejo de color correcto, incluido HDR
    • Renderizado de trazados en la GPU
    • Posible inclusión del renderizado de glifos
    • Renderizado fuera del hilo principal
    • Mejoras de rendimiento en dispositivos antiguos y menos potentes
  • Algunos de estos puntos serán el foco del trabajo a corto y mediano plazo
  • Los nuevos renderizadores tienen más funciones previstas, y los usuarios pueden probarlos directamente e informar si funcionan correctamente

1 comentarios

 
GN⁺ 2024-01-30
Comentarios en Hacker News
  • Hace mucho tiempo, quizá por 2010, creo que había un renderizador HTML experimental que permitía ejecutar apps GTK dentro del navegador y construir la UI con HTML+CSS común
    En ese momento fue realmente impactante, y creo que fue antes de Atom, VS Code, Electron, y quizá incluso antes de NodeJS
    No sé si ese renderizador sigue existiendo

    • ¿Te refieres a Broadway?
      https://docs.gtk.org/gtk4/broadway.html
      https://www.phoronix.com/news/GTK4-Broadway-Being-Used
      No lo consideraba un backend principal/oficial, pero sigue existiendo y también fue porteado a Gtk4
    • Aunque usa más HTML y CSS que cosas similares, me parece difícil llamarlo HTML+CSS común
      Porque en comportamiento se acerca más a un enfoque de canvas puro que rehace todo desde cero, descartando casi todo lo que ofrece el navegador
      Los criterios para juzgar si funciona bien suelen ser: (a) usar el scroll del navegador, (b) usar el renderizado de texto del navegador, y (c) tratar los enlaces como elementos reales, y Broadway falla en las tres
      Reimplementa el scroll, renderiza el texto en el servidor y lo envía como imagen, y parece que al intentar hacer clic en un enlace realmente se congela
      Además, da la impresión de que la entrada de texto también usa solo eventos de teclado, así que la composición de IME queda completamente rota, y la navegación por teclado probablemente tampoco es nativa sino del lado de GTK
      Tampoco puede ofrecer un árbol de accesibilidad de forma significativa
      Está bien como demo técnica o para uso personal aceptando sus limitaciones, pero no sirve para distribución pública y en la práctica se parece más a algo del tipo RDP/VNC con un poco de DOM mezclado
      También hay que recordar que todo el código corre del lado del servidor
    • En GTK3, llamarlo renderizador HTML ya es exagerar un poco
      Básicamente transmite datos de píxeles a un elemento canvas, así que es casi lo mismo que un VNC con visor web
      https://imgur.com/a/2EDZ2Ti
    • El nombre es Broadway: https://docs.gtk.org/gtk4/broadway.html
    • Hace tiempo hice una pequeña prueba de concepto ejecutándolo con broadway dentro de Docker, y funcionaba bastante bien
      https://github.com/moondev/gtk3-docker
      Mi caso de uso era ejecutar un navegador dentro del navegador para interactuar fácilmente con servicios clusterip de Kubernetes sin port forwarding ni proxies
      Otro ejemplo interesante es levantar virt-manager, ejecutar una VM con gtk virt-viewer y controlarla desde el navegador
      https://github.com/m-bers/docker-virt-manager
  • Ojalá GTK no siguiera la tendencia de poner widgets en la barra de título
    Algunas cosas se pueden arrastrar y otras no, y además se reduce el espacio para mostrar el nombre de la app y el nombre del archivo
    No es una queja exclusiva contra GTK

    • ¿Esa tendencia no la iniciaron gtk/gnome?
    • Ya es bastante malo que esto pase en GNOME; ojalá GTK no sume otro error más
  • Ajuste de escalado fraccional con precisión de píxel, qué bien, ¡uhú!

    • Durante más de 10 años GTK sostuvo que el escalado fraccional era “imposible”, y los desarrolladores de GTK bloquearon el escalado fraccional en el protocolo Wayland; por fin alcanzó paridad funcional con Qt en esta área
      Ahora, si también se soporta bien en Wayland, parece que por fin será posible tener soporte HiDPI en todos los principales entornos de escritorio de Linux
    • La explicación del post me resulta un poco confusa
      Dice que si una ventana de 1200×800 se escala a 125%, el renderizador unificado usa un framebuffer de 1500×1000 en lugar de dejar que el compositor reduzca una imagen de 2400×1600
      Según lo entiendo, eso significa que por el escalado de 125% la ventana debe dibujarse en pantalla como 1500×1000 píxeles, aunque en píxeles de la aplicación sea de 1200×800
      Como OpenGL y Vulkan renderizan con punto flotante, la idea sería dibujar directamente en un búfer que pueda renderizarse 1:1 en pantalla mediante transformación de coordenadas
      Si entendí bien, por fin parece una forma sensata de hacerlo
  • ¿Alguien entiende de verdad cómo funcionan los entornos de escritorio en Linux? Yo no mucho
    Cada vez siento más que solo se han vuelto más complejos y llenos de parches

    • El X Window System fue, en esencia, una apuesta equivocada sobre cómo evolucionarían las GUI y el hardware de las computadoras
      La estructura cliente/servidor terminó siendo lo opuesto al modelo altamente integrado de procesamiento gráfico al que llegamos
      En vez de abandonar X11 temprano y cortar pérdidas, tanto los vendors de Unix como el mundo open source pasaron demasiado tiempo intentando hacer limonada con un camión entero de limones podridos
      Por eso las GUI de Linux se quedaron tan atrás
      Apple pudo avanzar rápido con las GUI Unix porque no estaba atada a X11 y adoptó un modelo integrado; además, destaca que ahora hasta diseña sus propias GPU
    • GNOME está bastante cerca de ser el que va a la cabeza por ese lado
      Me pregunto qué tan grande será el impacto de la arquitectura de Wayland y si llegarán a existir realmente apps exclusivas de GNOME
  • Estaría bueno tener un renderizador de texto ANSI
    para poder ejecutar programas GTK dentro de mi xterm, y opcionalmente agregarle un poco de sixel

    • Hoy en día, la mayoría de las apps GTK se ven bastante parecidas
      una barra lateral, algunas acciones en la barra de título y una estructura de vista de detalles
      Las apps de Mac, las apps “modernas” de Windows y las apps móviles también se parecen
      Me pregunto si un toolkit de UX podría ser completamente declarativo y semántico
      algo como “vista maestro/detalle, una vista de lista con estos campos, se necesitan algunas acciones”, sin dar posiciones ni estilos a alto nivel, sino usando automáticamente los widgets apropiados del sistema
      Encima de eso, se podría añadir un poco de CSS o una vía de escape hacia widgets nativos
      Casi cualquier app que no sea un navegador, un editor WYSIWYG o un visor multimedia encajaría en este modelo, y el punto clave es que sería fácil generar una TUI a partir de esa descripción
    • Combinar broadway y carbonyl, mencionados en otro comentario, sería algo más o menos parecido
      https://github.com/fathyb/carbonyl
      https://i.imgur.com/pIQ4K7Q.png
  • Si hubieran usado https://wgpu.rs/, habrían obtenido DirectX y Metal gratis :)

  • Este trabajo se ve realmente divertido
    Mientras leía la parte sobre antialiasing, pensé que los campos de distancia con signo quizá también funcionarían bien para renderizar fuentes a escala arbitraria, como en los motores de juegos
    Valve publicó un buen paper sobre este tema
    En el código de UI o en el renderizado de decals de los renderizadores de juegos hay muchas técnicas geniales que también podrían servir para código GUI

  • No entiendo por qué se acepta una caída de rendimiento
    Yo hago la mayor parte de mi trabajo en hardware viejo, así que si estas funciones se pueden desactivar, preferiría desactivarlas, y puede que mi GPU ni siquiera las soporte

    • Creo que la palabra importante en “No, el nuevo renderizador todavía no es más rápido” es todavía
      Si hay una caída de rendimiento perceptible, se puede usar GSK_RENDERER=gl
      Si esto fuera Microsoft, Apple o Google, probablemente ni siquiera estarían discutiendo estas cosas
      Seguramente Microsoft diría “olvida la API anterior, aquí tienes la nueva”, Apple “es obligatorio a partir de ${WEIRD_NAME}” y Google “esa actualización no te va a llegar”
    • En GL, si por accidente no entras en un camino rápido, es muy fácil que se vuelva sorprendentemente lento; y al revés, si sí entras en ese camino, puede ser sorprendentemente rápido
      Lo decepcionante, sin embargo, es que el renderizador Vulkan apenas alcance un rendimiento casi igual al del renderizador GL existente
      Eso parece indicar que el problema está del lado del llamador, más que en la API 3D en sí
      Deberían haber seguido el rendimiento y hecho mejoras iterativas durante toda la implementación; confiar en la “pureza arquitectónica” no parece haber sido una buena idea
    • El único caso en que tolero una regresión de rendimiento es cuando la implementación anterior realmente estaba mal, no cuando solo era vieja o había que reescribirla en un framework o tecnología de moda
    • Estos renderizadores no son el valor predeterminado y probablemente no lo serán en el futuro
      Nunca he visto que convertir una API de renderizado de modo inmediato a modo retenido la haga más rápida
      De alguna forma podría lograrse, pero requeriría un trabajo enorme, y para corregir casos patológicos también harían falta cambios del lado del cliente de la API
    • El equipo de desarrollo de GNOME, y más ampliamente la gente de GTK, no parece preocuparse mucho por esto
      Según recuerdo, la mayoría usa MacBooks caros, así que muchos problemas se descartan con un “en mi computadora funciona bien”
      Por ejemplo, hay varios problemas de renderizado de fuentes que no afectan a las pantallas Retina
  • Espero que esto no suene amargo, pero la mayoría de los buenos desarrolladores de motores gráficos ya han venido construyendo renderizadores varias generaciones por delante de los renderizadores de toolkits GUI de código abierto
    Entre nosotros hay varias personas capaces de llevar renderizado verdaderamente de próxima generación al escritorio de código abierto, pero trabajan en empresas de desarrollo de videojuegos y de eso viven
    No tienen tiempo para contribuir al stack de código abierto
    Si la comunidad pudiera organizar un presupuesto para pagarles regularmente a este tipo de desarrolladores, las actualizaciones de renderizadores y toolkits serían muy diferentes
    Lo mismo aplica para otras apps de código abierto

    • He implementado renderizadores GUI orientados a GPU varias veces en el pasado; por ejemplo, está esto: 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
      Los gráficos 2D tienen muy poco en común con los motores de juegos
      En 2D normalmente llegan como entrada curvas Bézier y otros splines, hay mucho overdraw, y la gestión de memoria de VRAM se complica por las texturas proporcionadas por el usuario
      En cambio, los motores de juegos resuelven problemas difíciles que no tienen relación con los renderizadores 2D, como iluminación dinámica, efectos volumétricos y entornos dinámicos
    • Soy un poco escéptico con esa afirmación
      Siento que los toolkits de UI para juegos y los frameworks de GUI de escritorio viven en mundos distintos, con expectativas diferentes
      Por mi experiencia usando ambos en mi carrera, GTK/Qt por lo general manejan bien o muy bien cosas como la integración con el sistema operativo, funciones de accesibilidad, navegación por teclado y copiar/pegar
      Los toolkits de UI para juegos muchas veces renuncian por completo a esas cosas porque no las necesitan y, en cambio, se enfocan en rendimiento, tematización e integración con el motor del juego
      En teoría se puede decir que el renderizador es independiente de esas partes, pero en la práctica no lo es del todo
      Cuando el presupuesto es limitado, también cambia a qué funciones se les dedica tiempo
      Un renderizador muy rápido y preciso no es tan importante en un framework de GUI de escritorio como lo es en un toolkit de UI para juegos
    • ¿Cuántos de esos motores de juegos tienen un nivel de abstracción suficiente como para intercambiar un backend de PDF o SVG?
      ¿Cuántos soportan CMYK y unidades de impresión?
      Eso apenas rasca la superficie de las cosas que un renderizador GUI necesita pero un motor de juegos no
      Soy muy escéptico de que un grupo de desarrolladores de juegos pueda improvisar algo mucho más rápido que Skia sin sacrificar demasiadas funciones
    • La comunidad de la que hablas al final son personas como tú
      Gente que necesita ganarse la vida, pero contribuye en la medida de lo posible usando el software y aportando código de vez en cuando
      Claro, sería excelente si la comunidad pudiera reunir fondos, pero ese trabajo de coordinación en sí mismo también termina siendo, para alguien, un trabajo que no le da para vivir
      Me gusta el software de código abierto/libre, agradezco que exista y también contribuyo cuando puedo, pero desde hace mucho pienso que esto es una actividad de gente privilegiada
      Hay que tener tiempo libre, poder dedicar ese tiempo libre a algo que no mejora tu nivel de vida, y poder sostener eso de forma constante
    • Soy bastante escéptico con eso
      Trabajo en la industria de los videojuegos y, aunque los renderizadores 3D son muy buenos, nunca he visto un renderizador de UI 2D que se sienta competitivo
      ¿Qué usan para renderizar trazados y patrones?