Как увеличить скорость отрисовки на canvas?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Как увеличить скорость отрисовки на canvas?

Сообщение xterro » 03.03.2014 13:41:52

В редактор эл. схем, типа KiCAD, Geda, интересная для меня тема, хочу повозиться, да и опыта практического набраться не мешало бы. Это такая тема, которую я смутно представляю, решил на реальном примере, восполнить пробелы в опыте и знаниях.
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Как увеличить скорость отрисовки на canvas?

Сообщение zub » 03.03.2014 14:00:45

Вот http://wiki.lazarus.freepascal.org/Turbo_Circuit возможно будет полезно. Но там сделано на основе fpvectorial - не советую его юзать - недопилен.

>>Это такая тема, которую я смутно представляю, решил на реальном примере, восполнить пробелы в опыте и знаниях.
Эту тему вообще мало кто хорошо представляет, но все горазды советовать, особенно на лоре))
Последний раз редактировалось zub 03.03.2014 14:05:27, всего редактировалось 2 раз(а).
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как увеличить скорость отрисовки на canvas?

Сообщение xterro » 03.03.2014 14:03:59

Можно использовать в работе, в том же KiCAD, или свою телегу запилить, это уже вопрос отдельный, сейчас мне бы главное начать, но чтобы начать, необходимо понять некоторые фундаментальные вещи )
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Как увеличить скорость отрисовки на canvas?

Сообщение zub » 03.03.2014 14:05:37

Т.к. "компонет" обычно не сложная графическая еденица - можешь оптимизацией вообще не заморачиваться, делай всё в лоб, будет нормально работать. Потом по мере появления проблем будешь оптимизировать - переделывать. Изначально "правильного" пути тебе никто не подскажет))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как увеличить скорость отрисовки на canvas?

Сообщение xterro » 03.03.2014 14:29:26

Не не, немного не поняли. Как рисовать компонент, я знаю, меня интересуют концептуальные вещи. Т.е например, можно не париться, и рисовать всё как есть в границах ClientWindow, добавить масштабирование, путём умножения всего и вся на коэффициент, но ведь это будет не правильно? Например, вы в своём CAD как выводите информацию? Вы сразу определили какую-то область, на которой всё рисуете, а дальше просто всю эту область масштабируете?
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Как увеличить скорость отрисовки на canvas?

Сообщение debi12345 » 03.03.2014 16:07:24

Уберите вы этот guiif = interface, используйте обычные классы

Да, так значительно (те самые 5% проигрыша) быстрее, но придется делать неуклюжую вещь -
объявлять и имплементить все позднее переопределяемые методы пустыми в парент-классе - иначе полиморфизма не получишь.
Странно что использование безметодового (абстрактного) класса (=интерфейса) приводит к таким тормозам. Скорее всего дело именно в "безметодовости" (невозможности прописать VMT-зависимости на этапе компиляции).

Добавлено спустя 5 минут 6 секунд:
function test(TestImpl:Boolean;param:TParamType):TParamType;virtual;abstract;

ABSTRACT - в-о-о-т где его применение оказывается ! Не пользовался ранее - возьму на заметку :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Как увеличить скорость отрисовки на canvas?

Сообщение zub » 03.03.2014 19:16:11

xterro
Я использую OpenGL, соответственно масштаб и сдвиг модели сидит в матрице прецирования.
Допустим есть отрезок 0,0;1,1 - в зкаде всегда и выводится по этим координатам, независимо от зума и сдвига. Но зум и сдвиг участвует в формировании матрицы проецирования. Искллючение состовляют мелкие детали вдали от начала координат (с удалением больше 10e6), там я вычитаю из координат примитивов некую величину - центр виевфрустума - т.е. сдвигаю всё к началу координат, иначе появляется погрешность внутренних глных вычислений.

Канвас такое сделать не позволит, там координаты надо будет корректировать во время вывода. Но имхо какиелибо вычисления в момент отображения информации - зло, их надо по возможности избегать - считать зарание и хранить. ИМХО умножение и сложение (масштаб и сдвиг) можно оставить на момент вывода, а вот более сложные требующие умножения на матрицы - вращения, скосы, проекции считать заранее.

Кроме того если картинка не менялась, но ее требуется перерисовать - лучше не рисовать всё заново а восстановить каким либо быстрым способом (естественно перед этим ее нужно было сохранить в соответствующем виде) зкад умеет восстанавливать текстурами, AUX и ACCUM буферами, сохранением копии в памяти и полной перерисовкой - подходящий способ можно указать в настройках. В случае PaintBox насколько я понимаю этот пункт не понадобится

Ну и нужна отбраковка невидимых примитивов, хранение примитивов в какихлибо древовидных структурах для быстрого геометрического поиска и "пакетной" отбраковки невидимых примитивов.

еще - тут всплывали пунктирные линии предоставляемве канвасом. OpenGL предоставляет подобное, но я их использую только для отображения выделенных примитивов, если нужна какаянибудь штрихпунктирная линия - координаты всех штрихов расчитываю и рисую отдельными примитивами - сложно, но зато плный контроль как выглядит результат и практически любые типы штрихов, вплоть до надписей вставленных в линию
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как увеличить скорость отрисовки на canvas?

Сообщение debi12345 » 03.03.2014 19:21:39

Да, так значительно (те самые 5% проигрыша) быстрее

Один нюанс - это на одном только вызове. Если подряд выстроить много таких вызовов (например реализовав классы TPixel и TRect и работая через их методы при рисовании примитивов) - получим уже серьезные тормоза.
3 обращения = 1.05 pwr3 -1 = 16%
5 обращений = 1.05 pwr 5 -1= 28%
10 обращений = 1.05 pwr 10 -1 = 63%
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Как увеличить скорость отрисовки на canvas?

Сообщение zub » 03.03.2014 19:31:41

debi12345
>>TRect
Если все реализовать с головой никаких тормозов не будет, ну начертили вы 500 ректов - вызвали 500 раз виртуальный TMyImplGUI.DrawRect... Как тут уже замечали виртуальный вызов против внешнего вызова OpenGL - ничто по затратам.

>>TPixel
Так делать програмиста отучит общая тормознутость "прямого" "пиксельного" доступа к видеопамяти, а не невидимые на ее фоне затраты на виртуальный вызов.

Купите уже зажигалку, а не экономте на спичках))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как увеличить скорость отрисовки на canvas?

Сообщение xterro » 03.03.2014 19:32:30

Допустим есть отрезок 0,0;1,1 - в зкаде всегда и выводится по этим координатам, независимо от зума и сдвига.

Как раз интересный момент затронули, появился вопрос. В OpenGL координаты у нас от -1 до 1 по X и по Y, но пользователь привык к обычным координатам, с началом скажем в нижнем левом углу, и привык к циферкам типа X:800 Y:540. Соответственно и в файле данных(т.е куда сохраняем нашу картинку) координаты тоже должны храниться в каком то таком виде. Не будут же они храниться в виде скажем: -0,2;0,5? Или например обработка кликов мышки, там всё в координатах окна, т.е кликнули, получили цифра, скажем 400, 300 и как теперь проверить, что кликнули по линии, перевести как-то в координаты OpenGL? Как вы решали этот вопрос?
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Как увеличить скорость отрисовки на canvas?

Сообщение debi12345 » 03.03.2014 19:35:56

Ну и нужна отбраковка невидимых примитивов, хранение примитивов в какихлибо древовидных структурах для быстрого геометрического поиска

Хм, для облегчения этих страданий пил юзает даже игровые движки :
http://forum.cadstudio.ru/index.php?topic=25124.0.html
http://forum.cadstudio.ru/index.php?topic=20948.0.html
!

против внешнего вызова OpenGL -

АФАЙК, эти вызовы асинхронные - принимаемые в GL-конвенйер, то есть без ожидания, мгновенные, не сильно дольше чем "i:= i+1". Или ошибаюсь ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Как увеличить скорость отрисовки на canvas?

Сообщение zub » 03.03.2014 19:48:33

xterro
Координаты там абсолютно любые 0,0;1,1- просто пример, почитайте как настраивается матрица проецирования в "режиме" GLOrtho. Можно настроить для совпаденеия пиксел в пиксел, можно "бесплатно" учесть зум и сдвиг

debi12345
Игровые движки для СAD мало пригодны, смысл получить не статическую красивую картинку, а полностью редактируемый чертеж - много своей специфики.

>>АФАЙК, эти вызовы асинхронные
Асинхронные, но не бесплатные, копят данные но рано или поздно начинают их жевать. Кстати сделанны через указатель на процедуру в opengl.pas от fpc

>>10 обращений = 1.05 pwr 10 -1 = 63%
Хитрый расчет, если следовать ему LCL вообще должен стоять и не выполняться. представте сколько там вложенных виртуальных вызовов)) то что 5% было получено для maxint идущих подряд вызовов ни о чем не говорит?))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как увеличить скорость отрисовки на canvas?

Сообщение debi12345 » 03.03.2014 20:06:50

Хотя, чтобы не быть голословным, заменив "i:= i +1" на "Load_GL_EXT_abgr;", получил проигрыш в несчастный 1%. Хотя конкретно эта GL-команда - не конвейерная.

то что 5% было получено для maxint идущих подряд вызовов

Но согласитесь что желательно искать решения для максимального (в данном случае - молотильного) алгоритма, тогда и в будущем (ускорение отрисовки за счет умощнения аппаратуры и т.п.) не возникнет проблем масштабируемости. А они уже возникли у ТС - слабый проц (делающий 5% заметным по времени) и мощная (делающая накопленные "5% pmr дофига" относительно более чувствительным импактом) видяха.

Добавлено спустя 5 минут 59 секунд:
Хитрый расчет, если следовать ему LCL вообще должен стоять и не выполняться

Не стоять, а подтормаживать :
10 вызовов = 65% = меньше 2 раз
30 вызовов (близко к реальности) = 3 раза (тоже близко к реальности на молочении)
100 вызовов = 130 раз

Добавлено спустя 7 минут 10 секунд:
Хотя что-то я стормозил - тестировал-то на 10млн вызовов. И только на них набралось 5% :) На 30-ти вообще нет никакой разницы.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Как увеличить скорость отрисовки на canvas?

Сообщение zub » 03.03.2014 20:32:09

Соглашусь - Когда не остается возможности алгоритмической оптимизации не грех попытаться помочь компилятору сгенерировать более оптимальный код, но только постоянно свяряясь с профайлером, чтоб не обречь себя ради мнимой выгоды на мучительные воспоминания - что же я хотел сделать в этом куске кода?))
Да проигрышь в несколько процентов и выигрышь в читаемости кода (по мне тоже не бог весть какой) признаю. Но это полная ерунда по сравнению с отсутствием аппаратной акселерации у MiniQ
Вы так ръяно отстаиваите принципы MSE, но думаю она бы в подобной ситуации проиграла еще больше (не используя OpenGL) - т.к. на злополучной железке выступала бы против Qt который рисует контролы для LCL))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как увеличить скорость отрисовки на canvas?

Сообщение debi12345 » 03.03.2014 20:52:07

Вы так ръяно отстаиваите принципы MSE

Даже не думал об этом. Однако по инерции мышления применять ООП для молотильного и рисовального кода рука не поднималась - а оказывается (как выявило сегодняшнее практическое тестирование) не так страшен черт как его малюют. Ведь BLENDER весь написан на C++ ООП - и ничего, воркабален :)
.
но думаю она бы в подобной ситуации проиграла еще больше

Ну, Мартин использует кое-какие трюки и все тщательно тестирует на перформанс (до сих пор сидя на слабой машине), начиная с двойной буферизации.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 246

Рейтинг@Mail.ru