【发布时间】:2017-04-20 09:46:34
【问题描述】:
我只是想知道,wxWidget 是否比 qt 更快地满足我的特殊需求
简单的事情。我想像 Audacity 一样快速地绘制波形。我尝试了与 Audacity 中完全相同的方法,但我只提出了接近 Audacity 的性能,但仍然没有 Audacity 快。
我的想法是,Qt 对于具有难以置信的 性能/反馈的位图绘制来说不是最理想的。 来自 Audacity 文档:
画面更新混合使用了直接绘制和间接绘制 事件。更新图形显示的“正常”方法是调用 当某些东西使屏幕无效时的 Refresh() 方法。后来, 系统调用 OnPaint(),应用程序覆盖它以(重新)绘制 屏幕。在 wxWidgets 中,也可以直接绘制到屏幕上,无需 调用 Refresh() 而无需等待 OnPaint() 被调用。
因此,参考这一点,可以像使用 Qt 一样使用 wxwidget 绘制“更直接”,如果是这样,那真的更快吗? (我还没有发现使用 Qt 将“直接”绘制到帧缓冲区的任何可能性)
更新: 因为它被要求提供我的绘制代码(使用 qwt 和自己的 QwtPlotIntervalCurve 实现。在这种状态下不使用缓存/位图;随意提出优化建议;每个缩放阶段最多只能绘制 1024 个点)。此代码是针对最小值/最大值和 RMS 值完成的。
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();
}
更新 2: 现在分析附件:)
抱歉,这里是德语。
更新 3: 这就是东西的样子。这是一个没有任何噪音的正弦波。在绘制真实信号之前只需大约 1 或 2 个缩放阶段(如果可以,请尝试给我一个反馈,告诉我它对你来说是什么样的。那太好了,花了太多时间在“如何快速绘制波形和伟大的”)。是的,Audacity 阻止 rms 值大于最大/最小值。我稍后会添加。
不分离地绘制曲线会大大提高性能吗?
更新:
我将应用程序的处理器使用情况与“调整波形小部件的大小”期间的大胆程度进行了比较。在调整小部件大小时,Audacity 使用的处理器时间至少比我的应用程序少 10%。在此类操作中,我的计算机使用了 20%(我的 30%)。
【问题讨论】:
-
您是否配置文件您的代码和 Audacity 的代码,并发现差异在于底层工具包完成的位图绘制中的某个地方?如果是这样,请附上探查器结果。如果没有,请先配置文件。不要猜测。
-
无论如何:可以通过在小部件上设置
Qt::WA_PaintOnScreen标志直接在 X11 上的屏幕上绘制。这打破了其他的东西,不是最重要的优化(我们在 2016 年,双缓冲不再是问题),我认为这不会解决您的问题。 -
调查后绘制波形并不复杂。对于缩小,您只需将信号分成数据包,获取最大/最小值可选 rms,然后用垂直线绘制内容。这很清楚,应该运作良好,不是吗?我明白你的意思,对不起,我不能给你更多,因为我缺乏测试。在 Windows 系统下这甚至可能吗?
-
AFAIK 在 Visual Studio 中集成了一个 CPU 分析器,因此您可以从使用它开始。 (或 VTune,或其他一些 CPU 分析器)
-
看这段代码。也许我在这里做错了什么。但我知道这也应该已经可以正常工作了。然而,当我放大它时,它可能会导致一团糟。将来我会将此代码打包在一个自己的绘制语句中,用于最小/最大值和 RMS 值,而不是像现在分开的那样。是的,表现对其他人来说很棒,但与大胆相比,我认为它仍然可能会更好一些。感谢@peppe 的帮助和耐心!