aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp11
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp7
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.h2
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h3
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp3
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp6
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp33
7 files changed, 54 insertions, 11 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index eee8316d05..cc229708f1 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -371,6 +371,17 @@ QSGRenderNode::RenderState::~RenderState()
}
/*!
+ \class QSGRenderNode::RenderState
+ \brief Provides information about the projection matrix and clipping.
+ \inmodule QtQuick
+
+ The render state contains information for the renderer when invoking
+ commands to the scenegraph backends.
+
+ \sa QSGRenderNode::render()
+ */
+
+/*!
\fn const QMatrix4x4 *QSGRenderNode::RenderState::projectionMatrix() const
\return pointer to the current projection matrix.
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index 64f862f948..b0ab978908 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -9,7 +9,8 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcSgText, "qt.scenegraph.text")
-qint64 QSGDistanceFieldGlyphNode::m_totalAllocation = 0;
+// all SG glyph vertices and indices; only for qCDebug metrics
+static std::atomic<qint64> s_totalAllocation = 0;
QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGRenderContext *context)
: m_glyphNodeType(RootGlyphNode)
@@ -314,9 +315,9 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
}
}
- m_totalAllocation += vp.size() * sizeof(QSGGeometry::TexturedPoint2D) + ip.size() * sizeof(quint16);
+ s_totalAllocation += vp.size() * sizeof(QSGGeometry::TexturedPoint2D) + ip.size() * sizeof(quint16);
qCDebug(lcSgText) << "allocating for" << vp.size() << "vtx (reserved" << likelyGlyphCount * 4 << "):" << vp.size() * sizeof(QSGGeometry::TexturedPoint2D)
- << "bytes;" << ip.size() << "idx:" << ip.size() * sizeof(quint16) << "bytes; total bytes so far" << m_totalAllocation;
+ << "bytes;" << ip.size() << "idx:" << ip.size() * sizeof(quint16) << "bytes; total bytes so far" << s_totalAllocation;
g->allocate(vp.size(), ip.size());
memcpy(g->vertexDataAsTexturedPoint2D(), vp.constData(), vp.size() * sizeof(QSGGeometry::TexturedPoint2D));
memcpy(g->indexDataAsUShort(), ip.constData(), ip.size() * sizeof(quint16));
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
index d92bf0a836..04b17f0ab7 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
@@ -84,8 +84,6 @@ private:
uint m_dirtyGeometry: 1;
uint m_dirtyMaterial: 1;
-
- static qint64 m_totalAllocation; // all SG glyph vertices and indices; only for qCDebug metrics
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 73d30ffb6b..bbd169708a 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -105,6 +105,9 @@ WM_Obscure = QEvent::User + 1,
// (updatePaintNode())
WM_RequestSync = QEvent::User + 2,
+// Passed from the RL to the RT when a window is exposed
+WM_Exposed = QEvent::User + 3,
+
// Passed by the RL to the RT to free up maybe release SG and GL contexts
// if no windows are rendering.
WM_TryRelease = QEvent::User + 4,
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
index f1db5804e6..4c9facbb57 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp
+++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
@@ -9,6 +9,9 @@
#include <private/qsgplaintexture_p.h>
#include <QtGui/private/qshaderdescription_p.h>
#include <QQmlFile>
+
+#include <QtGui/qquaternion.h>
+
#include <QFile>
#include <QFileSelector>
#include <QMutexLocker>
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index 57cd51f171..25b7b620e0 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -1334,7 +1334,11 @@ QImage QSGRhiSupport::grabOffscreen(QQuickWindow *window)
// There was no rendercontrol which means a custom render target
// should not be set either. Set our own, temporarily.
- window->setRenderTarget(QQuickRenderTarget::fromRhiRenderTarget(rt.data()));
+ auto renderTarget = QQuickRenderTarget::fromRhiRenderTarget(rt.data());
+ // Pass on the scale factor. No need to use effectiveDevicePixelRatio(),
+ // because there is no rendercontrol anyway.
+ renderTarget.setDevicePixelRatio(window->devicePixelRatio());
+ window->setRenderTarget(renderTarget);
QRhiCommandBuffer *cb = nullptr;
if (rhi->beginOffscreenFrame(&cb) != QRhi::FrameOpSuccess) {
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index d2a160c420..fc92673d8e 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -335,6 +335,17 @@ bool QSGRenderThread::event(QEvent *e)
return true; }
+
+ case WM_Exposed: {
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Exposed");
+
+ mutex.lock();
+ window = static_cast<WMWindowEvent *>(e)->window;
+ waitCondition.wakeOne();
+ mutex.unlock();
+
+ return true; }
+
case WM_RequestSync: {
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestSync");
WMSyncEvent *se = static_cast<WMSyncEvent *>(e);
@@ -632,8 +643,14 @@ void QSGRenderThread::syncAndRender()
// An update request could still be delivered right before we get an
// unexpose. With Vulkan on Windows for example attempting to render
// leads to failures at this stage since the surface size is already 0.
- if (effectiveOutputSize.isEmpty())
+ if (effectiveOutputSize.isEmpty()) {
+ if (syncRequested) {
+ mutex.lock();
+ waitCondition.wakeOne();
+ mutex.unlock();
+ }
return;
+ }
const QSize previousOutputSize = cd->swapchain->currentPixelSize();
if (previousOutputSize != effectiveOutputSize || cd->swapchainJustBecameRenderable) {
@@ -1249,10 +1266,6 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
}
}
- // set this early as we'll be rendering shortly anyway and this avoids
- // specialcasing exposure in polishAndSync.
- w->thread->window = window;
-
#ifndef QT_NO_DEBUG
if (w->window->width() <= 0 || w->window->height() <= 0
|| (w->window->isTopLevel() && !w->window->geometry().intersects(w->window->screen()->availableGeometry()))) {
@@ -1271,6 +1284,10 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
if (!w->thread->isRunning()) {
qCDebug(QSG_LOG_RENDERLOOP, "- starting render thread");
+ // set this early as we'll be rendering shortly anyway and this avoids
+ // specialcasing exposure in polishAndSync.
+ w->thread->window = window;
+
if (!w->thread->rhi) {
QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
if (!w->thread->offscreenSurface)
@@ -1295,6 +1312,12 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
} else {
qCDebug(QSG_LOG_RENDERLOOP, "- render thread already running");
+
+ // set w->thread->window here too, but using an event so it's thread-safe
+ w->thread->mutex.lock();
+ w->thread->postEvent(new WMWindowEvent(w->window, QEvent::Type(WM_Exposed)));
+ w->thread->waitCondition.wait(&w->thread->mutex);
+ w->thread->mutex.unlock();
}
polishAndSync(w, true);