Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgdefaultcontext.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtQuick/private/qsgdefaultinternalrectanglenode_p.h>
8#include <QtQuick/private/qsgdefaultinternalimagenode_p.h>
9#include <QtQuick/private/qsgdefaultpainternode_p.h>
10#include <QtQuick/private/qsgdefaultglyphnode_p.h>
11#include <QtQuick/private/qsgcurveglyphnode_p.h>
12#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
13#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h>
14#include <QtQuick/private/qsgrhisupport_p.h>
15#include <QtQuick/private/qsgrhilayer_p.h>
16#include <QtQuick/private/qsgdefaultrendercontext_p.h>
17#include <QtQuick/private/qsgdefaultrectanglenode_p.h>
18#include <QtQuick/private/qsgdefaultimagenode_p.h>
19#include <QtQuick/private/qsgdefaultninepatchnode_p.h>
20#if QT_CONFIG(quick_sprite)
21#include <QtQuick/private/qsgdefaultspritenode_p.h>
22#endif
23#include <QtQuick/private/qsgrhishadereffectnode_p.h>
24#include <QtQuick/private/qsginternaltextnode_p.h>
25#include <QtQuick/private/qsgrhiinternaltextnode_p.h>
26
27#include <QOpenGLContext>
28
29#include <QtQuick/private/qquickwindow_p.h>
30#include <QtQuick/private/qquickitem_p.h>
31
32#include <private/qqmlglobal_p.h>
33
34#include <algorithm>
35
36#include <rhi/qrhi.h>
37
39
42 public:
43 ImageNode(QSGDefaultRenderContext *rc) : QSGDefaultInternalImageNode(rc) { }
45 };
46
48 public:
50 };
51}
52
53DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
54
55QSGDefaultContext::QSGDefaultContext(QObject *parent)
56 : QSGContext (parent)
57 , m_antialiasingMethod(QSGContext::UndecidedAntialiasing)
58 , m_distanceFieldDisabled(qmlDisableDistanceField())
59 , m_distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing)
60 , m_distanceFieldAntialiasingDecided(false)
61{
62 if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QSG_DISTANCEFIELD_ANTIALIASING"))) {
63 const QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING");
64 m_distanceFieldAntialiasingDecided = true;
65 if (mode == "subpixel")
66 m_distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing;
67 else if (mode == "subpixel-lowq")
68 m_distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing;
69 else if (mode == "gray")
70 m_distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
71 }
72
73 // Adds compatibility with Qt 5.3 and earlier's QSG_RENDER_TIMING
74 if (qEnvironmentVariableIsSet("QSG_RENDER_TIMING")) {
75 const_cast<QLoggingCategory &>(QSG_LOG_TIME_GLYPH()).setEnabled(QtDebugMsg, true);
76 const_cast<QLoggingCategory &>(QSG_LOG_TIME_TEXTURE()).setEnabled(QtDebugMsg, true);
77 const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERER()).setEnabled(QtDebugMsg, true);
78 const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERLOOP()).setEnabled(QtDebugMsg, true);
79 const_cast<QLoggingCategory &>(QSG_LOG_TIME_COMPILATION()).setEnabled(QtDebugMsg, true);
80 }
81}
82
83QSGDefaultContext::~QSGDefaultContext()
84{
85
86}
87
88void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext)
89{
90 m_mutex.lock();
91
92 auto rc = static_cast<const QSGDefaultRenderContext *>(renderContext);
93 if (m_antialiasingMethod == UndecidedAntialiasing) {
94 if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) {
95 const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD");
96 if (aaType == "msaa")
97 m_antialiasingMethod = MsaaAntialiasing;
98 else if (aaType == "vertex")
99 m_antialiasingMethod = VertexAntialiasing;
100 }
101 if (m_antialiasingMethod == UndecidedAntialiasing)
102 m_antialiasingMethod = rc->msaaSampleCount() > 1 ? MsaaAntialiasing : VertexAntialiasing;
103 }
104
105#if QT_CONFIG(opengl)
106 // With OpenGL ES, use GrayAntialiasing, unless
107 // some value had been requested explicitly. This could not be decided
108 // before without a context. Now the context is ready.
109 if (!m_distanceFieldAntialiasingDecided) {
110 m_distanceFieldAntialiasingDecided = true;
111 Q_ASSERT(rc->rhi());
112 if (rc->rhi()->backend() == QRhi::OpenGLES2
113 && static_cast<const QRhiGles2NativeHandles *>(rc->rhi()->nativeHandles())->context->isOpenGLES())
114 {
115 m_distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
116 }
117 }
118#endif
119
120 m_mutex.unlock();
121}
122
123void QSGDefaultContext::renderContextInvalidated(QSGRenderContext *)
124{
125}
126
127QSGRenderContext *QSGDefaultContext::createRenderContext()
128{
129 return new QSGDefaultRenderContext(this);
130}
131
132QSGInternalRectangleNode *QSGDefaultContext::createInternalRectangleNode()
133{
134 return m_antialiasingMethod == MsaaAntialiasing
135 ? new QSGMultisampleAntialiasing::RectangleNode
136 : new QSGDefaultInternalRectangleNode;
137}
138
139QSGInternalImageNode *QSGDefaultContext::createInternalImageNode(QSGRenderContext *renderContext)
140{
141 return m_antialiasingMethod == MsaaAntialiasing
142 ? new QSGMultisampleAntialiasing::ImageNode(static_cast<QSGDefaultRenderContext *>(renderContext))
143 : new QSGDefaultInternalImageNode(static_cast<QSGDefaultRenderContext *>(renderContext));
144}
145
146QSGPainterNode *QSGDefaultContext::createPainterNode(QQuickPaintedItem *item)
147{
148 return new QSGDefaultPainterNode(item);
149}
150
151QSGInternalTextNode *QSGDefaultContext::createInternalTextNode(QSGRenderContext *renderContext)
152{
153 return new QSGRhiInternalTextNode(renderContext);
154}
155
156QSGTextNode::RenderType QSGDefaultContext::processTextRenderType(QSGTextNode::RenderType renderType)
157{
158 if (renderType == QSGTextNode::QtRendering && m_distanceFieldDisabled)
159 return QSGTextNode::NativeRendering;
160 else
161 return renderType;
162}
163
164QSGGlyphNode *QSGDefaultContext::createGlyphNode(QSGRenderContext *rc,
165 QSGTextNode::RenderType renderType)
166{
167 if (renderType == QSGTextNode::CurveRendering) {
168 return new QSGCurveGlyphNode(rc);
169 } else if (renderType == QSGTextNode::NativeRendering) {
170 return new QSGDefaultGlyphNode(rc);
171 } else {
172 QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc);
173 node->setPreferredAntialiasingMode(m_distanceFieldAntialiasing);
174 return node;
175 }
176}
177
178QSGLayer *QSGDefaultContext::createLayer(QSGRenderContext *renderContext)
179{
180 return new QSGRhiLayer(renderContext);
181}
182
183QSurfaceFormat QSGDefaultContext::defaultSurfaceFormat() const
184{
185 QSurfaceFormat format = QSurfaceFormat::defaultFormat();
186 // These depend solely on the env.vars., not QQuickGraphicsConfiguration
187 // since that does not have a flag that maps 100% to QSG_NO_xx_BUFFER.
188 static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
189 static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER");
190 static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG");
191 static bool disableVSync = qEnvironmentVariableIsSet("QSG_NO_VSYNC");
192 if (useDepth && format.depthBufferSize() == -1)
193 format.setDepthBufferSize(24);
194 else if (!useDepth)
195 format.setDepthBufferSize(0);
196 if (useStencil && format.stencilBufferSize() == -1)
197 format.setStencilBufferSize(8);
198 else if (!useStencil)
199 format.setStencilBufferSize(0);
200 if (enableDebug)
201 format.setOption(QSurfaceFormat::DebugContext);
202 if (QQuickWindow::hasDefaultAlphaBuffer())
203 format.setAlphaBufferSize(8);
204 format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
205 if (disableVSync) // swapInterval defaults to 1, it has no -1 special value
206 format.setSwapInterval(0);
207 return format;
208}
209
210void QSGDefaultContext::setDistanceFieldEnabled(bool enabled)
211{
212 m_distanceFieldDisabled = !enabled;
213}
214
215bool QSGDefaultContext::isDistanceFieldEnabled() const
216{
217 return !m_distanceFieldDisabled;
218}
219
220QSGRendererInterface *QSGDefaultContext::rendererInterface(QSGRenderContext *renderContext)
221{
222 Q_UNUSED(renderContext);
223 return this;
224}
225
226QSGRectangleNode *QSGDefaultContext::createRectangleNode()
227{
228 return new QSGDefaultRectangleNode;
229}
230
231QSGImageNode *QSGDefaultContext::createImageNode()
232{
233 return new QSGDefaultImageNode;
234}
235
236QSGNinePatchNode *QSGDefaultContext::createNinePatchNode()
237{
238 return new QSGDefaultNinePatchNode;
239}
240
241#if QT_CONFIG(quick_sprite)
242QSGSpriteNode *QSGDefaultContext::createSpriteNode()
243{
244 return new QSGDefaultSpriteNode;
245}
246#endif
247
248QSGGuiThreadShaderEffectManager *QSGDefaultContext::createGuiThreadShaderEffectManager()
249{
250 return new QSGRhiGuiThreadShaderEffectManager;
251}
252
253QSGShaderEffectNode *QSGDefaultContext::createShaderEffectNode(QSGRenderContext *renderContext)
254{
255 return new QSGRhiShaderEffectNode(static_cast<QSGDefaultRenderContext *>(renderContext));
256}
257
258QSGRendererInterface::GraphicsApi QSGDefaultContext::graphicsApi() const
259{
260 return QSGRhiSupport::instance()->graphicsApi();
261}
262
263void *QSGDefaultContext::getResource(QQuickWindow *window, Resource resource) const
264{
265 if (!window)
266 return nullptr;
267
268 // Unlike the graphicsApi and shaderType and similar queries, getting a
269 // native resource is only possible when there is an initialized
270 // rendercontext, or rather, only within rendering a frame, as per
271 // QSGRendererInterface docs. This is good since getting some things is
272 // only possible within a beginFrame - endFrame with the RHI.
273
274 const QSGDefaultRenderContext *rc = static_cast<const QSGDefaultRenderContext *>(
275 QQuickWindowPrivate::get(window)->context);
276 QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
277
278#if QT_CONFIG(vulkan)
279 if (resource == VulkanInstanceResource)
280 return window->vulkanInstance();
281#endif
282 return const_cast<void *>(rhiSupport->rifResource(resource, rc, window));
283}
284
285QSGRendererInterface::ShaderType QSGDefaultContext::shaderType() const
286{
287 return RhiShader;
288}
289
290QSGRendererInterface::ShaderCompilationTypes QSGDefaultContext::shaderCompilationType() const
291{
292 return OfflineCompilation;
293}
294
295QSGRendererInterface::ShaderSourceTypes QSGDefaultContext::shaderSourceType() const
296{
297 return ShaderSourceFile;
298}
299
300QT_END_NAMESPACE
301
302static void initResources()
303{
304 Q_INIT_RESOURCE(scenegraph_shaders);
305}
306
307Q_CONSTRUCTOR_FUNCTION(initResources)
ImageNode(QSGDefaultRenderContext *rc)
Combined button and popup list for selecting options.