Russian Qt Forum
Ноябрь 25, 2024, 03:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: тормоза с QGraphicsPixmapItem в X11  (Прочитано 9407 раз)
BlackTass
Гость
« : Август 01, 2009, 22:23 »

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

Попробовал написать наследника, который хранит QImage и передает его для отрисовки. Не помогло Грустный скорость осталась примерно та же
Записан
Rcus
Гость
« Ответ #2 : Август 02, 2009, 09:54 »

А какие режимы кеширования вы пробовали? Покажете может граф KCachegrind в bottleneck'е (или приложите сам файл callgrind.out.<pid>). Еще неплохо бы приложить пример, или укажите в каком из стандартных примеров проявляется подобное поведение.
Записан
BlackTass
Гость
« Ответ #3 : Август 02, 2009, 12:17 »

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

Если в vTune, то лучше картинкой - графы в пнг мало весят. Просто без него мало что можно утверждать, например при профилировании примера ported asteroids сразу понятно откдуа идут основные преобразования в QImage (по-умолчанию QGraphicsPixmapItem::shape() использует createHeuristicMask).
Записан
BlackTass
Гость
« Ответ #5 : Август 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).
Записан
BlackTass
Гость
« Ответ #6 : Август 02, 2009, 23:38 »

Вторая часть коллгринда
Записан
Rcus
Гость
« Ответ #7 : Август 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
Записан
BlackTass
Гость
« Ответ #8 : Август 05, 2009, 08:43 »

Rcus, скажите вы посмотрели лог коллгринда? есть какие нибудь соображения?
Записан
Rcus
Гость
« Ответ #9 : Август 05, 2009, 09:03 »

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

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

В аттаче тестовое приложение, на котором происходят вышеназванные тормоза (чтобы оно нормально работало надо положить к нему в папку файл test.jpg с каким-нить немаленьким изображением (5-10 мегапиксельная фотка вполне подойдет, я тестировал на 8мп фотке)). Класс QGraphicsPixmapOptimizedItem пытается оптмизировать работу пейнтера кешируя не только пиксмап, но и имадж. Впринципе с ним побыстрее, но все равно не так гладко скроллируется как хотелось бы.
Записан
Rcus
Гость
« Ответ #12 : Август 09, 2009, 00:34 »

........ Что-то у меня энтузиазма поубавилось после чтения исходников qgraphicscene.cpp перед сном, надо на свежую голову это читать. В общем при трансформации не подхватывается кеш, а почему надо читать или трассировать. И конечно большие картинки в транформации в graphicsview это изврат Улыбающийся
Записан
BlackTass
Гость
« Ответ #13 : Август 09, 2009, 00:49 »

А есть другие варианты сделать просмотрщик изображений с фичами масштаба, поворота и прочим? Можно конечно самому прогонять через матрицы поворота и масштаба, но если уже есть готовый инструмент почему бы его не использовать, пусть и подпилив напильником Подмигивающий.
Записан
BlackTass
Гость
« Ответ #14 : Август 09, 2009, 02:11 »

Помогло решение с рисованием не QGraphicsPixmapItem, а QGraphicsRectItem с картинкой в качестве кисти (QBrush).
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.15 секунд. Запросов: 21.