1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt3D 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 "qwaitfence.h" |
41 | #include "qwaitfence_p.h" |
42 | #include <Qt3DRender/private/qframegraphnode_p.h> |
43 | #include <Qt3DRender/private/qframegraphnodecreatedchange_p.h> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | namespace Qt3DRender { |
48 | |
49 | QWaitFencePrivate::QWaitFencePrivate() |
50 | : QFrameGraphNodePrivate() |
51 | , m_handleType(QWaitFence::NoHandle) |
52 | , m_handle(QVariant()) |
53 | , m_waitOnCPU(false) |
54 | , m_timeout(std::numeric_limits<quint64>::max()) |
55 | { |
56 | } |
57 | |
58 | /*! |
59 | \class Qt3DRender::QWaitFence |
60 | \inmodule Qt3DRender |
61 | \brief FrameGraphNode used to wait for a fence in the graphics command |
62 | stream to become signaled. |
63 | |
64 | Fence allow to synchronosize GPU and CPU workloads. GPU commands usually |
65 | are non-blocking. When issued, commands are inserted in command buffers |
66 | which will be read at a later time by the GPU. In some cases, you want to |
67 | continue processing or issue specific command only when you are sure a |
68 | command has been executed by the hardware. Fences are a way to do so. This |
69 | is especially important when using 3rd party engines with Qt3D, Qt3D should |
70 | only access shared resources when we know the other engine command are done |
71 | modifying the resource. |
72 | |
73 | QWaitFence is a FrameGraph node that will force to wait for it to become |
74 | signaled before subsequent commands are inserted into the command stream. |
75 | It can then be used in conjunction with \l QSetFence and contains |
76 | properties to configure how long it should wait and whether it should block |
77 | on the CPU side. |
78 | |
79 | \note Qt 3D uploads GPU resources (Texture, Shaders, Buffers) before |
80 | issuing draw calls. |
81 | |
82 | \since 5.13 |
83 | */ |
84 | |
85 | QWaitFence::QWaitFence(Qt3DCore::QNode *parent) |
86 | : QFrameGraphNode(*new QWaitFencePrivate(), parent) |
87 | { |
88 | } |
89 | |
90 | QWaitFence::~QWaitFence() |
91 | { |
92 | } |
93 | |
94 | /*! |
95 | \qmlproperty bool WaitFence::waitOnCPU |
96 | |
97 | Specifies whether the CPU should be block while waiting for the fence to |
98 | become signaled. This is false by default. |
99 | */ |
100 | /*! |
101 | \property Qt3DRender::QWaitFence::waitOnCPU |
102 | |
103 | Specifies whether the CPU should be block while waiting for the fence to |
104 | become signaled. This is false by default. |
105 | */ |
106 | bool QWaitFence::waitOnCPU() const |
107 | { |
108 | Q_D(const QWaitFence); |
109 | return d->m_waitOnCPU; |
110 | } |
111 | |
112 | void QWaitFence::setWaitOnCPU(bool waitOnCPU) |
113 | { |
114 | Q_D(QWaitFence); |
115 | if (d->m_waitOnCPU == waitOnCPU) |
116 | return; |
117 | d->m_waitOnCPU = waitOnCPU; |
118 | emit waitOnCPUChanged(waitOnCPU); |
119 | } |
120 | |
121 | /*! |
122 | \qmlproperty int WaitFence::timeout |
123 | |
124 | Specifies the maximum amount of time in nanoseconds to wait for the fence |
125 | to become signaled. |
126 | */ |
127 | /*! |
128 | \property Qt3DRender::QWaitFence::timeout |
129 | |
130 | Specifies the maximum amount of time in nanoseconds to wait for the fence |
131 | to become signaled. |
132 | */ |
133 | quint64 QWaitFence::timeout() const |
134 | { |
135 | Q_D(const QWaitFence); |
136 | return d->m_timeout; |
137 | } |
138 | |
139 | void QWaitFence::setTimeout(quint64 timeout) |
140 | { |
141 | Q_D(QWaitFence); |
142 | if (d->m_timeout == timeout) |
143 | return; |
144 | d->m_timeout = timeout; |
145 | emit timeoutChanged(timeoutChanged: timeout); |
146 | } |
147 | |
148 | QWaitFence::QWaitFence(QWaitFencePrivate &dd, Qt3DCore::QNode *parent) |
149 | : QFrameGraphNode(dd, parent) |
150 | { |
151 | } |
152 | |
153 | /*! |
154 | \qmlproperty HandleType WaitFence::handleType |
155 | |
156 | Specifies the type of handle being used. Currently only OpenGL Fence ids |
157 | are supported. |
158 | */ |
159 | /*! |
160 | \property Qt3DRender::QWaitFence::handleType |
161 | |
162 | Specifies the type of handle being used. Currently only OpenGL Fence ids |
163 | are supported. |
164 | */ |
165 | QWaitFence::HandleType QWaitFence::handleType() const |
166 | { |
167 | Q_D(const QWaitFence); |
168 | return d->m_handleType; |
169 | } |
170 | |
171 | void QWaitFence::setHandleType(QWaitFence::HandleType type) |
172 | { |
173 | Q_D(QWaitFence); |
174 | if (d->m_handleType != type) { |
175 | d->m_handleType = type; |
176 | emit handleTypeChanged(handleType: type); |
177 | } |
178 | } |
179 | |
180 | /*! |
181 | \qmlproperty variant WaitFence::handle |
182 | |
183 | Holds the underlying fence handle wrapped in a variant. |
184 | */ |
185 | /*! |
186 | \property Qt3DRender::QWaitFence::handle |
187 | |
188 | Holds the underlying fence handle wrapped in a QVariant. |
189 | */ |
190 | QVariant QWaitFence::handle() const |
191 | { |
192 | Q_D(const QWaitFence); |
193 | return d->m_handle; |
194 | } |
195 | |
196 | void QWaitFence::setHandle(QVariant handle) |
197 | { |
198 | Q_D(QWaitFence); |
199 | if (d->m_handle != handle) { |
200 | d->m_handle = handle; |
201 | emit handleChanged(handle); |
202 | } |
203 | } |
204 | |
205 | Qt3DCore::QNodeCreatedChangeBasePtr QWaitFence::createNodeCreationChange() const |
206 | { |
207 | auto creationChange = QFrameGraphNodeCreatedChangePtr<QWaitFenceData>::create(arguments: this); |
208 | QWaitFenceData &data = creationChange->data; |
209 | Q_D(const QWaitFence); |
210 | data.handleType = d->m_handleType; |
211 | data.handle = d->m_handle; |
212 | data.timeout = d->m_timeout; |
213 | data.waitOnCPU = d->m_waitOnCPU; |
214 | return creationChange; |
215 | } |
216 | |
217 | } // Qt3DRender |
218 | |
219 | QT_END_NAMESPACE |
220 | |