diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2014-10-29 10:48:54 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2014-10-29 10:48:54 +0100 |
commit | 4e33b069c426c975319d91e11223114fd0d8ad40 (patch) | |
tree | d73e1251bc313b7303fdb000c0789cdfb4c7bb1f /src/quick/scenegraph | |
parent | d9e70d1a49af347f79db7e64bdd8e2e8083a77b5 (diff) | |
parent | 05d8ffb4dff5e693967c8ee7cee6d6158eadccbd (diff) |
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts:
src/quick/items/qquickaccessibleattached_p.h
src/quick/items/qquickwindow.cpp
src/quick/scenegraph/qsgthreadedrenderloop.cpp
Change-Id: I8bf07487a75f9d1b0d6efa5914dd06875fc9654d
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 18 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 36 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 21 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 24 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/shaders/styledtext.vert | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/shaders/styledtext_core.vert | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/shaders/textmask.vert | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/shaders/textmask_core.vert | 3 |
10 files changed, 85 insertions, 39 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index ac45cf70db..ef125e07a9 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -228,6 +228,7 @@ void qsg_dumpShadowRoots(BatchRootInfo *i, int indent) void qsg_dumpShadowRoots(Node *n) { +#ifndef QT_NO_DEBUG_OUTPUT static int indent = 0; ++indent; @@ -247,6 +248,9 @@ void qsg_dumpShadowRoots(Node *n) qsg_dumpShadowRoots(*child); --indent; +#else + Q_UNUSED(n) +#endif } Updater::Updater(Renderer *r) @@ -1073,6 +1077,7 @@ void Renderer::turnNodeIntoBatchRoot(Node *node) void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) { +#ifndef QT_NO_DEBUG_OUTPUT if (Q_UNLIKELY(debug_change())) { QDebug debug = qDebug(); debug << "dirty:"; @@ -1100,7 +1105,7 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) else debug << node; } - +#endif // As this function calls nodeChanged recursively, we do it at the top // to avoid that any of the others are processed twice. if (state & QSGNode::DirtySubtreeBlocked) { @@ -1847,7 +1852,7 @@ void Renderer::uploadBatch(Batch *b) e = e->nextInBatch; } } - +#ifndef QT_NO_DEBUG_OUTPUT if (Q_UNLIKELY(debug_upload())) { const char *vd = b->vbo.data; qDebug() << " -- Vertex Data, count:" << b->vertexCount << " - " << g->sizeOfVertex() << "bytes/vertex"; @@ -1880,11 +1885,11 @@ void Renderer::uploadBatch(Batch *b) } const quint16 *id = -#ifdef QSG_SEPARATE_INDEX_BUFFER +# ifdef QSG_SEPARATE_INDEX_BUFFER (const quint16 *) (b->ibo.data); -#else +# else (const quint16 *) (b->vbo.data + b->drawSets.at(0).indices); -#endif +# endif { QDebug iDump = qDebug(); iDump << " -- Index Data, count:" << b->indexCount; @@ -1900,6 +1905,7 @@ void Renderer::uploadBatch(Batch *b) qDebug() << " -- DrawSet: indexCount:" << s.indexCount << " vertices:" << s.vertices << " z:" << s.zorders << " indices:" << s.indices; } } +#endif // QT_NO_DEBUG_OUTPUT unmap(&b->vbo); #ifdef QSG_SEPARATE_INDEX_BUFFER @@ -2121,6 +2127,7 @@ void Renderer::renderMergedBatch(const Batch *batch) Element *e = batch->first; Q_ASSERT(e); +#ifndef QT_NO_DEBUG_OUTPUT if (Q_UNLIKELY(debug_render())) { QDebug debug = qDebug(); debug << " -" @@ -2139,6 +2146,7 @@ void Renderer::renderMergedBatch(const Batch *batch) debug << "opacity:" << e->node->inheritedOpacity(); batch->uploadedThisFrame = false; } +#endif QSGGeometryNode *gn = e->node; diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index b87ab3686f..2a0fae9f72 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -162,7 +162,6 @@ public: , m_vsync(0) , m_mode(VSyncMode) , m_bad(0) - , m_reallyBad(0) , m_good(0) { QScreen *screen = QGuiApplication::primaryScreen(); @@ -185,6 +184,7 @@ public: { m_time = 0; m_timer.start(); + m_wallTime.restart(); QAnimationDriver::start(); } @@ -192,7 +192,7 @@ public: { return m_mode == VSyncMode ? qint64(m_time) - : QAnimationDriver::elapsed(); + : qint64(m_time) + m_wallTime.elapsed(); } void advance() Q_DECL_OVERRIDE @@ -217,25 +217,22 @@ public: m_time += m_vsync; - if (delta > m_vsync * 5) { - ++m_reallyBad; - ++m_bad; - } else if (delta > m_vsync * 1.25) { - ++m_bad; + if (delta > m_vsync * 1.25) { + m_lag += (delta / m_vsync); + m_bad++; + // We tolerate one bad frame without resorting to timer based. This is + // done to cope with a slow loader frame followed by smooth animation. + // However, on the second frame with massive lag, we switch. + if (m_lag > 10 && m_bad > 2) { + m_mode = TimerMode; + qCDebug(QSG_LOG_INFO, "animation driver switched to timer mode"); + m_wallTime.restart(); + } } else { - // reset counters on a good frame. - m_reallyBad = 0; + m_lag = 0; m_bad = 0; } - // rational for the 3 and 50. If we have several really bad frames - // in a row, that would indicate a huge performance problem and we should - // switch right away. For the case of m_bad, we're a bit more tolerant. - if (m_reallyBad > 3 || m_bad > 50) { - m_mode = TimerMode; - qCDebug(QSG_LOG_INFO, "animation driver switched to timer mode"); - } - } else { if (delta < 1.25 * m_vsync) { ++m_good; @@ -249,6 +246,8 @@ public: if (m_good > 10 && !qsg_useConsistentTiming()) { m_time = elapsed(); m_mode = VSyncMode; + m_bad = 0; + m_lag = 0; qCDebug(QSG_LOG_INFO, "animation driver switched to vsync mode"); } } @@ -260,8 +259,9 @@ public: float m_vsync; Mode m_mode; QElapsedTimer m_timer; + QElapsedTimer m_wallTime; + float m_lag; int m_bad; - int m_reallyBad; int m_good; }; diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 802c92be9f..5cca474ea1 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> @@ -58,6 +59,21 @@ static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity) return QVector4D(c.x() * o, c.y() * o, c.z() * o, o); } +static inline int qsg_device_pixel_ratio(QOpenGLContext *ctx) +{ + int devicePixelRatio = 1; + 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(); + } + return devicePixelRatio; +} + class QSGTextMaskShader : public QSGMaterialShader { public: @@ -101,6 +117,7 @@ void QSGTextMaskShader::initialize() m_matrix_id = program()->uniformLocation("matrix"); m_color_id = program()->uniformLocation("color"); m_textureScale_id = program()->uniformLocation("textureScale"); + program()->setUniformValue("dpr", (float) qsg_device_pixel_ratio(QOpenGLContext::currentContext())); } void QSGTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) @@ -350,8 +367,8 @@ 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 = qsg_device_pixel_ratio(ctx); + 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 962b0f866d..ecfbe0323c 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -41,6 +41,7 @@ #include <QtCore/private/qabstractanimation_p.h> #include <QtGui/QOpenGLContext> +#include <QtGui/QOffscreenSurface> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> @@ -274,15 +275,30 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) m_windows.remove(window); hide(window); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); - if (gl) - gl->makeCurrent(window); + + bool current = false; + QScopedPointer<QOffscreenSurface> offscreenSurface; + if (gl) { + QSurface *surface = window; + // There may be no platform window if the window got closed. + if (!window->handle()) { + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(gl->format()); + offscreenSurface->create(); + surface = offscreenSurface.data(); + } + current = gl->makeCurrent(surface); + } + if (Q_UNLIKELY(!current)) + qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; + d->cleanupNodesOnShutdown(); if (m_windows.size() == 0) { rc->invalidate(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete gl; gl = 0; - } else if (gl && window == gl->surface()) { + } else if (gl && window == gl->surface() && current) { gl->doneCurrent(); } } @@ -358,7 +374,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); 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 5ed42d5e1d..5218552427 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -407,7 +407,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(); @@ -545,6 +545,11 @@ void QSGRenderThread::syncAndRender() qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- updatePending, doing sync"; sync(exposeRequested); } +#ifndef QSG_NO_RENDER_TIMING + if (profileFrames) + syncTime = threadTimer.nsecsElapsed(); +#endif + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); if (!syncResultedInChanges && !repaintRequested) { qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- no changes, render aborted"; @@ -554,10 +559,6 @@ void QSGRenderThread::syncAndRender() return; } - if (profileFrames) - syncTime = threadTimer.nsecsElapsed(); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); - qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering started"; diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 56626e8e42..469cd1d21b 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -290,7 +290,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; } diff --git a/src/quick/scenegraph/shaders/styledtext.vert b/src/quick/scenegraph/shaders/styledtext.vert index 14fefc2564..7001bbc262 100644 --- a/src/quick/scenegraph/shaders/styledtext.vert +++ b/src/quick/scenegraph/shaders/styledtext.vert @@ -1,6 +1,7 @@ uniform highp mat4 matrix; uniform highp vec2 textureScale; uniform highp vec2 shift; +uniform highp float dpr; attribute highp vec4 vCoord; attribute highp vec2 tCoord; @@ -12,5 +13,5 @@ void main() { sampleCoord = tCoord * textureScale; shiftedSampleCoord = (tCoord - shift) * textureScale; - gl_Position = matrix * floor(vCoord + 0.5); + gl_Position = matrix * floor(vCoord * dpr + 0.5) / dpr; } diff --git a/src/quick/scenegraph/shaders/styledtext_core.vert b/src/quick/scenegraph/shaders/styledtext_core.vert index 65bdb66814..c522877bb3 100644 --- a/src/quick/scenegraph/shaders/styledtext_core.vert +++ b/src/quick/scenegraph/shaders/styledtext_core.vert @@ -9,10 +9,11 @@ out vec2 shiftedSampleCoord; uniform mat4 matrix; uniform vec2 textureScale; uniform vec2 shift; +uniform float dpr; void main() { sampleCoord = tCoord * textureScale; shiftedSampleCoord = (tCoord - shift) * textureScale; - gl_Position = matrix * round(vCoord); + gl_Position = matrix * round(vCoord * dpr) / dpr; } diff --git a/src/quick/scenegraph/shaders/textmask.vert b/src/quick/scenegraph/shaders/textmask.vert index dd8918839e..4c678270d0 100644 --- a/src/quick/scenegraph/shaders/textmask.vert +++ b/src/quick/scenegraph/shaders/textmask.vert @@ -1,5 +1,6 @@ uniform highp mat4 matrix; uniform highp vec2 textureScale; +uniform highp float dpr; attribute highp vec4 vCoord; attribute highp vec2 tCoord; @@ -9,5 +10,5 @@ varying highp vec2 sampleCoord; void main() { sampleCoord = tCoord * textureScale; - gl_Position = matrix * floor(vCoord + 0.5); + gl_Position = matrix * floor(vCoord * dpr + 0.5) / dpr; } diff --git a/src/quick/scenegraph/shaders/textmask_core.vert b/src/quick/scenegraph/shaders/textmask_core.vert index d145d33195..f996040f70 100644 --- a/src/quick/scenegraph/shaders/textmask_core.vert +++ b/src/quick/scenegraph/shaders/textmask_core.vert @@ -7,9 +7,10 @@ out vec2 sampleCoord; uniform mat4 matrix; uniform vec2 textureScale; +uniform float dpr; void main() { sampleCoord = tCoord * textureScale; - gl_Position = matrix * round(vCoord); + gl_Position = matrix * round(vCoord * dpr) / dpr; } |