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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Медленно работает drawPixmap.  (Прочитано 4719 раз)
alexman
Гость
« : Апрель 20, 2011, 21:49 »

1. Есть QGraphicsView. В качестве вьюпорта установлен QGLWidget.
2. Есть наследник от QGraphicsItem c переопределенным методом paint. В связи с багом в Qt реализовал свое кеширование айтема. Примерный код:
Код:
void paint( QPainter* painter, const QStyleOptionGraphicsItem*, QWidget* = 0 )
{
      const QRectF& rect = painter->worldTransform().inverted().mapRect( QRectF( painter->viewport() ) );
      if ( changed( rect ) ) { //Если текущая область изменилась, то перерисовываем кеш _cache - внутреннее поле класс, QPixmap _cache.
            _cache = QPixmap( painter->viewport().size() );
            _cache.fill( QColor( 0, 0, 0, 0 ) );

           //Рисовка в кеш.
      }

      //Отображение кеша:
      painter->setWorldMatrixEnabled( false );
      painter->drawPixmap( 0, 0, _cache );
      painter->setWorldMatrixEnabled( true );
}

Так вот под Windows XP для некоторых моделей NVIDIA-карт медленно работает painter->drawPixmap( 0, 0, _cache ); Проявил следующим образом: открыл notepad и поводил по окну - перерисовка тормозит. Как можно данный косяк оптимизировать? Заранее спасибо!
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Апрель 21, 2011, 08:34 »

Цитировать
В связи с багом в Qt реализовал свое кеширование айтема.
Интересно - что за баг?
Цитировать
Проявил следующим образом: открыл notepad и поводил по окну - перерисовка тормозит. Как можно данный косяк оптимизировать?
А разве на QGLWidget backing store не работает?

Попробуй вместо QPixmap использовать QImage.

Имхо у тебя что-то не так с дизайном, т.к. этот наследник QGraphicsItem завазан на painter->viewport().size().
Для чего вообще это делается? Если для отрисовки подложки, то лучше использовать QGraphicsView::drawBackground().
Записан

Qt 5.11/4.8.7 (X11/Win)
alexman
Гость
« Ответ #2 : Апрель 21, 2011, 09:06 »

Цитировать
В связи с багом в Qt реализовал свое кеширование айтема.
Интересно - что за баг?
Кеш с ключом QGraphicsItem::DeviceCoordinateCache в последней версии не работает! Ранее работал.

Цитировать
Попробуй вместо QPixmap использовать QImage.
Попробую!

Цитировать
Имхо у тебя что-то не так с дизайном, т.к. этот наследник QGraphicsItem завазан на painter->viewport().size().
Для чего вообще это делается? Если для отрисовки подложки, то лучше использовать QGraphicsView::drawBackground().
Что не так то Непонимающий Есть айтем, у него свой кеш, который меняется, когда текущий view rect изменился. Ну а далее при следующих вызывах рисуется только QPixmap.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Апрель 21, 2011, 09:10 »

Как и при каких условиях у тебя задаётся painter->viewport()?
Записан

Qt 5.11/4.8.7 (X11/Win)
alexman
Гость
« Ответ #4 : Апрель 21, 2011, 09:14 »

Как и при каких условиях у тебя задаётся painter->viewport()?
В смысле? Из Qt Assistant:
Код:
QRect QPainter::viewport () const
Returns the viewport rectangle.
Мной явно нигде это не задается! Максимум что я вызываю - это void QGraphicsView::fitInView ( const QRectF & rect, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio ).
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Апрель 21, 2011, 09:20 »

Т.е. получается, что размер твоего айтема всегда равен размеру твоего QGraphicsView?
Тогда зачем он вообще нужен? Ведь всё можно отрисовать в QGraphicsView::drawBackground().
« Последнее редактирование: Апрель 21, 2011, 09:21 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
alexman
Гость
« Ответ #6 : Апрель 21, 2011, 09:27 »

Говорил же код примерный! Можно сделать пересечение с boundingRect() и тогда уже размер айтема не будет равен размеру QGraphicsView.

Код:
Тогда зачем он вообще нужен? Ведь всё можно отрисовать в QGraphicsView::drawBackground().
Айтемов может быть много и хотелось бы оставить qt-ый механизм рисовки! Может что-то не пойму! Что даст QGraphicsView::drawBackground()? Я же указал тонкое место. Медленно работает drawPixmap.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Апрель 21, 2011, 09:36 »

Цитировать
Можно сделать пересечение с boundingRect() и тогда уже размер айтема не будет равен размеру QGraphicsView.
Кстати, а QGraphicsItem::boundingRect() не забыл правильно перегрузить?

Цитировать
Что даст QGraphicsView::drawBackground()?
Отрисовка будет делаться только для clipping region и достаточно быстро, т.к. в этом случае не придётся делать composing.
С отрисовкой QGraphicsItem может быть всё намного сложнее.

Записан

Qt 5.11/4.8.7 (X11/Win)
alexman
Гость
« Ответ #8 : Апрель 21, 2011, 09:43 »

Цитировать
Можно сделать пересечение с boundingRect() и тогда уже размер айтема не будет равен размеру QGraphicsView.
Кстати, а QGraphicsItem::boundingRect() не забыл правильно перегрузить?
Неа.

Цитировать
Что даст QGraphicsView::drawBackground()?
Отрисовка будет делаться только для clipping region и достаточно быстро, т.к. в этом случае не придётся делать composing.
С отрисовкой QGraphicsItem может быть всё намного сложнее.
Да, но есть одно но: айтемы могут менять (довольно часто, приложение интерактивное) и всё равно придется все перерисовывать. В реализованом же случае перерисовывать необходимо будет только изменный айтем и это плюс в моем случае, так как рисовка затратная!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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