[Qt-interest] QPainter::drawLine performances

Jason H scorp1us at yahoo.com
Thu Jul 1 16:27:07 CEST 2010


Line drawing sucks. (Technical term, sucks CPU)

Even 3D cards have a problem with it. As a mater of fact the NVIDIA QuadroFX(sp?) professional cards have hardware support for line drawing. You had to add/remove two resistors to the consumer line of the card to make it the 'pro' grade which got you hardware line computation. You're also using anti aliasing which will suck it down. In contract 3D textures are very light weight, so wire frame models are actually worse than the real thing in almost every case. 

I think your only option is to manually cull the lines for use tin he GV.  See the 10000 chips example for ideas on how to optimize for level of detail too.




________________________________
From: Laurent Astart <laurent.astart at gmail.com>
To: qt-interest at trolltech.com
Sent: Thu, July 1, 2010 5:32:34 AM
Subject: [Qt-interest] QPainter::drawLine performances

Hi,

I'm new to the list but I'm using Qt for some time now. Those days I stumbled onto a problem which puzzled me. I'm working on a big software using Qt 4.5.3 and experienced performances problems. Eventually I found what the problem is and builded an example to try some things. I created a widget (RenderArea) and my problem is entirely contained within the paintEvent. Here is the function :

void RenderArea::paintEvent(QPaintEvent *event)
{
  QRect 
rect(QPoint(0, 0), QPoint(640, 480));
  QPainterPath path;
  
path.addRect(rect);

  QPainter painter(this);
  
painter.setPen(QPen(Qt::blue, 3, Qt::DashLine, Qt::SquareCap, 
Qt::RoundJoin));
  painter.setBackground(QBrush(QColor(255, 255, 
255), Qt::SolidPattern));
  
painter.setRenderHint(QPainter::Antialiasing, true);
  
painter.setClipRect(rect);
  //painter.setClipPath(path);
  bool 
hasClip = painter.hasClipping();

  painter.eraseRect(rect);

  CHighResTimeCounter counter;
  counter.Start();
  
painter.drawLine(QPoint(-64000000, -48000000), QPoint(64000000, 
48000000));
  int msCount = counter.Count();

  QString perf = 
QString("Perf: %1 ms (clipping %2)").arg(msCount).arg(hasClip ? 
"enabled" : "disabled");
  emit PaintStatus(perf);
}

Whatever I do (clipping or not, rectangle or path, etc.), the render time is around 5500 ms. When I reduce the line size by ten times in each direction, I decrease the render time by ten. Moreover, when the line is entirely outside the widget view, the render time is the same. Even when the bounding box of the line doesn't intersect the widget view, the render time is the same. I suspect the drawLine function to draw every pixel, then reject the ones outside the port or the clipping.

My question is : Is there a way to reduce the drawing to a couple of ms without surcharging the drawLine function ? I'd like to avoid calling a precomputing function on my lines. The reasons are :
1) A lot of code is involved, but I use only one painter. It would be simpler to configure it properly.
2) I'm not sure I will be able to create a good intersection function, especially with dashed/dotted lines and antialiasing.

For the ones curious about why I'm trying to draw huge lines in comparison of widget size, I'm working on a cartographic software. Some vector data are sometimes huge (just imagine maritime routes or airways) and the user sometimes zoom to a hundred meters zone. In this case, a 100 Nm line is huge compared to the widget size.

Thanks in advance for your help.
Laurent



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20100701/b5d80bcc/attachment.html 


More information about the Qt-interest-old mailing list