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 "qsgrendernode.h"
41#include "qsgrendernode_p.h"
42
43QT_BEGIN_NAMESPACE
44
45/*!
46 \class QSGRenderNode
47 \brief The QSGRenderNode class represents a set of custom rendering commands
48 targeting the graphics API that is in use by the scenegraph.
49 \inmodule QtQuick
50 \since 5.8
51 */
52
53QSGRenderNode::QSGRenderNode()
54 : QSGNode(RenderNodeType),
55 d(new QSGRenderNodePrivate)
56{
57}
58
59/*!
60 Destructs the render node. Derived classes are expected to perform cleanup
61 similar to releaseResources() in here.
62
63 When a low-level graphics API is in use, the scenegraph will make sure
64 there is a CPU-side wait for the GPU to complete all work submitted to the
65 scenegraph's graphics command queue before the scenegraph's nodes are
66 deleted. Therefore there is no need to issue additional waits here, unless
67 the render() implementation is using additional command queues.
68
69 \sa releaseResources()
70 */
71QSGRenderNode::~QSGRenderNode()
72{
73 delete d;
74}
75
76QSGRenderNodePrivate::QSGRenderNodePrivate()
77 : m_matrix(nullptr)
78 , m_clip_list(nullptr)
79 , m_opacity(1)
80{
81}
82
83/*!
84 This function should return a mask where each bit represents graphics states changed by
85 the \l render() function:
86 \list
87 \li DepthState - depth write mask, depth test enabled, depth comparison function
88 \li StencilState - stencil write masks, stencil test enabled, stencil operations,
89 stencil comparison functions
90 \li ScissorState - scissor enabled, scissor test enabled
91 \li ColorState - clear color, color write mask
92 \li BlendState - blend enabled, blend function
93 \li CullState - front face, cull face enabled
94 \li ViewportState - viewport
95 \li RenderTargetState - render target
96 \endlist
97
98 The function is called by the renderer so it can reset the states after
99 rendering this node. This makes the implementation of render() simpler
100 since it does not have to query and restore these states.
101
102 The default implementation returns 0, meaning no relevant state was changed
103 in render().
104
105 With APIs other than OpenGL the relevant states are only those that are set
106 via the command list (for example, OMSetRenderTargets, RSSetViewports,
107 RSSetScissorRects, OMSetBlendFactor, OMSetStencilRef in case of D3D12), and
108 only when such commands were added to the scenegraph's command list queried
109 via the QSGRendererInterface::CommandList resource enum. States set in
110 pipeline state objects do not need to be reported here. Similarly, draw
111 call related settings (root signature, descriptor heaps, etc.) are always
112 set again by the scenegraph so render() can freely change them.
113
114 The software backend exposes its QPainter and saves and restores before and
115 after invoking render(). Therefore reporting any changed states from here
116 is not necessary.
117
118 \note This function may be called before render().
119 */
120QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
121{
122 return nullptr;
123}
124
125/*!
126 \fn void QSGRenderNode::render(const RenderState *state)
127
128 This function is called by the renderer and should paint this node with
129 directly invoking commands in the graphics API (OpenGL, Direct3D, etc.)
130 currently in use.
131
132 The effective opacity can be retrieved with \l inheritedOpacity().
133
134 The projection matrix is available through \a state, while the model-view
135 matrix can be fetched with \l matrix(). The combined matrix is then the
136 projection matrix times the model-view matrix. The correct stacking of the
137 items in the scene is ensured by the projection matrix.
138
139 When using the provided matrices, the coordinate system for vertex data
140 follows the usual QQuickItem conventions: top-left is (0, 0), bottom-right
141 is the corresponding QQuickItem's width() and height() minus one. For
142 example, assuming a two float (x-y) per vertex coordinate layout, a
143 triangle covering half of the item can be specified as (width - 1, height - 1),
144 (0, 0), (0, height - 1) using counter-clockwise direction.
145
146 \note QSGRenderNode is provided as a means to implement custom 2D or 2.5D
147 Qt Quick items. It is not intended for integrating true 3D content into the
148 Qt Quick scene. That use case is better supported by
149 QQuickFramebufferObject, QQuickWindow::beforeRendering(), or the
150 equivalents of those for APIs other than OpenGL.
151
152 Clip information is calculated before the function is called, it is however
153 not enabled. Implementations wishing to take clipping into account can set
154 up scissoring or stencil based on the information in \a state. Some
155 scenegraph backends, software in particular, use no scissor or stencil.
156 There the clip region is provided as an ordinary QRegion.
157
158 For OpenGL the following states are set on the render thread's context
159 before this function is called:
160 \list
161 \li glDepthMask(false)
162 \li glDisable(GL_DEPTH_TEST)
163 \li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip
164 \li glScissor(state.scissorRect.x(), state.scissorRect.y(),
165 state.scissorRect.width(), state.scissorRect.height()) depending on clip
166 \li glEnable(GL_BLEND)
167 \li glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
168 \li glDisable(GL_CULL_FACE)
169 \endlist
170
171 States that are not listed above, but are included in \l StateFlags, can
172 have arbitrary values.
173
174 \l changedStates() should return which states this function changes. If a
175 state is not covered by \l StateFlags, the state should be set to the
176 default value according to the OpenGL specification. For other APIs, see
177 the documentation for changedStates() for more information.
178
179 \note Depth writes are disabled when this function is called (for example,
180 glDepthMask(false) in case of OpenGL). Enabling depth writes can lead to
181 unexpected results, depending on the scenegraph backend in use, so nodes
182 should avoid this.
183
184 For APIs other than OpenGL, it will likely be necessary to query certain
185 API-specific resources (for example, the graphics device or the command
186 list/buffer to add the commands to). This is done via QSGRendererInterface.
187
188 \sa QSGRendererInterface, QQuickWindow::rendererInterface()
189 */
190
191/*!
192 This function is called when all custom graphics resources allocated by
193 this node have to be freed immediately. In case the node does not directly
194 allocate graphics resources (buffers, textures, render targets, fences,
195 etc.) through the graphics API that is in use, there is nothing to do here.
196
197 Failing to release all custom resources can lead to incorrect behavior in
198 graphics device loss scenarios on some systems since subsequent
199 reinitialization of the graphics system may fail.
200
201 \note Some scenegraph backends may choose not to call this function.
202 Therefore it is expected that QSGRenderNode implementations perform cleanup
203 both in their destructor and in releaseResources().
204
205 Unlike with the destructor, it is expected that render() can reinitialize
206 all resources it needs when called after a call to releaseResources().
207
208 With OpenGL, the scenegraph's OpenGL context will be current both when
209 calling the destructor and this function.
210 */
211void QSGRenderNode::releaseResources()
212{
213}
214
215/*!
216 \enum QSGRenderNode::StateFlag
217
218 This enum is a bit mask identifying several states.
219
220 \value DepthState Depth
221 \value StencilState Stencil
222 \value ScissorState Scissor
223 \value ColorState Color
224 \value BlendState Blend
225 \value CullState Cull
226 \value ViewportState View poirt
227 \value RenderTargetState Render target
228
229 */
230
231/*!
232 \enum QSGRenderNode::RenderingFlag
233
234 Possible values for the bitmask returned from flags().
235
236 \value BoundedRectRendering Indicates that the implementation of render()
237 does not render outside the area reported from rect() in item
238 coordinates. Such node implementations can lead to more efficient rendering,
239 depending on the scenegraph backend. For example, the software backend can
240 continue to use the more optimal partial update path when all render nodes
241 in the scene have this flag set.
242
243 \value DepthAwareRendering Indicates that the implementations of render()
244 conforms to scenegraph expectations by only generating a Z value of 0 in
245 scene coordinates which is then transformed by the matrices retrieved from
246 RenderState::projectionMatrix() and matrix(), as described in the notes for
247 render(). Such node implementations can lead to more efficient rendering,
248 depending on the scenegraph backend. For example, the batching OpenGL
249 renderer can continue to use a more optimal path when all render nodes in
250 the scene have this flag set.
251
252 \value OpaqueRendering Indicates that the implementation of render() writes
253 out opaque pixels for the entire area reported from rect(). By default the
254 renderers must assume that render() can also output semi or fully
255 transparent pixels. Setting this flag can improve performance in some
256 cases.
257
258 \sa render(), rect()
259 */
260
261/*!
262 \return flags describing the behavior of this render node.
263
264 The default implementation returns 0.
265
266 \sa RenderingFlag, rect()
267 */
268QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
269{
270 return nullptr;
271}
272
273/*!
274 \return the bounding rectangle in item coordinates for the area render()
275 touches. The value is only in use when flags() includes
276 BoundedRectRendering, ignored otherwise.
277
278 Reporting the rectangle in combination with BoundedRectRendering is
279 particularly important with the \c software backend because otherwise
280 having a rendernode in the scene would trigger fullscreen updates, skipping
281 all partial update optimizations.
282
283 For rendernodes covering the entire area of a corresponding QQuickItem the
284 return value will be (0, 0, item->width(), item->height()).
285
286 \note Nodes are also free to render outside the boundaries specified by the
287 item's width and height, since the scenegraph nodes are not bounded by the
288 QQuickItem geometry, as long as this is reported correctly from this function.
289
290 \sa flags()
291*/
292QRectF QSGRenderNode::rect() const
293{
294 return QRectF();
295}
296
297/*!
298 \return pointer to the current model-view matrix.
299 */
300const QMatrix4x4 *QSGRenderNode::matrix() const
301{
302 return d->m_matrix;
303}
304
305/*!
306 \return the current clip list.
307 */
308const QSGClipNode *QSGRenderNode::clipList() const
309{
310 return d->m_clip_list;
311}
312
313/*!
314 \return the current effective opacity.
315 */
316qreal QSGRenderNode::inheritedOpacity() const
317{
318 return d->m_opacity;
319}
320
321QSGRenderNode::RenderState::~RenderState()
322{
323}
324
325/*!
326 \fn const QMatrix4x4 *QSGRenderNode::RenderState::projectionMatrix() const
327
328 \return pointer to the current projection matrix.
329
330 The model-view matrix can be retrieved with QSGRenderNode::matrix().
331 Typically \c{projection * modelview} is the matrix that is then used in the
332 vertex shader to transform the vertices.
333 */
334
335/*!
336 \fn const QMatrix4x4 *QSGRenderNode::RenderState::scissorRect() const
337
338 \return the current scissor rectangle when clipping is active.
339
340 \note Be aware of the differences between graphics APIs: for some the
341 scissor rect is only active when scissoring is enabled (for example,
342 OpenGL), while for others the scissor rect is equal to the viewport rect
343 when there is no need to scissor away anything (for example, Direct3D 12).
344 */
345
346/*!
347 \fn const QMatrix4x4 *QSGRenderNode::RenderState::scissorEnabled() const
348
349 \return the current state of scissoring.
350
351 \note Only relevant for graphics APIs that have a dedicated on/off state of
352 scissoring.
353 */
354
355/*!
356 \fn const QMatrix4x4 *QSGRenderNode::RenderState::stencilValue() const
357
358 \return the current stencil reference value when clipping is active.
359 */
360
361/*!
362 \fn const QMatrix4x4 *QSGRenderNode::RenderState::stencilEnabled() const
363
364 \return the current state of stencil testing.
365
366 \note With graphics APIs where stencil testing is enabled in pipeline state
367 objects, instead of individual state-setting commands, it is up to the
368 implementation of render() to enable stencil testing with operations
369 \c KEEP, comparison function \c EQUAL, and a read and write mask of \c 0xFF.
370 */
371
372/*!
373 \fn const QRegion *QSGRenderNode::RenderState::clipRegion() const
374
375 \return the current clip region or null for backends where clipping is
376 implemented via stencil or scissoring.
377
378 The software backend uses no projection, scissor or stencil, meaning most
379 of the render state is not in use. However, the clip region that can be set
380 on the QPainter still has to be communicated since reconstructing this
381 manually in render() is not reasonable. It can therefore be queried via
382 this function. The region is in world coordinates and can be passed
383 to QPainter::setClipRegion() with Qt::ReplaceClip. This must be done before
384 calling QPainter::setTransform() since the clip region is already mapped to
385 the transform provided in QSGRenderNode::matrix().
386 */
387
388/*!
389 \return pointer to a \a state value.
390
391 Reserved for future use.
392 */
393void *QSGRenderNode::RenderState::get(const char *state) const
394{
395 Q_UNUSED(state);
396 return nullptr;
397}
398
399QT_END_NAMESPACE
400