Когда хочется красивый GUI, а gpu нет

в 20:41, , рубрики: c++, nanogui, UI, никто не читает теги, Работа с векторной графикой

Обычно для рабочих утилит не требуется вменяемый UI, с кнопками, списками, окнами, поддержкой мыши и прочей мелочевкой, большинство рабочих «хотелок» можно упаковать в скрипты и иногда запускать их с параметром --help, и так будет даже правильней с точки зрения настройки и масштабирования. Все становится хуже, когда тулами начинают пользоваться не только команда разработки, но и сторонние люди. А они не всегда готовы вникать в стройные мысли, уложенные в строчки кода. И тогда приходится городить UI, а он у разработчиков выходит обычно простой, квадратный, функциональный и совсем скучный. Некоторое время назад я работал над небольшой системой управления вентиляцией/обогрева/камерами и еще того «что придумает вон тот дядечка в желтой каске» для подземной автостоянки.

Когда хочется красивый GUI, а gpu нет - 1


(Здесь была картинка с UI системы, но разработчик попросил её убрать. Если вам не хочется читать о прогулках по граблевому полю, то ссылки на гитхаб в конце статьи)

Система была построена на китайском нонейм SoC, для которой производитель расстарался портировать SDL фреймворк первой версии. Внутренние тулы и скрипты доработали до такой степени, что они превратились в развесистый и «красивый» макет c вкладками, списками, попапами, тенями, градиентом, прозрачностью и другими плюшками.

Для реализации всех красивостей был выбран nanogui, простой и неприхотливый, и при этом «могущий» всё что было нужно. Ровно было на бумаге, да забыли про OpenGLовраги. Почти полностью реализованный UI системы управления стали запускать на железе, а там черный экран, все инициализации OpenGL3 проходят без ошибок, буферы ставятся, а шейдеры компилятся, но нет… черный экран, под каким углом не посмотри.

Сначала грешили на мои кривые руки, потом на руки Антохи-разработчика, ответственного за драйвера и железо, потом запустили тестовый пример рендера треугольника из состава сдк SoC, и снова черный экран, документацию и примеры как обычно читают в последнюю очередь.

Что-то тут неправильно подумали мы с коллегой и пошли сначала на китайский форум, а не найдя там внятных ответов уже и к разработчику, ответ был неутешительный, реализации opengl нет, и скорее всего не будет, потому что линейку снимают с производства.
— А как же SDL фреймворк? — спросили мы
— Рисуем попиксельно в видеопамять. — Ответили нам наши китайские друзья.

В тот день я увидел грустные глаза программиста, который подсчитывает сколько LoC он отправит в /dev/null. Но бросать уже готовое решение было очень обидно, (в интернетах найдется всё) оказывается жить без OpenGL в nanogui можно на software рендере.

Только жить получается очень медленно, на большом ПК пару секунд на фрейм, на китайском чуде инженерной мысли уже примерно 20-25 секунд для отрисовки. Тогда решили рендерить не весь UI сразу, а только нужные (измененные) части виджетов, но даже в таком режиме, со всеми хаками и оптимизациями выходило больше 10 секунд на один фрейм, нежизнеспособно…

Покурив немного примеры сдк выяснили, что копирование готовых текстур в видеопамять «мгновенное» (по сравнению с 10 секундами конечно), и занимает примерно 1мс на текстуру 512х512 без прозрачности и 2мс для такой же с прозрачностью, если копировать несколько таких текстур друг за другом то время растет нелинейно катастрофически, связано это оказалось с ограниченным объемом буфера видеопамяти, переполнение которого приводило к сбросу буфера и рендеру того что было на экран (велик не мой, он уже там стоял), т.е. для не совсем мертвого интерфейса мы можем копировать не более 50-100 текстур за фрейм и не сразу, а только дождавшись пока видеодрайвер заберет данные из буфера.

Следующей итерацией стал рендер виджета в собственную текстуру в потоке, а на время создания текстуры виджет рисовался примерно похожим на финальный результат, только квадратным способом, рисовать всякие линии, фигуры можно было сразу в видеопамять бесплатно.

Почти победив чудо китайской мысли «без» GPU, все таки нельзя назвать 20 FPS достойным результатом, и почти сдав проект, я попросил у заказчика разрешения забрать часть наработок в опенсорс. Первый SDL сейчас не очень в моде, поэтому было решено использовать рендер nanogui в software режиме на SDL2 и выложить это на гитхабе. Может кому понадобится :)

Дочитав до конца статью, %читатель% вправе спросить, а зачем было городить эту кучу кода
ради скругленных уголков и теней? Во первых это красиво (с), во вторых «вон тот дядечка в желтой каске» уже оплатил разработку системы и скругленные уголки там, к сожалению, (или счастью) попали в ТЗ, осталось сделать их с градиентом и добавить немного теней.

Вот такое было оригинальное лето 2017 года в солнечном Сочи.

Так выглядит OpenGL рендер

Когда хочется красивый GUI, а gpu нет - 2

Так выглядит software рендер на ПК

Когда хочется красивый GUI, а gpu нет - 3

Ссылки:

Оригинальный wjakob/nanogui
NanoVG software render
NanoGUI + SDL + software render

P.S. Не верьте китайцамразработчикам, говорящим о наличие OpenGL в системе, проверяйте работоспособность всех компонентов, знать бы еще как :)

Автор: dalerank

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js