1 điểm bởi GN⁺ 2024-01-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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

 
GN⁺ 2024-01-30
Ý 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

    • Ý bạn là Broadway à?
      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
    • Dù nó dùng HTML và CSS nhiều hơn những thứ tương tự, tôi nghĩ khó có thể gọi là HTML+CSS thông thường
      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ới GTK3 thì gọi cái này là HTML renderer có hơi quá
      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
    • Tên nó là Broadway: https://docs.gtk.org/gtk4/broadway.html
    • Trước đây tôi từng làm một proof of concept nhỏ chạy trong Docker bằng Broadway, và nó hoạt động khá tốt
      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

    • Chẳng phải xu hướng đó do gtk/gnome tạo ra sao?
    • Chỉ riêng việc chuyện này xảy ra trong GNOME đã đủ tệ rồi, tôi mong GTK đừng mắc thêm một sai lầm nữa
  • Fractional scaling chính xác đến từng pixel, hay đấy, woohoo!

    • Suốt hơn 10 năm GTK cứ khẳng định fractional scaling là “không thể”, và các nhà phát triển GTK đã ngăn fractional scaling trong giao thức Wayland, nhưng cuối cùng GTK cũng đạt mức ngang bằng tính năng với Qt ở mảng này
      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
    • Phần giải thích trong bài blog hơi khó hiểu
      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

    • X Window System về cơ bản là một canh bạc sai lầm về cách GUI và phần cứng máy tính sẽ tiến hóa
      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
    • Ở phía đó, GNOME gần như là người đi đầu
      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

    • Dạo này hầu hết ứng dụng GTK trông khá giống nhau
      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
    • Kết hợp broadway được nhắc ở bình luận khác với carbonyl thì cũng khá giống
      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

    • Trong câu “Không, renderer mới vẫn chưa nhanh hơn”, từ quan trọng là chưa
      Nếu có suy giảm hiệu năng thấy rõ thì có thể dùng GSK_RENDERER=gl
      Microsoft, 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 đó”
    • Với GL, nếu vô tình bỏ lỡ fast path thì rất dễ chậm đến ngạc nhiên, và ngược lại nếu đi đúng đường đó thì cũng có thể nhanh đến ngạc nhiên
      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
    • Trường hợp duy nhất tôi chấp nhận hồi quy hiệu năng là khi bản triển khai trước đó thực sự sai, chứ không phải chỉ vì nó cũ hoặc cần viết lại bằng một framework/công nghệ đang thịnh hành
    • Các renderer này không phải mặc định và có lẽ sau này cũng sẽ không trở thành mặc định
      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
    • Nhóm phát triển GNOME, rộng hơn là phía GTK, dường như không mấy bận tâm
      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

    • Trước đây tôi từng triển khai vài GUI renderer nhắm tới GPU, ví dụ như cái này: 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
      Đồ 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 hơi hoài nghi về lập luận này
      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 trong số các game engine đó có mức trừu tượng đủ để thay sang backend PDF hoặc SVG?
      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
    • Cộng đồng được nói đến ở đây rốt cuộc là những người như bạn
      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 khá hoài nghi về điều đó
      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?