Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: BlackTass от Август 01, 2009, 22:23



Название: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 01, 2009, 22:23
Есть QGraphicsView с одним QGraphicsPixmapItem'ом. При любой трансформации (поворот, зум) начинает безбожно тормозить прокрутка (только при работе в X11). Попробовал перевести на ГЛ, но столкнулся с проблемами работы самого ОГЛя у нескольких пользователей (вместо изображения каша из пикселей цветов, отдаленно напоминающих цвета пикселей изображения). Попробовал использовать кеширование, но не помогло. После профилирования увидел что вероятная проблема в постоянном преобразовании пиксмапа в QImage при отрисовке, но пока решил неписать наследника, а порыскать как-бы можно ускорить это дело штатными средствами.


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 02, 2009, 00:49
Попробовал написать наследника, который хранит QImage и передает его для отрисовки. Не помогло :( скорость осталась примерно та же


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: Rcus от Август 02, 2009, 09:54
А какие режимы кеширования вы пробовали? Покажете может граф KCachegrind в bottleneck'е (или приложите сам файл callgrind.out.<pid>). Еще неплохо бы приложить пример, или укажите в каком из стандартных примеров проявляется подобное поведение.


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 02, 2009, 12:17
А какие режимы кеширования вы пробовали? Покажете может граф KCachegrind в bottleneck'е (или приложите сам файл callgrind.out.<pid>). Еще неплохо бы приложить пример, или укажите в каком из стандартных примеров проявляется подобное поведение.
Пробовал оба кеширования у айтема (ItemCoordinateCache, DeviceCoordinateCache) и пробовал выставлять большой размер кеша (около 400 мегабайт) через QPixmapCache::setCacheLimit(). Такой вопрос, может я неправильно включаю кеширование? Его надо включать каждый раз, когда меняется пиксмап (через setPixmap()), или можно только один раз при создании самого айтема (я делал именно так)?
Есть профилирование в vTune. Могу выслать его, как доберусь до компа с ним, либо перепрофилировать в кешгринде.


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: Rcus от Август 02, 2009, 12:23
Если в vTune, то лучше картинкой - графы в пнг мало весят. Просто без него мало что можно утверждать, например при профилировании примера ported asteroids сразу понятно откдуа идут основные преобразования в QImage (по-умолчанию QGraphicsPixmapItem::shape() использует createHeuristicMask).


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 02, 2009, 23:38
qgraphicspixmapoptimizeditem.cpp (класс наследника QGraphicsPixmapItem с сохранением имаджа ждя исключения постоянного перевода в QImage):
Код:
#include "qgraphicspixmapoptimizeditem.h"
#include <QStyle>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QImage>
#include <QDebug>


QGraphicsPixmapOptimizedItem::QGraphicsPixmapOptimizedItem()
        : QGraphicsPixmapItem()
{
    currImage = 0;
}


void QGraphicsPixmapOptimizedItem::setPixmap(const QPixmap &pixmap)
{
    QGraphicsPixmapItem::setPixmap(pixmap);
    if (currImage)
        delete currImage;
    currImage = new QImage(pixmap.toImage());
}

void QGraphicsPixmapOptimizedItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget);

    painter->setRenderHint(QPainter::SmoothPixmapTransform,
                           (transformationMode() == Qt::SmoothTransformation));

    QRectF exposed = option->exposedRect.adjusted(-1, -1, 1, 1);
    exposed &= QRectF(offset().x(), offset().y(), currImage->width(), currImage->height());
    painter->drawImage(exposed, *currImage, exposed.translated(-offset()));
}

Класс ViewImageWidget - наследник QMainWindow, который на себе содержит QGraphicsView и тулбар с кнопками для зума и прочего.
Конструктор (кусок относящийся к айтему):
Код:
ViewImageWidget::ViewImageWidget(QWidget *parent) :
    QMainWindow(parent),
    m_ui(new Ui::ViewImageWidget)
{
    m_ui->setupUi(this);
    graphicsScene = new QGraphicsScene();
    m_ui->imageView->setScene(graphicsScene);
    m_ui->imageView->setDragMode(QGraphicsView::ScrollHandDrag);
    pixmapItem = new QGraphicsPixmapOptimizedItem();
    pixmapItem->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
    pixmapItem->setCacheMode(QGraphicsPixmapItem::DeviceCoordinateCache);
    pixmapItem->setTransformationMode(Qt::SmoothTransformation);
    graphicsScene->addItem(pixmapItem);
// ...
}

Собственно метод обновления пиксмапа в айтеме (currImagePath хранит путь до изображения)
Код:
void ViewImageWidget::updateImage()
{
// ...
    ((QGraphicsPixmapOptimizedItem *)pixmapItem)->setPixmap(QPixmap(currImagePath));
    if (pixmapItem && (pixmapItem->pixmap().width() > m_ui->imageView->width() || pixmapItem->pixmap().height() > m_ui->imageView->height()))
        m_ui->imageView->fitInView(pixmapItem, Qt::KeepAspectRatio);
}

в main.cpp есть строка QPixmapCache::setCacheLimit(409600);

лог коллгринда во вложении (разбит сплитом на две части после упаковки в .tar.bz2).


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 02, 2009, 23:38
Вторая часть коллгринда


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: Rcus от Август 03, 2009, 09:40
Что-то у меня с руками, может почтой пошлете?
Код:
$ cat callgrind.out.5060.tar.bz2.part_aa.txt callgrind.out.5060.tar.bz2.part_ab.txt > callgrind.out.5060.tar.bz2 && tar -jxvf callgrind.out.5060.tar.bz2

bzip2: Data integrity error when decompressing.
        Input file = (stdin), output file = (stdout)

It is possible that the compressed file(s) have become corrupted.
You can use the -tvv option to test integrity of such files.

You can use the `bzip2recover' program to attempt to recover
data from undamaged sections of corrupted files.

tar: Child returned status 2
tar: Exiting with failure status due to previous errors


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 05, 2009, 08:43
Rcus, скажите вы посмотрели лог коллгринда? есть какие нибудь соображения?


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: Rcus от Август 05, 2009, 09:03
Что-то не посмотрел вначале исходники... Ну 60% идет на drawImage (и всего 16 вызовов), только я не понял при чем тут QGraphicsPixmapItem в этом случае. Чтобы были соображения нужно взять 40k chips и модифицировать для отображения QPixmap'ов, но времени нет.


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 05, 2009, 11:15
Что-то не посмотрел вначале исходники... Ну 60% идет на drawImage (и всего 16 вызовов), только я не понял при чем тут QGraphicsPixmapItem в этом случае. Чтобы были соображения нужно взять 40k chips и модифицировать для отображения QPixmap'ов, но времени нет.
про то куда идет основное время я знаю;)
я завтра тогда постараюсь выложить коллгринд для модифицированных чипов


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 08, 2009, 23:20
В аттаче тестовое приложение, на котором происходят вышеназванные тормоза (чтобы оно нормально работало надо положить к нему в папку файл test.jpg с каким-нить немаленьким изображением (5-10 мегапиксельная фотка вполне подойдет, я тестировал на 8мп фотке)). Класс QGraphicsPixmapOptimizedItem пытается оптмизировать работу пейнтера кешируя не только пиксмап, но и имадж. Впринципе с ним побыстрее, но все равно не так гладко скроллируется как хотелось бы.


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: Rcus от Август 09, 2009, 00:34
........ Что-то у меня энтузиазма поубавилось после чтения исходников qgraphicscene.cpp перед сном, надо на свежую голову это читать. В общем при трансформации не подхватывается кеш, а почему надо читать или трассировать. И конечно большие картинки в транформации в graphicsview это изврат :)


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 09, 2009, 00:49
А есть другие варианты сделать просмотрщик изображений с фичами масштаба, поворота и прочим? Можно конечно самому прогонять через матрицы поворота и масштаба, но если уже есть готовый инструмент почему бы его не использовать, пусть и подпилив напильником ;).


Название: Re: тормоза с QGraphicsPixmapItem в X11
Отправлено: BlackTass от Август 09, 2009, 02:11
Помогло решение с рисованием не QGraphicsPixmapItem, а QGraphicsRectItem с картинкой в качестве кисти (QBrush).