Russian Qt Forum
Ноябрь 22, 2024, 17:12
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Дополнительные компоненты
>
[qwt] Производительность при перерисовки графика
Страниц:
1
[
2
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: [qwt] Производительность при перерисовки графика (Прочитано 16024 раз)
Racheengel
Джедай : наставник для всех
Offline
Сообщений: 2679
Я работал с дискетам 5.25 :(
Re: [qwt] Производительность при перерисовки графика
«
Ответ #15 :
Январь 10, 2014, 01:03 »
Цитата: Old от Январь 09, 2014, 20:26
Лучше рендерить долгую графику в отдельном потоке в теневой буфер и обновлять окно, только когда оно будет полностью сформировано.
а еще лучше тогда параллельно в нескольких потоках... смотря сколько ядер на целевой машине, конечно...
Но имхо лучшее решение - просто математические выкинуть ненужные точки перед рендером.
Записан
What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.
COVID не волк, в лес не уйдёт
Akon
Гость
Re: [qwt] Производительность при перерисовки графика
«
Ответ #16 :
Январь 10, 2014, 10:45 »
Qwt 6 (как минимум) выкидывает ненужные точки (есть такая настройка). Может она делает это не самым быстрым образом? У меня точек сотни тысяч/единицы миллионов, поэтому даже сам расчет получается долгим, я полагаю.
Я даже не ставлю сейчас цели оптимизировать рисование (хотя это было бы здорово), а просто прерывать его пользовательским коллбэком. Т.е., через каждые, скажем, 10000 точек Qwt будет звать внешний коллбэк.
Половина кадра:
Покуда endPaint() не торкнули, рендеринг не начнется. Поэтому, по частям мы отрисовку наблюдать не будем.
А все эти вставки идут до endPaint(), разумеется.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: [qwt] Производительность при перерисовки графика
«
Ответ #17 :
Январь 10, 2014, 11:33 »
Цитата: Old от Январь 09, 2014, 20:26
Все таки, пока кадр не готов полностью, показывать его не стоит.
Этой проблемы нет (double-buffer)
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: [qwt] Производительность при перерисовки графика
«
Ответ #18 :
Январь 10, 2014, 11:57 »
Цитата: Igors от Январь 10, 2014, 11:33
Цитата: Old от Январь 09, 2014, 20:26
Все таки, пока кадр не готов полностью, показывать его не стоит.
Этой проблемы нет (double-buffer)
Вы выходите из paintEvent и не происходит обновление окна?
Покажите код вашего обработчика и назовите платформу.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: [qwt] Производительность при перерисовки графика
«
Ответ #19 :
Январь 10, 2014, 12:45 »
Цитата: Old от Январь 10, 2014, 11:57
Вы выходите из paintEvent и не происходит обновление окна?
Покажите код вашего обработчика и назовите платформу.
Когда прерывание обнаружено - экран еще НЕ обновлен, и я могу решить что с ним делать.
Цитата: Old от Январь 09, 2014, 20:26
Ага, только никто не гарантирует, что скопившиеся события обработаются быстро.
Нарисовали половину кадра, пользователь нажал мышь, вышли из рисовалки, пользователь увидел на экране половину картинки, а ваша программа ушла обрабатывать события... и делала это секунду (ну обработку одного из событий делал
специалист
профессионал)
Ну что же Вы выдвигаете такие "абсурдные" требования? (как Вы сами давеча говорили в др теме)
Это где ж видано чтобы рисовалось а события были запрещены? Вот напр Qt Dnd таких ограничений не имеет. И.т.д.
Цитата: Old от Январь 09, 2014, 20:26
и только после этого мы вернулись и дорисовали кадр.
Ну "дорисовать" - это вряд ли, напр OpenGL рисование не инкрементально. Придется начинать все с нуля.
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: [qwt] Производительность при перерисовки графика
«
Ответ #20 :
Январь 10, 2014, 13:15 »
Цитата: Igors от Январь 10, 2014, 12:45
что же Вы выдвигаете такие "абсурдные" требования? (как Вы сами давеча говорили в др теме)
Это где ж видано чтобы рисовалось а события были запрещены?
А в чем абсурдность и причем запрещенность событий?
Смотрите, вы вышли из paintEvent, управление вернулось в цикл обработки событий и сработал таймер, в обработчике которого мы полезли проверять обновления на сайт и длилось это действо секунду. Потом мы вернулись в цикл и перешли опять к рисованию. Вот и задержка между началом и продолжением рисования.
А что получили - непонятно? Рисовать все равно начали заново.
Как я понимаю если пользователь будет клацать мышкой, программа может вообще никогда ничего не нарисовать.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: [qwt] Производительность при перерисовки графика
«
Ответ #21 :
Январь 10, 2014, 14:00 »
Цитата: Old от Январь 10, 2014, 13:15
Как я понимаю если пользователь будет клацать мышкой, программа может вообще никогда ничего не нарисовать.
Это нормально, пусть меньше клацает
Другое дело если операция интерактивна, обычно когда пользователь перемещает объекты мышью. Тогда нужно разрешать лишь небольшое число событий.
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: [qwt] Производительность при перерисовки графика
«
Ответ #22 :
Январь 10, 2014, 14:10 »
Нормально? Ну не знаю, у нас разные представления о "нормально".
Записан
Akon
Гость
Re: [qwt] Производительность при перерисовки графика
«
Ответ #23 :
Январь 12, 2014, 21:07 »
1. Я тут сделал следующую пробную реализацию: перекрыл QwtPlotCurve::drawSeries() с целью вызывать пользовательский коллбэк через каждые 10000 точек. Коллбэк делает следующее:
Код:
QCoreApplication::sendPostedEvents(&processingObject_, QEvent::MetaCall);
т.е. вызывает слоты некоего processingObject_, которые на данный момент имеются в очереди сообщений. Никакие другие события в очереди сообщений не обрабатываются. Вызванный т.о. слот processingObject_ в свою очередь может вызвать синхронную перерисовку другого виджета (repaint()), например, находящегося ниже по лейауту относительно QwtPlot.
Так вот, работает это несколько некорректно - не полностью или вовсе не отрисовываются другие виджеты главного окна. Я не стал разбираться. Полагаю, что причина может быть в следующем: Кьют (в моем случае) использует двойную буферизацию (backingStore) при отрисовке виджетов, а также не использует нативные контролы, т.е. сам рисует виджеты. Когда от системы приходит событие перерисовки (свернули/развернули окно, например), то если содержимое виджета не меняется, то и QWidget::paintEvent() по идее звать не нужно - в систему пойдут данные из кэша. А вот если содержимое виджета меняется (например, QLabel::setText("...")), то необходимо еще и кэш обновить. Т.е. QWidget::paintEvent() должно вызываться из контекста, связанного с этой синхронизацией. И прямой вызов repaint() одного виджета из paintEvent() другого не имеет этого контекста (не реентерабельный контекст). Но это просто поверхностное рассуждение, если кто занимался вопросом, просьба прояснить ситуацию.
2. Несколько копнул Qwt 6 на предмет отрисовки.
Например, имеется 120000 точек, шкала по оси абсцисс установлена так, что отображается только первые 10000 точек. Что делает Qwt при измененнии кривой и репаинте:
а) вне зависимости от шкалы на отрисовку спускает все 120000 точек.
б) уменьшает кол-во точек, т.к. при отрисовке большого кол-ва точек некоторые будут просто проецироваться в один и тот же пиксель. Но! При этом она чешет все 120000 вместо того, чтобы "прощупать", где начинаются видимые точки.
в) полученные точки перед отрисовкой клиппируются, т.е. в полилинии остаются те, которые соответствуют видимым 10000.
г) паинтер рисует полилинию.
Вообще, архитектура Qwt совсем небыстрая, я бы сказал в стиле Java, а не С++. Например, исключительно часто вызываемая функция QwtSeriesData::sample() виртуальная. Это как если бы в STL у нас бы был базовый интерфейс итератора с виртуальными функциями доступа к данным
Это удобно, но гораздо медленнее.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: [qwt] Производительность при перерисовки графика
«
Ответ #24 :
Январь 13, 2014, 12:47 »
Цитата: Akon от Январь 12, 2014, 21:07
Так вот, работает это несколько некорректно - не полностью или вовсе не отрисовываются другие виджеты главного окна. Я не стал разбираться. Полагаю, что причина может быть в следующем: Кьют (в моем случае) использует двойную буферизацию (backingStore) при отрисовке виджетов, а также не использует нативные контролы, т.е. сам рисует виджеты. Когда от системы приходит событие перерисовки (свернули/развернули окно, например), то если содержимое виджета не меняется, то и QWidget::paintEvent() по идее звать не нужно - в систему пойдут данные из кэша. А вот если содержимое виджета меняется (например, QLabel::setText("...")), то необходимо еще и кэш обновить. Т.е. QWidget::paintEvent() должно вызываться из контекста, связанного с этой синхронизацией. И прямой вызов repaint() одного виджета из paintEvent() другого не имеет этого контекста (не реентерабельный контекст). Но это просто поверхностное рассуждение, если кто занимался вопросом, просьба прояснить ситуацию.
Сейчас у меня несколько похожие проблемы. Что мне удалось выяснить
1) Qt обеспечивает double-buffer там где ОС его не имеет (Вындоуз), иначе используется буфер ОС (OSX). В любом случае QPainter рисует в буфере, в чем легко убедиться поставив break в paintEvent - никаких изменений на экране еще нет. Выталкивание буфера на экран происходит по окончании paint. Важно что вызов repaint НЕ гарантирует немедленной перерисовки на всех платформах. При этом QApplication::flush никак не поможет, т.к. внутренний буфер еще не обновлен (paintEvent не было)
2) Qt часто вызывает/провоцирует paint сам вызовом update. Напр при переключении активного окна оба (новое и старое) будут перерисованы. То же самое при свертке/развертке. Избавиться от этого можно, но с трудом. Вот если таскаем окно - да, нижние не будут перерисовываться, срабатывает буфер.
3)
Цитата: Akon от Январь 12, 2014, 21:07
а также не использует нативные контролы, т.е. сам рисует виджеты
Это не одно и то же. На OSX каждому Qt контролу соответствует нативный контрол OC (т.е. используются), но рисуются они не ОС'ом, а самим Qt
Возвращаясь к Вашим проблемам - я бы для начала проверил вызов repaint др контрола (из рисования графика). Да, это не будет работать на ОС с нативным double-buffer, ну так может это для Вас и не актуально. Если работает - то через notify отловить update (для которого не было парного paint) и после выхода из sendPostedEvents самому сделать repaint.
Все-таки оптимизация самого процесса рисования выглядит привлекательнее (то конечно легко говорить
)
Записан
Akon
Гость
Re: [qwt] Производительность при перерисовки графика
«
Ответ #25 :
Январь 13, 2014, 14:11 »
Ок. Спасибо.
Цитировать
а также не использует нативные контролы, т.е. сам рисует виджеты
Я имел ввиду, что системные дескрипторы на эти виджеты не создаются, следовательно, система о них ничего не знает и при перерисовке торкает их парента, который с дескриптором (QMainWindow?). Буду знать про MacOS.
Записан
Страниц:
1
[
2
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...