Trình kết xuất mới cho GTK
(blog.gtk.org)- Nền tảng kết xuất của GTK được tổ chức lại thành ngl cho GL và vulkan cho Vulkan, với cấu trúc hợp nhất nơi cả hai trình kết xuất được build từ cùng một mã nguồn
- Phần triển khai chung lấy luồng API Vulkan làm chuẩn để trừu tượng hóa khác biệt giữa GL 3.3+ và GLES 3.0+, nhờ đó cùng sử dụng hạ tầng kết xuất như duyệt scene graph và cache
- Trình kết xuất mới ưu tiên độ chính xác và khả năng bảo trì hơn là tốc độ trước mắt, đồng thời cải thiện anti-aliasing, fractional scaling, số điểm dừng màu gradient không giới hạn và hỗ trợ dmabuf
- Nhà phát triển ứng dụng cần kiểm tra việc không hỗ trợ node glshader, thay đổi trong cách xử lý vị trí phân số và khả năng phát sinh vấn đề driver; ngay cả khi trông giống lỗi driver thì vẫn nên báo cho GTK
- Trong snapshot GTK 4.13.6, ngl là mặc định mới nhưng vẫn đang ở giai đoạn thử nghiệm; nếu có vấn đề lớn thì GTK 4.14 có thể quay lại trình kết xuất gl cũ
Trình kết xuất hợp nhất cho GL và Vulkan
- GTK bổ sung trình kết xuất mới ngl cho GL và vulkan cho Vulkan
- Hai trình kết xuất được build từ cùng một mã nguồn, nên được gọi là trình kết xuất hợp nhất
- Mô hình triển khai tuân theo API Vulkan, đồng thời bao gồm lớp trừu tượng để xử lý khác biệt giữa GL 3.3+ và GLES 3.0+
- Nhờ cấu trúc này, có thể dùng chung các phần nền tảng vốn trước đây phải bảo trì riêng cho từng trình kết xuất
- duyệt scene graph
- duy trì transform và các trạng thái khác
- cache texture và glyph
- công việc giữ cho cả hai trình kết xuất luôn đồng bộ với phiên bản mới nhất
Điều kiện để mở rộng sang Metal và DirectX
- Có khả năng mở rộng cùng cách tiếp cận này sang trình kết xuất dựa trên Metal của macOS hoặc DirectX của Windows
- Vulkan và GL có lợi thế là về cơ bản cùng dùng ngôn ngữ shader GLSL
- Điều kiện tương tự không áp dụng cho Metal hay DirectX, nên sẽ cần viết shader trùng lặp hoặc dùng công cụ chuyển đổi như SPIRV-Cross
- Những người đóng góp quan tâm đến công việc này đều được hoan nghênh
Cách triển khai và ubershader
- Trình kết xuất GL cũ dùng shader đơn giản cho từng loại rendernode, và thường xuyên dựa vào kết xuất offscreen với nội dung phức tạp
- Trình kết xuất hợp nhất cũng có shader theo từng node mạnh hơn, nhưng đồng thời dùng các shader phức tạp để diễn giải dữ liệu buffer thay vì offscreen
- Trong lập trình game, cách tiếp cận này được gọi là ubershader
- Cách triển khai mới hiện kém tối ưu hơn trình kết xuất GL cũ, nhưng ưu tiên độ chính xác và khả năng bảo trì để xử lý đúng nhiều cây rendernode đa dạng hơn
Chất lượng kết xuất và tính năng mới
-
Anti-aliasing
- Trình kết xuất GL cũ có thể làm mất các chi tiết nhỏ đến mức nằm lọt giữa ranh giới một hàng pixel
- Vấn đề này có thể ảnh hưởng cả đến gạch chân như mnemonic
- Trình kết xuất hợp nhất giữ lại các chi tiết nhỏ tốt hơn và cũng giảm hiện tượng răng cưa ở viền primitive
-
Fractional scaling
- Anti-aliasing là nền tảng để xử lý đúng tỷ lệ phân số
- Khi scale một cửa sổ 1200×800 lên 125%, trình kết xuất hợp nhất dùng framebuffer 1500×1000
- Cách này xử lý ít pixel hơn nhiều và cho hình ảnh sắc nét hơn so với việc để compositor downscale ảnh 2400×1600
-
Gradient tùy ý
- Trình kết xuất GL cũ chỉ xử lý tối đa 6 điểm dừng màu trong gradient tuyến tính, xuyên tâm và hình nón
- Trình kết xuất hợp nhất cho phép số điểm dừng màu không giới hạn
- Gradient cũng được áp dụng anti-aliasing để tạo đường mượt ở các biên sắc nét
-
dmabuf
- GTK đã triển khai hỗ trợ dmabuf và công việc offload đồ họa từ mùa thu năm ngoái
- Trình kết xuất mới hỗ trợ điều này và mở rộng API render_texture để có thể tạo dmabuf khi được yêu cầu tạo texture
- Hiện tại phần mở rộng này chỉ áp dụng cho trình kết xuất Vulkan
Những điểm nhà phát triển ứng dụng cần kiểm tra
-
Không hỗ trợ node glshader
- Node glshader hữu ích trong demo GTK 4.0 nhưng bị gắn chặt với trình kết xuất GL cũ
- Node đó giả định API GLSL do trình kết xuất cũ cung cấp
- Trình kết xuất mới không hỗ trợ node glshader
- Tài liệu GTK hướng dẫn nên kiểm tra trước khi phụ thuộc vào shader, và nếu thất bại thì dùng shader đơn giản hơn hoặc đường thay thế không dùng shader
- Từ sau GTK 4.0, các tính năng như node mask và hỗ trợ texture straight-alpha đã được thêm vào nên nhiều trường hợp dùng glshader node không còn cần thiết nữa
-
Vị trí phân số
- Trình kết xuất GL cũ làm tròn vị trí nên ngay cả khi truyền vị trí phân số, vấn đề có thể không lộ ra
- Trình kết xuất mới đặt đúng tại vị trí đã chỉ định
- Khác biệt này có thể tạo ra kết quả ngoài ý muốn, nên cần kiểm tra vị trí có đúng như mong muốn hay không
- Đặc biệt cần chú ý kiểu vẽ theo phong cách cairo, nơi đặt đường ở vị trí nửa pixel để lấp đầy chính xác một hàng pixel
-
Vấn đề driver
- Trình kết xuất mới sử dụng driver đồ họa theo cách mới và khác, nên có thể làm phát sinh vấn đề phía driver
- Dù vấn đề có vẻ giống lỗi driver thì vẫn nên báo cho GTK
- Điều này giúp xác định mã mới hoạt động tốt đến đâu trên nhiều driver và phần cứng khác nhau
Tình trạng hiệu năng hiện tại
- Trình kết xuất mới hiện vẫn chưa nhanh hơn trình kết xuất cũ
- Trình kết xuất GL cũ đã được tối ưu mạnh cho tốc độ, dùng shader đơn giản hơn và không phải thực hiện các phép tính cần cho những tính năng như anti-aliasing
- Mục tiêu cuối cùng là làm cho trình kết xuất mới nhanh hơn, nhưng hiện tại tính năng mới và độ chính xác mới là cải tiến lớn hơn
- Tất cả trình kết xuất dựa trên GPU hiện đều đủ nhanh để render ứng dụng GTK ở 60fps hoặc 144fps
- Trong các benchmark không mang tính khoa học, trình kết xuất Vulkan đạt mức gần tương đương hoặc nhỉnh hơn trình kết xuất GL cũ trong một số trường hợp
- Lý do trình kết xuất GL mới chậm hơn vẫn chưa được lần ra
Thay đổi mặc định và các ngoại lệ
- Trong snapshot GTK 4.13.6 vừa phát hành, trình kết xuất ngl đã trở thành mặc định mới
- Thay đổi này là thử nghiệm, cần được kiểm tra rộng hơn trên nhiều ứng dụng để xác nhận mức sẵn sàng cho production
- Nếu xuất hiện vấn đề lớn, GTK 4.14 có thể quay lại trình kết xuất gl cũ
- Trình kết xuất Vulkan hiện vẫn chưa phải mặc định
- Bản port WebKit GTK4 chạy được với GL nhưng không chạy với Vulkan
- GtkGLArea và GtkMediaStream hiện tạo texture GL, và trình kết xuất Vulkan không thể nhập trực tiếp các texture này
- Nếu các vấn đề này được giải quyết trong tương lai gần, quyết định về trình kết xuất mặc định sẽ được xem xét lại
- Nếu dùng GTK trên phần cứng rất cũ, trình kết xuất GL cũ có thể phù hợp hơn
- Trình kết xuất GL cũ đòi hỏi ít điều kiện từ GPU hơn
- Có thể ghi đè lựa chọn trình kết xuất bằng biến môi trường
GSK_RENDERER - Ví dụ:
GSK_RENDERER=gl
Những việc có thể làm tiếp theo
- Trình kết xuất mới là nền tảng để triển khai các tính năng đã được mong muốn từ lâu
- Các hướng có thể làm tiếp theo gồm
- xử lý màu đúng cách, bao gồm HDR
- path rendering trên GPU
- khả năng bao gồm cả glyph rendering
- kết xuất ngoài main thread
- cải thiện hiệu năng trên các thiết bị cũ và yếu hơn
- Một số hạng mục sẽ là trọng tâm công việc trong ngắn hạn và trung hạn
- Trình kết xuất mới còn có thêm nhiều tính năng được lên kế hoạch, và người dùng có thể tự thử để phản hồi xem chúng hoạt động ra sao
1 bình luận
Ý kiến trên Hacker News
Từ rất lâu rồi, có lẽ khoảng năm 2010, hình như từng có một renderer HTML thử nghiệm cho phép chạy ứng dụng GTK trong trình duyệt và dựng UI bằng HTML+CSS thông thường
Khi đó nó thật sự gây sốc, và có vẻ là trước cả khi Atom, VS Code, Electron, thậm chí có thể cả NodeJS xuất hiện
Không rõ renderer đó còn tồn tại không
https://docs.gtk.org/gtk4/broadway.html
https://www.phoronix.com/news/GTK4-Broadway-Being-Used
Tôi không nghĩ nó là backend chính thống/chính thức, nhưng nó vẫn còn và đã được port sang Gtk4
Vì đặc tính hoạt động của nó gần với cách tiếp cận canvas thuần túy, vứt bỏ gần như mọi thứ trình duyệt cung cấp và xây lại từ đầu
Tiêu chí để đánh giá hoạt động đúng thường là (a) dùng cuộn của trình duyệt, (b) dùng render văn bản của trình duyệt, (c) xử lý link như các phần tử thật, nhưng Broadway thất bại ở cả ba điểm
Nó tự triển khai lại cuộn, render văn bản ở phía server rồi gửi dưới dạng ảnh, và khi cố bấm vào link thì hình như thật sự bị treo
Thêm vào đó, nhập văn bản có vẻ cũng chỉ dùng key event nên việc composition của IME hỏng hoàn toàn, và điều hướng bằng bàn phím nhiều khả năng cũng là phía GTK chứ không phải native
Nó cũng không cung cấp được cây accessibility một cách có ý nghĩa
Dùng làm demo kỹ thuật hoặc cho mục đích cá nhân chấp nhận giới hạn thì ổn, nhưng không phù hợp để phát hành công khai, và về bản chất gần với kiểu RDP/VNC có pha chút sử dụng DOM hơn
Cũng cần nhớ rằng toàn bộ mã đều chạy trên server
Về cơ bản nó stream dữ liệu pixel vào phần tử canvas, gần như giống VNC có kèm trình xem web
https://imgur.com/a/2EDZ2Ti
https://github.com/moondev/gtk3-docker
Trường hợp sử dụng của tôi là chạy trình duyệt bên trong trình duyệt, để dễ dàng tương tác với các dịch vụ Kubernetes clusterip mà không cần port forwarding hay proxy
Một ví dụ thú vị khác là mở virt-manager, chạy VM bằng gtk virt-viewer và điều khiển trong trình duyệt
https://github.com/m-bers/docker-virt-manager
Tôi mong GTK không đi theo xu hướng nhét widget vào thanh tiêu đề
Có cái kéo được, có cái không, và không gian để hiển thị tên ứng dụng cùng tên file cũng bị giảm
Đây không chỉ là phàn nàn riêng về GTK
Fractional scaling chính xác đến từng pixel, hay đấy, woohoo!
Giờ chỉ cần Wayland hỗ trợ đúng cách nữa, có lẽ tất cả các môi trường desktop Linux chính sẽ có thể hỗ trợ HiDPI
Bài viết nói rằng nếu scale cửa sổ 1200×800 lên 125%, renderer hợp nhất sẽ dùng framebuffer 1500×1000 thay vì để compositor thu nhỏ ảnh 2400×1600
Theo tôi hiểu, do tỷ lệ 125%, cửa sổ cần được vẽ trên màn hình ở 1500×1000 pixel, còn theo pixel của ứng dụng thì là 1200×800
OpenGL và Vulkan render bằng số thực dấu phẩy động, nên có lẽ ý là thông qua biến đổi tọa độ, có thể vẽ trực tiếp vào buffer có thể render 1:1 lên màn hình
Nếu đúng như vậy thì cuối cùng cũng trông như một cách làm hợp lý
Có ai thật sự hiểu môi trường desktop trên Linux hoạt động như thế nào không? Tôi thì không rõ
Tôi chỉ có cảm giác nó ngày càng phức tạp và chắp vá thêm
Kiến trúc client/server rốt cuộc lại trái ngược hoàn toàn với mô hình xử lý đồ họa tích hợp cao mà chúng ta đã đi tới
Thay vì sớm từ bỏ X11 để cắt lỗ, cả các nhà cung cấp Unix lẫn phía nguồn mở đều đã cố làm lemonade từ cả xe tải chanh hỏng trong quá lâu
Vì vậy GUI Linux mới tụt hậu như thế
Apple không bị trói vào X11 và đã chấp nhận mô hình tích hợp, nên có thể nhanh chóng phát triển GUI Unix; điều đáng chú ý là giờ họ còn thiết kế cả GPU riêng
Tôi tò mò kiến trúc Wayland sẽ có tác động lớn đến đâu, và liệu ứng dụng dành riêng cho GNOME có thật sự xuất hiện hay không
Giá mà có một trình kết xuất văn bản ANSI
để tôi có thể chạy chương trình GTK trong xterm của mình, và tùy chọn thêm chút sixel nữa thì tốt
Một sidebar, vài hành vi trên thanh tiêu đề, cấu trúc master/detail
Ứng dụng Mac, ứng dụng Windows “Modern”, ứng dụng di động cũng tương tự
Tôi tự hỏi liệu một bộ công cụ UX có thể hoàn toàn mang tính khai báo và ngữ nghĩa hay không
Tức là ở mức cao chỉ nói “master/detail, một list view có các trường như thế này, cần vài hành động”, không đưa vị trí hay style, rồi tự động dùng widget hệ thống phù hợp
Bên trên đó có thể đặt thêm một chút CSS hoặc một lối thoát để rẽ sang widget native
Gần như mọi ứng dụng không phải trình duyệt, trình biên tập WYSIWYG hay trình xem media đều có vẻ khớp với khuôn này, và điểm mấu chốt là từ mô tả như vậy có thể dễ dàng tạo ra TUI
https://github.com/fathyb/carbonyl
https://i.imgur.com/pIQ4K7Q.png
Nếu dùng https://wgpu.rs/ thì đã có DirectX và Metal miễn phí rồi :)
Công việc này trông thật sự thú vị
Khi đọc phần khử răng cưa, tôi nghĩ liệu signed distance field như trong game engine có hoạt động tốt cho việc render phông chữ ở tỉ lệ tùy ý không
Valve từng có một bài báo hay về chủ đề này
Trong code UI của game renderer hay phần render decal có nhiều kỹ thuật hay ho có thể hữu ích cho code GUI
Tôi không hiểu vì sao suy giảm hiệu năng lại được chấp nhận
Tôi làm hầu hết công việc trên phần cứng cũ, nên nếu tắt được các tính năng này thì tôi muốn tắt, và GPU của tôi thậm chí có thể không hỗ trợ chúng
Nếu có suy giảm hiệu năng thấy rõ thì có thể dùng
GSK_RENDERER=glMicrosoft, Apple, Google có lẽ thậm chí đã không bàn tới chuyện này
Có lẽ Microsoft sẽ nói “quên API cũ đi, đây là API mới”, Apple sẽ nói “bắt buộc từ ${WEIRD_NAME}”, còn Google thì “bạn không nhận được bản cập nhật đó”
Nhưng điều đáng thất vọng là renderer Vulkan chỉ đạt hiệu năng gần như tương đương renderer GL hiện có
Điều này có vẻ là dấu hiệu cho thấy vấn đề nằm ở phía caller hơn là ở chính API 3D
Đáng ra trong suốt quá trình triển khai phải theo dõi hiệu năng và cải tiến lặp lại, chứ dựa vào “sự thuần khiết về kiến trúc” có lẽ không phải ý hay
Tôi chưa từng thấy trường hợp nào chuyển API render immediate mode sang retained mode mà lại nhanh hơn
Có lẽ theo cách nào đó vẫn có thể làm được, nhưng sẽ cần khối lượng công việc khổng lồ, và để sửa các ca bệnh lý thì cũng cần thay đổi ở phía client của API
Theo tôi nhớ thì đa số họ dùng MacBook đắt tiền, nên nhiều vấn đề bị gạt đi kiểu “máy tôi chạy ổn”
Ví dụ có nhiều vấn đề về render phông chữ không ảnh hưởng tới màn hình Retina
Tôi không muốn nghe có vẻ cay đắng, nhưng phần lớn các lập trình viên engine đồ họa giỏi từ lâu đã làm ra các renderer đi trước renderer của bộ công cụ GUI mã nguồn mở vài thế hệ
Trong số chúng tôi có nhiều người có thể mang khả năng render thế hệ kế tiếp thực sự đến desktop mã nguồn mở, nhưng họ đang làm ở các công ty phát triển game và đó là kế sinh nhai của họ
Không có thời gian để đóng góp cho stack mã nguồn mở
Nếu cộng đồng có thể tổ chức ngân sách để trả tiền định kỳ cho những lập trình viên như vậy, việc cập nhật renderer và toolkit sẽ khác đi rất nhiều
Các ứng dụng mã nguồn mở khác cũng vậy
Đồ họa 2D có rất ít điểm chung với game engine
Trong 2D, đầu vào thường là Bézier và các spline khác, có nhiều overdraw, và việc quản lý bộ nhớ VRAM trở nên phức tạp vì các texture do người dùng cung cấp
Ngược lại, game engine đang giải quyết những bài toán khó không liên quan đến renderer 2D, như chiếu sáng động, hiệu ứng thể tích, môi trường động
Tôi cảm thấy các toolkit UI cho game và framework GUI desktop sống trong hai thế giới riêng, với kỳ vọng khác nhau
Theo kinh nghiệm dùng cả hai trong sự nghiệp của tôi, GTK/Qt thường xử lý tốt hoặc rất tốt các chức năng như tích hợp hệ điều hành, tính năng trợ năng, điều hướng bằng bàn phím, sao chép/dán
Toolkit UI cho game thường không cần những thứ này nên hay bỏ hẳn, thay vào đó tập trung vào hiệu năng, theme và tích hợp với game engine
Về lý thuyết có thể nói renderer độc lập với các phần này, nhưng thực tế thì không hoàn toàn như vậy
Khi ngân sách hạn chế, việc dành thời gian cho tính năng nào cũng khác nhau
Một renderer cực nhanh và chính xác không quan trọng với framework GUI desktop bằng với toolkit UI cho game
Có bao nhiêu cái hỗ trợ CMYK và đơn vị in ấn?
Đây mới chỉ là chạm nhẹ bề mặt của những thứ GUI renderer cần nhưng game engine thì không
Tôi rất hoài nghi chuyện các lập trình viên game tụ lại có thể nhanh chóng làm ra thứ gì đó nhanh hơn Skia rất nhiều mà không phải hy sinh nhiều tính năng
Những người phải kiếm sống, nhưng đóng góp trong khả năng của mình bằng cách dùng phần mềm và thỉnh thoảng đóng góp mã
Tất nhiên nếu cộng đồng có thể gây quỹ thì rất tuyệt, nhưng bản thân việc điều phối đó cũng là việc không nuôi sống ai đó
Tôi thích phần mềm mã nguồn mở/phần mềm tự do, biết ơn vì nó tồn tại và cũng đóng góp khi có thể, nhưng từ lâu tôi đã nghĩ đây là một mưu cầu của những người có đặc quyền
Bạn phải có thời gian rảnh, phải có khả năng dùng thời gian rảnh đó vào việc không nâng cao mức sống của mình, và phải có thể làm thế một cách đều đặn
Tôi làm trong ngành game, và các renderer 3D thì rất tốt, nhưng tôi chưa thấy renderer UI 2D nào có thể xem là cạnh tranh được
Họ đang dùng gì để render path và pattern?