Название: Нагрузка на процессор и QWidgetBackingStore Отправлено: kamil от Январь 18, 2016, 14:28 Столкнулся с проблемой, в приложении есть QGraphicsView, вывод которого идет через QOpenglWidget, для разгрузки процессора.
QGraphicsView обновляется на частоте примерно 30Гц, и если обновляется только он, то нагрузка на процессор 10-15%: (http://zaripov.net/1.png) Но если еще и обновлять другие элементы ui, например QLabel на той же частоте, то нагрузка возрастает до процентов 40%: (http://zaripov.net/2.png) Если, например QGraphicsView удалить из ui, то даже при обновлении QLabel нагрузка не превысит 5%. С чем может быть связано такое странное поведение? То, что я смог увидеть в профайлере это то, что функция convertRGBA8888FromARGB32PM_sse4(unsigned int*, unsigned int const*, int, QPixelLayout const*, unsigned int const*) начинает вызываться намного чаще. Эта функция, в свою очередь вызывается из QWidgetBackingStore::sync(). В документации по поводу QWidgetBackingStore::sync() сказано: Synchronizes the backing store, i.e. dirty areas are repainted and flushed. Но не понятно почему он начинает вызываться чаще, если в ui есть QGraphicsView. Может у кого есть соображения по этому поводу? Mac OS X 10.11.2 Qt 5.5.1 Clang x64 Название: Re: Нагрузка на процессор Отправлено: Igors от Январь 18, 2016, 15:35 Напрашивается вывод что обновление QLabel ведет к обновлению всего окна, или самой его затратной части - сцены. Покажите как (какими вызовами) обновляете то и это
Название: Re: Нагрузка на процессор Отправлено: kamil от Январь 18, 2016, 16:59 Да, это первая мысль, которая приходит в голову.
Для обновления всего используется один таймер, который вызывается с частотой примерно 30 Гц. Слот update() viewport'a QGraphicsView, соединен с сигналом timeout таймера. Слот, в котором вызывается QLabel::setText("..."), тоже подсоединен к сигналу timeout таймера. А для чего вообще нужен QWidgetBackingStore? Из описания в документации я не до конца понял. Название: Re: Нагрузка на процессор Отправлено: Igors от Январь 19, 2016, 09:26 А для чего вообще нужен QWidgetBackingStore? Из описания в документации я не до конца понял. Это кеш окна, сначала содержимое формируется в нем, а потом выводится на экран. При использовании OpenGL да, перерисовка кнопки ведет к перерисовке всего окна. Я спрашивал у Qt почему, мне посоветовали использовать QOpenGLWindow если хочу макс производительности. Так я и сделал. Хотя это было минимум с год назад, может проблема уже и решена.Для обновления всего используется один таймер, который вызывается с частотой примерно 30 Гц. Попробуйте setUpdatesEnabled(false) для QGraphicsView. В какой момент делать setUpdatesEnabled(true) - хз, пока просто посмотрите что с загрузкой. Ну и "радикальное" решение - не использовать OpenGL, если нет массивной геометрии он не особо выгоден.Слот update() viewport'a QGraphicsView, соединен с сигналом timeout таймера. Слот, в котором вызывается QLabel::setText("..."), тоже подсоединен к сигналу timeout таймера. Название: Re: Нагрузка на процессор и QWidgetBackingStore Отправлено: kamil от Январь 19, 2016, 14:56 Цитировать Ну и "радикальное" решение - не использовать OpenGL, если нет массивной геометрии он не особо выгоден. Без OpenGL, к сожалению не прокатит. В QGraphicsView идет отрисовка HUD поверх видео, если делать это на процессоре, то одно ядро загрузиться как минимум процентов на 40%, и это на i5. Если отключть обновления setUpdatesEnabled(false) QGraphicsView, то нагрузка все равно слишком высока, не смотря на то, что отрисовка на QGraphicsView не идет, QWidgetBackingStore::sync() все так же есть больше всех остальных. Что это может значить? Название: Re: Нагрузка на процессор и QWidgetBackingStore Отправлено: Igors от Январь 20, 2016, 13:32 Если отключть обновления setUpdatesEnabled(false) QGraphicsView, то нагрузка все равно слишком высока, не смотря на то, что отрисовка на QGraphicsView не идет, QWidgetBackingStore::sync() все так же есть больше всех остальных. Что это может значить? Убедитесь что до вызовов paint дело не доходит при setUpdatesEnabled(false). Если грузит и без paint - ну значит слишком много жрет "compositing" (QOpenGLWidget сначала рендерится в текстуру, а потом окно "собирается" в общую текстуру и уже выводится OpenGL). Тогда переходите на QOpenGLWindow, там мелкие проблемы с ивентами, но с производительностью все "как доктор прописал". Вот только обычные виджеты поверх QOpenGLWindow - увы, нельзяНазвание: Re: Нагрузка на процессор и QWidgetBackingStore Отправлено: kamil от Январь 23, 2016, 18:56 Да, похоже надо переходить на QOpenGLWindow. Только вот не до конца понятно из документации как в качестве viewport для QGraphicsView назначить QOpenGLWindow.
Я правильно понимаю что надо внутри конструктора QGraphicsView создать QWidget используя QWidget::createWindowContainer() и потом передать получившийся контейнер в setViewport(widget)? Я попробовал так подсунуть, но на месте виджета черная картинка. UPD: Все, уже нашел что установить QOpenGLWindow в качестве viewport не получится. Как тогда наиболее безболезненно перетащить в QOpenGLWindow QGraphicsVideoItem? Как это вообще можно сделать? UPD2: Если использовать устаревший QGLWidget то нагрузка становится нормальной, но при изменении размера виджета, область под QGraphicsView вначале закрашивается черным, а потом только новым содержимым, может кто знает, можно ли это побороть. Если можно, то вариант с устаревшим QGLWidget меня устроит. Название: Re: Нагрузка на процессор и QWidgetBackingStore Отправлено: Igors от Январь 24, 2016, 13:18 Все, уже нашел что установить QOpenGLWindow в качестве viewport не получится. Если нетрудно покажите где это написаноКак тогда наиболее безболезненно перетащить в QOpenGLWindow QGraphicsVideoItem? Как это вообще можно сделать? Никогда не использовал QGraphicsVideoItem, не подскажу. Можно попробовать перед рисованием сделать контекст QOpenGLWindow текущим (в перекрытом QGraphicsVideoItem::paint)Если можно, то вариант с устаревшим QGLWidget меня устроит. Там тоже несладко, "зато" перспектив ноль, а в след версии Qt от такого legacy может и избавятсяНазвание: Re: Нагрузка на процессор и QWidgetBackingStore Отправлено: kamil от Январь 24, 2016, 15:57 Все, уже нашел что установить QOpenGLWindow в качестве viewport не получится. Если нетрудно покажите где это написаноhttp://blog.qt.io/blog/2014/11/20/qt-weekly-20-completing-the-offering-qopenglwindow-and-qrasterwindow/: Pascal Henze Can i use QOpenGLWindow as viewport of a QGraphicsView to enable openGL drawing in a QGraphicsScene ? Laszlo AgocsLaszlo Agocs No, you can only use QGLWidget or QOpenGLWidget as a viewport for widgets. Вроде как в официальном блоге qt. Но может с 21.11.2014 что-то изменилось, я не знаю. Если можно, то вариант с устаревшим QGLWidget меня устроит. Там тоже несладко, "зато" перспектив ноль, а в след версии Qt от такого legacy может и избавятсяСогласен, что это не самый лучший вариант, так что буду пробовать делать с QOpenGLWindow. UPD: Хорошо, а как для начала правильно выводить QGraphicsItem в QOpengGLWindow? Через QPainter painter(this), или есть что попроще? |