[Qt-interest] QGraphicsView performance issue
Alexis Ménard
alexis.menard at trolltech.com
Tue May 12 09:57:34 CEST 2009
On Tuesday 12 May 2009 05:32:56 Santhosh Y wrote:
> Hi,
>
> As a part of optimization I did the following:
>
> - From the scene of 30,000 items, I figured out the areas(QRectF area1,
> QRectF area2) which needs
> repainting for a "particular_functionality"
> ---------------------------------------------------------------------------
>--------------------------- class GraphicsView :: public QGraphicsView{};
>
> void
> GraphicsView::paintEvent (QPaintEvent* e)
> {
> if (particular_functionality) { // customizing the paintevent
>
> // painting only area1
> QPaintEvent ar1 (area1); // QRectF area1
> QGraphicsView::paintEvent(&ar1);
>
> // painting only area2
> QPaintEvent ar2 (area2); // QRectF area2
> QGraphicsView::paintEvent(&ar2);
>
> particular_functionality = false;
> } else { // normal paint events on Graphicsview
> QGraphicsView::paintEvent (e); // not being disturbed
> }
> }
> ---------------------------------------------------------------------------
>---------------------------
>
> The issue with the above code is that, the area1& area2 are only being
> repainted and the rest of the area is being erased.
> I am not understanding why the rest of the area is being erased.
>
> I am not using any optimization flags such as
> setOptimizationFlags( QGraphicsView::DontSavePainterState);
>
> Please tell me how to avoid the rest of the area from being erased.
> Good part of this customizing paintevent is that, it is very fast when
> I am selectively painting the area.
I would say it is because the exposed rect that you receive from the
paintEvent has mark all the scene as dirty (because of a previous update())
and because you hi-jack the paintEvent those area that are not in area1 or in
area 2 won't be redrawn. This approach is not the correct one. But what is
slow exactly items discovery (estimateItemsInRect in qgraphicsscene.cpp?)
or the painting itself?
>
> Regards,
> Santhosh.
>
> Alexis Ménard wrote:
> > On Monday 11 May 2009 17:09:44 Santhosh Y wrote:
> >> Alexis Ménard wrote:
> >>> On Monday 11 May 2009 16:10:04 Santhosh Y wrote:
> >>>> Please read my comments below
> >>>>
> >>>> Alexis Ménard wrote:
> >>>>> On Monday 11 May 2009 15:01:52 Santhosh Y wrote:
> >>>>>> Santhosh Y wrote:
> >>>>>>> Hi,
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>>>> I added 30,000 items to the scene.
> >>>>>>> While updating the scene, the response from the view is very slow.
> >>>>>>>
> >>>>>>> Among these 30,000 items only 3,000 items have the distinctive
> >>>>>>> locations and the rest of 27,000 items have the same location of
> >>>>>>> those 3,000 items.
> >>>>>>>
> >>>>>>> In such a scenario to improve the performance, what flags
> >>>>>>> I should use on the scene to improve the performance.
> >>>>>
> >>>>> If the painting (paint method) is slow on items, you can use the
> >>>>> cache mode, itemCoordinateCache if you have no transformations
> >>>>> otherwise DeviceCoordinateCache.
> >>>>
> >>>> I am not able to find the above flag for setting cache mode.
> >>>> I am using 4.3.3 version of Qt.
> >>>> I can use only cacheNone or cacheBackGround.
> >>>
> >>> OoOooOOooooOOo. Then i fully encourage you to upgrade to 4.5. Lot of
> >>> performance improvements has been made since 4.3.3 and those repaint
> >>> bugs has been
> >>> probably fixed. And you have more features.
> >>
> >> Is 4.5 released for windows version.
> >
> > Yes and more 4.5.1. As always Qt is cross platform all version are
> > released at the same time and it is the same source code anyway.
> >
> >>>>> If you trigger full updates on the scene, then you need to set the
> >>>>> viewportUpdate to fullviewport update because sometimes it is slower
> >>>>> to caculate the exact dirty area than repainting the all scene (aka
> >>>>> OpenGL).
> >>>>>
> >>>>>> To add to the above issue, what I have observed is that,
> >>>>>> paintEvent() on QGraphicsview is being called multiple times
> >>>>>> which is taking around 3 sec for each call to pick the items from
> >>>>>> the visible region for sending to
> >>>>>
> >>>>> That why we are working on an API to allow you to create your custom
> >>>>> indexing where you can skip some parts of the scene or skipping items
> >>>>> that you don't need.
> >>>>>
> >>>>>> QGraphicsScene::drawItems(QPainter* p, int numItems, QGraphicsItem**
> >>>>>> items, const QStyleOptionGraphicsItem* options )
> >>>>>> function dispatch.
> >>>>>>
> >>>>>> Can anybody tell me how to track from where this paintEvent call is
> >>>>>> dispatched so many times.
> >>>>>
> >>>>> recalculateContentSize can be the source of those calls because you
> >>>>> query a full update (see below).
> >>>>>
> >>>>>> I have no QGraphicsView::update() calls in my code, but I have the
> >>>>>> QGraphicsScene::update() calls.
> >>>>>
> >>>>> Calling update on the scene is not a good idea unless you give a
> >>>>> rectangle to update(). Without parameter it will redraw everything...
> >>>>> Why do you need to update the whole scene? Updating the content
> >>>>> should triggers updates on items for you...
> >>>>
> >>>> I removed all the QGraphicsScene::update () calls. Still the
> >>>> performance have not improved.
> >>>>
> >>>>>> But none of the QGraphicsScene::update () call is immediately
> >>>>>> resulting a QGraphicsView::paintEvent(QPaintEvent*)
> >>>>>>
> >>>>>> My observation is that all the mutliple calls on
> >>>>>> QGraphicsView::paintEvent(QPaintEvent*) are resulting from the
> >>>>>> following stack.
> >>>>>> --------------------------------------------------------------------
> >>>>>>-- -- --- ---------------------------
> >>>>>> QGraphicsView::paintEvent(QPaintEvent * e=0x0012b550) Line 1282
> >>>>>> C++ QtGuid4.dll!QWidget::event(QEvent * event=0x0012b550) Line 6256
> >>>>>> C++ QtGuid4.dll!QFrame::event(QEvent * e=0x0012b550) Line 641
> >>>>>> C++ QtGuid4.dll!QAbstractScrollArea::viewportEvent(QEvent *
> >>>>>> e=0x0012b550) Line 909 + 0xc bytes C++
> >>>>>> QtGuid4.dll!QGraphicsView::viewportEvent(QEvent *
> >>>>>> event=0x0012b550) Line 2324 C++
> >>>>>> QtGuid4.dll!QAbstractScrollAreaPrivate::viewportEvent(QEvent *
> >>>>>> event=0x0012b550) Line 78 + 0x28 bytes C++
> >>>>>> QtGuid4.dll!QAbstractScrollAreaFilter::eventFilter(QObject *
> >>>>>> o=0x08705aa0, QEvent * e=0x0012b550) Line 89 + 0x29 bytes C++
> >>>>>> QtGuid4.dll!QApplicationPrivate::notify_helper(QObject *
> >>>>>> receiver=0x08705aa0, QEvent * e=0x0012b550) Line 3533 + 0x1b bytes
> >>>>>> C++ QtGuid4.dll!QApplication::notify(QObject * receiver=0x08705aa0,
> >>>>>> QEvent * e=0x0012b550) Line 3482 + 0x10 bytes C++
> >>>>>> QtCored4.dll!QCoreApplication::notifyInternal(QObject *
> >>>>>> receiver=0x08705aa0, QEvent * event=0x0012b550) Line 516 C++
> >>>>>> QtCored4.dll!QCoreApplication::sendSpontaneousEvent(QObject *
> >>>>>> receiver=0x08705aa0, QEvent * event=0x0012b550) Line 188 + 0x38
> >>>>>> bytes C++
> >>>>>> QtGuid4.dll!qt_sendSpontaneousEvent(QObject *
> >>>>>> receiver=0x08705aa0, QEvent * event=0x0012b550) Line 1182 + 0xe
> >>>>>> bytes C++
> >>>>>> QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice *
> >>>>>> pdev=0x02a0a878, const QRegion & rgn={...}, const QPoint &
> >>>>>> offset={...}, int flags=4) Line 1195 + 0xd bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=0, const QRegion & rgn={...}, const QPoint & offset={...}, int
> >>>>>> flags=4) Line 1099 C++
> >>>>>> QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice *
> >>>>>> pdev=0x02a0a878, const QRegion & rgn={...}, const QPoint &
> >>>>>> offset={...}, int flags=4) Line 1231 + 0x2e bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=2, const QRegion & rgn={...}, const QPoint & offset={...}, int
> >>>>>> flags=4) Line 1099 C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=3, const QRegion & rgn={...}, const QPoint & offset={...}, int
> >>>>>> flags=4) Line 1089 + 0x20 bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=4, const QRegion & rgn={...}, const QPoint & offset={...}, int
> >>>>>> flags=4) Line 1089 + 0x20 bytes C++
> >>>>>> QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice *
> >>>>>> pdev=0x02a0a878, const QRegion & rgn={...}, const QPoint &
> >>>>>> offset={...}, int flags=4) Line 1231 + 0x2e bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=13, const QRegion & rgn={...}, const QPoint & offset={...},
> >>>>>> int flags=4) Line 1099 C++
> >>>>>> QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice *
> >>>>>> pdev=0x02a0a878, const QRegion & rgn={...}, const QPoint &
> >>>>>> offset={...}, int flags=4) Line 1231 + 0x2e bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=5, const QRegion & rgn={...}, const QPoint & offset={...}, int
> >>>>>> flags=4) Line 1099 C++
> >>>>>> QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice *
> >>>>>> pdev=0x02a0a878, const QRegion & rgn={...}, const QPoint &
> >>>>>> offset={...}, int flags=4) Line 1231 + 0x2e bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=40, const QRegion & rgn={...}, const QPoint & offset={...},
> >>>>>> int flags=4) Line 1099 C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=41, const QRegion & rgn={...}, const QPoint & offset={...},
> >>>>>> int flags=4) Line 1089 + 0x20 bytes C++
> >>>>>>
> >>>>>> QtGuid4.dll!QWidgetBackingStore::paintSiblingsRecursive(QPaintDevice
> >>>>>> * pdev=0x02a0a878, const QList<QObject *> & siblings={...}, int
> >>>>>> index=42, const QRegion & rgn={...}, const QPoint & offset={...},
> >>>>>> int flags=4) Line 1089 + 0x20 bytes C++
> >>>>>> QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice *
> >>>>>> pdev=0x02a0a878, const QRegion & rgn={...}, const QPoint &
> >>>>>> offset={...}, int flags=5) Line 1231 + 0x2e bytes C++
> >>>>>> QtGuid4.dll!QWidgetBackingStore::cleanRegion(const QRegion &
> >>>>>> rgn={...}, QWidget * widget=0x0012fd58, bool
> >>>>>> recursiveCopyToScreen=false) Line 1000 C++
> >>>>>> QtGuid4.dll!qt_syncBackingStore(QRegion rgn={...}, QWidget *
> >>>>>> widget=0x0012fd58, bool recursive=false) Line 230 C++
> >>>>>> QtGuid4.dll!QETWidget::translatePaintEvent(const tagMSG &
> >>>>>> msg={...}) Line 3094 + 0x2b bytes C++
> >>>>>> QtGuid4.dll!QtWndProc(HWND__ * hwnd=0x000a1118, unsigned int
> >>>>>> message=15, unsigned int wParam=0, long lParam=0) Line 1680 + 0xc
> >>>>>> bytes C++
> >>>>>> --------------------------------------------------------------------
> >>>>>>-- -- --- ---------------------------
> >>>>>>
> >>>>>> Please tell me how to track the event call of paint over
> >>>>>> QGraphicsView.
--
Alexis Ménard
Software Engineer, Widgets Team 1
Qt Software, Nokia Norge AS, Sandakerveien 116, 0484 Oslo, Norway
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090512/43d74c09/attachment.html
More information about the Qt-interest-old
mailing list