PDA

View Full Version : Significant performance issue with high dpi



mwh
26th January 2024, 10:45
Hello,

I have a simple test program that plots 10 curves with 288 points each:

.h


class MyPlot : public QwtPlot
{
public:
void drawCanvas(QPainter* painter) override
{
const auto start = std::chrono::system_clock::now();
QwtPlot::drawCanvas(painter);
const auto end = std::chrono::system_clock::now();
const auto dt = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
qDebug().nospace() << "dt = " << dt.count() << "ms";
}
};


class QwtPlotClient : public QDialog
{
Q_OBJECT

public:
QwtPlotClient(QWidget* parent = nullptr);

private:
Ui::QwtPlotClientClass m_ui;
MyPlot* m_plot = nullptr;

};


.cpp


namespace
{
std::vector<QVector<QPointF>> createPlotData(int curveCount = 10, int pointsPerCurve = 288)
{
std::vector<QVector<QPointF>> result;
std::default_random_engine engine(std::random_device{}());
std::uniform_real_distribution<double> distribution(-100.0, 100.0);
for (int curveIndex = 0; curveIndex < curveCount; curveIndex++)
{
QVector<QPointF> curvePoints;
double x = 0.0;
for (int point = 0; point < pointsPerCurve; point++)
{
curvePoints << QPointF(x, distribution(engine));
x += 2.0;
}
result.push_back(curvePoints);
}
return result;
}
}

QwtPlotClient::QwtPlotClient(QWidget* parent)
: QDialog(parent),
m_plot(new MyPlot)
{
m_ui.setupUi(this);
m_ui.plotFrame->layout()->addWidget(m_plot);

const auto curvePointsList = createPlotData();
for (const auto& curvePoints : curvePointsList)
{
auto* curve = new QwtPlotCurve();
curve->setSamples(curvePoints);
curve->attach(m_plot);
}
}


In my main.cpp I define if the program uses high dpi settings or not:


int main(int argc, char *argv[])
{
// Comment the following 4 lines for NOT using high dpi settings
QCoreApplication::setAttribute(Qt::AA_EnableHighDp iScaling);
QGuiApplication::setHighDpiScaleFactorRoundingPoli cy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPi xmaps);
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLC ontexts);

QApplication a(argc, argv);
QwtPlotClient w;
w.show();
return a.exec();
}


As you can see I measure the time that the qwt plot needs for drawing the canvas (see MyPlot::drawCanvas). The results are (on my computer, you probably will have different absolute values):

High dpi settings off: ~25ms (for Debug) / ~10ms (for Release)
High dpi settings on: ~800ms ms (for Debug) / ~570ms (for Release)

I tested this with Qt 5.14.0 and Qwt 6.2.1. (I also tested with Qwt 6.2.0 and the numbers for high dpi settings on are even a bit larger.)

Is there anything I can do? Or do you plan to "fix" this in the near future?

Uwe
26th January 2024, 12:52
Qwt can do some algorithmic workarounds to avoid doing unnecessary stuff, but in the end it is Qt that is doing the rendering. So I'm afraid there is not much Qwt can do here.

In case you are on X11 I recommend to use the hardware accelerated X11 paint engine. ( export QT_XCB_NATIVE_PAINTING=1 ) instead of the homebrew raster paint engine, that is enabled as default.
On Windows you can go with OpenGL, but according to the docs it does not seem to support AA_EnableHighDpiScaling.

By the way: did you check which of the flags is hurting most ?

Uwe

mwh
29th January 2024, 06:53
The flag that hurts most is Qt::AA_EnableHighDpiScaling. The other three flags seem to have almost no effect on the performance at all.

Thank you for your reply and explanation. Since we plan to migrate to Qt6.5 in the near future and our Qt expert mentiones that a lot of improvements were made for high dpi in Qt6, we hope that this will mitigate the bad render performance for qwt, too.

Uwe
29th January 2024, 10:56
we hope that this will mitigate the bad render performance.
I would be surprised if this would be the case. In the end the raster paint engine has to fill significantly more pixels, where the majority will be found somehow by interpolating - what is simply way more expensive.
IMHO your options are not to enable AA_EnableHighDpiScaling or to avoid the raster paint engine.

HTH,
Uwe