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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QPixmap - тормоза в иксах  (Прочитано 4984 раз)
mal
Гость
« : Июль 21, 2010, 13:23 »

Qt-4.6.2
Юзаю GraphicsViewFramesork.
Столкнулся с такой проблемой:
Портировал проект под линукс и обнаружил, что банальный ресайз сцены, у которой на бэкграунд положен пиксмап приводит к жутким тормозам. Соответственно всякая интерактивная работа с графическими примитивами накладываемыми поверх пиксмапа тоже встает колом. Если же погасить пиксмап, то все начинает летать.
Тема тут уже поднималась про тормоза с примером в иксах из /demos/chip - и она действительно есть!  Как только мы уменьшаем картинку с чипами до момента, когда начинает отрисовываться png  с народом на лужайке - наблюдается тот же эффект с торможением при ресайзе и, например, при скроллинге.
В винде понятно все прекрасно.
Возникает вопрос, что с этим делать в иксах ?   В замешательстве
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Июль 21, 2010, 13:31 »

Qt это делает отвратительно, поэтому
уберите вашу установку подложки и перегрузите QGraphicsScene::drawBackground():

Код
C++ (Qt)
void YourScene::drawBackground( QPainter* p, const QRectF& clip )
{
if( !bg_image_ )   // QImage* bg_image_ - предварительно загруженная картинка
{
QGraphicsScene::drawBackground( p, clip );
return;
}
 
p->eraseRect( clip );
 
QMatrix wm( p->worldMatrix() );
 
if( wm.m11() != 1 &&
clip.intersects( bg_image_->rect() ) )
{
QImage img;
QRectF c( clip );
if( wm.m11() > 1 )
c.adjust( -1, -1, 1, 1 );
 
qreal cx = c.x();
qreal cy = c.y();
qreal cw = qMax( 16., c.width() );
qreal ch = qMax( 16., c.height() );
 
if( cx < 0 )
{
cw += cx;
cx = 0;
}
if( cy < 0 )
{
ch += cy;
cy = 0;
}
 
cw = qMin( cw, bg_image_->width() - cx );
ch = qMin( ch, bg_image_->height() - cy );
img = bg_image_->copy( QRectF( cx, cy, cw, ch ).toRect() );
cw = qRound( cw * wm.m11() );
ch = qRound( ch * wm.m11() );
img = img.scaled( (int) cw, (int) ch, Qt::IgnoreAspectRatio,
/*wm.m11() > .8 ? Qt::SmoothTransformation :*/ Qt::FastTransformation );
p->setWorldMatrix( QMatrix( 1, 0, 0, 1, wm.dx(), wm.dy() ) );
p->drawImage( QPointF( cx * wm.m11(), cy * wm.m11() ), img );
p->setWorldMatrix( wm );
} else
{
p->drawImage(
QPointF( clip.x(), clip.y() ),
*bg_image_,
QRectF( clip.x(), clip.y(),
qMin( clip.width(), qreal( bg_image_->width() ) ),
qMin( clip.height(), qreal( bg_image_->height() ) ) ) );
}
}
 

Но, т.к. мы отрисовываем только кусок,
нужно будет у QGraphicsView выставить setCacheMode( CacheBackground ),
иначе из-за скейлинга этот кусок не будет "стыковаться" со всей подложкой.
« Последнее редактирование: Ноябрь 26, 2010, 14:41 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
mal
Гость
« Ответ #2 : Июль 21, 2010, 14:37 »

GreatSnake
Спасибо!  Веселый
Конечно скорость все-таки не такая как в винде, но уже гораздо приемлемей! И примитивы не встают колом.  Веселый
Теперь брать в руки напильник и пилить код. Ибо много было завязано на пиксмап бросаемый в качестве бэкграунда. Но это уже детали.
« Последнее редактирование: Июль 21, 2010, 14:46 от mal » Записан
SABROG
Гость
« Ответ #3 : Июль 21, 2010, 15:32 »

Тема тут уже поднималась про тормоза с примером в иксах из /demos/chip - и она действительно есть!  Как только мы уменьшаем картинку с чипами до момента, когда начинает отрисовываться png  с народом на лужайке - наблюдается тот же эффект с торможением при ресайзе и, например, при скроллинге.
В винде понятно все прекрасно.
Возникает вопрос, что с этим делать в иксах ?   В замешательстве
У меня одинаково быстро работает и в винде и в линуксе.
Записан
mal
Гость
« Ответ #4 : Июль 22, 2010, 10:28 »

Полазил по форумам  - наткнулся на такой костыль - если сделать
view->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
то вроде как все должно стать пучком.
Попробовал на винде - даже в дебаге все заметно ускоряется!  Веселый
Сейчас пересобереру Qt с поддержкой opengl в линуксе, и тогда проверю, как прога проведет себя в штатном режиме с этим костылем.

*
Нда. Под иксами с этим opengl-ным костылем пиксмап не отображается вообще.  В замешательстве.
Значит напильник и метод GreatSnake'a .

***
Брр - вообщем проверил все под иксами на локальной машине  - все работает! Костыль помог.
То что я написал выше  - я работаю с иксами у себя из под винды через XMing - потому такая шняга. 
Более того, если заходишь с иксовой машины на другую иксовую машину - то наблюдается такой же странный эффект, что вьюха не отображает ничего.
Похоже, что opengl не отрабатывается корректно при работе не на локальной машине. Почему - пока не знаю В замешательстве

ЗЫ Но костыль таки работает!  Веселый

« Последнее редактирование: Июль 22, 2010, 14:40 от mal » Записан
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #5 : Июль 22, 2010, 15:44 »

наткнулся на такой костыль - если сделать
view->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
то вроде как все должно стать пучком.
Кстати, а почему "костыль"? Это просто включение отрисовки через OpenGL pipeline в Qt.
Записан
mal
Гость
« Ответ #6 : Июль 22, 2010, 18:17 »

Пусть не костыль, пусть лекарство.  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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