[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