Pull to refresh

Comments 21

В практической компьютерной графике просто огромное количество упрощений, и в видео рассказано лишь об одном из. Никакой Америки они не открыли.
Причем здесь Америка? Они рассказывают о конкретной проблеме, которой не существовало бы, если бы преобразование цветов делали по правилам и фактически по определению (про которое забыли).
Потому что это не баг, а сознательное упрощение.
Кодирование-декодирование гаммы — это два возведения в степень, несколько умножений и сложений, причем в вещественных числах. На каждый пиксель. Даже сегодня это выглядит заметной нагрузкой, а лет 20 назад это был анриал полный.
На это пошли сознательно, принеся в жертву немного качества в пользу колоссального ускорения. И, как я уже говорил, это далеко не еднственное подобное упрощение. Потому что если копать глубже, даже смешивание с учетом гаммы (как они описывают) тоже не вполне корректно, там нужно еще очень сильно наворачивать формулы. Настолько сильно, что в реалтайме не справятся даже современные компьютеры.
Я взялся за написание своей реализации AlphaBlend функции не веря в то, что смогу победить ребят из майкрософта. Это был просто спортивный интерес, который, тем не менее, дал результат.
А вот это вы зря. «Ребята из майкрософта» (Apple, Google, Intel'а — выберите себе компанию по вкусу) могут, конечно, сделать версию, которая будет супер-пупер быстрой и классной — но у них уйдёт на это немало времени. А когда у вас есть тысячи других задач и десятки (или уже сотни?) миллионов строк кода, то до всего руки просто не доходят.

Оптимизированы «до упора» только функции, которые нужны реально очень-очень большому проценту разработчиков и которые вызывают проблемы в реальных программах. Я думаю 90% (если не 99%) функций в Windows (Android, iOS — далее по вкусу) можно серьёзно ускорить.
Но ведь не на всех поддерживаемых Windows платформах есть SSE инструкции?
Да и AlphaBlend вроде бы аппаратно ускорена… Не помню уже, BitBlt точно, имеются ввиду последние версии ОС.
В последних версиях ОС как раз всё тухло. Лет примерно 20 назад — да, всё выполнялось аппаратно. Cirrus Logic, S3 и прочие всякие Tridentы рулили. А потом — настала эпоха 3D, а на 2D разработчики малость подзабили потому как CPU стали достаточно быстрыми чтобы это не было проблемой. А код ведь старый, писался ещё до того, как MMX (не то, что SSE) появился — и таким он, скорее всего, и остался, так как никого особо не трогал (даже современные браузеры все свои эффекты не через GDI, а через DirectX рисуют!).
Не на всех. Там где нет ssse3, используется обычная c/c++ реализация. Вот только ssse3 появилась как минимум в Core 2 duo, т.е. охват этой ssse3 оптимизации по железу довольно неплох (если не сказать, 100%-й)
> Да и AlphaBlend вроде бы аппаратно ускорена
Возможно она ускорена, если работает с видеопамятью. При работе с обычным Memory DC — максимум mmx, и то не факт.
Ассемблер это очень замечательно, но рекомендую переписать с использованием интринсиков если хотите другие платформы и/или битность (x64 например).
Кстати, иногда компилятор умудряется замечательно заоптимизировать интринсик-код давая фору даже «ручному» коду.
image
Но как же… а начать с упрощения самой формулы?

NewColor = DstColor * (1 - SrcAlpha) + SrcColor * SrcAlpha;
NewColor = DstColor - DstColor * SrcAlpha + SrcColor * SrcAlpha;
NewColor = DstColor + SrcAlpha * (SrcColor - DstColor);
//после деления на 255:
NewColor = (DC/255 + SA/255 * (SC/255 - DC/255))*255
NewColor = (SC - DC) * SA/255 + DC

Это вы к тому, что можно работать с нормальным, не premultiplied цветом не увеличивая количество умножений? Да, это неплохой вариант. Но я не стал его рассматривать по трем причинам (3-я — основная):
1. AlphaBlend меня уже приучил к premultiplied. Менять привычки бывает непросто.
2. В сокращенной формуле, хоть и такое же количество умножений, как и при работе с premultiplied, однако, есть дополнительная операция вычитания, которая, к тому же, порождает отрицательные значения. Это требует дополнительных усилий.
3. Путь оптимизации, предполагающий переход на premultiplied, затмил мой разум и я просто упустил этот момент из виду.

Зато, если у меня возникнет необходимость написать AlphaBlend на нормальных пикселях, без предумножения, я сразу вспомню об этом упрощении и сделаю все как надо. За что вам спасибо.
Рекомендую посмотреть в сторону intrinsic-ов: это почти прямое отражение mmx, sse и avx инструкций на «сишные функции». В итоге компилятор занимается подбором регистров, упорядочиванием и выравниванием команд, а программист говорит, что именно делать. В качестве бонуса получается некая «переносимость», т. к. intrinsics, в отличие от inline assembler'а, в различных компиляторах.
У Intel есть замечательный гайд: https://software.intel.com/sites/landingpage/IntrinsicsGuide/
Гайд прекрасный! Но вы не внимательны: в статье есть ссылка на этот гайд. Собственно, по нему я все и делал.
Что же касается использования интринсиков вместо голого асма — я не отвергаю интрисики — штука крайне полезная. Просто ассемблер… ну это как первая любовь. Неравнодушен я к нему. Я же и оптимизировал в основном из спортивного интереса. Несомненно, как только появится свободное время, я перепишу часть кода на интринсики. Да я в любом случае это сделаю, т.к. у меня в планах перейти на 64 бита.
С другой стороны, перенимая опыт разработчиков кодека VPx: там 64 битный код написан на интринсиках или вообще на C, а 32-битный — на ассемблере. Думаю поступить также.
Пост хороший с точки зрения теории смешивания цветов. Но не могу не спросить, под какой Windows вы программируете, что там до сих пор есть необходимость работать с GDI? О_о
Хм… В любой?
Нативный(не wpf) интерфейс весь GDI рисуется, и если необходимо создать свой контрол, либо изменить проприсовку у стандартного необходимо использовать GDI.
Вы правильно заметили («если не WPF»), но вопрос не поняли. Если у вас Windows 7+ какой смысл в нативном интерфейсе и WinAPI, если есть WPF, есть C++/CLI (если не устраивает C#). Для меня единственной осмысленной причиной этого может быть поддержка Windows XP и ниже. Отсюда и вопрос.
Кстати да, XP я поддерживаю, причем приходится прилагать определенные усилия к этому. Например, первая версия с поддержкой видеозвонков не видела камеру под XP. Два дня убил, чтобы найти причину.
А вот qTox, кажется, отказался от поддержки XP. Не проверял, может и ошибаюсь, но что-то такое на эту тему видел в чате разработчиков Tox'а.
Смысл нативного интерфейса — в его нативности, WPF не всегда на 100% выглядит нативным, и к сожалению бывает привередлив к видеокартам, что приводит к тому что словить глюки отрисовки, и как не странно тормоза, в программах на древнем win32 GUI можно реже чем на WPF. В конце концов GDI потребляет меньше памяти.
Опять же большенство приложений, в том числе и системные, базируется на GDI-шной отрисовке.
Все технологии имеют свои недостатки, но часто отрисовка GDI бывает оправдана.
Я понимаю ваш вопрос. Действительно, существует огромное количество средств создать графический интерфейс у своего приложения, не работая с GDI напрямую. Однако вы должны понимать, что все эти средства так или иначе основаны на GDI, исключая, возможно, какие-то специальные разработки майкрософта, а также интерфейс, на основе 3D графики (в играх, например).
Так что я, сознательно отказавшись от всех этих средств (почему — отдельный вопрос), встал перед выбором: либо GDI, либо Direct3D (или OpenGL). Как показала практика, GDI вполне себе быстр и нет необходимости прибегать к мощностям GPU. Во всяком случае, решение этого вопроса я отложил на неопределенный срок.
Sign up to leave a comment.

Articles

Change theme settings