diff options
author | Laszlo Agocs <laszlo.agocs@digia.com> | 2014-10-22 10:27:46 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@digia.com> | 2014-10-22 12:32:47 +0200 |
commit | 9b965f3fa0899e27667aba4c437206fdf7a14969 (patch) | |
tree | 959dc767ff968be55bd35ccd55b3262b22acaafd /src/quick | |
parent | d8447fd1b95e6a3f85e7aaed74755e95ecc91dc8 (diff) |
Fix disfunctional QQuickRenderControl with multiple screens
Having a retina and non-retina screen connected resulted in getting
no output from QQuickRenderControl and QQuickWidget on the
non-retina screen.
This is caused by the fact that Quick is blindly calling
QWindow::devicePixelRatio(). This approach is wrong when using
QQuickRenderControl since the QQuickWindow does not have an actual
native window and so devicePixelRatio() merely returns some default value
which will definitely be wrong for one of the screens.
The patch fixes the problem by introducing
QQuickWindow::effectiveDevicePixelRatio(), which, via
QQuickRenderControl::renderWindowFor, supports the redirected case too.
Task-number: QTBUG-42114
Change-Id: I057e01f0a00758dde438fc9b10af3a435b06bb0b
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickimagebase.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickrendercontrol.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource.cpp | 4 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 23 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 13 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 2 |
9 files changed, 40 insertions, 12 deletions
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp index 5ec3e81727..1a5d115a3c 100644 --- a/src/quick/items/qquickimagebase.cpp +++ b/src/quick/items/qquickimagebase.cpp @@ -206,7 +206,7 @@ void QQuickImageBase::load() options |= QQuickPixmap::Cache; d->pix.clear(this); - const qreal targetDevicePixelRatio = (window() ? window()->devicePixelRatio() : qApp->devicePixelRatio()); + const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio()); d->devicePixelRatio = 1.0; QUrl loadUrl = d->url; diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 79db80595b..7ccd3a0fb4 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -318,7 +318,7 @@ QImage QQuickRenderControl::grab() return QImage(); render(); - QImage grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->devicePixelRatio(), false, false); + QImage grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false); return grabContent; } diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 52e5ba2464..ccff98828c 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -628,7 +628,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint // Crate large textures on high-dpi displays. if (sourceItem()) - textureSize *= d->window->devicePixelRatio(); + textureSize *= d->window->effectiveDevicePixelRatio(); const QSize minTextureSize = d->sceneGraphContext()->minimumFBOSize(); // Keep power-of-two by doubling the size. @@ -637,7 +637,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint while (textureSize.height() < minTextureSize.height()) textureSize.rheight() *= 2; - m_texture->setDevicePixelRatio(d->window->devicePixelRatio()); + m_texture->setDevicePixelRatio(d->window->effectiveDevicePixelRatio()); m_texture->setSize(textureSize); m_texture->setRecursive(m_recursive); m_texture->setFormat(GLenum(m_format)); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 4ec901ceb4..f6c1412aff 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -365,7 +365,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) emit q->beforeRendering(); runAndClearJobs(&beforeRenderingJobs); int fboId = 0; - const qreal devicePixelRatio = q->devicePixelRatio(); + const qreal devicePixelRatio = q->effectiveDevicePixelRatio(); renderer->setDeviceRect(QRect(QPoint(0, 0), size * devicePixelRatio)); if (renderTargetId) { fboId = renderTargetId; @@ -374,7 +374,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) renderer->setViewportRect(QRect(QPoint(0, 0), size * devicePixelRatio)); } renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size)); - renderer->setDevicePixelRatio(q->devicePixelRatio()); + renderer->setDevicePixelRatio(devicePixelRatio); context->renderNextFrame(renderer, fboId); emit q->afterRendering(); @@ -3160,7 +3160,7 @@ QImage QQuickWindow::grabWindow() d->syncSceneGraph(); d->renderSceneGraph(size()); - QImage image = qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false); + QImage image = qt_gl_read_framebuffer(size() * effectiveDevicePixelRatio(), false, false); d->cleanupNodesOnShutdown(); d->context->invalidate(); context.doneCurrent(); @@ -3923,6 +3923,23 @@ void QQuickWindow::runJobsAfterSwap() d->runAndClearJobs(&d->afterSwapJobs); } +/*! + * Returns the device pixel ratio for this window. + * + * This is different from QWindow::devicePixelRatio() in that it supports + * redirected rendering via QQuickRenderControl. When using a + * QQuickRenderControl, the QQuickWindow is often not created, meaning it is + * never shown and there is no underlying native window created in the + * windowing system. As a result, querying properties like the device pixel + * ratio cannot give correct results. Use this function instead. + * + * \sa QWindow::devicePixelRatio() + */ +int QQuickWindow::effectiveDevicePixelRatio() const +{ + QWindow *w = QQuickRenderControl::renderWindowFor(const_cast<QQuickWindow *>(this)); + return w ? w->devicePixelRatio() : devicePixelRatio(); +} #include "moc_qquickwindow.cpp" diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index b52d6b807e..3cac691963 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -142,6 +142,8 @@ public: void scheduleRenderJob(QRunnable *job, RenderStage schedule); + int effectiveDevicePixelRatio() const; + Q_SIGNALS: void frameSwapped(); Q_REVISION(2) void openglContextCreated(QOpenGLContext *context); diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 802c92be9f..b30a504da9 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -41,6 +41,7 @@ #include <private/qfontengine_p.h> #include <private/qopenglextensions_p.h> +#include <QtQuick/qquickwindow.h> #include <QtQuick/private/qsgtexture_p.h> #include <private/qrawfont_p.h> @@ -350,8 +351,16 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat) : QFontEngine::Format_A32; } - qreal devicePixelRatio = ctx->surface()->surfaceClass() == QSurface::Window ? - static_cast<QWindow *>(ctx->surface())->devicePixelRatio() : ctx->screen()->devicePixelRatio(); + qreal devicePixelRatio; + if (ctx->surface()->surfaceClass() == QSurface::Window) { + QWindow *w = static_cast<QWindow *>(ctx->surface()); + if (QQuickWindow *qw = qobject_cast<QQuickWindow *>(w)) + devicePixelRatio = qw->effectiveDevicePixelRatio(); + else + devicePixelRatio = w->devicePixelRatio(); + } else { + devicePixelRatio = ctx->screen()->devicePixelRatio(); + } QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio); if (!fontEngine->supportsTransformation(glyphCacheTransform)) diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index f2586b1e40..c66915d19d 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -372,7 +372,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) renderTime = renderTimer.nsecsElapsed(); if (data.grabOnly) { - grabContent = qt_gl_read_framebuffer(window->size() * window->devicePixelRatio(), false, false); + grabContent = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), false, false); data.grabOnly = false; } diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 7ac5f0a921..155b52b31a 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -417,7 +417,7 @@ bool QSGRenderThread::event(QEvent *e) QQuickWindowPrivate::get(window)->renderSceneGraph(windowSize); qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- grabbing result"; - *ce->image = qt_gl_read_framebuffer(windowSize * window->devicePixelRatio(), false, false); + *ce->image = qt_gl_read_framebuffer(windowSize * window->effectiveDevicePixelRatio(), false, false); } qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result"; waitCondition.wakeOne(); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 10eba74607..070d6b82fd 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -286,7 +286,7 @@ QImage QSGWindowsRenderLoop::grab(QQuickWindow *window) d->syncSceneGraph(); d->renderSceneGraph(window->size()); - QImage image = qt_gl_read_framebuffer(window->size() * window->devicePixelRatio(), false, false); + QImage image = qt_gl_read_framebuffer(window->size() * window->effectiveDevicePixelRatio(), false, false); return image; } |