- Die GTK-Rendering-Basis wird mit ngl für GL und vulkan für Vulkan neu aufgestellt; beide Renderer haben eine integrierte Struktur und werden aus derselben Quelle gebaut
- Die gemeinsame Implementierung orientiert sich am Ablauf der Vulkan-API und abstrahiert die Unterschiede zwischen GL 3.3+ und GLES 3.0+, sodass Rendering-Infrastruktur wie Scene-Graph-Traversierung und Caches gemeinsam genutzt wird
- Der neue Renderer priorisiert vorerst Korrektheit und Wartbarkeit statt Geschwindigkeit und verbessert Antialiasing, fraktionale Skalierung, unbegrenzte Gradient-Farbstopps und dmabuf-Unterstützung
- App-Entwickler sollten prüfen, dass glshader-Knoten nicht unterstützt werden, wie sich die Behandlung fraktionaler Positionen verändert und ob Treiberprobleme auftreten; auch wenn es nach einem Treiberproblem aussieht, sollte es an GTK gemeldet werden
- Im Snapshot von GTK 4.13.6 ist ngl der neue Standard, befindet sich aber noch in der Erprobungsphase; bei größeren Problemen kann in GTK 4.14 zum bisherigen gl-Renderer zurückgekehrt werden
Ein integrierter Renderer für GL und Vulkan
- GTK fügt den neuen Renderer ngl für GL und den neuen Renderer vulkan für Vulkan hinzu
- Da beide Renderer aus derselben Quelle gebaut werden, werden sie als integrierter Renderer bezeichnet
- Das Implementierungsmodell folgt der Vulkan-API und enthält Abstraktionen, um die Unterschiede zwischen GL 3.3+ und GLES 3.0+ zu behandeln
- Dadurch kann Basisarbeit, die bisher pro Renderer separat gepflegt wurde, gemeinsam genutzt werden
- Traversierung des Scene Graph
- Verwaltung von Transformationen und anderem Zustand
- Textur- und Glyph-Cache
- Arbeit, um beide Renderer auf dem aktuellen Stand zu halten
Bedingungen für eine Erweiterung auf Metal und DirectX
- Es besteht die Möglichkeit, denselben Ansatz auf einen Metal-basierten Renderer unter macOS oder einen DirectX-basierten Renderer unter Windows auszuweiten
- Vulkan und GL sind hier im Vorteil, weil sie im Kern dieselbe Shader-Sprache, GLSL, teilen
- Für Metal oder DirectX gilt diese Voraussetzung nicht; dort müssten Shader doppelt geschrieben oder Konvertierungswerkzeuge wie SPIRV-Cross eingesetzt werden
- Beitragende mit Interesse an dieser Arbeit sind willkommen
Implementierungsansatz und Ubershader
- Der bisherige GL-Renderer verwendet für jeden rendernode-Typ einfache Shader und greift bei komplexen Inhalten häufig auf Offscreen-Rendering zurück
- Der integrierte Renderer besitzt ebenfalls leistungsfähigere node-spezifische Shader, verwendet aber zusätzlich komplexe Shader, die statt Offscreen-Rendering Buffer-Daten interpretieren
- Im Game Programming wird dieser Ansatz als Ubershader bezeichnet
- Die neue Implementierung ist noch weniger optimiert als der bisherige GL-Renderer, kann dafür mit Schwerpunkt auf Korrektheit und Wartbarkeit vielfältigere rendernode-Bäume korrekt verarbeiten
Rendering-Qualität und neue Funktionen
-
Antialiasing
- Der bisherige GL-Renderer konnte kleine Details verlieren, wenn sie schmal genug waren, um zwischen die Grenzen einer Pixelzeile zu fallen
- Dieses Problem kann sogar Unterstreichungen wie bei Mnemonics betreffen
- Der integrierte Renderer bewahrt kleine Details besser und reduziert auch Treppeneffekte an den Konturen von Primitive-Formen
-
Fraktionale Skalierung
- Antialiasing ist die Grundlage dafür, fraktionale Skalierung korrekt zu behandeln
- Wenn ein 1200×800-Fenster auf 125 % skaliert wird, verwendet der integrierte Renderer einen 1500×1000-Framebuffer
- Das verarbeitet deutlich weniger Pixel und liefert ein schärferes Bild, als den Compositor ein 2400×1600-Bild herunterskalieren zu lassen
-
Beliebige Gradients
- Der bisherige GL-Renderer verarbeitet bei linearen, radialen und konischen Gradients höchstens 6 Farbstopps
- Der integrierte Renderer erlaubt eine unbegrenzte Anzahl an Farbstopps
- Auch auf Gradients wird Antialiasing angewendet, sodass an scharfen Übergängen weiche Linien entstehen
-
dmabuf
- GTK hat im vergangenen Herbst an dmabuf-Unterstützung und Graphics Offloading gearbeitet
- Der neue Renderer unterstützt dies und erweitert die render_texture-API so, dass beim Anfordern der Texturerzeugung dmabuf erstellt werden kann
- Derzeit gilt diese Erweiterung nur für den Vulkan-Renderer
Was App-Entwickler prüfen sollten
-
Keine Unterstützung für glshader-Knoten
- glshader-Knoten waren in den GTK-4.0-Demos nützlich, sind aber eng an den bisherigen GL-Renderer gebunden
- Diese Knoten setzen die vom bisherigen Renderer bereitgestellte GLSL-API voraus
- Der neue Renderer unterstützt glshader-Knoten nicht
- Die GTK-Dokumentation empfiehlt, vor der Abhängigkeit von Shadern zu prüfen und bei Fehlschlag einen einfacheren Shader oder einen alternativen Pfad ohne Shader zu verwenden
- Seit GTK 4.0 wurden Funktionen wie mask-Knoten und Unterstützung für Straight-Alpha-Texturen hinzugefügt, sodass viele Anwendungsfälle für glshader-Knoten nicht mehr nötig sind
-
Fraktionale Positionen
- Der bisherige GL-Renderer rundete Positionen, weshalb Probleme möglicherweise nicht sichtbar wurden, selbst wenn fraktionale Positionen übergeben wurden
- Der neue Renderer platziert Inhalte genau an der angegebenen Position
- Dieser Unterschied kann unbeabsichtigte Ergebnisse erzeugen; daher sollte geprüft werden, ob die Positionen den gewünschten Werten entsprechen
- Vorsicht ist besonders bei cairo-artigem Zeichnen geboten, bei dem Linien auf halben Pixelpositionen liegen, um exakt eine Pixelzeile zu füllen
-
Treiberprobleme
- Der neue Renderer nutzt Grafiktreiber auf neue und andere Weise und kann daher Treiberprobleme auslösen
- Auch wenn ein Problem wie ein Treiberproblem aussieht, sollte es an GTK gemeldet werden
- Das hilft dabei einzuschätzen, wie gut der neue Code mit verschiedenen Treibern und auf unterschiedlicher Hardware funktioniert
Aktueller Stand der Performance
- Der neue Renderer ist derzeit noch nicht schneller als der bisherige Renderer
- Der bisherige GL-Renderer ist stark auf Geschwindigkeit optimiert, verwendet einfachere Shader und führt die für Funktionen wie Antialiasing nötigen Berechnungen nicht aus
- Das Ziel ist letztlich, den neuen Renderer schneller zu machen; derzeit sind jedoch neue Funktionen und Korrektheit die größeren Verbesserungen
- Alle GPU-basierten Renderer sind aktuell schnell genug, um GTK-Apps mit 60 fps oder 144 fps zu rendern
- In nicht wissenschaftlichen Benchmarks liegt der Vulkan-Renderer ungefähr auf dem Niveau des bisherigen GL-Renderers oder ist in manchen Fällen leicht vorn
- Warum der neue GL-Renderer langsamer ist, wurde bisher noch nicht nachvollzogen
Änderung des Standards und Ausnahmen
- Im gerade veröffentlichten GTK-4.13.6-Snapshot ist der ngl-Renderer zum neuen Standard geworden
- Diese Änderung ist ein Testlauf und muss in mehr Apps breiter getestet werden, um die Produktionsreife zu bestätigen
- Wenn größere Probleme auftreten, kann in GTK 4.14 zum bisherigen gl-Renderer zurückgekehrt werden
- Der Vulkan-Renderer ist noch nicht der Standard
- Der WebKit-GTK4-Port funktioniert mit GL, aber nicht mit Vulkan
- GtkGLArea und GtkMediaStream erzeugen derzeit GL-Texturen, die der Vulkan-Renderer nicht direkt importieren kann
- Wenn diese Probleme in naher Zukunft gelöst werden, soll die Entscheidung über den Standard-Renderer erneut geprüft werden
- Wer GTK auf sehr alter Hardware verwendet, fährt mit dem bisherigen GL-Renderer möglicherweise besser
- Der bisherige GL-Renderer stellt geringere Anforderungen an die GPU
- Mit der Umgebungsvariable
GSK_RENDERERkann die Renderer-Auswahl überschrieben werden - Beispiel:
GSK_RENDERER=gl
Mögliche nächste Schritte
- Der neue Renderer bildet die Grundlage für Funktionen, die man sich seit Langem gewünscht hat
- Zu den möglichen nächsten Arbeiten gehören unter anderem
- korrekte Farbverarbeitung einschließlich HDR
- Path Rendering auf der GPU
- möglicherweise einschließlich Glyph Rendering
- Rendering außerhalb des Main Thread
- Performance-Verbesserungen auf alten und weniger leistungsfähigen Geräten
- Einige dieser Punkte sollen im kurz- bis mittelfristigen Fokus stehen
- Für den neuen Renderer sind weitere Funktionen geplant, und Nutzer können ihn direkt testen und rückmelden, ob er funktioniert
1 Kommentare
Meinungen auf Hacker News
Vor langer Zeit, vermutlich um 2010 herum, gab es meiner Erinnerung nach einen experimentellen HTML-Renderer, der GTK-Apps im Browser laufen ließ und die UI mit normalem HTML+CSS aufbaute.
Damals war das wirklich beeindruckend, und es war wohl noch vor Atom, VS Code, Electron und vielleicht sogar NodeJS.
Ich weiß nicht, ob dieser Renderer noch existiert.
https://docs.gtk.org/gtk4/broadway.html
https://www.phoronix.com/news/GTK4-Broadway-Being-Used
Ich hätte es nicht für ein Mainstream-/offizielles Backend gehalten, aber es existiert noch und wurde auch auf Gtk4 portiert.
Denn vom Verhalten her ist es eher ein reiner Canvas-Ansatz, bei dem fast alles, was der Browser bereitstellt, verworfen und von Grund auf neu gebaut wird.
Die Kriterien dafür, ob es sich richtig verhält, sind meist (a) Browser-Scrolling nutzen, (b) Browser-Text-Rendering nutzen, (c) Links als echte Elemente behandeln; Broadway scheitert an allen drei Punkten.
Es implementiert Scrolling neu, rendert Text auf dem Server und schickt ihn als Bild, und wenn man versucht, Links anzuklicken, scheint es tatsächlich stehenzubleiben.
Außerdem scheint die Texteingabe nur Key-Events zu verwenden, wodurch IME-Komposition komplett kaputtgeht; auch die Tastaturnavigation ist vermutlich nicht nativ, sondern kommt von GTK.
Einen sinnvollen Accessibility-Tree stellt es ebenfalls nicht bereit.
Für Technikdemos oder persönliche Nutzung, bei der man die Grenzen akzeptiert, ist es in Ordnung, aber für eine öffentliche Auslieferung ungeeignet; faktisch ist es eher etwas in der Art von RDP/VNC mit ein wenig DOM-Nutzung.
Man sollte auch bedenken, dass der gesamte Code auf dem Server läuft.
Im Grunde werden Pixeldaten in ein canvas-Element gestreamt, also ist es fast dasselbe wie VNC mit Web-Viewer.
https://imgur.com/a/2EDZ2Ti
https://github.com/moondev/gtk3-docker
Mein Anwendungsfall war, im Browser einen Browser auszuführen, um ohne Port-Forwarding oder Proxy einfach mit Kubernetes-clusterip-Services zu interagieren.
Ein weiteres cooles Beispiel ist, virt-manager zu starten, mit gtk virt-viewer eine VM laufen zu lassen und sie im Browser zu bedienen.
https://github.com/m-bers/docker-virt-manager
Ich hoffe, GTK folgt nicht dem Trend, Widgets in die Titelleiste zu setzen.
Manche Dinge lassen sich ziehen und manche nicht, und es bleibt weniger Platz, um App-Name und Dateiname anzuzeigen.
Das ist keine Beschwerde nur über GTK.
Pixelgenaues fraktionales Skalieren, schön, juhu!
Wenn es nun in Wayland richtig unterstützt wird, dürfte HiDPI-Unterstützung in allen wichtigen Linux-Desktop-Umgebungen möglich werden.
Dort steht, dass der vereinheitlichte Renderer bei einem 1200×800-Fenster mit 125% Skalierung einen 1500×1000-Framebuffer verwendet, statt den Compositor ein 2400×1600-Bild herunterskalieren zu lassen.
So wie ich es verstehe, bedeutet das: Wegen des 125%-Faktors soll das Fenster auf dem Bildschirm mit 1500×1000 Pixeln gezeichnet werden, während es aus Sicht der Anwendungspixel 1200×800 ist.
OpenGL und Vulkan rendern mit Fließkommawerten, also dürfte es darum gehen, über eine Koordinatentransformation direkt in einen Puffer zu zeichnen, der 1:1 auf dem Bildschirm gerendert werden kann.
Wenn das stimmt, sieht es endlich nach einer vernünftigen Methode aus.
Gibt es jemanden, der wirklich versteht, wie Desktop-Umgebungen unter Linux funktionieren? Ich jedenfalls nicht.
Es fühlt sich nur so an, als würde alles immer komplexer und weiter angeflanscht.
Die Client/Server-Struktur stand am Ende im direkten Gegensatz zu dem hochintegrierten Grafikverarbeitungsmodell, bei dem wir gelandet sind.
Statt X11 früh aufzugeben und die Verluste zu begrenzen, haben sowohl Unix-Anbieter als auch die Open-Source-Seite viel zu lange versucht, aus einer ganzen Wagenladung fauler Zitronen Limonade zu machen.
Deshalb ist die Linux-GUI so weit zurückgefallen.
Apple war nicht an X11 gebunden und konnte, weil es das integrierte Modell übernahm, Unix-GUIs schnell weiterentwickeln; bemerkenswert ist, dass sie inzwischen sogar eigene GPUs entwerfen.
Ich bin gespannt, wie groß der Einfluss der Wayland-Architektur sein wird und ob tatsächlich GNOME-spezifische Apps entstehen.
Ein ANSI-Text-Renderer wäre schön
Damit ich GTK-Programme in meinem xterm ausführen kann, optional auch mit ein bisschen sixel dazu
Sidebar, ein paar Aktionen in der Titelleiste, Detailansicht-Struktur
Mac-Apps, „moderne“ Windows-Apps und mobile Apps sind ähnlich
Ich frage mich, ob ein UX-Toolkit vollständig deklarativ und semantisch sein könnte
Also auf hoher Ebene etwa: „Master/Detail-Ansicht, eine Listenansicht mit diesen Feldern, einige Aktionen werden benötigt“, ohne Positionen oder Stil vorzugeben, und es verwendet automatisch die passenden System-Widgets
Darüber könnte man noch ein wenig CSS oder einen Ausweg zu nativen Widgets legen
Fast jede App, die kein Browser, WYSIWYG-Editor oder Media-Viewer ist, dürfte in dieses Schema passen; der entscheidende Punkt ist, dass sich aus so einer Beschreibung leicht eine TUI erzeugen ließe
https://github.com/fathyb/carbonyl
https://i.imgur.com/pIQ4K7Q.png
Hätte man https://wgpu.rs/ verwendet, hätte man DirectX und Metal gratis dazubekommen :)
Diese Arbeit sieht wirklich interessant aus
Beim Lesen des Abschnitts über Antialiasing dachte ich, dass Signed Distance Fields vielleicht auch für Font-Rendering in beliebiger Skalierung gut funktionieren würden, so wie in Game-Engines
Valve hat zu diesem Thema einmal ein gutes Paper veröffentlicht
Im UI-Code von Game-Renderern oder beim Decal-Rendering gibt es viele schöne Techniken, die auch für GUI-Code nützlich sein könnten
Ich verstehe nicht, warum Performance-Einbußen akzeptiert werden
Ich erledige die meisten Arbeiten auf alter Hardware; solche Funktionen würde ich gern abschalten, wenn das möglich ist, und auf meiner GPU werden sie vielleicht nicht einmal unterstützt
Wenn es merkliche Performance-Einbußen gibt, kann man
GSK_RENDERER=glverwendenMicrosoft, Apple oder Google hätten so etwas wahrscheinlich nicht einmal diskutiert
Microsoft hätte vermutlich gesagt: „Vergesst die alte API, hier ist die neue API“, Apple: „Ab ${WEIRD_NAME} verpflichtend“, und Google: „Dieses Update bekommt ihr nicht“
Enttäuschend ist allerdings, dass der Vulkan-Renderer nur ungefähr die gleiche Performance wie der bestehende GL-Renderer erreicht
Das wirkt wie ein Hinweis darauf, dass das Problem eher auf der Seite des Aufrufers liegt als bei der 3D-API selbst
Man hätte die Performance während der gesamten Implementierung verfolgen und iterativ verbessern sollen; sich auf „architektonische Reinheit“ zu verlassen, war wohl keine gute Idee
Ich habe noch nie erlebt, dass eine Immediate-Mode-Rendering-API schneller wird, indem man sie in einen Retained Mode umwandelt
Irgendwie ist das sicher möglich, aber es würde enorm viel Arbeit erfordern, und um pathologische Fälle zu beheben, wären wohl auch Änderungen aufseiten der API-Clients nötig
Soweit ich mich erinnere, nutzen die meisten teure MacBooks, sodass viele Probleme mit „funktioniert auf meinem Rechner“ abgetan werden
Zum Beispiel gibt es mehrere Probleme beim Font-Rendering, die Retina-Displays nicht betreffen
Ich hoffe, das klingt nicht verbittert, aber die meisten guten Grafik-Engine-Entwickler haben längst Renderer gebaut, die den Renderern von Open-Source-GUI-Toolkits um mehrere Generationen voraus sind.
Unter uns gibt es mehrere Leute, die echtes Rendering der nächsten Generation auf den Open-Source-Desktop bringen könnten, aber sie arbeiten bei Spieleentwicklungsfirmen, und das sichert ihren Lebensunterhalt.
Sie haben keine Zeit, zum Open-Source-Stack beizutragen.
Wenn die Community ein Budget organisieren könnte, um solche Entwickler regelmäßig zu bezahlen, würde das bei Renderer- und Toolkit-Updates einen großen Unterschied machen.
Dasselbe gilt für andere Open-Source-Apps.
2D-Grafik hat sehr wenig mit Game-Engines gemeinsam.
In 2D bekommt man als Eingabe üblicherweise Bézierkurven und andere Splines, es gibt viel Overdraw, und vom Nutzer bereitgestellte Texturen machen die Verwaltung des VRAM-Speichers kompliziert.
Game-Engines lösen dagegen schwierige Probleme wie dynamische Beleuchtung, volumetrische Effekte und dynamische Umgebungen, die mit 2D-Renderern nichts zu tun haben.
Game-UI-Toolkits und Desktop-GUI-Frameworks leben meiner Ansicht nach in getrennten Welten mit unterschiedlichen Erwartungen.
Nach meiner Erfahrung mit beidem in meiner Laufbahn sind GTK/Qt bei Betriebssystemintegration, Barrierefreiheit, Tastaturnavigation und Funktionen wie Kopieren/Einfügen meist gut bis sehr gut.
Game-UI-Toolkits brauchen diese Dinge nicht und lassen sie deshalb oft komplett fallen; stattdessen konzentrieren sie sich auf Performance, Themes und Integration in die Game-Engine.
Theoretisch kann man sagen, dass der Renderer von diesen Bereichen unabhängig ist, praktisch stimmt das aber nicht vollständig.
Bei begrenztem Budget unterscheidet sich auch, in welche Funktionen man Zeit investiert.
Ein sehr schneller und exakter Renderer ist in Desktop-GUI-Frameworks nicht so wichtig wie in Game-UI-Toolkits.
Wie viele unterstützen CMYK und Druckeinheiten?
Das kratzt nur an der Oberfläche dessen, was GUI-Renderer brauchen, Game-Engines aber nicht.
Ich bin sehr skeptisch, dass sich Spieleentwickler zusammentun und mal eben etwas bauen könnten, das deutlich schneller als Skia ist, ohne viele Funktionen zu opfern.
Menschen, die ihren Lebensunterhalt verdienen müssen, aber Software nutzen und, soweit möglich, gelegentlich Code beitragen.
Natürlich wäre es großartig, wenn die Community Geld sammeln könnte, aber auch diese Koordinationsarbeit ist für irgendjemanden wieder etwas, das nicht den Lebensunterhalt sichert.
Ich mag Open Source/freie Software, bin dankbar, dass es sie gibt, und trage bei, wenn ich kann, aber ich denke schon lange, dass das eine Beschäftigung privilegierter Menschen ist.
Man muss freie Zeit haben, diese freie Zeit für etwas einsetzen können, das den eigenen Lebensstandard nicht erhöht, und das auch noch kontinuierlich tun können.
Ich arbeite in der Spielebranche, und 3D-Renderer sind sehr gut, aber ich habe noch keinen 2D-UI-Renderer gesehen, den ich als konkurrenzfähig bezeichnen würde.
Was verwendet ihr für das Rendern von Pfaden und Mustern?