- 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
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
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
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
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
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
Ajuste de escalado fraccional con precisión de píxel, qué bien, ¡uhú!
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
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
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
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 sixeluna 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
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
Si hay una caída de rendimiento perceptible, se puede usar
GSK_RENDERER=glSi 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”
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
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
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
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
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 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
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
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?