Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: yarick от Ноябрь 09, 2012, 15:04



Название: QPainter тормозит при сглаживании!
Отправлено: yarick от Ноябрь 09, 2012, 15:04
Рисую 100 простых линий в небольшом экране - и наблюдаю тормоза... Задача-то простейшая, если все виджеты QT рисуются через пейнт, то почему рисование простой линии так тормозит?

Код:
#include <QtGui>

class MyClass : public QWidget{
public:
  MyClass(){

  }
  void paintEvent(QPaintEvent* event)
  {
    int i=0;

    QTime time;
    time.start();

    for(i=0;i<100;i++){
        QPainter p(this);
        p.setRenderHint(QPainter::Antialiasing,true);
        p.setPen(QPen(Qt::blue,2,Qt::SolidLine));
        p.drawLine(0,0,640,480);
        p.end();
      }

    qDebug()<<"paint"<< " mc = " <<time.elapsed();
  }
};

int main(int argc, char* argv[]){
  QApplication app(argc, argv);

  MyClass* myClass = new MyClass();

  myClass->resize(640,480);
  myClass->show();

  return app.exec();
}

Со сглаживанием (в дебаг режиме) - выполняется 25-30 мс, без него 3-5 мс (что также не приемлимо для 100 простых линий). Комп у меня мощный, но в проекте тормоза заметны, т.к. там я часто с перерисовкой работаю....
В релиз-режиме быстрее, но не значительно


Название: Re: QPainter тормозит при сглаживании!
Отправлено: _OLEGator_ от Ноябрь 09, 2012, 15:05
Ну как минимум QPainter и всю приблуду надо вынести из цикла, оставив в нем только drawLine.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 09, 2012, 16:51
+ возможно поможет QPainterPath сначала добавить в него все что нужно ,а потом уже нарисовать все это дело.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 09, 2012, 17:00
Преобразовал ваш пример вот так

Код:
    QTime time;
    time.start();

    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing,true);
    p.setPen(QPen(Qt::blue,2,Qt::SolidLine));

    QPainterPath path;

    for(int i=0;i<100;i++){
        path.moveTo(0,0);
        path.lineTo(640,480);
     }

    p.drawPath(path);
    p.end();

    qDebug()<< "paint"<< " mc = " <<time.elapsed();

выполняется 1-2 мс против того что было с вашим примером 40 - 60мс  :)


Название: Re: QPainter тормозит при сглаживании!
Отправлено: gil9red от Ноябрь 09, 2012, 21:43
Уберете сглаживание будет меньше тормозить :)


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 09, 2012, 23:16
А если сглаживание нужно оставить ? :) Просто сглаживание будет отрабатывать для каждого вызова drawLine поэтому лучше использовать drawPath тогда сглаживание отработает всего один раз  :)


Название: Re: QPainter тормозит при сглаживании!
Отправлено: yarick от Ноябрь 10, 2012, 13:07
Ну как минимум QPainter и всю приблуду надо вынести из цикла, оставив в нем только drawLine.
Цикл сделан ради примера - чтобы измерить время и сравнить. В реальной программе будет рисоваться много разных линий (около 5-10) и перерисовываться около 100 раз в секунду.

А на счёт path - это действительно хорошая идея, спасибо

Что касается сглаживания - без него никак - программа будет выглядеть слишком некрасиво. И про неё кое кто скажет - "Так верстают только ******"


Название: Re: QPainter тормозит при сглаживании!
Отправлено: _OLEGator_ от Ноябрь 10, 2012, 14:11
"Цикл сделан ради примера" - отличный ответ!
Ему указали на ошибку и возможную проблему в коде, а он еще и сопротивляется...
5-10 линий - это ничто.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: Igors от Ноябрь 10, 2012, 14:38
В реальной программе будет рисоваться много разных линий (около 5-10) и перерисовываться около 100 раз в секунду.
И что, на каждой операции рисования заряжать painter ?  :)

+ возможно поможет QPainterPath сначала добавить в него все что нужно ,а потом уже нарисовать все это дело.
А каким образом он ускорит рисование и "сглаживание"? Я так понимаю что это просто метафайл, т.е. что рисовать он знает - но сам-то не рисует. Или как?


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 10, 2012, 19:44
Да, по сути QPainterPath хранит в себе информацию того что нужно нарисовать. Теперь по поводу того почему он работает быстрее, посмотрел код Qt и вот что увидел: Когда мы вызываем код drawLine(блаблабла), внутри QPainter вызывается код для рисования нескольких линий drawLines(&l,1) - &l видимо ссылка на координаты, 1 - индекс линии, это несколько странно на мой взгляд ибо я бы сделал наоборот из drawLines вызывал drawLine, ну да ладно это не суть. Смотрю дальше и вижу что drawLines в случае использования сглаживания вызывает создание ,что бы вы думали QPainterPath и уже затем вызов drawPath :) Тоесть получается следуещее - когда мы 100 раз рисуем линии мы на самом деле 100 раз создаем QPainterPath и его отрисовываем со всякими сглаживаниями и прочим, но когда мы сами создаем QPainterPath это происходит только один раз :)


Название: Re: QPainter тормозит при сглаживании!
Отправлено: _OLEGator_ от Ноябрь 10, 2012, 19:59
ecspertiza, все верно.
Данная процедура, например, значительно ускоряет отрисовку текста.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: alexman от Ноябрь 10, 2012, 19:59
Споры излишне. QPainter медленно рисует линии любым способом:(


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 10, 2012, 20:01
Думаю это будет не только к линиям относиться, у себя в проекте давно хотел перейти на QPainterPath ,но все руки не доходят, теперь вот и причину весомую нашел, да и удобнее он :) Но это уже пожалуй оффтопик.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: alexman от Ноябрь 10, 2012, 20:04
Думаю это будет не только к линиям относиться, у себя в проекте давно хотел перейти на QPainterPath ,но все руки не доходят, теперь вот и причину весомую нашел, да и удобнее он :) Но это уже пожалуй оффтопик.
Если много линий, то и QPainterPath не спасет. OpenGL в этом плане гораздо шустрее.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: _OLEGator_ от Ноябрь 10, 2012, 20:23
У всех свое понимание "много линий".
Для отрисовки графиков, например, не обязательно прибегать к использованию OpenGL - это как минимум не разумно и трудозатратно.
Отрисовка кстати еще ускоряется, если рисовать на QGLWidget.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: Igors от Ноябрь 10, 2012, 22:27
но когда мы сами создаем QPainterPath это происходит только один раз :)
Для одной линии :) Если 100 разных линий - мы ничего не экономим. Вот если повторное рисование - есть смысл. Но, как всегда с метафайлом, возни много - хотя бы отследить что изменилось. Поэтому обычно энтузиазма не вызывает.

Интереснее как он делает пресловутое "сглаживание" ?


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 10, 2012, 22:40
Для одной линии :) Если 100 разных линий - мы ничего не экономим.

Почему ? сейчас попробую объяснить как я понял, то что в исходниках нашел, на псевдокоде

вот так
Код:
QPainter painter(this);
for (int i = 0; i < 100; ++i) {
   painter.drawLine(.....);
}

100 раз вызывается рисование drawPath более того в этом случае мы 100 раз создаем QPainterPath, вполне возможно что так и сглаживание будет вызвано 100 раз, но если мы делаем

Код:
QPainter painter(this);
QPainterPath path
for (int i = 0; i < 100; ++i) {
   path.moveTo(...);
   path.lineTo(...);
}

painter.drawPath(path);

то рисование вызывается 1 раз для 100 линий. То есть экономия на лицо ))))


Название: Re: QPainter тормозит при сглаживании!
Отправлено: vregess от Ноябрь 10, 2012, 22:59
ecspertiza, все верно.
Данная процедура, например, значительно ускоряет отрисовку текста.

Можешь по подробнее: Качество текста не страдает? Почему быстрее?
Извините, что вклинился.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: alexman от Ноябрь 11, 2012, 09:16
У всех свое понимание "много линий".
Для отрисовки графиков, например, не обязательно прибегать к использованию OpenGL - это как минимум не разумно и трудозатратно.
Отрисовка кстати еще ускоряется, если рисовать на QGLWidget.
Говоря об OpenGL, подразумевал QGLWidget.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: _OLEGator_ от Ноябрь 11, 2012, 12:41
to alexman:
Для меня это было не очевидно, теперь все прояснилось.

to ck:
Качество текста не страдает. Насколько я помню, то при отрисовке текста, он тоже преобразуется в QPainterPath (по сути векторизация текста), а потом отрисовывается.
Надо вспоминать и искать (писать) тесты по этому поводу. Но точно могу сказать, что отрисовка текста под углом производилась быстрее.
Ну и чтобы не быть голословным, сейчас накидаю тестовый проектик.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: Igors от Ноябрь 11, 2012, 12:57
но если мы делаем

Код:
QPainter painter(this);
QPainterPath path
for (int i = 0; i < 100; ++i) {
   path.moveTo(...);
   path.lineTo(...);
}

painter.drawPath(path);

то рисование вызывается 1 раз для 100 линий. То есть экономия на лицо ))))
Давайте проверим (аттач). У меня экономия никак не превышает 5%. а у Вас? Да, и, строго говоря, результаты не равны (см строку "check it"). Правда здесь "просто линии", на них экономить не актуально. Вот напр с текстом ситуация может быть другой.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: _OLEGator_ от Ноябрь 11, 2012, 13:14
Вот тестовый проект, только при использовании QPainterPath у меня FPS скачет сильно (от 3.5 до 25, 50 и 100), хз почему.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 11, 2012, 13:26
Igors, вот мои результаты

Код:
"path = 0, draw time = 0.194. Press a key to redraw" 
"path = -1, draw time = 0.377. Press a key to redraw"
"path = 0, draw time = 0.194. Press a key to redraw"
"path = -1, draw time = 0.388. Press a key to redraw"
"path = 0, draw time = 0.192. Press a key to redraw"
"path = -1, draw time = 0.385. Press a key to redraw"

а вот результаты если добавить сглаживание

Код:
"path = 0, draw time = 0.771. Press a key to redraw" 
"path = -1, draw time = 0.143. Press a key to redraw"
"path = 0, draw time = 0.745. Press a key to redraw"
"path = -1, draw time = 0.141. Press a key to redraw"
"path = 0, draw time = 0.709. Press a key to redraw"
"path = -1, draw time = 0.14. Press a key to redraw"

тоесть на мой взгляд результат на лицо :) Пробовл под Mac OS 10.7.4 Qt 4.8.1 как руки до винды доберуться попробую там.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: Igors от Ноябрь 11, 2012, 15:08
Ага, не все так просто (я смотрел 32-bit, OSX 10.6.8, Qt 4.7.4). А в 64 результаты похожи на Ваши

Цитировать
"path = 0, draw time = 0.277. Press a key to redraw"
"path = 1, draw time = 0.322. Press a key to redraw"
"path = 0, draw time = 0.279. Press a key to redraw"
"path = 1, draw time = 0.307. Press a key to redraw"
"path = 0, draw time = 0.278. Press a key to redraw"
"path = 1, draw time = 0.307. Press a key to redraw"
Т.е прямой вывод чуть быстрее. Однако при вкл сглаживании QPainterPath быстрее в разы

Цитировать
"path = 0, draw time = 0.478. Press a key to redraw"
"path = 1, draw time = 0.082. Press a key to redraw"
"path = 0, draw time = 0.457. Press a key to redraw"
"path = 1, draw time = 0.081. Press a key to redraw"
"path = 0, draw time = 0.453. Press a key to redraw"
"path = 1, draw time = 0.081. Press a key to redraw"

А как он сглаживает? Или пользователем Qt это неинтересно?  :)
К сожалению, атрибутов QPainterPath не помнит (аттач)


Название: Re: QPainter тормозит при сглаживании!
Отправлено: vregess от Ноябрь 11, 2012, 15:10
У меня другие результаты.

Без сглаживания.
Код:
"path = 0, draw time = 0.236. Press a key to redraw"
"path = 1, draw time = 0.263. Press a key to redraw"
"path = 0, draw time = 0.26. Press a key to redraw"
"path = 1, draw time = 0.244. Press a key to redraw"
"path = 0, draw time = 0.25. Press a key to redraw"
"path = 1, draw time = 0.252. Press a key to redraw"

Со сглаживанием. painter.setRenderHint(QPainter::Antialiasing,true);
Код:
"path = 0, draw time = 0.562. Press a key to redraw"
"path = 1, draw time = 0.545. Press a key to redraw"
"path = 0, draw time = 0.556. Press a key to redraw"
"path = 1, draw time = 0.565. Press a key to redraw"
"path = 0, draw time = 0.549. Press a key to redraw"
"path = 1, draw time = 0.57. Press a key to redraw"

Win7 x64, qt 4.8.3-x32, msvc 2010


Название: Re: QPainter тормозит при сглаживании!
Отправлено: vregess от Ноябрь 11, 2012, 15:21
Вот тестовый проект, только при использовании QPainterPath у меня FPS скачет сильно (от 3.5 до 25, 50 и 100), хз почему.

Мои результаты.

Код:
QPainter::drawText 3.9 - 4.5
QStaticText        4.2 - 5
QPainterPath       ~1.9


Название: Re: QPainter тормозит при сглаживании!
Отправлено: panAlexey от Ноябрь 12, 2012, 10:50
Думаю это будет не только к линиям относиться, у себя в проекте давно хотел перейти на QPainterPath ,но все руки не доходят, теперь вот и причину весомую нашел, да и удобнее он :) Но это уже пожалуй оффтопик.
Если много линий, то и QPainterPath не спасет. OpenGL в этом плане гораздо шустрее.
На машинах, где есть хорошая/мощная видуха.
На встроенных старых лучше не надо...


Название: Re: QPainter тормозит при сглаживании!
Отправлено: alexman от Ноябрь 12, 2012, 11:21
Думаю это будет не только к линиям относиться, у себя в проекте давно хотел перейти на QPainterPath ,но все руки не доходят, теперь вот и причину весомую нашел, да и удобнее он :) Но это уже пожалуй оффтопик.
Если много линий, то и QPainterPath не спасет. OpenGL в этом плане гораздо шустрее.
На машинах, где есть хорошая/мощная видуха.
На встроенных старых лучше не надо...
Ну Вы вспомните еще ламповые машины ;)


Название: Re: QPainter тормозит при сглаживании!
Отправлено: panAlexey от Ноябрь 12, 2012, 15:20
Думаю это будет не только к линиям относиться, у себя в проекте давно хотел перейти на QPainterPath ,но все руки не доходят, теперь вот и причину весомую нашел, да и удобнее он :) Но это уже пожалуй оффтопик.
Если много линий, то и QPainterPath не спасет. OpenGL в этом плане гораздо шустрее.
На машинах, где есть хорошая/мощная видуха.
На встроенных старых лучше не надо...
Ну Вы вспомните еще ламповые машины ;)
Это объективная реальность для устоявшихся контор, которые работают не один десяток лет.
Наличие парка старых машин. Надо с этим считаться.


Название: Re: QPainter тормозит при сглаживании!
Отправлено: ecspertiza от Ноябрь 12, 2012, 15:31
пошел уже такой оффтопик:) Но я соглашусь с panAlexey, очень в редких случаях для простого рисовани можно использовать OpenGL. Ибо вот к примеру у меня ноут со встроенной видюхой, и если я тот же пример запущу с использованием OpenGL впоне возможно что он будет еще и медленнее работать, просто был такой случай с qml когда для ускорения использовали OpenGL ,но если запускали софт на машинах без нормальной видюхи то софт вис, хотя по сути это ускорение и не нужно было.

А как он сглаживает? Или пользователем Qt это неинтересно?  :)

можно глянуть в qpainterengine_x11.cpp например :) строка 1739 , я просто в этом не сильно понимаю :)