1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qsgengine_p.h"
41
42#include <QtQuick/qsgtexture.h>
43#include <private/qsgcontext_p.h>
44#include <private/qsgrenderer_p.h>
45#include <private/qsgplaintexture_p.h>
46
47#if QT_CONFIG(opengl)
48# include <QtGui/QOpenGLContext>
49# include <private/qsgdefaultrendercontext_p.h>
50#endif
51
52QT_BEGIN_NAMESPACE
53
54#if QT_DEPRECATED_SINCE(5, 15)
55
56/*!
57 \class QSGEngine
58 \brief The QSGEngine class allows low level rendering of a scene graph.
59 \inmodule QtQuick
60 \since 5.4
61
62 \deprecated
63
64 A QSGEngine can be used to render a tree of QSGNode directly on a QWindow
65 or QOpenGLFramebufferObject without any integration with QML, QQuickWindow
66 or QQuickItem and the convenience that they provide.
67
68 This means that you must handle event propagation, animation timing,
69 and node lifetime yourself.
70
71 \note This class is for very low level access to an independent scene graph.
72 Most of the time you will instead want to subclass QQuickItem and insert
73 your QSGNode in a normal QtQuick scene by overriding QQuickItem::updatePaintNode().
74
75 \warning This class is only suitable when working directly with OpenGL. It
76 is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
77 path}.
78
79 \sa QSGAbstractRenderer
80 */
81
82/*!
83 \enum QSGEngine::CreateTextureOption
84
85 The CreateTextureOption enums are used to customize how a texture is wrapped.
86
87 \value TextureHasAlphaChannel The texture has an alpha channel and should
88 be drawn using blending.
89
90 \value TextureOwnsGLTexture The texture object owns the texture id and
91 will delete the GL texture when the texture object is deleted.
92
93 \value TextureCanUseAtlas The image can be uploaded into a texture atlas.
94
95 \value TextureIsOpaque The texture object is opaque.
96 */
97
98QSGEnginePrivate::QSGEnginePrivate()
99 : sgContext(QSGContext::createDefaultContext())
100 , sgRenderContext(sgContext.data()->createRenderContext())
101{
102}
103
104/*!
105 Constructs a new QSGEngine with its \a parent
106 */
107QSGEngine::QSGEngine(QObject *parent)
108 : QObject(*(new QSGEnginePrivate), parent)
109{
110}
111
112/*!
113 Destroys the engine
114 */
115QSGEngine::~QSGEngine()
116{
117}
118
119/*!
120 Initialize the engine with \a context.
121
122 \warning You have to make sure that you call
123 QOpenGLContext::makeCurrent() on \a context before calling this.
124 */
125void QSGEngine::initialize(QOpenGLContext *context)
126{
127 Q_D(QSGEngine);
128#if QT_CONFIG(opengl)
129 if (context && QOpenGLContext::currentContext() != context) {
130 qWarning(msg: "WARNING: The context must be current before calling QSGEngine::initialize.");
131 return;
132 }
133#endif
134 if (d->sgRenderContext && !d->sgRenderContext->isValid()) {
135 d->sgRenderContext->setAttachToGraphicsContext(false);
136#if QT_CONFIG(opengl)
137 QSGDefaultRenderContext *rc = qobject_cast<QSGDefaultRenderContext *>(object: d->sgRenderContext.data());
138 if (rc) {
139 QSGDefaultRenderContext::InitParams params;
140 params.sampleCount = qMax(a: 1, b: context->format().samples());
141 params.openGLContext = context;
142 // leave the size hint and surface unset, we do not know, that's fine
143 rc->initialize(params: &params);
144 } else {
145 d->sgRenderContext->initialize(params: nullptr);
146 }
147#else
148 d->sgRenderContext->initialize(nullptr);
149#endif
150#if QT_CONFIG(opengl)
151 if (context)
152 connect(sender: context, signal: &QOpenGLContext::aboutToBeDestroyed, receiver: this, slot: &QSGEngine::invalidate);
153#endif
154 }
155
156#if !QT_CONFIG(opengl)
157 Q_UNUSED(context);
158#endif
159}
160
161/*!
162 Invalidate the engine releasing its resources
163
164 You will have to call initialize() and createRenderer() if you
165 want to use it again.
166 */
167void QSGEngine::invalidate()
168{
169 Q_D(QSGEngine);
170 d->sgRenderContext->invalidate();
171}
172
173/*!
174 Returns a renderer that can be used to render a QSGNode tree
175
176 You call initialize() first with the QOpenGLContext that you
177 want to use with this renderer. This will return a null
178 renderer otherwise.
179 */
180QSGAbstractRenderer *QSGEngine::createRenderer() const
181{
182 Q_D(const QSGEngine);
183 if (!d->sgRenderContext->isValid())
184 return nullptr;
185
186 QSGRenderer *renderer = d->sgRenderContext->createRenderer();
187 renderer->setCustomRenderMode(qgetenv(varName: "QSG_VISUALIZE"));
188 return renderer;
189}
190
191/*!
192 Creates a texture using the data of \a image
193
194 Valid \a options are TextureCanUseAtlas and TextureIsOpaque.
195
196 The caller takes ownership of the texture and the
197 texture should only be used with this engine.
198
199 \sa createTextureFromId(), QSGSimpleTextureNode::setOwnsTexture(), QQuickWindow::createTextureFromImage()
200 */
201QSGTexture *QSGEngine::createTextureFromImage(const QImage &image, CreateTextureOptions options) const
202{
203 Q_D(const QSGEngine);
204 if (!d->sgRenderContext->isValid())
205 return nullptr;
206 uint flags = 0;
207 if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas;
208 if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha;
209 return d->sgRenderContext->createTexture(image, flags);
210}
211
212/*!
213 Creates a texture object that wraps the GL texture \a id uploaded with \a size
214
215 Valid \a options are TextureHasAlphaChannel and TextureOwnsGLTexture
216
217 The caller takes ownership of the texture object and the
218 texture should only be used with this engine.
219
220 \sa createTextureFromImage(), QSGSimpleTextureNode::setOwnsTexture(), QQuickWindow::createTextureFromId()
221 */
222QSGTexture *QSGEngine::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const
223{
224 Q_D(const QSGEngine);
225 if (d->sgRenderContext->isValid()) {
226 QSGPlainTexture *texture = new QSGPlainTexture();
227 texture->setTextureId(id);
228 texture->setHasAlphaChannel(options & TextureHasAlphaChannel);
229 texture->setOwnsTexture(options & TextureOwnsGLTexture);
230 texture->setTextureSize(size);
231 return texture;
232 }
233 return nullptr;
234}
235
236/*!
237 Returns the current renderer interface if there is one. Otherwise null is returned.
238
239 \sa QSGRenderNode, QSGRendererInterface
240 \since 5.8
241 */
242QSGRendererInterface *QSGEngine::rendererInterface() const
243{
244 Q_D(const QSGEngine);
245 return d->sgRenderContext->isValid()
246 ? d->sgRenderContext->sceneGraphContext()->rendererInterface(renderContext: d->sgRenderContext.data())
247 : nullptr;
248}
249
250/*!
251 Creates a simple rectangle node. When the scenegraph is not initialized, the return value is null.
252
253 This is cross-backend alternative to constructing a QSGSimpleRectNode directly.
254
255 \since 5.8
256 \sa QSGRectangleNode
257 */
258QSGRectangleNode *QSGEngine::createRectangleNode() const
259{
260 Q_D(const QSGEngine);
261 return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createRectangleNode() : nullptr;
262}
263
264/*!
265 Creates a simple image node. When the scenegraph is not initialized, the return value is null.
266
267 This is cross-backend alternative to constructing a QSGSimpleTextureNode directly.
268
269 \since 5.8
270 \sa QSGImageNode
271 */
272
273QSGImageNode *QSGEngine::createImageNode() const
274{
275 Q_D(const QSGEngine);
276 return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createImageNode() : nullptr;
277}
278
279/*!
280 Creates a nine patch node. When the scenegraph is not initialized, the return value is null.
281
282 \since 5.8
283 */
284
285QSGNinePatchNode *QSGEngine::createNinePatchNode() const
286{
287 Q_D(const QSGEngine);
288 return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createNinePatchNode() : nullptr;
289}
290
291#endif
292
293QT_END_NAMESPACE
294
295#include "moc_qsgengine.cpp"
296

source code of qtdeclarative/src/quick/scenegraph/util/qsgengine.cpp