Название: [РЕШЕНО] Оптимизации рендеринга QGraphicsView на разных платформах Отправлено: Pritcher от Май 05, 2015, 18:46 Привет!
Я разрабатываю пиксельный графический редактор. Все реализуется с помощью QGraphicsScene & QGraphicsView с вьюпортом QOpenGLWidget. Есть необходимость выделять текущий пиксель (находящийся под курсором). Для этого я в методе QGraphicsView::drawForeground отрисовываю точку методом QPainter::drwaPoint. Помимо этого есть док, в котором отображаются координаты текущего положение курсора. Итого в методе QGraphicsScene::mouseMoveEvent происходит emit сигнала для сообщения о смене положения курсора. На Linux такое решение поставленной задачи не приносит хлопот, всё отрисовывается так, как и задумывалось. На Windows 7 же без принудительного вызова update() по рабочей области в методе mouseMoveEvent вызов drawForeground не происходит, а => нет отрисовки пикселя. У меня на стационарном ПК стоит старенький Athlon 5000+ 2х2.6 Гц, Win7 и все эти операции занимают у моего проца около 70%. Товарищи смеются, а у меня никаких идей, как можно было бы сократить нагрузку. Может, кто-нибудь предложит что-нибудь конструктивное? На моём ноуте Linux, i5 4x2.6, жрёт максимум 5%. У товарища на ноутбуке Win8 i3 4х2.5 — 13,5%. P.S. Пробовал ставить фиксированный фпс (50-60 апдейтов в секунду), вызывая QGraphicsView::setViewportUpdateMode( QGraphicsView::NoViewportUpdate ), особых изменений не было. Крутой нагрузки в методе drawForeground нет, лишь проверка на попадание курсора в рабочую область и отрисовка около 100 различных примитивов с помощью QPainter (пиксельная сетка, тайловая сетка, тайловые номера). При этом опытным путем выяснено, что основная нагрузка именно на update(), вызываемом в mouseMoveEvent. P.S.S. Изначально курсор был отдельным элементом QGraphicsItem, но от этой идеи пришлось отказаться, т.к. при масштабировании квадратик курсора размером в 1 пиксель имел сторону несколько бОльшую, чем квадратик, отображаемый как пиксель QImage. Таким способом можно было бы отказаться от постоянной перерисовки всей сцены, но проблему с одинаковыми сторонами не решил. Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Racheengel от Май 06, 2015, 01:11 Пикселы на QGraphicsScene это печально :( Надо свою отрисовку через QPainter делать.
Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Igors от Май 06, 2015, 09:29 Создать окно (а не просто виджет) наверху и двигать его, тогда этим займется ОС, сцена перерисовываться не будет. Правда это немалые хлопоты с фокусом, но все лучше чем перерисовка (потенциально огромной) сцены (у меня с OpenGL)
Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Pritcher от Май 06, 2015, 10:17 Создать окно (а не просто виджет) наверху и двигать его, тогда этим займется ОС, сцена перерисовываться не будет. Правда это немалые хлопоты с фокусом, но все лучше чем перерисовка (потенциально огромной) сцены (у меня с OpenGL) Идея интересная! Но вот сама реализация редактора на QGraphicsScene имеет место быть? Или же стоит реализовывать всё на QWidget, с рисованием на QImage (как это сделано, например, в редакторе EasyPaint (http://qt-apps.org/content/show.php/EasyPaint?content=140877))? Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Igors от Май 06, 2015, 10:33 Но вот сама реализация редактора на QGraphicsScene имеет место быть? Перечитал первый пост. Если юзаете QOpenGLWidget - то можно просто создать обычный виджет (не окно) наверху. Собственно в этом и достоинство QOpenGLWidget - его можно совмещать, комбинировать с другими и/или обычными как угодно, это не вызывает перерисовок всей сцены (в отличие от QGLWidget или QOpenGLWindow). Точнее: рисование будет вызвано, но его можно пропустить, останется старый буфер.С точки зрения пиксельного редактора - ну хз, я не вижу зачем здесь вообще OpenGL если операции растровые. Ну может как-то "на перспективу" Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Pritcher от Май 06, 2015, 15:40 Перечитал первый пост. Если юзаете QOpenGLWidget - то можно просто создать обычный виджет (не окно) наверху. Собственно в этом и достоинство QOpenGLWidget - его можно совмещать, комбинировать с другими и/или обычными как угодно, это не вызывает перерисовок всей сцены (в отличие от QGLWidget или QOpenGLWindow). Точнее: рисование будет вызвано, но его можно пропустить, останется старый буфер. С точки зрения пиксельного редактора - ну хз, я не вижу зачем здесь вообще OpenGL если операции растровые. Ну может как-то "на перспективу" Хм, дельное замечание по поводу QOpenGLWidget. Я его применял по причине того, что рендеринг был быстрее, без него текущий пиксель не всегда успевал за курсором. Но это было на ранней стадии разработки, когда не было никаких оптимизаций и было немалое количество неверных решений. Сейчас же убрал этот вьюпорт, собрал с -O3 и загруженность процессора упала. Хоть и грузит всё ядро на моём проце, но уже одно и довольно терпимо в целом. Пиксель под курсором раньше был больше размером потому, что QRectF размером 1х1 в Qt почему-то больше, чем точка, рисуемая QPainter::drawPoint. Спасибо за совет. Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Pritcher от Май 06, 2015, 19:25 Ну что ж, вроде, смог снизить нагрузку на моём проце до 25% в самых "тяжелых" моментах.
Создал таймер с интервалом в 16 мсек, добавил в mousePressEvent: Код
Название: Re: Оптимизации рендеринга на разных платформах Отправлено: Igors от Май 07, 2015, 07:02 Ну что ж, вроде, смог снизить нагрузку на моём проце до 25% в самых "тяжелых" моментах. Что-то "не то", все равно слишком много. Неясно Вы используете QOpenGLWidget или уже от него отказались. Если используете - поставьте печать на каждое его paintGL, увидите много интересногоНазвание: Re: [РЕШЕНО] Оптимизации рендеринга QGraphicsView на разных платформах Отправлено: Fregloin от Май 07, 2015, 09:10 какая версия Qt у вас? Если 5я, то нет смысла заморачиваться с QGLWidget. Если 4я то тут я не помощник, хотя у меня сложные сцены рисовались побыстрее чем у вас в любом случае.
Попробуйте поиграться с параметрами кеширования сцены. Название: Re: [РЕШЕНО] Оптимизации рендеринга QGraphicsView на разных платформах Отправлено: Pritcher от Май 09, 2015, 09:15 ]Что-то "не то", все равно слишком много. Неясно Вы используете QOpenGLWidget или уже от него отказались. Если используете - поставьте печать на каждое его paintGL, увидите много интересного Что вы имеете в виду под "печатью"? Отказался. Дело в том, что у меня процессор в аналогичном редакторе выдаёт ровно такие же цифры в нагрузке, поэтому меня устраивает такая производительность. Протестировал на более современных системах, более 8% не выдаёт. Когда делаю вьюпорт QOpenGLWidget, то нагрузка в любой момент, когда активно окно приложения, 70%. Вот собственно мои действия, что привели к уменьшению нагрузки: 1) Оставил родной вьюпорт для QGraphicsView 2) Добавил таймер какая версия Qt у вас? Если 5я, то нет смысла заморачиваться с QGLWidget. Если 4я то тут я не помощник, хотя у меня сложные сцены рисовались побыстрее чем у вас в любом случае. У меня Qt 5-ой версии, иначе я не смог бы использовать QOpenGLWidget.Попробуйте поиграться с параметрами кеширования сцены. Спасибо за совет, попробую на досуге. |