2
votes

I'm just wondering, whether wxWidget is for my special needs faster than qt

Simple thing. I want to draw waveforms as fast as Audacity. I tried quite the same approach like in Audacity but I've come only up with a performance which comes near to Audacity, but still isn't as fast as Audacity.

My thought is, that Qt is suboptimal for bitmap drawing with incredible performance/feedback. From the Audacity documentation:

The screen update uses a mixture of direct drawing and indirect paint events. The "normal" way to update a graphical display is to call the Refresh() method when something invalidates the screen. Later, the system calls OnPaint(), which the application overrides to (re)draw the screen. In wxWidgets, you can also draw directly to the screen without calling Refresh() and without waiting for OnPaint() to be called.

So refering to this, it's possible to draw "more direct" with wxwidget as I could with Qt and if so is that really faster? (I haven't found any posibility for drawing "direct" to the framebufferwith Qt)

UPDATE: Because it was asked for I give my draw code (using qwt with own implementation of QwtPlotIntervalCurve. In this state without caching/bitmap usage; Feel free to suggest optimizations; There will only be a maximum of 1024 points drawn every zoom stage). This code is done for the min / max values and for the RMS values.

void WaveformWidget::QwtPlotIntervalCurveFast::drawTube(QPainter * painter, const QwtScaleMap & xMap, const QwtScaleMap & yMap, const QRectF & canvasRect, int from, int to) const
{
  painter->save(); //Not best performance but for some people it suits.
  painter->setPen(this->pen()); //Feel free to use it.
  std::vector<QwtIntervalSample> draw = getToDrawData(xMap, yMap);
  double x, y1, y2;
  std::vector<QLine> lines(draw.size());
  for (int i = 0; i < draw.size(); i++) {
      x = xMap.transform(draw[i].value);
      y1 = yMap.transform(draw[i].interval.minValue());
      y2 = yMap.transform(draw[i].interval.maxValue());
      lines[i] = (QLine(x, y1, x, y2));
  }
  painter->drawLines(lines.data(), lines.size());
  painter->restore();
}

UPDATE 2: Now profiling attachment :)

Sorry for it's being in german.

CPU usage during resize of waveform (those tiny peaks)

Update 3: That's how the stuff looks like. It's a sin wave without any noise. Simply about 1 or 2 zoom stages before the real signal would be drawn( if you can please try to give me a feedback on how it's looking like for you. That would be great, spent too much time on "how to draw waveforms fast and great"). And yes Audacity stops rms values from being greater than max/min values. I'll add that later.

enter image description here

Would drawing the curves unseperated boost the performance that much?

Update:

I compared the processor usage of my application to audacity during "resizing the waveform widget". Audacity does at least use 10 % less processor time than my application during resizing the widget. The total usage of audacity during such operations lies with my computer at 20 % (mine 30%).

1
Did you profile your code and Audacity's, and found the difference to be somewhere in the bitmap painting done by the underlying toolkits? If so, attach the profiler results. If not, profile first. Don't double guess.peppe
Regardless: it is possible to paint directly to the screen on X11 by setting the Qt::WA_PaintOnScreen flag on your widget. Which breaks other things, is not the most important optimization (we're in 2016, double buffering is not a problem any more), and which I don't believe will fix your issue.peppe
Drawing waveforms after investigation isn't that complicated. For zooming out you just divide the signal into packets, get max/min values optional rms and then draw the stuff with vertical lines. That's quite clear and should work well, shouldn't it? I do see your point, I'm sorry, that I cannot give you more than this because my lack of tests. Is that even possible unter Windows Systems?realvictorprm
AFAIK there's a CPU profiler integrated in Visual Studio, so you could start by using that. (Or VTune, or some other CPU profiler)peppe
Look at this code. Maybe I'm doing something already here wrong. But I understood that this should already work fine too. However as more as I zoom in it can result in a mess. In future I'll pack this code in a own draw statement for both min/max values and RMS values and not like now seperated. Yes performance is for other people great, but in comparison to audacity it still could be a bit better in my opinion. Thank's for help and patience @peppe !realvictorprm

1 Answers

0
votes

Poorly I can only answer this question for windows systems.

I encountered that wxWidgets is in this case faster than qt.

What I think causes this is that painting can be applied independently of a paint event and painting is done directly on the screen. Furthermore wxWidgets can use os specific acceleration if double buffering is wished (e.g. a native bitmap).

In contrast, Qt uses double buffering which (so far I know) cannot be disabled on Windows system (however on linux systems it can).

Because this question is only answered for Windows system I do not accept it.

PS: If someone could make some tests for Linux systems, please do and or contact me, I will provide the code.