Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 05, 2006, 21:09 Сабж. QPainter::drawText довольно сильно тормозит. Есть ли возможность ускорить вывод текста?
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 05, 2006, 22:48 Убрать антиалиасинг, трансформацию, полупрозрачньІе цвета текста.
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 06, 2006, 09:47 Упс, не указал выше - все и так выставлено по минимуму. Рисуется таблица, заполняются ячейки текстом. Если развернута на весь экран - одна отрисовка занимает до 400 мс. Тачка не медленная, Атлон 2500... Причем пофиг, выводишь ты 1 символ в ячейке или 10 - скорость одинаковая...
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: C.H. от Декабрь 06, 2006, 10:28 а ты сразу на экране рисуешь или в памяти а потом на экран??
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: crocus от Декабрь 06, 2006, 11:48 Не флейма ради:
В стандартном примере textedit есть принтпревью, так вот оно тоже очень тормозит-может реализация в самой библиотеке тормозная??? Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: ElderOrb от Декабрь 06, 2006, 11:55 Можно попробовать воспользоваться QPainter-ом от QGLWidget-а. Иначе для чего существует void QPainter::setRedirected ? :) (Сам я так делать ни разу не пробовал, но где-то на форуме qtcenter.org проскакивала похожая мысль для ускорения отрисовки сложных виджэтов. )
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 06, 2006, 12:10 Неужели тормозит и в рилизной сборке?
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: crocus от Декабрь 06, 2006, 12:16 -static -release тормозит пендыр!!!
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Tonal от Декабрь 06, 2006, 12:57 Профилировать пробовал?
Точно тормозит именно drawText? От видюхи не зависит? Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 06, 2006, 16:37 Не поверю, пока не увижу код. Откройте в Ассистанте какую-нибудь тяжёлую страницу и бьІстро мотайте её ползунком. Тормоза наблюдаете? И я нет. Значит дело не в скорости отрисовки текста, а в чём-то другом.
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: crocus от Декабрь 06, 2006, 19:31 http://doc.trolltech.com/4.2/demos-textedit-printpreview-cpp.html
Попробуйте открыть в %QTDIR%\demos\textedit\release\textedit.exe любой документ .txt или .htm страниц на 20, откройте Print Preview и ,как вы говорите, просто помотайте ползунком туда-сюда - вы обалдеете от скорости. И хотелось бы по этому вопросу узнать компетентное мнение nEoN !!! Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 06, 2006, 23:39 тормозит именно drawText, профилером смотрел. от видюхи не зависит.
ассистант - он же не текст печатает, а графику. т.е. все кеширует. а у меня так низя :( Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 07, 2006, 00:53 Ассистант печатает не текст, а графику? А как вьІ обьясните динамическое изменение размеров окна Ассистанта? Конечно же происходит переразбиение структорированного текста, что и вьІзьІвает тормоза однократно. Но, в, вцелом, результат одинаковьІй - никаких тормозов при скроллировании текста, когда в drawText() подставляются готовьІе блоки.
Так что, дело не в рисовании текста, а в чём-то другом. Возможно есть прецендентьІ для проблем кеширования. Сам лично наблюдал тормоза при разбиении текста после изменения размеров текста Ассистанта (Cotrol + Скролл Вниз, потом Control + Скролл Вверх). Но само рисование работает на ура. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Tonal от Декабрь 07, 2006, 09:28 Цитата: "crocus" http://doc.trolltech.com/4.2/demos-textedit-printpreview-cpp.html Попробуйте открыть в %QTDIR%\demos\textedit\release\textedit.exe любой документ .txt или .htm страниц на 20, откройте Print Preview и ,как вы говорите, просто помотайте ползунком туда-сюда - вы обалдеете от скорости. А ты в тот код заглядывал? ;-) Они же там в paintEvent ВСЕ страницы полностью отрисовывают! Понятно, что чем больше страниц, тем сильнее тормоза. Тут любая система рисования загнётся. :-\ Можно элементарно вычислить, какие страницы должны отображаться и показывать только их. В примере этим просто не озадачились - минус тролям (хотя и маленький ;) ) Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 07, 2006, 15:28 Ассистант, он че делает - при ресайзе, заново все отрисовывает в кэш.
Это понятно, что потом работает быстро (при скроле). Но у меня проблема в том, что кэшировать нельзя - это таблица с кучей динамически изменяющихся данных. Т.е. каждые 50-100мс данные обновляются. А отрисовка занимает порядка 400-500мс на экран. Вот в чем лажа. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 07, 2006, 17:17 Цитата: "Racheengel" Ассистант, он че делает - при ресайзе, заново все отрисовывает в кэш. Это понятно, что потом работает быстро (при скроле). Неужели вьІ думаете, что Ассистант рисует во внеекранньІй буфер страницу размером 400 кб, а потом просто бьІстро её блитит. Давайте прикинем, размер такого буфера получается должен исчисляться сотнями мегабайт, а время на его заполнение - десятками секунд при однократном ресайзе, смене шрифта. Кроме того забудем про гиперссьІлки, вьІделение текста мьІшью, поиск - ведь ето картинка. Вам не кажется, что кеширование динамически изменяющихся частей по крайней мере глупо. Затем и придумали paintEvent(). Содержимое хранится в виде текста и каждьІй раз при скролле заново перерисовьІвается. Есть множество других накладньІх расходов, связанньІх с рисованием, например, частая смена CompositionMode. То что задержка именно в drawText() может всего-лишь служить симптомом к реальной ошибке. Сложно сказать в чём именно проблема, не видя код. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Tonal от Декабрь 07, 2006, 20:28 Цитата: "Racheengel" Но у меня проблема в том, что кэшировать нельзя - это таблица с кучей динамически изменяющихся данных. Т.е. каждые 50-100мс данные обновляются. А отрисовка занимает порядка 400-500мс на экран. И тебе надо постоянно перерисовывать ВСЮ таблицу?Она ВСЯ одновременно отображается на экране? Может быть всётаки можно ограничить подмножество того, что надо рисовать сейчас? И не пытаться перерисовать то, чего точно нет на экране? Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Вячеслав от Декабрь 07, 2006, 23:20 Таки может gl прикрутить ? на off-screen рендеринг ? а рисовать только картинки ?
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 08, 2006, 01:25 Мне надо отображать часть таблицы, но если даже эта часть отображается в окне на весь экран - это самое окно с частью данных рисуется не особо быстро. Выводимые данные, естественно, фильтруются.
Код отрисовки - Он простой. Цитировать void QicsGrid::paintEvent ( QPaintEvent * event ) { QPainter p(this); p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing, false); p.setPen(Qt::black); p.setBrush(Qt::white); p.drawRect(event->rect()); int row_from = m_rowOrigin; int rows_to_draw = rows(); int col_from = m_colOrigin; int cols_to_draw = columns(); int x = 0; int y = 0; m_rowsFit = m_colsFit = 0; for (int i = row_from; i < rows_to_draw; i++) { // if row hidden then continue if (rowVis()) continue; int row = rowOrder(); int h = rowSize()[/*row*/i]; x = 0; m_colsFit = 0; for (int j = col_from; j < cols_to_draw; j++) { // if col hidden then continue if (colVis()[j]) continue; int col = colOrder()[j]; int w = colSize()[/*col*/j]; QRect r(x,y,w,h); QicsCellItem *ci = cellItem(i, j); if (ci) { p.setPen(ci->colorForeGround); p.setBrush(ci->colorBackGround); } else { p.setPen(Qt::black); p.setBrush(Qt::white); } p.drawRect(r); QVariant v = data(row, col, i, j); if (v.isValid()) { p.drawText(r, Qt::AlignCenter, v.toString()); } x += w; if (x >= width()) break; m_colsFit++; } y += h; if (y >= height()) break; m_rowsFit++; } } Тормозит в точке p.drawText(r, Qt::AlignCenter, v.toString()). добавлено спустя 5 минут: Возможно, трабла кроется в том, что у меня много вызовов drawText (в цикле) для отрисовки сравнительно малых порций текста... Но обойти это никак нельзя. Наверное, тормоза происходят даже не при отрисовке, а именно при предварительных расчетах/настройках и т.д. Печально, однака... Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 08, 2006, 14:01 Рисование белого фона текущей перерисовьІваемой части происходит неправильно: QPainter::drawRect() будет рисовать чёрньІе рамки где попало. Нужно юзать: p.setPen( Qt::NoPen ). Или, если рамка нужна на всё окно, - рисовать не drawRect( event->rect() ), а drawRect( rect() ) (QPainter сам соптимизирует заполнение цветом только текущего фрагмента из QPaintEvent).
Сразу бросается в глаза отсутствие проверки на пересечение текста и event->rect(). Проверка происходит где-то извне: rowVis(), colVis(). Естественно, что ети проверки вьІберут лишние фрагментьІ, которьІх сейча не видно. Как следствие - лишние вьІзовьІ drawText(). Тормоза из-за накладньІх расходов. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Tonal от Декабрь 08, 2006, 14:31 Вот в этом фрагменте:
Код:
Ты вызываешь QicsCellItem *ci = cellItem(i, j); и QVariant v = data(row, col, i, j); Я бы это совместил - сделал в QicsCellItem функцию возвращающую сторку для отрисовки. ;-) Кстати, в самом QicsCellItem можно и закешировать представление строки как QPixmap. И возвращать именно его. Тогда, если одновременно изменяется относительно небольшое количество данных, должен получится существенный выигрыш. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 09, 2006, 00:04 Рамки - это как раз правильно (вокруг каждой ячейки рисуется черная рамка).
Не понимаю, что имеется в виду под отсутствием проверки на пересечение текста и event->rect(). event->rect() - это вся область, требующая перерисовки, т.е. размер viewport. Собственно, в эвенте и отрисовываются все ячейки, попавшие на экран. rowVis(), colVis() - возвращают списки невидимых строк/столбцов. Они служат для определения того, какие строки/столбцы выключены пользователем (т.е. вообще не должны рисоваться). Отрисока начинается с ячейки [m_rowOrigin, m_colOrigin] - т.е. она попадает в верхний левый угол. Далее, 2 цикла по строкам и по столбцам, которые итерируют только по ячейкам, попавшим в viewport (для этого происходит подсчет суммы ширины/высоты отрисованных ячеек, и когда это значение превышает размер видимой области - рисование в этом направлении прекращается). Кэширование QPixmap делать пробовал. Но оно не помогает, если меняются одновременно ВСЕ ячейки, а наоборот, приводит к двойным тормозам и отжиранию памяти. Кстати, если закомментить вызов drawText() - все летает (но контента ячеек не видно, естессно). Если же заставить выводить даже хотя бы один символ - все, дрова... Тормоза... Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Tonal от Декабрь 09, 2006, 11:33 Можно ещё схему кеширования придумать, например, если много значений совпадает, то кешируем не по ячейкам, а по значениям.
Строим QMap<QString, QPixmap>. Если такой способ не канает, можно построить мап по всем символам, которые могут встречатся в значени, и собираем из них картинку - может получиться быстрее, хотя , думаю это то автоматом делается... Да, что за задача такая? И зачем эти значения отображать с такой частотой? Их же невозможно будет осознать! Даже одно значение, не говоря уж о многих значениях в таблице на весь экран. Может лучше как-нибудь по другому эту информацию отобразить? Хотя-бы цветовыми градациями, а при наведении мышки, или выделении показывать собственно значение. Иначе, даже если скорости ты добьешся, смысла в этом не будет. ;-) Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 09, 2006, 14:36 Цитата: "Racheengel" Рамки - это как раз правильно (вокруг каждой ячейки рисуется черная рамка). Имелось в виду, зачем делать в начале рисования: Код: p.setPen(Qt::black); Результат етого кода - чёрная рамка где попало. Но её не видно потому, что позже тьІ её закрашиваешь рамками для ячеек. Цитата: "Racheengel" Не понимаю, что имеется в виду под отсутствием проверки на пересечение текста и event->rect(). event->rect() - это вся область, требующая перерисовки, т.е. размер viewport. Собственно, в эвенте и отрисовываются все ячейки, попавшие на экран. Не угадал. Viewport и текущая область рисования - разньІе вещи. viewport != event->rect() ОтрисовьІвать нужно только то, что попало в прямоугольник, записанньІй в класс собьІтия - ето оптимизация по скорости, для ето и придумали. Например, если нужно проскроллировать всего на несколько пикселей - прийдёт собьІтие, содержащее прямоугольний именно из етих пикселей, остальная часть просто скопируется подсистемой в другую часть екрана. ОбратньІй случай - если делается QPixmap::grabWidget() - в QPaintEvent попадёт прямоугольник, включающий даже области за пределами вьюпорта. Ещё вопрос. А стандартньІе проги Qt у тебя как работают со скоростю рисования текста? Например Assistant с большой страницей. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Tonal от Декабрь 09, 2006, 16:14 Я так понял, что у Racheengel данные изменяются каждые 50 - 100мсек.
Причём он утверждает, что они ВСЕ изменяются. И он делает repaint всей таблице. Не совсем ясно, общее количество строк и столвцов на экране, но тут можно очень быстро до тормозов доехать. Я бы лучше подумал, как изменить отображение, т.к. с описанной таблицей работать почти не возможно... Если это конечно на какой-то двумерный джек-пот, или цветомузыка. Но тогда не ясно, зачем строки - можно цветами обойтись. ;-) Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 09, 2006, 16:25 Даже если данньІе изменяются 50 - 100 мс у Qt хватает можностей для отрисовки текста по всему екрану. Другой вопрос: на какого юзера рассчитано изменение большого количества текста на всём екране с частотой 10-20 раз в секунду? Даже в графическом представлении человек не способен уследить за большим количеством информации в реальном времени, разве что неспеша по логам.
Ещё можно обновлять по частям: QWidget::update( const QRect & rect ). Подсистема сама склеит области в один регион и отдаст вам его единождьІ в QPaintEvent'е. Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 10, 2006, 20:57 Приложение - таблица для отображения биржевой активности.
Скоростьб обновления не устраивает клиента :( Да и при скроле мышью притормаживает, неприятно. Насчет viewport != event->rect() - у меня наблюдается как раз обратное. С каждым вызовом эвента viewport == event->rect()... (оно и логично - если весь экран обновляется). Ассистант, зараза, быстро работает, это и обидно... Но с др. стороны - ассистант-то так часто не апдейтится... Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Dendy от Декабрь 10, 2006, 21:27 Если вьІложишь проект, которьІй возможно собрать и протестить самому - будеть идеально. А про viewport == event->rect() так ето просто частньІй случай. Правильно нужно делать как в теории, теория описана в документации.
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 11, 2006, 00:18 Могу выложить, куда?
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: cancroid от Декабрь 11, 2006, 14:51 Цитата: "Racheengel" Могу выложить, куда? Выложи на Лесной Базар или на Рапиду. А еще лучше - дай логин/пароль от ицэсовского SVN-а чтобы проще было скачать! Питэр будет в восторге! Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 12, 2006, 22:18 :)
Название: Qt 4.2 - QPainter::drawText, как ускорить? Отправлено: Racheengel от Декабрь 25, 2006, 23:00 В общем - вроде дошел до пристойного решения - сделал кэш символов для каждого используемого фонта. В первый раз при выводе текста для каждого входящего в него символа создается монохромный битмап и суется в таблицу для соответствующего QFont. При отрисовке каждый символ берется из кэша, меняются цветовые атрибуты, и он выводится как картинка QImage. Проверил - реально в 2-3 раза быстрее, чем QPainter::drawText. Возможно, напишу статью про это.
|