Improve graph HighDPI scaling (#1963)

This commit is contained in:
karliss 2019-12-22 20:56:33 +02:00 committed by GitHub
parent 4cce7cf22c
commit 550d079f14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 21 deletions

View File

@ -186,6 +186,12 @@ int main(int argc, char *argv[])
initializeSettings(); initializeSettings();
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // needed for QtWebEngine inside Plugins
#ifdef Q_OS_WIN
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
#endif
CutterApplication a(argc, argv); CutterApplication a(argc, argv);

View File

@ -178,7 +178,7 @@ qreal GraphView::getCacheDevicePixelRatioF()
QSize GraphView::getRequiredCacheSize() QSize GraphView::getRequiredCacheSize()
{ {
return viewport()->size() * getRequiredCacheDevicePixelRatioF(); return viewport()->size() * qhelpers::devicePixelRatio(this);
} }
qreal GraphView::getRequiredCacheDevicePixelRatioF() qreal GraphView::getRequiredCacheDevicePixelRatioF()
@ -213,16 +213,15 @@ void GraphView::paintEvent(QPaintEvent *)
auto gl = glWidget->context()->extraFunctions(); auto gl = glWidget->context()->extraFunctions();
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, cacheFBO); gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, cacheFBO);
gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glWidget->defaultFramebufferObject()); gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glWidget->defaultFramebufferObject());
auto dpr = qhelpers::devicePixelRatio(this);
gl->glBlitFramebuffer(0, 0, cacheSize.width(), cacheSize.height(), gl->glBlitFramebuffer(0, 0, cacheSize.width(), cacheSize.height(),
0, 0, viewport()->width(), viewport()->height(), 0, 0, viewport()->width() * dpr, viewport()->height() * dpr,
GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_COLOR_BUFFER_BIT, GL_NEAREST);
glWidget->doneCurrent(); glWidget->doneCurrent();
#endif #endif
} else { } else {
QRectF target(0.0, 0.0, viewport()->width(), viewport()->height());
QRectF source(0.0, 0.0, pixmap.width(), pixmap.height());
QPainter p(viewport()); QPainter p(viewport());
p.drawPixmap(target, pixmap, source); p.drawPixmap(QPoint(0, 0), pixmap);
} }
} }
@ -253,7 +252,7 @@ void GraphView::addViewOffset(QPoint move, bool emitSignal)
void GraphView::paintGraphCache() void GraphView::paintGraphCache()
{ {
#ifndef CUTTER_NO_OPENGL_GRAPH #ifndef CUTTER_NO_OPENGL_GRAPH
QOpenGLPaintDevice *paintDevice = nullptr; std::unique_ptr<QOpenGLPaintDevice> paintDevice;
#endif #endif
QPainter p; QPainter p;
if (useGL) { if (useGL) {
@ -261,6 +260,7 @@ void GraphView::paintGraphCache()
auto gl = QOpenGLContext::currentContext()->functions(); auto gl = QOpenGLContext::currentContext()->functions();
bool resizeTex = false; bool resizeTex = false;
QSize sizeNeed = getRequiredCacheSize();
if (!cacheTexture) { if (!cacheTexture) {
gl->glGenTextures(1, &cacheTexture); gl->glGenTextures(1, &cacheTexture);
gl->glBindTexture(GL_TEXTURE_2D, cacheTexture); gl->glBindTexture(GL_TEXTURE_2D, cacheTexture);
@ -270,13 +270,13 @@ void GraphView::paintGraphCache()
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
resizeTex = true; resizeTex = true;
} else if (cacheSize != viewport()->size()) { } else if (cacheSize != sizeNeed) {
gl->glBindTexture(GL_TEXTURE_2D, cacheTexture); gl->glBindTexture(GL_TEXTURE_2D, cacheTexture);
resizeTex = true; resizeTex = true;
} }
if (resizeTex) { if (resizeTex) {
cacheSize = viewport()->size(); cacheSize = sizeNeed;
gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport()->width(), viewport()->height(), 0, GL_RGBA, gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cacheSize.width(), cacheSize.height(), 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr); GL_UNSIGNED_BYTE, nullptr);
gl->glGenFramebuffers(1, &cacheFBO); gl->glGenFramebuffers(1, &cacheFBO);
gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO); gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO);
@ -285,33 +285,29 @@ void GraphView::paintGraphCache()
gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO); gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO);
} }
gl->glViewport(0, 0, viewport()->width(), viewport()->height()); gl->glViewport(0, 0, viewport()->width(), viewport()->height());
gl->glClearColor(1.0f, 0.0f, 0.0f, 1.0f); gl->glClearColor(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF(), 1.0f);
gl->glClear(GL_COLOR_BUFFER_BIT); gl->glClear(GL_COLOR_BUFFER_BIT);
paintDevice = new QOpenGLPaintDevice(viewport()->size()); paintDevice.reset(new QOpenGLPaintDevice(cacheSize));
p.begin(paintDevice); p.begin(paintDevice.get());
#endif #endif
} else { } else {
auto dpr = qhelpers::devicePixelRatio(this); auto dpr = qhelpers::devicePixelRatio(this);
pixmap = QPixmap(getRequiredCacheSize()); pixmap = QPixmap(getRequiredCacheSize() * dpr);
pixmap.setDevicePixelRatio(dpr); pixmap.setDevicePixelRatio(dpr);
pixmap.fill(backgroundColor);
p.begin(&pixmap); p.begin(&pixmap);
p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing);
p.setViewport(this->viewport()->rect());
} }
paint(p, offset, this->viewport()->rect(), current_scale); paint(p, offset, this->viewport()->rect(), current_scale);
p.end(); p.end();
#ifndef CUTTER_NO_OPENGL_GRAPH
delete paintDevice;
#endif
} }
void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, bool interactive) void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, bool interactive)
{ {
QPointF offsetF(offset.x(), offset.y()); QPointF offsetF(offset.x(), offset.y());
p.setBrush(backgroundColor);
p.drawRect(viewport);
p.setBrush(Qt::black); p.setBrush(Qt::black);
int render_width = viewport.width(); int render_width = viewport.width();
@ -320,7 +316,7 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b
// window - rectangle in logical coordinates // window - rectangle in logical coordinates
QRect window = QRect(offset, QSize(qRound(render_width / scale), qRound(render_height / scale))); QRect window = QRect(offset, QSize(qRound(render_width / scale), qRound(render_height / scale)));
p.setWindow(window); p.setWindow(window);
QRect windowF(window.x(), window.y(), window.width(), window.height()); QRectF windowF(window.x(), window.y(), window.width(), window.height());
for (auto &blockIt : blocks) { for (auto &blockIt : blocks) {
GraphBlock &block = blockIt.second; GraphBlock &block = blockIt.second;
@ -346,7 +342,7 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b
QPen pen(ec.color); QPen pen(ec.color);
pen.setStyle(ec.lineStyle); pen.setStyle(ec.lineStyle);
pen.setWidthF(pen.width() * ec.width_scale); pen.setWidthF(pen.width() * ec.width_scale);
if (scale_thickness_multiplier * ec.width_scale > 1.01 && pen.widthF() * scale < 2) { if (scale_thickness_multiplier && ec.width_scale > 1.01 && pen.widthF() * scale < 2) {
pen.setWidthF(ec.width_scale / scale); pen.setWidthF(ec.width_scale / scale);
} }
if (pen.widthF() * scale < 2) { if (pen.widthF() * scale < 2) {
@ -359,6 +355,8 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b
p.setPen(pen); p.setPen(pen);
auto drawArrow = [&](QPointF tip, QPointF dir) { auto drawArrow = [&](QPointF tip, QPointF dir) {
pen.setWidth(0);
p.setPen(pen);
QPolygonF arrow; QPolygonF arrow;
arrow << tip; arrow << tip;
QPointF dy(-dir.y(), dir.x()); QPointF dy(-dir.y(), dir.x());
@ -402,6 +400,7 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b
void GraphView::saveAsBitmap(QString path, const char *format) void GraphView::saveAsBitmap(QString path, const char *format)
{ {
QImage image(width, height, QImage::Format_RGB32); QImage image(width, height, QImage::Format_RGB32);
image.fill(backgroundColor);
QPainter p; QPainter p;
p.begin(&image); p.begin(&image);
paint(p, QPoint(0, 0), image.rect(), 1.0, false); paint(p, QPoint(0, 0), image.rect(), 1.0, false);