Программирование

Трудовые будни

Вот решил я для экономии памяти - для распаковки JPEG иметь буфер на одну строчку и сразу распихивать ее куда надо (в tiled-буферы с перекрытиями).

Как мне повезло, что тестировать-отлаживать я начал на progressive JPEG......

Записки сумасшедшего: Qt+OpenGL

Мы продолжаем наш репортаж про Qt и OpenGL.

В Qt, если кто не знает, есть приятные врапперы для OpenGL. QOpenGLShaderProgram для шейдеров, QOpenGLBuffer для буферов ну и так далее. Я ими пользуюсь, потому что удобно, сахарок вкусный типа QOpenGLVertexArrayObject::Binder, опять же деструкторы все удалят и так далее.

И есть QOpenGLTexture, любовь с ней в FRV у меня не задалась (делаю все руками в результате), а тут в рамках HelloWorld-2017 решил вернуться к ней.

И получился (почти)...

Если к кошке приставить голову тигра....

Каких-то жалких 4.5 года назад KDAB начали рекламировать использование современного OpenGL изнутри Qt.

Я их начитался еще тогда и возжелал. Однако требования к железу (OpenGL 3.3/DirectX 11) поднимать в FastRawViewer не хотелось и руки дошли вот только сейчас, для нового проекта, благо железо подросло и OpenGL 3.3 есть во всем вменяемом (включая Intel, кто до сих пор работает на SandyBridge с тамошним видео - пусть страдает).

Однако научные исследования показали, что реально OpenGL CoreProfile так чтобы все...

"Hello world" - 2017

Вот значит написал программу, которая ничего (почти) не делает:

$ cat *.cpp *.h *.pro *.frag *.vert *.qrc | wc -l 3584

Нельзя сказать, что совсем уж ничего:

  • Окошко есть
    • в окошко выводит OpenGL (или OpenGL ES 3 поверх DX11). Разноцветный треугольник, что еще можно выводить.
    • и конечно с шейдерами, их компиляцией, сохранением/загрузкой бинарного представления и т.п.
    • и сolor management есть (и сохранение/чтение device link LUT, чтобы каждый раз не пересчитывать таблицу)
    • настройки есть, их чтение, сохранение, редактирование (втч.
  • ...

30 лет в строю

Я, конечно, не красный граф и не могу пока с ним меряться трудовым стажем.

Однако где-то в этих числах ноября 1987-го года, то есть 30 лет назад, я получил свою первую зарплату за программирование. На биофаке МГУ, в Налимовской лаборатории, что-то там программировал по "планированию факторного эксперимента".

Не помню что программировал, не помню на чем (но процентов 90 за фортран-77), а вот зарплату первую помню и как в здании биофака заблудился, зарплату получив, - тоже помню. И IBM PS/2 Model 50 помню прекрасно (как-то меня пронесло мимо ДВК/PDP, сразу началось с ЕС ЭВМ и дальше PC).

Но с тех пор - не останавливался. Так и программирую за деньги (программировать просто так я начал, понятно, раньше).

А благодарить надо школу, ибо все началось на УПК, на специальности "оператор ЭВМ".

Лучшее - враг....

After Qt 5.3’s introduction of QQuickWidget, Qt 5.4 adds QOpenGLWidget, the long-awaited replacement for the legacy QGLWidget.

Писали нам в Qt Weekly три года назад.

Я тогда попробовал, но Qt 5.4 глючила на маке (уже не помню даже в каком месте), держать две ветки кода было не с руки, так и используем legacy QGLWidget в FRV.

Прошло три года и руки дошли попробовать еще раз, уже в Qt 5.6. Такой вот бутерброд (если вкратце):

QGraphicsView...

Q: Win32 CryptAPI

Граждане программисты,

а ткните носом, как проверить валидность подписи EXE-файла (MS Authenticode) без WinVerifyTrust, а с использованием только CryptoAPI. Ведь должно же быть можно?

Трудовые будни

А вот вы знали, что Adobe XMP SDK может в некоторых случаях при записи XMP модифицировать еще и EXIF у файла?

И я не знал.

А поскольку случаи - некоторые, то в наших тестах оно как-то не вылезло (дальше нецензурно).

Разборки показали, что это, смешно сказать, рекомендованное поведение:

When the file format supports both Exif and XMP, a Changer SHOULD update both forms of a value. If only
...

О программистах и пользователях

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

Вот есть такая библиотека декодирования RAW, RawSpeed. Хорошая, в том смысле что быстрая, местами сильно быстрее LibRaw, местами - не сильно. Ее сначала разрабатывал Клаус Пост, а потом, весной где-то, передал текущей команде darktable.

И вот ее теперешний майнтайнер берет и одним движением вставляет дополнительную проверку на размер изображения, например вот эту: ...

Удивительное рядом (о совместимости ABI компиляторов)

Волею судеб тут пришлось делать следующие упражнения:

  • Собрать некую библиотеку (C++) с помощью Visual Studio 2013 тулсетом для XP (Platform toolset: v120_xp) и использовать ее потом из Visual Studio 2010.
  • Собрать некую библиотеку (C++) с помощью Clang (clang-cl, версия 4.0.1) и использовать (вызывать) ее потом из кода, собираемого Visual Studio (в данном случае 2015, но думаю проделать то же с 2010 и 2013). А из clang-собранной библиотеки зовется еще одна, собранная 2015-й студией.

Причина была одна и та же, первая "некая библиотека" не собирается 2010й студией, ибо используемый C++ новее, аналогично и со второй (сходу только Clang/gcc, под MSVC надо править, но очень уж не хотелось).

На удивление, оба варианта проканали вообще без каких-то проблем (я опасался, что придется тянуть всякие чужие C/C++ рантаймы, но нет). Про Clang известно, что над совместимостью по name mangling и подобному там все еще ведутся улучшения, но базовые вещи работают уже.

Еще более на удивление, с clang-cl работают базовые вещи у отладчика VisualStudio (небазовые не пробовал).

Итого: вот просто берешь и используешь (в случае Clang - запускаешь еще батник для интеграции с VS).

Вот что не работает с раздачи, так это cmake, которому указано что используется clang-овский toolset. Оно каким-то чудом узнает, что вот работает clang (хоть и -cl) и пытается совать туда clang-овские же свитчи командной строки, а clang-cl их не понимает. Надо править бы, но я этот ad-hoc язык не знаю и очень не хочу узнавать.

 

Трудовые будни

Кто нибудь может мне объяснить, отчего вот такой вот кусок кода перестал работать в Win10 (в анонс не лезет - перейдите в полный текст :)

Есть многое на свете....

А вот возьмем OS X Sierra. Есть один (то есть единственный) пользователь, на компьютере которого не работает такой вот код:

QString xmpfile = ....; // вычислить имя XMP из имени raw
QFile xmpw(xmpfile);
if (!xmpw.open(QIODevice::WriteOnly)) -> тут обрабатываем ошибку

И ошибка - EACCESS, прав нету

А вот такой вот код работает:

QString xmpfile = ....; // вычислить имя XMP из имени raw
int fd = open(xmpfile.toUtf8().data(), O_WRONLY | O_CREAT | O_TRUNC, 0664);

То есть открывается дескриптор...

Q: про Qt

Граждане, а есть опыт подачи своих патчей в Qt?

Не багфиксов, а расширения функциональности существующих модулей (QDirModel/QFileSystemModel).

Есть смысл куда-то сначала написать (в development?) на предмет "а оно вообще интересно кому-то"?

Я просто опасаюсь потратить на это время - и без результата. Особенно с учетом того, что мы работаем с Qt 5.4, а патчи попадут - если попадут - куда-то в район 5.9

Qt ненависти псто (3)

А вот, значит, еще про Qt.

Допустим, у нас есть QListView (с кастомными элементами, но это в данном случае несущественно). В нем мелко показаны фигульки.

Хотим: при клике на фигульку спрятать QListView и на его месте показать фигульку крупно (в QGraphicsView, хотя это тоже не так и важно).

Первые грабли зарыты в "спрятать-показать". Если запихнуть их, скажем, в один QLayout и делать  QListView->hide(); QGraphicsView->show(), то оно может валится. Не всегда. При некоторых размерах окна. Ну ладно, сначала show/hide, а потом...

Qt MVC: ненависти псто - 2

А вот например Qt. Обычный такой QTableView на две колонки, хочется банального:

  1. Чтобы занимало окошко целиком, даже если строки короткие, иначе там odd/even rows некрасиво.
  2. Чтобы если строки длинные - был бы скроллбар.

Осложняется, правда, тем, что некоторые строки - HTML-ные, то есть их надо руками рендерить. Соответственно, для DisplayRole надо отдавать пустой текст (это я сейчас знаю!), HTML-ку получать другой ролью и рендерить самостоятельно.

И что вы думаете? ДВА ДНЯ. И то, полностью не победил, скроллбар в результате есть всегда. Ну хоть так.

При этом узнал, что SizeHint есть:

  1. В Q...ItemModel::data()
  2. В QTableView::sizeHintForColumn
  3. В QItemDelegate::sizeHint

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

Qt MVC: ненависти псто!

Вот есть такой Qt. А в нем полноценный Model-View: QAbstractItemModel (и потомки), QAbstractItemView (и потомки) ну и "контроллер", то есть делегат.

И вот допустим мы отображаем некий список (произведя его из QListItemModel) в некоем вью (произведя его из QListView). Стандартные средства - хороши, пока их хватает. Иконка, подпись, чекбокс, все есть. Раскраска - стайлшитом.

Идем дальше, стандартных средств не хватает, хотим нарисовать полоску/иконку/хреновинку. Ну отлично, QStyledItemDelegate, базовый класс нарисует основу, мы потом разукрасим.

Правда выясняется, что оформление...

AVX2 и VPGATHERDD - продолжение

Продолжаем дневник программиста на AVX2 (начало и продолжение).

Добрался до 4-го места, которое хотелось пооптимизировать окончательно уже года два как: берем 16-битные целые (RAW-данные), конвертируем в плавучку, вычитаем черный, результат записываем. То есть первый этап дебайеризации.

Параллельно считаем RAW-гистограмму и карту пересвета-недосвета (на самом деле там карта экспозиции считается, а не просто пересвет-недосвет, а дальше она визуализируется с лимитами, все что выше/ниже лимита раскрашивается.).

Вот в этом месте VPGATHERDD (из RAW-значений в экспозицию по LUT) внезапно дал выигрыш...

Еще про AVX2 и VPGATHERDD

Продолжение вот к этому вот тексту и к тамошним комментариям:

1. Собрался с духом и переписал тройку мест на 256-битные команды. Помогло: время исполнения этих кусочков упало на 15-25%. Буду дальше писать.

Это без особой оптимизации, старый код у меня SSE3, никаких BLENDPS/EXTRACTPS не использовалось, соответственно и AVX2 - это чисто замена _mm_ на _mm256_ ну и типы 256-битные. В уже переписанных кусках буду еще смотреть на DPPS: на SandyBridge эта инструкция выигрыша не давала, но может быть поможет на Haswell+.

2. А вот с VPGATHERDD - сплошное разочарование:

  • Для гистограммы (когда gather, потом инкремент, потом поэлементная запись) - получается серьезный проигрыш в производительности, а код сложнее.
  • Для операций вида bitmap[index][channel] = contrast_curve[value] проигрыш тоже есть, хотя и незначительный. Совсем оптимизированное (читаем только 6 элементов, для альфа-канала берем defaults т.е. через masked load) - совсем незначительно медленнее, единицы процентов на всю функцию, но медленнее.

Уж не знаю, кому эта VPGATHERDD в таком виде нужна. Ну разве только на новых процессорах она побыстрее.

Про AVX2

Давненько я в этом блоге на ассемблере не писал.

Вот значит кусочек FRV, который накладывает выходную тоновую кривую. Точнее, два кусочка, один на старом добром SSE2 (которого там ровно одна команда, сконвертировать float-int), а второй - на новом модном AVX2, правда 128-битном, но зато с table lookup.

#ifndef USE_AVX
        uint32_t __declspec(align(16)) dpix[4
...

Q: Qt, Dynamic OpenGL, OES/ARB extensions

Вот что-то наткнулся и смотрю как на новые ворота.

Преамбула:

  1. Вот есть такой Qt, в нем есть работа с OpenGL
  2. У кого OpenGL нету или кривой - есть библиотека ANGLE, которая эмулирует OpenGL ES2 (или 3) поверх DirectX 9 (или, соответственно, 11).
  3. OpenGL ES от простого отличается, в числе прочего, названиями extensions. Ну, к примеру, GL_OES_get_program_binary у ES/GL_ARB_get_program_binary у обычного.
  4. У Qt 5.4 (под Windows) появилась возможность динамической загрузки имплементации OpenGL. До инициализации QApplication говоришь что хочешь, а дальше
  5. ...

Pages

Subscribe to Программирование