Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: xokc от Январь 07, 2010, 12:26



Название: Тормоза в polyline
Отправлено: xokc от Январь 07, 2010, 12:26
Посоветуйте, как ускорить painter.polyline?
Отрисовка линии из 1024 точек на QPixmap шириной в 1280 px с включенным antialiasing на Core2Duo - не более 11 кадров в секунду. Почему?
P.S. Qt 4.6.0, Win32


Название: Re: Тормоза в polyline
Отправлено: BRE от Январь 07, 2010, 12:35
Посоветуйте, как ускорить painter.polyline?
Отрисовка линии из 1024 точек на QPixmap шириной в 1280 px с включенным antialiasing на Core2Duo - не более 11 кадров в секунду. Почему?
P.S. Qt 4.6.0, Win32
Qt собран без OpenVG?
Интересно проверить какие будут результаты с и без OpenVG.


Название: Re: Тормоза в polyline
Отправлено: xokc от Январь 07, 2010, 17:53
Qt собран без OpenVG. Но, насколько я понял, OpenVG юзается только при рисовании на экране, а при рисовании на pixmap все равно используется софтовый рендерер, который чего-то сильно разочаровывает по скорости антиалиасинга.


Название: Re: Тормоза в polyline
Отправлено: xokc от Январь 07, 2010, 19:50
Повторил эксперимент с двумя polyline с 1024 точками на почти full-screen  с 1680х1050. Результат удручил - меньше 4 fps. Компилятор - MinGW. C painter.setRenderHint(QPainter::Antialiasing, false) получаю при тех же условиях 161 fps. Что-то не так в норвежско-финском королевстве?


Название: Re: Тормоза в polyline
Отправлено: Dendy от Январь 07, 2010, 23:43
Код выложите, посмотрим.


Название: Re: Тормоза в polyline
Отправлено: panAlexey от Январь 08, 2010, 12:00
Почему?
Велком: http://www.prog.org.ru/topic_11868_0.html


Название: Re: Тормоза в polyline
Отправлено: Tonal от Январь 08, 2010, 13:09
Таки нужен код.
Очень много тормозов можно навертеть вокруг простой polyline. :)


Название: Re: Тормоза в polyline
Отправлено: xokc от Январь 08, 2010, 15:15
Велком: http://www.prog.org.ru/topic_11868_0.html

Это я все читал - разговор ни о чем. То бишь о призводительности drawText.

Вот и код собственно. Постарался максимально упростить - при разрешении 1680х1050 2 вызова painter.drawPolyline на 1024 точках с включенным антиалиасингом - 1 fps!!!!


Название: Re: Тормоза в polyline
Отправлено: Igors от Январь 08, 2010, 18:26
Попробуйте заменить drawPolyline на цикл drawLine. Оно конечно подгадит "на стыках" но рисовать должно повеселее


Название: Re: Тормоза в polyline
Отправлено: xokc от Январь 08, 2010, 21:37
Пробовал QPainterPath - мертвому припарки - 1 fps. А вот заменил по совету Igors каждый из вызовов drawPolyline на цикл c drawLine - 30 (!!!) fps. Картинка, правда несколько изменилась, но несущественно. Что же там такого страшного в drawPolyline делается?


Название: Re: Тормоза в polyline
Отправлено: Igors от Январь 08, 2010, 21:56
Пробовал QPainterPath - мертвому припарки - 1 fps. А вот заменил по совету Igors каждый из вызовов drawPolyline на цикл c drawLine - 30 (!!!) fps. Картинка, правда несколько изменилась, но несущественно. Что же там такого страшного в drawPolyline делается?
Много чего  :) По своей работе мне AA заниматься приходится. Есть методы AA (adaptive (частный случай average), oversampling - техники смешивания суб-пикселей), есть базовые параметры - в общем это бандура солидная и падение скорости в 20-30 раз не есть багво (хотя конечно это слабо).

Но  я совершенно ничего не знаю что имеется ввиду "Qt AA" - и вводить в заблуждение не могу (может это совсем другое). Для Вашего графика (конкретный/частный случай) возможно не менее 20 fps без видимого падения квачества (добавить простой анализ polyline)


Название: Re: Тормоза в polyline
Отправлено: xokc от Январь 08, 2010, 23:30
Для Вашего графика (конкретный/частный случай) возможно не менее 20 fps без видимого падения квачества (добавить простой анализ polyline)
Спасибо. Да мне больше 10 fps и не нужно. Под анализом polyline понимается что-нибудь вроде "Polyline simplification using Douglas-Peucker algorithm"?
 


Название: Re: Тормоза в polyline
Отправлено: Dendy от Январь 09, 2010, 03:10
Что же там такого страшного в drawPolyline делается?

Как мимимум рисуется сглаживание на изломе линий с помощью QPen::joinStyle(), чего нет в рисовании отдельными линиями.


Название: Re: Тормоза в polyline
Отправлено: Igors от Январь 09, 2010, 14:50
Под анализом polyline понимается что-нибудь вроде "Polyline simplification using Douglas-Peucker algorithm"?
Нет, то другая песня, упрощать полилинию команды не было. Я имел ввиду: по своей природе AA "не любит" большие области. Поэтому если Вы будете использовать тот же drawPolyline, но рисовать, напр. по 5 точек - я предполагаю скорость будет приемлемой. Но тут есть одно "но" - нужно аккуратно "разрезать на порционные куски". Если просто "рисовать по N точек", то картинка может "интерферировать" - в одних местах график будет выглядеть ярче, в др. бледнее. Нужно ставить места разрывов там где наклон достаточно мал.

Конечно, это экспериментальная идея, сам не проверял  :)


Название: Re: Тормоза в polyline
Отправлено: panAlexey от Январь 09, 2010, 17:32
Но, насколько я понял, OpenVG юзается только при рисовании на экране, а при рисовании на pixmap все равно используется софтовый рендерер, который чего-то сильно разочаровывает по скорости антиалиасинга.
Ты правильно понял, проверил на практике.


Название: Re: Тормоза в polyline
Отправлено: xokc от Январь 10, 2010, 00:15
Поэтому если Вы будете использовать тот же drawPolyline, но рисовать, напр. по 5 точек - я предполагаю скорость будет приемлемой. Но тут есть одно "но" - нужно аккуратно "разрезать на порционные куски". Если просто "рисовать по N точек", то картинка может "интерферировать" - в одних местах график будет выглядеть ярче, в др. бледнее. Нужно ставить места разрывов там где наклон достаточно мал.
Ну вообще-то у меня много задач и без отрисовки антиалиасных полилиний :). Пусть они сейчас рисуются через цикл drawLine, но ведь как красив был код с drawPolyline. Вдруг оно само как-нибудь оптимизируется.


Название: Re: Тормоза в polyline
Отправлено: manarch от Март 10, 2010, 12:03
Вот натолкнулся на тему. Только не понял в чем проблема использования OpenGL для ускорения отрисовки? Изменяем немного продставленный код:
Код:
    QGLWidget glw;

    QPainter painter(&glw);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(QColor(0x77EEFF));
    painter.drawPolyline(polygon);      // Собственно все тормоза в этих двух
    painter.setPen(Qt::magenta);
    painter.drawPolyline(polymax);      // вызовах drawPolyline

   *img = glw.grabFrameBuffer();       // копируем буфер изображения в QImage
и вуаля... скорость  отрисовки снизилась а fps повысилась.


Название: Re: Тормоза в polyline
Отправлено: GreatSnake от Март 10, 2010, 12:09
А насколько важно сразу отрисовывать в QPixmap, а не в QImage?
QPixmap может быть очень тяжелым для такого множества линий, да и не только для них.
Попробуйте сначала рисовать в QImage.


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 10, 2010, 21:09
Никакой видимой разницы между быстродействием QPixmap и QImage в этом случае я не заметил.


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 10, 2010, 21:11
Вот натолкнулся на тему. Только не понял в чем проблема использования OpenGL для ускорения отрисовки?
Все бы ничего, только у меня OpenGL framebuffer на компе не поддерживается


Название: Re: Тормоза в polyline
Отправлено: SABROG от Март 10, 2010, 21:30
Картинка каждый раз перерисовывается полностью или её можно сдвигать и дорисовывать?


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 11, 2010, 20:32
Перерисовывается полностью


Название: Re: Тормоза в polyline
Отправлено: SABROG от Март 12, 2010, 01:19
Чего-то у меня твоя программа вылетает с AV:

Код:
Program received signal SIGSEGV, Segmentation fault.
0x0040140f in renderImage (img=0x22fef8, ptr=0x22f6f4, ptm=0x22eef4,
    len=2147483647) at main.cpp:16
16              else ptm[i] -= (ptm[i] - ptr[i]) / 25;
(gdb) p i
$1 = 2182
(gdb) p &ptm[i]
$3 = (quint16 *) 0x230000

Стек что ли переполняется?


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 12, 2010, 18:52
Сейчас не готов комментировать - давно уже это было. За выходные посмотрю.


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 13, 2010, 22:47
Даже не знаю, что и сказать. Все нормально работает. Только мееееедленно. :(


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 13, 2010, 23:09
Попробовал еще и это.
Только не понял в чем проблема использования OpenGL для ускорения отрисовки?
и вуаля... скорость  отрисовки снизилась а fps повысилась.
fps-то повысилась примерно в 6 раз. Но всего лишь до 4.7 по сравнению c 0.75. Т.е. все равно ни в какие ворота. Кроме того, и антиалиасинг куда-то пропал. Так что такого OpenGL мне не надо.


Название: Re: Тормоза в polyline
Отправлено: SABROG от Март 14, 2010, 04:20
Даже не знаю, что и сказать. Все нормально работает. Только мееееедленно. :(
Какой компилятор? Я на MinGW собирал.


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 14, 2010, 10:21
WinXP MinGW Qt 4.6.0


Название: Re: Тормоза в polyline
Отправлено: GreatSnake от Март 18, 2010, 10:31
Цитировать
Никакой видимой разницы между быстродействием QPixmap и QImage в этом случае я не заметил.
А я заметил!

Ваш оригинальный код с QImage
5.219 secs (1.91608 fps)

c QPixmap
0.594 secs (16.835 fps)

Xorg/fglrx, Radeon HD4200, PhenomII X4 925


Название: Re: Тормоза в polyline
Отправлено: xokc от Март 18, 2010, 20:02
А я заметил!
Безумно рад за Вас. Про то, что для X Windows разница имеется я наслышан (например, http://www.prog.org.ru/index.php?topic=9858.msg57015#msg57015). Повторюсь в третий раз у меня WinXP MinGW Qt 4.6.0. И проблема актуальна именно в этой конфигурации.


Название: Re: Тормоза в polyline
Отправлено: aydef от Июль 30, 2010, 23:09
это код из Qwt, который все проясняет.

static inline void drawPolyline(QPainter *painter,
    const QPointF *points, int pointCount, bool polylineSplitting)
{
    bool doSplit = false;
    if ( polylineSplitting )
    {
        const QPaintEngine *pe = painter->paintEngine();
        if ( pe && pe->type() == QPaintEngine::Raster )
        {
            /*
                The raster paint engine seems to use some algo with O(n*n).
                ( Qt 4.3 is better than Qt 4.2, but remains unacceptable)
                To work around this problem, we have to split the polygon into
                smaller pieces.
             */
            doSplit = true;
        }
    }

    if ( doSplit )
    {
        const int splitSize = 20;
        for ( int i = 0; i < pointCount; i += splitSize )
        {
            const int n = qMin(splitSize + 1, pointCount - i);
            painter->drawPolyline(points + i, n);
        }
    }
    else
        painter->drawPolyline(points, pointCount);
}
 


Название: Re: Тормоза в polyline
Отправлено: xokc от Август 02, 2010, 20:51
это код из Qwt, который все проясняет.
Что именно он проясняет? Что drawPolyline тормозит? Так это понятно было с самого начала.