Page 1 of 2 12 LastLast
Results 1 to 20 of 80

Thread: GraphicsView performance problems

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    That looks really weird.
    The reason probably once again that the time is spent inside of Qt-Code and not yours, so sadly that does not help.
    These figures are wrong. All functions from inside Qt should be counted on behalf of the functions calling them and here all functions have nothing but zeros. The application needs to run longer.

    Or it could have been inlined, again not really helpfull :-/
    Yes, that's possible, especially if they were implemented inside the class header and optimisations were enabled.

    You must be sure to disable inlining optimisations. You can use -fno-inline to disable inlining.

  2. #2
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: GraphicsView performance problems

    Yup! you both are right. Anyway I am recompiling Qt tomorrow. I'll surely post after I do that. In the meanwhile I'd like to inform you people that I have never used cachegrind. Is that better than gprof ? If yes how should I use that ?
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  3. #3
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Did you try my last modification? Did it change anything for you?

    Quote Originally Posted by Gopala Krishna View Post
    Yup! you both are right. Anyway I am recompiling Qt tomorrow. I'll surely post after I do that. In the meanwhile I'd like to inform you people that I have never used cachegrind. Is that better than gprof ? If yes how should I use that ?
    You do not need to compile anything special (besides DEBUG of course ;-)

    Then call
    $valgrind --tool=callgrind ./YOUR_APP
    this will produce a file called callgrind.out.PID_OF_PROCESS

    then you can call
    $kcachegrind callgrind.out.PID_OF_PROCESS
    http://kcachegrind.sourceforge.net/cgi-bin/show.cgi

  4. #4
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    Did you try my last modification? Did it change anything for you?



    You do not need to compile anything special (besides DEBUG of course ;-)

    Then call


    this will produce a file called callgrind.out.PID_OF_PROCESS

    then you can call


    http://kcachegrind.sourceforge.net/cgi-bin/show.cgi
    Thanks ! Here is the output as attachment
    EDIT: My quota of attachment is almost over. I'll update a bit later.
    Last edited by Gopala Krishna; 17th February 2007 at 15:34. Reason: updated contents
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: GraphicsView performance problems

    I have modified my application which uses QGraphicsView framework to draw a grid simmilar to yours and I implemented it in a worst possible way:
    Qt Code:
    1. void drawBackground ( QPainter * painter, const QRectF & rect ){
    2. static QPen p(QColor(150,150,150));
    3. painter->setPen(p);
    4. for(int row=10+((int)(rect.top())/10)*10; row<rect.bottom(); row+=10){
    5. for(int col = 10+((int)(rect.left())/10)*10; col<rect.right(); col+=10)
    6. painter->drawPoint(col, row);
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    Profiling info (compiled with -fno-inline -ggdb -pg) looks like this:
    text Code:
    1. % cumulative self self total
    2. time seconds seconds calls us/call us/call name
    3. 33.33 0.02 0.02 1547664 0.01 0.01 QRectF::right() const
    4. 33.33 0.04 0.02 SpecScene::drawBackground(QPainter*, QRectF const&)
    5. 16.67 0.05 0.01 1527572 0.01 0.01 QPainter::drawPoint(int, int)
    To copy to clipboard, switch view to plain text mode 
    As you see 33% of the application time is spent in drawBackground and half of it is used to calculate QRectF::right() (which makes sense as it gets calculated in each iteration of the loop) and pretty much is used to actually draw the points.

    text Code:
    1. index % time self children called name
    2. <spontaneous>
    3. [1] 83.3 0.02 0.03 SpecScene::drawBackground(QPainter*, QRectF const&) [1]
    4. 0.02 0.00 1547627/1547664 QRectF::right() const [2]
    5. 0.01 0.00 1527572/1527572 QPainter::drawPoint(int, int) [3]
    6. 0.00 0.00 20635/20651 QRectF::bottom() const [35]
    7. 0.00 0.00 20055/20055 QRectF::left() const [36]
    8. 0.00 0.00 580/580 QRectF::top() const [93]
    9. 0.00 0.00 1/702 QColor::QColor(int, int, int, int) [92]
    To copy to clipboard, switch view to plain text mode 
    As you see it is actually more time consuming to calculate the rectangle coords than to draw points!

    Some facts:
    - I use Qt4.2.2 on i686 Linux,
    - I didn't use antialiasing,
    - I didn't use scaling (so I have an identity matrix when it comes to viewport-window transformations),
    - scene size was about 1200x1000,
    - I didn't compile Qt with profiling information (so I guess it's not required after all),
    - I got detailed info about both mine and Qt methods,
    - the result is pretty fast.

    I got a pretty good result, but I didn't suffer from viewport-window transformations which might be your case if you scale the view. I didn't use antialiasing for my view, as points are points - they don't suffer from the aliasing effect. I could easily improve the implementation by calculating rectangle coordinates once per drawBackground() which should reduce the execution effort by half.

    It is up to you to do the interpretation of the results. My impression is that it is not really drawBackground() which causes the slowdown - maybe it is just called too often by other parts of the system? Maybe you abuse update()?

  6. #6
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Quote Originally Posted by wysota View Post
    I have modified my application which uses QGraphicsView framework to draw a grid simmilar to yours and I implemented it in a worst possible way:

    Profiling info (compiled with -fno-inline -ggdb -pg) looks like this:
    text Code:
    1. % cumulative self self total
    2. time seconds seconds calls us/call us/call name
    3. 33.33 0.02 0.02 1547664 0.01 0.01 QRectF::right() const
    4. 33.33 0.04 0.02 SpecScene::drawBackground(QPainter*, QRectF const&)
    5. 16.67 0.05 0.01 1527572 0.01 0.01 QPainter::drawPoint(int, int)
    To copy to clipboard, switch view to plain text mode 
    Well, if you disable inlining, no wonder right() is expensive. calling a function 1.5 Million times just takes its time...inlining is there for a reason ;-)

    So I would not call this run very exemplary... :-)

  7. #7
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    just a note:
    If you like to profile further into the drawing part,
    you need to call:
    valgrind --tool=callgrind --seperate-callers=5 --seperate-recs=10 ./YOUR_APP
    Otherwise you will get "cycles", which is not very helpfull in this task..

    BUT: this takes up much more memory to analyze later...

  8. #8
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Hi,

    well I just love to play with this... ;-)


    Here is another (and much faster) way to write the drawBackground function...with the added niceness that it helps avoiding the color errors ;-)

    You might want to check if this survives zooming etc.

    Qt Code:
    1. void drawBackground(QPainter *painter, const QRectF &rect)
    2. {
    3. const int gridSize = 25;
    4.  
    5. if (backgroundCache.isNull()) {
    6. backgroundCache = QPixmap(gridSize, gridSize);
    7. const int middle = gridSize / 2;
    8. QPainter backgroundPainter(&backgroundCache);
    9. backgroundPainter.setRenderHints(painter->renderHints());
    10. backgroundPainter.fillRect(QRect(0, 0, gridSize, gridSize), QBrush(Qt::white));
    11. backgroundPainter.setPen(backgroundPen);
    12. backgroundPainter.setBrush(backgroundBrush);
    13. backgroundPainter.drawLine(0, middle, gridSize, middle);
    14. backgroundPainter.drawLine(middle, 0, middle, gridSize);
    15. }
    16.  
    17. const int realLeft = static_cast<int>(std::floor(rect.left()));
    18. const int realRight = static_cast<int>(std::ceil(rect.right()));
    19. const int realTop = static_cast<int>(std::floor(rect.top()));
    20. const int realBottom = static_cast<int>(std::ceil(rect.bottom()));
    21.  
    22.  
    23. const int firstLeftGridLine = realLeft - (realLeft % gridSize);
    24. const int firstTopGridLine = realTop - (realTop % gridSize);
    25.  
    26.  
    27. QPainterPath background;
    28. for (int x = firstLeftGridLine; x < realRight; x += gridSize) {
    29. for (int y = firstTopGridLine; y < realBottom; y += gridSize) {
    30. painter->drawPixmap(x, y, backgroundCache);
    31. }
    32. }
    33. }
    To copy to clipboard, switch view to plain text mode 

    Have a nice day :-)
    Last edited by camel; 17th February 2007 at 16:26.

  9. The following user says thank you to camel for this useful post:

    Gopala Krishna (17th February 2007)

  10. #9
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    Hi,

    well I just love to play with this... ;-)


    Here is another way to write the drawBackground function...with the added niceness that it helps avoiding the color errors ;-)

    You might want to check if this survives zooming etc.

    Qt Code:
    1. void drawBackground(QPainter *painter, const QRectF &rect)
    2. ...
    To copy to clipboard, switch view to plain text mode 

    Have a nice day :-)
    Not bad idea! That problem solved !!! Thanks a lot.
    Now the next problem is performance !
    A good day to you too
    Last edited by Gopala Krishna; 17th February 2007 at 16:32. Reason: updated contents
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  11. #10
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    just a note:
    If you like to profile further into the drawing part,
    you need to call:


    Otherwise you will get "cycles", which is not very helpfull in this task..

    BUT: this takes up much more memory to analyze later...
    I get the following error
    valgrind: Bad option '--seperate-callers=5'; aborting.
    I am trying to analyse the code as it is now. I am getting lost here and there but kcachegrind is a cool tool. Needs some time to get used to it. Thanks for helping me till now. I'll continue with this tomorrow.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  12. #11
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Quote Originally Posted by Gopala Krishna View Post
    I get the following error
    valgrind: Bad option '--seperate-callers=5'; aborting.
    I think they changed the option names during 3.1 and 3.2 (which I use)

    try:
    valgrind --tool=callgrind --fn-caller=5 --fn-recursion=10 ./YOUR_APP

  13. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    Well, if you disable inlining, no wonder right() is expensive. calling a function 1.5 Million times just takes its time...inlining is there for a reason ;-)

    So I would not call this run very exemplary... :-)
    It means that QRectF::right() takes longer than QPainter::drawPoint() and right() is not a very complex method

    After getting rid of the right() and bottom() calls inside the loop the result of profiling is as follows:
    text Code:
    1. 50.00 0.06 0.06 SpecScene::drawBackground(QPainter*, QRectF const&)
    2. 25.00 0.09 0.03 1460235 0.02 0.02 QPoint::QPoint(int, int)
    3. 16.67 0.11 0.02 1454915 0.01 0.03 QPainter::drawPoint(int, int)
    To copy to clipboard, switch view to plain text mode 

    The QPoint constructor is called by QPainter::drawPoint, so we can forget about it. The whole method takes over 90% of the whole application time and gives a total of less than 0.1s. That's not much

    It is important to see what the bottleneck is instead of shooting blind. No matter how much you optimise QPainter::drawLines() if it's not the bottleneck, you won't get a decent improvement.

    In my opinion it would be much simpler and faster to simply apply a backgroundBrush with the grid to the scene and forget about points and lines. You wouldn't get any painter paths then, no floating point operations. The only thing that could slow down the process is the matrix transformation, so try to avoid it.

  14. #13
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Quote Originally Posted by wysota View Post
    It is important to see what the bottleneck is instead of shooting blind. No matter how much you optimise QPainter::drawLines() if it's not the bottleneck, you won't get a decent improvement.
    That is why I look into my KCachgrind and follow the callgraph and sources ;-)

    The problem is not drawPoints, as that does not do much.

    The problem with drawLines and friends is that it often (with antialiasing) first creates a painterpath from those lines and then paints them. This takes time, not least because of memory allocation.

    This is why I said use painterpaths directly.

    Optimizing the returnvalue of boundingrect and shape is so easy (and makes the code much nicer in my opinion) so that I would not even consider it a optimization, its just nicer programming. (besides helping during run-time of course ;-)

    Quote Originally Posted by wysota View Post
    In my opinion it would be much simpler and faster to simply apply a backgroundBrush with the grid to the scene and forget about points and lines. You wouldn't get any painter paths then, no floating point operations. The only thing that could slow down the process is the matrix transformation, so try to avoid it.
    I cuncur there, see my last post about the drawbackground function.
    To use a background brush would be the logical next step ;-)

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    The problem with drawLines and friends is that it often (with antialiasing) first creates a painterpath from those lines and then paints them. This takes time, not least because of memory allocation.

    This is why I said use painterpaths directly.
    If you disable antialiasing, there is a possibility that painter paths will not be used. And there is no point in having antialiasing enabled for drawing horizontal or vertical lines, as these don't suffer from the aliasing effect. You can safely temporarily disable antialiasing while painting those.
    Qt Code:
    1. bool isAA = painter->renderHints() & QPainter::Antialiasing;
    2. painter->setRenderHint(QPainter::Antialiasing, false);
    3. painter->drawLines(...);
    4. painter->setRenderHint(QPainter::Antialiasing, isAA);
    To copy to clipboard, switch view to plain text mode 

    Another possibility of painter paths being active is that there is scaling involved. But while zooming in, the number of lines needed to draw should decrease. While zooming out on the other hand you can draw fewer lines as too many of them will clutter the scene anyway.

    You can also store the path in a member variable and then only draw the path on the painter. But I think using a background brush will be much faster, especially with smooth scaling disabled.

  16. #15
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Quote Originally Posted by wysota View Post
    If you disable antialiasing, there is a possibility that painter paths will not be used. And there is no point in having antialiasing enabled for drawing horizontal or vertical lines, as these don't suffer from the aliasing effect. You can safely temporarily disable antialiasing while painting those.
    The problem being of course that the lines look differenty ;-)
    But some people might see that as an advantage in this case.

    Quote Originally Posted by wysota View Post
    Another possibility of painter paths being active is that there is scaling involved. But while zooming in, the number of lines needed to draw should decrease. While zooming out on the other hand you can draw fewer lines as too many of them will clutter the scene anyway.

    You can also store the path in a member variable and then only draw the path on the painter. But I think using a background brush will be much faster, especially with smooth scaling disabled.
    In this case the brush is faster. Storing the path in a member variable is not possible in this case, as the lines to draw will change wildly during repaints, and I am not sure how efficient it would be to crop out the rest if you draw all possible lines.

    For the other items, I did just that, storing the path. which works out quite well. I might be possible to also use pixmaps here, but that is probably rather a space/time tradeoff... :-)

  17. #16
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: GraphicsView performance problems

    Quote Originally Posted by camel View Post
    The problem being of course that the lines look differenty ;-)
    Could you explain what you mean by that? Antialiasing shouldn't have any positive effect on horizontal/vertical lines... You can reduce the contrast by using antialiasing on horizontal/vertical lines, but that doesn't improve the line. You can just change the colour you use for drawing and have the same optical effect...

    By the way... by a "line" I understand a "thin line" not a "thick filled rectangle". Of course you can still have a simmilar effect to antialiasing by using a pen different than a brush...

  18. #17
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: GraphicsView performance problems

    Quote Originally Posted by wysota View Post
    Could you explain what you mean by that? Antialiasing shouldn't have any positive effect on horizontal/vertical lines... You can reduce the contrast by using antialiasing on horizontal/vertical lines, but that doesn't improve the line. You can just change the colour you use for drawing and have the same optical effect...

    By the way... by a "line" I understand a "thin line" not a "thick filled rectangle". Of course you can still have a simmilar effect to antialiasing by using a pen different than a brush...
    I did not say "positive effect", I just said "effect"

    Why the effect:
    A one-pixel line not antialiased is exactly one pixel wide
    A one-pixel line antialiased will have the centre of the line on the border between two pixels. (See here


    If you do not use anti-aliasing for all horizontal and vertical lines (such as the resistors in this example) you will have two very different looking lines.

    You might like the effect of having different lines or not, but they will look different :-)
    Last edited by camel; 17th February 2007 at 17:44. Reason: write it less confusing

  19. #18
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: GraphicsView performance problems

    Quote Originally Posted by Gopala Krishna View Post
    The main problem is probably not "within" drawBackground but the method which calls it more often than necessary.
    That's why I mentioned update(). Try reducing the number of items (for example by simplifying the resistor item to consist of only one item), it may improve performance.

    I mean though we optimize drawBackground() , we need to find out why it is called many times than necessary.
    Funny... I have just taken a look at the profiling info you provided and it seems that it's not mentioned how many time drawBackground() is called. But it might be because of an incorrect compilation of the application (that's why you don't get detailed profiling information for drawBackground()).
    I feel this because of experimenting with larger boundingRect gave good performance - i.e lesser drawBackground calls.
    Increasing boundingRect() causes less modifications of the BSP tree while moving items.

    I tried by disabling indexing in mousePressEvent() when selectedItems().isEmpty() == false and enabling it again in release event. This didn't help much either
    Try disabling it entirely.

    Quote Originally Posted by camel View Post
    I did not say "positive effect", I just said "effect"
    OK

    If you do not use anti-aliasing for all horizontal and vertical lines (such as the resistors in this example) you will have two very different looking lines.
    I didn't say not to antialias the resistors but the grid. You won't notice any differences between lines then as all grid lines will be drawn in the same way and you can manipulate the contrast (as antialiasing blurs the edges of lines to reduce the contrast) by changing the colour of the pen.

  20. #19
    Join Date
    Jan 2006
    Posts
    128
    Thanked 28 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Wink Re: GraphicsView performance problems

    I just wanted to post my last version of the to-be-optimized app.

    Little changes I made, were for example:
    * making sure that it actually paints correctly (also when the view gets to big, and we start to receive negative coordinates ;-)
    * setting QGraphicsScene::NoIndex, with no obvious negative effects
    * noticing that it is actually faster (on X11) to draw the pixmap by hand a few times than to use a brush :-/
    * setting clipping to the exposed rect while painting the nodes

    The top timespenders in the app are basically all related to QRegion, i.e. collision detection and repainting. These can only be optimized...well indirectly...


    Anyways, if anybody would like to try out that version, here it is
    Qt Code:
    1. #include <QtGui>
    2. #include <cmath>
    3.  
    4.  
    5. namespace {
    6. static inline int gridFloor(const qreal& value)
    7. {
    8. if (value < 0) {
    9. return -1 * static_cast<int>(std::ceil(qAbs(value)));
    10. } else {
    11. return static_cast<int>(std::floor(value));
    12. }
    13. }
    14.  
    15. static inline int gridCeil(const qreal &value)
    16. {
    17. if (value < 0) {
    18. return -1 * static_cast<int>(std::floor(qAbs(value)));
    19. } else {
    20. return static_cast<int>(std::ceil(value));
    21. }
    22. }
    23.  
    24. static inline int nextSmallerGrid(const int &value, const int &gridSize)
    25. {
    26. if (value < 0) {
    27. const int absValue = qAbs(value);
    28. return -1 * (absValue + gridSize - (absValue % gridSize));
    29. } else {
    30. return value - (value % gridSize);
    31. }
    32. }
    33. }
    34.  
    35. class GridScene : public QGraphicsScene
    36. {
    37. public:
    38. GridScene(qreal x, qreal y, qreal w, qreal h)
    39. : QGraphicsScene(x, y, w, h)
    40. {
    41. setItemIndexMethod(QGraphicsScene::NoIndex);
    42. }
    43.  
    44. protected:
    45. void drawBackground(QPainter *painter, const QRectF &rect)
    46. {
    47. const int gridSize = 25;
    48.  
    49. if (backgroundCache.isNull()) {
    50. backgroundCache = QPixmap(gridSize, gridSize);
    51. const int middle = gridSize / 2;
    52. {
    53. QPainter backgroundPainter(&backgroundCache);
    54. backgroundPainter.setRenderHints(painter->renderHints());
    55. backgroundPainter.fillRect(QRect(0, 0, gridSize, gridSize), QBrush(Qt::white));
    56. backgroundPainter.setPen(QPen(Qt::darkGreen,0));
    57. backgroundPainter.setBrush(Qt::NoBrush);
    58. backgroundPainter.drawLine(0, middle, gridSize, middle);
    59. backgroundPainter.drawLine(middle, 0, middle, gridSize);
    60. }
    61. }
    62.  
    63. const int realLeft = gridFloor(rect.left());
    64. const int realRight = gridCeil(rect.right());
    65. const int realTop = gridFloor(rect.top());
    66. const int realBottom = gridCeil(rect.bottom());
    67.  
    68.  
    69. const int firstLeftGridLine = nextSmallerGrid(realLeft, gridSize);
    70. const int firstTopGridLine = nextSmallerGrid(realTop, gridSize);
    71.  
    72. QRectF cacheRect(0, 0, gridSize, gridSize);
    73. for (int x = firstLeftGridLine; x < realRight; x += gridSize) {
    74. for (int y = firstTopGridLine; y < realBottom; y += gridSize) {
    75. painter->drawPixmap(QRectF(x, y, gridSize, gridSize),
    76. backgroundCache,
    77. cacheRect);
    78. }
    79. }
    80. }
    81.  
    82. private:
    83. QPixmap backgroundCache;
    84. };
    85.  
    86. namespace {
    87. static inline QPainterPath constructNodeShape(const QRectF& elipseRect)
    88. {
    89. path.addEllipse(elipseRect);
    90. return path;
    91. }
    92. }
    93.  
    94. class Node : public QGraphicsItem
    95. {
    96. public:
    97. Node(QGraphicsItem *par = 0, QGraphicsScene *sc = 0)
    98. : QGraphicsItem(par,sc),
    99. elipseRect(-4.0, -4.0, 8.0, 8.0),
    100. elipsePath(constructNodeShape(QRectF(-3.0, -3.0, 2.0*3.0, 2.0*3.0))),
    101. elipseShape(constructNodeShape(elipseRect)),
    102. nodePen(Qt::darkRed),
    103. nodeBrush(Qt::NoBrush)
    104. {
    105. setFlags(0);
    106. setAcceptedMouseButtons(0);
    107. }
    108.  
    109. void paint(QPainter* p,const QStyleOptionGraphicsItem *o, QWidget *)
    110. {
    111. p->setPen(nodePen);
    112. p->setBrush(nodeBrush);
    113. p->setOpacity(1.0);
    114.  
    115. p->setClipRect(o->exposedRect);
    116. p->drawPath(elipsePath);
    117. }
    118.  
    119. QPainterPath shape() const
    120. {
    121. return elipseShape;
    122. }
    123.  
    124. QRectF boundingRect() const
    125. {
    126. return elipseRect;
    127. }
    128.  
    129. protected:
    130. const QRectF elipseRect;
    131. const QPainterPath elipsePath;
    132. const QPainterPath elipseShape;
    133. const QPen nodePen;
    134. const QBrush nodeBrush;
    135. };
    136.  
    137.  
    138. namespace {
    139. static inline QPainterPath constructResistorPath()
    140. {
    141. QPainterPath resistorPath;
    142. resistorPath.addRect(QRectF(-18.0, -9.0, 36.0, 18.0));
    143. resistorPath.moveTo(-27, 0);
    144. resistorPath.lineTo(-18, 0);
    145. resistorPath.moveTo(18, 0);
    146. resistorPath.lineTo(27, 0);
    147. return resistorPath;
    148. }
    149. }
    150.  
    151. class Resistor : public QGraphicsItem
    152. {
    153. public:
    154. Resistor(QGraphicsItem *par = 0, QGraphicsScene *scene = 0)
    155. : QGraphicsItem(par,scene),
    156. resistorPath(constructResistorPath()),
    157. boundingBox(resistorPath.boundingRect().adjusted(-1, -1, 1, 1)),
    158. resistorSelectedPen(Qt::darkBlue),
    159. resistorOpenPen(Qt::darkGray,1),
    160. resistorBrush(Qt::NoBrush)
    161. {
    162. setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable);
    163. // comment the following 4 lines to see the performance difference
    164. QGraphicsTextItem *t = new QGraphicsTextItem("R1 = 100k",this,scene);
    165. t->setPos(0,-35);
    166. Node * node = new Node(this,scene);
    167. node->setPos(QPointF(-30,0));
    168. node = new Node(this,scene);
    169. node->setPos(QPointF(30,0));
    170. }
    171.  
    172. void paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *)
    173. {
    174. if(!(o->state & QStyle::State_Open))
    175. p->setPen(resistorOpenPen);
    176. if(o->state & QStyle::State_Selected)
    177. p->setPen(resistorSelectedPen);
    178.  
    179. p->setClipRect( o->exposedRect );
    180. p->setBrush(resistorBrush);
    181. p->drawPath(resistorPath);
    182. }
    183.  
    184. QRectF boundingRect() const
    185. {
    186. return boundingBox;
    187. }
    188.  
    189. private:
    190. const QPainterPath resistorPath;
    191. const QRectF boundingBox;
    192. const QPen resistorSelectedPen;
    193. const QPen resistorOpenPen;
    194. const QBrush resistorBrush;
    195. };
    196.  
    197. int main(int argc,char *argv[])
    198. {
    199. QApplication app(argc,argv);
    200. GridScene scene(0,0,1024,768);
    201. for(int j = 2; j < 4; ++j)
    202. for(int i = 1; i <11; ++i)
    203. {
    204. Resistor *r = new Resistor(0,&scene);
    205. r->setPos(j*100, i * 50);
    206. }
    207. QGraphicsView *view = new QGraphicsView(&scene);
    208. view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    209. view->setDragMode(QGraphicsView::RubberBandDrag);
    210. view->show();
    211. return app.exec();
    212. }
    To copy to clipboard, switch view to plain text mode 


    Uiiii....that was fun... ;-)

  21. #20
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: GraphicsView performance problems

    Quote Originally Posted by wysota View Post
    That's why I mentioned update(). Try reducing the number of items (for example by simplifying the resistor item to consist of only one item), it may improve performance.
    This won't be possible since I need node to be independent of component.

    Quote Originally Posted by wysota View Post
    Funny... I have just taken a look at the profiling info you provided and it seems that it's not mentioned how many time drawBackground() is called. But it might be because of an incorrect compilation of the application (that's why you don't get detailed profiling information for drawBackground()).
    I'll post the proper one after recompilation today.

    Quote Originally Posted by wysota View Post
    Increasing boundingRect() causes less modifications of the BSP tree while moving items. Try disabling it entirely.
    Could the last post in this thread mean an improvement of performance in Qt4.3 with indexing enabled.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

Similar Threads

  1. Performance problems with overlapping qgraphicsitems
    By brjames in forum Qt Programming
    Replies: 13
    Last Post: 4th May 2008, 21:42
  2. QT GraphicsView Help
    By mistertoony in forum Qt Programming
    Replies: 15
    Last Post: 15th February 2007, 04:17
  3. Replies: 1
    Last Post: 4th October 2006, 16:05
  4. QT4 Plugins - problems, problems
    By NormanDunbar in forum Qt Programming
    Replies: 6
    Last Post: 9th May 2006, 15:39
  5. Increasing performance from Qtextedit, listview, etc?
    By taylor34 in forum Qt Programming
    Replies: 1
    Last Post: 16th February 2006, 10:20

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.