aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-29 10:48:54 +0100
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-29 10:48:54 +0100
commit4e33b069c426c975319d91e11223114fd0d8ad40 (patch)
treed73e1251bc313b7303fdb000c0789cdfb4c7bb1f /src/quick/scenegraph
parentd9e70d1a49af347f79db7e64bdd8e2e8083a77b5 (diff)
parent05d8ffb4dff5e693967c8ee7cee6d6158eadccbd (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.cpp18
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp36
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp21
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp24
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp11
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/shaders/styledtext.vert3
-rw-r--r--src/quick/scenegraph/shaders/styledtext_core.vert3
-rw-r--r--src/quick/scenegraph/shaders/textmask.vert3
-rw-r--r--src/quick/scenegraph/shaders/textmask_core.vert3
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;
}