commit -m "better"
2.96K subscribers
868 photos
105 videos
3 files
2.07K links
just random thoughts
Download Telegram
commit -m "better"
Замахнулся на святое - на ImGui. https://github.com/ocornut/imgui Давно хотел попробовать собрать себе что-то интересное с использованием этой библиотеки: * пощупать вживую immediate mode gui. * для галочки, что, вот, "и это у меня работает". * мне кажется…
Будни #bootstrap, обещаный текст про сборку reddit desktop, #imgui

* оно требует libmpv, для просмотра видосиков. Почему не ffmpeg напрямую - загадка. Все бы ничего, но сборка libmpv(или это свойство waf вообще) страдает обычным для OSS багом - "а давайте не будем устаналивать в систему артефакты для статически слинкованных библиотек, только для динамических". Пришлось применять тяжелую машинерию, в виде враппера над компилятором.

* оно требует vcpkg, причем хочет, чтобы vcpkg использовался и под Linux. А это жестейшая жесть, потому что vcpkg предполагает сборку под Windows, единственная OSS система сборки, которая там как-то работает - это cmake, и поэтому vcpkg сам для всех своих пакетов готовит файлы для cmake discovery - https://github.com/microsoft/vcpkg/tree/master/ports/bzip2, и сборку под cmake переделывает. Это привело к тому, что discovery в этом проекте без vcpkg не работает, пришлось патчить.

* по ходу сборки обнаружилось, что сломан boost - https://git.sr.ht/~pg/ix/tree/main/item/pkgs/lib/boost/ix.sh#L35 А чо, он же header-only, при его сборки компилябельность заголовков не проверяется.

* после того, как прошел configure, обнаружилось, что у коллеги забыты многие include. Возможно, это как раз связано с вчерашней темой про llvm14/15.

* самая мякотка - я не знаю, чо там наворотил автор в своем коде, но единичный файл у него компиляется дольше, чем в одном вам всем известном проекте в Я на букву М, и больше 4 потоков мой ноут не выдерживал - уходил в ядерные стектрейсы по памяти.

* пришлось выкорчевывать использование glfw - это такой лоадер для opengl, который у меня не имеет никакого смысла, и только усложняет сборку.

Кажется, я так процедурно(патчи регулярками над всем кодом) не издевался ни над одним пакетом - https://git.sr.ht/~pg/ix/tree/main/item/pkgs/bin/reddit/desktop/ix.sh#L50

Оно после этого собралось, слинковалось, но не заработало.

С сообщением, что не может загрузить в рантайме вот эту функцию - https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3_loader.h#L656

Тут я подумал, что попал, потому что, как выяснилось, реализация imgui на opengl завязана на динамический загрузчик функций из glx(это привязка X11 к opengl).

А X11 у меня нет.

Я тут уже, было, решил сдаться, но потом почитал код, и понял, что, кроме самого загрузчика, далее код использует конвенциональный opengl, без glx.

Ну и я реализовал эту фабрику по загрузке функций сам - https://git.sr.ht/~pg/ix/tree/main/item/pkgs/lib/mesa/gl/dl/glx/ix.sh#L15, благо, сама фабрика по загрузке opengl у меня уже была реализована, для эмуляции dlopen. Тут тонкое, но забавное, место - эта фабрика для opengl идет в мою фабрику по динамической загрузке символов, реализованной внутри моей реализации dlopen.

Короче, оно собралось, и показало работающий imgui gui. Думаю, я тут опять первопроходец, так как, повторю, на базе чистого wayland стоковый код работать не может.

Победа?

Какое там, картинка была заблюреной, видно, что hidpi в imgui не работал, хотя и заявлен.

Рассказ про это - в следующей серии!
🔥12❤‍🔥1
commit -m "better"
Будни #bootstrap, обещаный текст про сборку reddit desktop, #imgui * оно требует libmpv, для просмотра видосиков. Почему не ffmpeg напрямую - загадка. Все бы ничего, но сборка libmpv(или это свойство waf вообще) страдает обычным для OSS багом - "а давайте…
#imgui, #wayland, #sdl, #hidpi #gold

Так, третья, заключительная, часть рассказа про "собрать какое-нибудь приложение c imgui".

Прошлый рассказ я закончил на том, что у меня все собралось, запустилось, но было очень сильно замылено.

Скриншот мне делать лень, поэтому просто представьте себе, что картинка была rendered в буфер 100x100, который был растянут на экран 200x200.

Кстати, ровно та же проблема у меня наблюдалась с #dosbox.

Суммарно на решение это проблемы я потратил часов 10, фактически, все прошлые выходные. Зачем? Ну, потому что интересен процесс, а не результат. И потому что, предполагается, что владелец дистрибутива способен такие проблемы пользователей решать, я так думаю.

Я, пожалуй, не буду вдаваться в детали процесса, это слишком долго, я просто расскажу, как устроен hidpi в wayland, к чему это привело в модели sdl, и что я с этим сделал.

* В wayland у каждого буфера, в том числе on screen, есть, кроме обычных WxH(+ формат, но нам это не интересно), еще параметр scale. На мой взгляд, назван он неверно, и это долго меня сбивало с толку.

* Когда композитор отрисовыает буфер приложения в экранный буффер, он масштабирует буфер приложения в отношение scale этих двух буферов. Ну, то есть, если screen->scale == 2, app->scale == 1, то буфер от приложения будет увеличен в 2 раза.

* После чего композитор попиксельно отображает буфер приложения в экранный буффер, отсекая лишнее.

Давайте на примерах:

* screen == 200x200x2, app == 100x100x1. Увеличим app buffer в 2 раза, отобразим получившуюся картинку 200x200 as is. Так, фактически, работают старые приложения, которые не hidpi-aware.

* screen == 200x200x2, app == 100x100x2. Мы получим, что приложение заняло верхнюю левую четверть отведенного ей экрана.

* screen == 200x200x2, app == 200x200x2. Четкая, pixel perfect, картинка.

Что еще важно понимать?

Если композитор имеет размер буфера для приложения 200x200, и screen scale 2, то он, в качестве желаемых размерностей пошлет приложению 100x100, чтобы non-hidpi-aware приложения как-то работали. hidpi aware приложения, для того, чтобы рассчитать размер буфера для отрисовки, должны эту величину умножить на переданный scale.

А дальше все тулкиты изголяются, кто во что горазд.

Например, что делает SDL:

* Он hidpi aware, поэтому он выделяет буфер размера w * scale, h * scale. То есть, цепочка: композитор имеет буфер 200x200x2, он передает в SDL 100x100x2, SDL выделяет буфер для рисования 200x200x2. https://github.com/libsdl-org/SDL/blob/main/src/video/wayland/SDL_waylandwindow.c#L1901-L1905

* Далее SDL делает что-то странное. Он говорит, что всю отрисовку теперь мы будем делать в неких point, point у нас 100x100, каждый point физически отображается в 2 пикселя. https://discourse.libsdl.org/t/high-dpi-mode/34411

* ImGui берет размерности экрана в этих point, 100x100, делает gl viewport 100x100 над буфером 200x200, и рисует в свое удовольствие заблюренный контент.

То есть, как будто hidpi aware приложение само готовит контент низкого разрешения.

Я пробовал починить это разными способами, лучше всего сработал такой - https://git.sr.ht/~pg/ix/commit/fab9a5086801ea5e41d1e454f6c3a26abe9a06ed#pkgs/bin/reddit/desktop/hidpi/imgui_impl_sdl.cpp:

* В коде ImGui умножить размеры, передаваемые SDL, на scale.

* Получится так, что мы создадим viewport 200x200 над буфером 200x200, и отрисовка будет pixel perfect.

Почему я не могу расценивать это как финальное решение:

* Потому что, кроме gui, SDL возвращает масштабированными события от мыши, и получается, когда я их умножаю на scale, я теряю точность(мышка двигается по 2 пикселя по вертикали и гризонтали). Я не смог это заметить глазами на retina display, но как-то неаккуратно. https://forums.libsdl.org/viewtopic.php?p=43373

На мой взгляд, тут баг в SDL, что, когда приложение говорит, что оно hidpi aware, то надо ему возвращать настоящие пиксели, а не points.

Что мне делать с моим патчем в ImGui, я пока не понимаю.

BTW, должен сказать, что, после моего фикса, hidpi support в imgui кажется очень классным, потому что все размеры во float, и привязаны к размеру шрифта.
🔥9👍2
#imgui #insane

Решил закрепить успех, и собрать что-нить еще с imgui.

Выбор пал на https://github.com/WerWolv/ImHex, потому что много звезд, и оно использует glfw, а не SDL, для создания контекста.

Что в процессе сборки узнала девочка Антон:

* Автор проекта - сумасшедший. В целом, в этом ничего плохого нет, но вот https://github.com/WerWolv/ImHex/releases/tag/v1.19.2 "Upgraded codebase to C++23" - это немного за гранью. Я пока не нашел связку компилятор + c++ lib, с которой бы это завелось, поэтому я откатился на прошлый релиз.

* glfw + imgui, с точки зрения hidpi, работают гораздо корректнее. Плясать с бубном пока не пришлось.

* Оказывается, в с++ теперь есть вот такое, а я не знал:

view_hex_editor.cpp:202:69: 
error: no member named
'boyer_moore_horspool_searcher'
in namespace 'std'
return std::search(haystackBegin,
haystackEnd,
std::boyer_moore_horspool_searcher(
needleBegin, needleEnd));

Ну, как, в с++ есть, а в libc++ только-только завезли. https://reviews.llvm.org/D121074

* Пришлось сделать вот такое:

s|std::abs(index)|(index > 0 ? index : -index)|


потому что не во всех стандартных библиотеках есть std::abs для int128_t, дээээ.
👍4😁4🐳4
Продолжал эксперименты с #imgui

Выяснил, что оно фигачит 60rps даже в моменты, когда это не требуется от слова совсем - https://github.com/ocornut/imgui/pull/5116

Ну, то есть, gui должен перерисовываться только в случае прихода какого-то event, от мышки, клавиатуры, или от таймера(для создания анимаций).

ImGUI, будучи заточенным под игры, шпарит всегда с максимально возможной скоростью, а это греет GPU.

Нет в жизни счастья :(
🤔3
commit -m "better"
Продолжал эксперименты с #imgui Выяснил, что оно фигачит 60rps даже в моменты, когда это не требуется от слова совсем - https://github.com/ocornut/imgui/pull/5116 Ну, то есть, gui должен перерисовываться только в случае прихода какого-то event, от мышки…
https://github.com/ocornut/imgui/releases/tag/v1.90

Люблю рассматривать релизы #imgui, потому что там всегда есть список новых приложений, которые его используют.

Это вообще какая-то совершенно потрясающая вещь - в списке каждый раз 10 - 20 новых приложений, это примерно столько же, сколько во всем Gnome core.

Судя по всему, на imgui очень легко писать сложные gui, нужные для тулинга, и которые нужно написать быстро, а завтра - выкинуть. И в этом процессе нет места вылизыванию blur на уголках окон по 100500 раз.

Короче, промышленный инструмент, а не вот эти ваши изыски над css.

Мне очень импонирует идея gui как очень тонкой прослойки над системным 3D API, потому что все классические gui типа qt/gtk, которые интегрировали 3d постфактум, сделали это плохо, неполно, и поэтому ты не знаешь, какая часть сцены у тебя отрендерится в 3d, и что приведет к тому, что случится 100500 копирований какого-нибудь буффера из/в память видеокарты.

К сожалению, в Linux 3d драйвера - это .so в userspace, вместо того, чтобы быть каким-нибудь dbus daemon, который бы умел кешировать и компилировать шейдерные программы, что не очень изящно ложится в мою модель статической линковки (бинари довольно заметно распухают, это не то чтобы сильно важно, но как-то "неаккуратно").

Поэтому я, конечно, очень жду, когда gui можно будет компилировать в что-то типа #WASM #WASI, и чтобы 3d драйвера жили исключительно в одном бинаре с WebAssembly VM, о как. Это, если что, не влажная фантазия, у вас прямо сейчас так работает webgl в браузере!
👍12🥰4🤔3🤯2🐳1