Apakah perangkat keras data GUI yang dipercepat disimpan di GPU

8

Saya sedang melakukan penelitian tentang bagaimana sebagian besar perangkat keras perpustakaan GUI dipercepat bekerja. Saya sebenarnya hanya peduli tentang rendering backend mereka di sini. Saya mencoba mencari tahu apa yang akan menjadi cara terbaik untuk mencoba dan menulis sendiri sebagai semacam proyek sampingan. Saya mencoba untuk mendapatkan kinerja terbaik di sini daripada fitur yang terlalu mewah. Saya ingin dapat menggambar primitif, teks dan animasi.

Beberapa perpustakaan bagus yang saya tahu adalah Qt, Skia dan Kairo (meskipun saya tidak yakin apa sajian HWA ada di dalamnya). Saya juga telah melihat NanoVG yang merupakan perpustakaan kecil yang tampaknya memiliki pengikut yang layak. Saya tidak berhasil mencapai kinerja yang layak dengan NanoVG meskipun ...

Satu hal yang mengejutkan saya adalah bahwa semua perpustakaan ini tampaknya menggunakan konsep "melukis" di mana setiap bentuk primitif digambar dari awal berulang kali. Yang saya maksud dengan itu adalah bahwa dari API, tidak tampak seolah-olah bentuk dibuat sebagai "objek" pada GPU atau apa pun terminologinya dan kemudian dibiarkan di sana untuk diterjemahkan "secara otomatis". Dengan kata lain, mereka tidak tertinggal di memori GPU karena digambar ulang dalam beberapa lingkaran besar. Singkatnya, tampaknya untuk setiap persegi panjang yaitu yang perlu ditarik, seluruh negara OpenGL diatur hanya untuk membuat persegi panjang itu dan kemudian dihancurkan lagi. Tampaknya seolah-olah bentuk-bentuk yang diberikan ini kemudian setidaknya diberikan di tujuan akhir mereka, memungkinkan GPU untuk kemudian menyusun seluruh adegan.

Cara saya berharap perpustakaan ini bekerja adalah dengan benar-benar menyimpan seluruh adegan pada GPU (maafkan istilah yang mengerikan). Sebagai contoh, primitif akan triangulasi dan dibiarkan di memori di mana setelah beberapa proses rumit akan digunakan untuk memiliki loop rendering utama untuk adegan tersebut. Selanjutnya akan ada mekanisme untuk memperbarui atribut atau menghapus atau menambah primitif. Ini deskripsi yang tidak jelas, tetapi saya pikir Anda mendapatkan idenya.

Yang ingin saya tanyakan sekarang, adalah apakah ada manfaat kinerja untuk pendekatan "melukis" dibandingkan dengan pendekatan "diselamatkan" (sekali lagi, tidak tahu apakah ada nama yang tepat untuk hal-hal ini ...). Mungkin semacam mekanisme caching yang rumit? Atau apakah ini lebih sederhana untuk dikerjakan?

Saya menyadari bahwa pendekatan "diselamatkan" mungkin menggunakan lebih banyak memori pada GPU tetapi apakah semua panggilan OpenGL diperlukan untuk pendekatan "pengecatan" tidak terlalu mahal? Saya kira orang mungkin bisa mengimbangi ini dengan caching bentuk yang diberikan tetapi apakah GPU benar-benar memberikan manfaat yang begitu besar ketika melakukan rasterisasi sekali-sekali (atau tidak terlalu biasa) dibandingkan dengan CPU, terutama mengingat komunikasi atas? Juga, apakah overhead komunikasi ini tidak menimbulkan masalah serius untuk animasi ketika menggambar harus dilakukan untuk setiap frame?

Saya cukup yakin bahwa NanoVG tidak memiliki mekanisme caching internal dan saya akan berasumsi bahwa ini bisa bertanggung jawab atas kinerjanya yang agak loyo. Qt di sisi lain tampaknya memiliki kinerja luar biasa sehingga pasti melakukan sesuatu yang benar. Google juga tampaknya dapat memanfaatkan Skia dengan baik.

PS. Saya bukan profesional dalam hal apa pun dan baru mulai mempelajari OpenGL.

EDIT: Kemungkinan lain yang saya pikirkan adalah bahwa mungkin pendekatan "melukis" dianggap perlu semata-mata karena manfaat ingatannya? Alasan saya akan berpikir itu adalah karena semua perpustakaan ini tentu saja dimulai pada era yang berbeda dan juga menargetkan platform tertanam yang berarti bahwa memori GPU mungkin sangat langka pada platform target (ed) dan bahwa menggunakan sesedikit mungkin itu mungkin lebih penting daripada kinerja. Sekali lagi, dalam situasi seperti ini, saya tidak yakin bahwa rasterisasi GPU frame-by-frame yang diberikan overhead komunikasi akan mengungguli CPU, terutama mengingat kemungkinan jumlah piksel yang rendah pada platform dengan memori yang sangat sedikit.

Selanjutnya saya telah membaca di http://blog.qt.io/blog/2010/01/06/qt-graphics-and-performance-opengl/ bahwa Qt rupanya memadukan kode shader dari segmen yang sudah di-prakode pada saat runtime sebelum "melukis" dan kemudian berharap untuk kompiler OGL untuk memasukkan kode dengan benar saat runtime. Ini terdengar seperti overhead inisialisasi OGL bahkan lebih kepada saya ...

Gerharddc
sumber
2
TL; DR; tidak akan membahayakan di sini
Kromster

Jawaban:

6

Menyimpan seluruh jendela sebagai objek tunggal ke dalam GPU (akan berupa sekelompok persegi panjang yang disimpan sebagai VBO) dan kemudian merendernya dalam satu panggilan draw OpenGL akan cepat, tetapi ia memiliki beberapa kelemahan:

  • Keseluruhan geometri harus dirender menggunakan shader tunggal. Memiliki shader terpisah (untuk salinan buram, salinan transparan, gradien, ...) lebih bermanfaat.
  • Seluruh geometri hanya dapat digunakan dari jumlah tekstur yang terbatas. Bahkan jika Anda menggunakan atlas, Anda membutuhkan banyak tekstur untuk GUI. (Potongan tema GUI, ikon, font, ...)
  • Anda harus membangun kembali dan memuat kembali seluruh objek ke GPU setelah setiap perubahan.
  • Setiap widget harus dapat menghasilkan potongan geometri mereka yang lebih sulit untuk abstrak daripada lukisan 2D.
  • Pada beberapa GPU Anda dapat membuat barang 2D (mengisi area dengan warna, menyalin dari gambar ke gambar, ...) dengan perintah 2D yang lebih cepat daripada menggunakan pipa 3D.

Jika Anda memecahnya menjadi beberapa objek, maka Anda akhirnya berakhir dengan satu atau beberapa persegi panjang per objek. Lebih mudah dan lebih cepat untuk membuatnya tanpa benda yang tersimpan.

Apa yang dilakukan kerangka kerja GUI adalah melacak bagian mana dari jendela yang diubah dan hanya mengecat ulangnya. Gambar lama di-cache dalam GPU. Pendekatan ini dapat digunakan dengan berbagai backend gambar, tidak hanya rendering yang dipercepat OpenGL / DirectX.

Jika Anda ingin memeriksa contoh pustaka GUI yang menghasilkan geometri yang dapat Anda masukkan ke dalam OpengGL (atau ke api 3D yang berbeda), lihat librocket . Ini benar-benar dapat memanggang geometri statis bersama-sama dan membuatnya dalam panggilan draw tunggal, tetapi setiap elemen yang akan sering berubah atau perlu di-render dengan shadernya sendiri harus tetap terpisah.

michalsrb
sumber
Ok terima kasih. Apakah seluruh frame sebelumnya di-cache sebagai gambar atau semua elemen di-cache dalam atlas? Alasan saya bertanya adalah karena saya tidak melihat bagaimana caching frame akan mendukung misalnya menerjemahkan satu elemen. Mempertahankan atlas tentu saja akan banyak usaha.
Gerharddc
Seluruh konten jendela biasanya di-cache. Saya yakin beberapa kerangka kerja GUI menyimpan beberapa tahap perantara juga, konten apa pun yang dapat digulirkan akan menjadi kandidat yang baik. Saya tidak berpikir menerjemahkan adalah operasi umum di GUI selain dari area yang dapat digulir. Kebanyakan pengecatan ulang kecil dan ada di tempat yang disebabkan oleh widget yang berubah pada hower atau klik, mengubah teks, ... Hal-hal seperti dialog dan menu secara teknis adalah jendela yang terpisah, kompositor jendela modern mengurus untuk memindahkannya tanpa pengecatan.
michalsrb
Saya rasa itu masuk akal. Apakah itu berarti seluruh jendela harus digambar ulang jika saya tiba-tiba memindahkan sesuatu seperti tombol?
Gerharddc
Itu sangat tergantung pada bagaimana kerangka kerja spesifik diimplementasikan. Tetapi kemungkinan memindahkan tombol akan memicu semacam pembaruan tata letak dan sebagian besar jendela, jika tidak seluruhnya, harus dicat ulang.
michalsrb