1/****************************************************************************
2**
3** Copyright (C) 2016 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:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QTest>
31#include <Qt3DRender/qcomputecommand.h>
32#include <Qt3DRender/private/qcomputecommand_p.h>
33#include <Qt3DRender/private/computecommand_p.h>
34#include <Qt3DRender/private/nodemanagers_p.h>
35#include <Qt3DRender/private/managers_p.h>
36#include <Qt3DCore/private/qbackendnode_p.h>
37#include <Qt3DCore/private/qaspectmanager_p.h>
38#include <Qt3DCore/private/qscene_p.h>
39#include <Qt3DCore/qpropertyupdatedchange.h>
40#include "qbackendnodetester.h"
41#include "testrenderer.h"
42#include "testpostmanarbiter.h"
43
44
45class tst_ComputeCommand : public Qt3DCore::QBackendNodeTester
46{
47 Q_OBJECT
48
49private Q_SLOTS:
50
51 void checkInitialState()
52 {
53 // GIVEN
54 Qt3DRender::Render::ComputeCommand backendComputeCommand;
55
56 // THEN
57 QCOMPARE(backendComputeCommand.isEnabled(), false);
58 QVERIFY(backendComputeCommand.peerId().isNull());
59 QCOMPARE(backendComputeCommand.x(), 1);
60 QCOMPARE(backendComputeCommand.y(), 1);
61 QCOMPARE(backendComputeCommand.z(), 1);
62 QCOMPARE(backendComputeCommand.hasReachedFrameCount(), false);
63 QCOMPARE(backendComputeCommand.runType(), Qt3DRender::QComputeCommand::Continuous);
64 QCOMPARE(backendComputeCommand.frameCount(), 0);
65 }
66
67 void checkCleanupState()
68 {
69 // GIVEN
70 TestRenderer renderer;
71 Qt3DRender::Render::ComputeCommand backendComputeCommand;
72 Qt3DRender::QComputeCommand computeCommand;
73 computeCommand.setWorkGroupX(256);
74 computeCommand.setWorkGroupY(512);
75 computeCommand.setWorkGroupZ(128);
76 computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
77 computeCommand.trigger(frameCount: 1);
78
79 // WHEN
80 backendComputeCommand.setRenderer(&renderer);
81 simulateInitializationSync(frontend: &computeCommand, backend: &backendComputeCommand);
82
83 backendComputeCommand.setEnabled(true);
84 backendComputeCommand.hasReachedFrameCount();
85
86 backendComputeCommand.cleanup();
87
88 // THEN
89 QCOMPARE(backendComputeCommand.isEnabled(), false);
90 QCOMPARE(backendComputeCommand.hasReachedFrameCount(), false);
91 }
92
93 void checkInitializeFromPeer()
94 {
95 // GIVEN
96 TestRenderer renderer;
97 Qt3DRender::QComputeCommand computeCommand;
98 computeCommand.setWorkGroupX(256);
99 computeCommand.setWorkGroupY(512);
100 computeCommand.setWorkGroupZ(128);
101 computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
102 computeCommand.trigger(frameCount: 6);
103
104 {
105 // WHEN
106 Qt3DRender::Render::ComputeCommand backendComputeCommand;
107 backendComputeCommand.setRenderer(&renderer);
108 simulateInitializationSync(frontend: &computeCommand, backend: &backendComputeCommand);
109
110 // THEN
111 QCOMPARE(backendComputeCommand.isEnabled(), true);
112 QCOMPARE(backendComputeCommand.peerId(), computeCommand.id());
113 QCOMPARE(backendComputeCommand.x(), computeCommand.workGroupX());
114 QCOMPARE(backendComputeCommand.y(), computeCommand.workGroupY());
115 QCOMPARE(backendComputeCommand.z(), computeCommand.workGroupZ());
116 QCOMPARE(backendComputeCommand.runType(), computeCommand.runType());
117 QCOMPARE(backendComputeCommand.frameCount(), 6);
118 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
119 }
120 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
121 {
122 // WHEN
123 Qt3DRender::Render::ComputeCommand backendComputeCommand;
124 backendComputeCommand.setRenderer(&renderer);
125 computeCommand.setEnabled(false);
126 simulateInitializationSync(frontend: &computeCommand, backend: &backendComputeCommand);
127
128 // THEN
129 QCOMPARE(backendComputeCommand.peerId(), computeCommand.id());
130 QCOMPARE(backendComputeCommand.isEnabled(), false);
131 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
132 }
133 }
134
135 void checkSceneChangeEvents()
136 {
137 // GIVEN
138 Qt3DRender::Render::ComputeCommand backendComputeCommand;
139 Qt3DRender::QComputeCommand computeCommand;
140 TestRenderer renderer;
141 backendComputeCommand.setRenderer(&renderer);
142 simulateInitializationSync(frontend: &computeCommand, backend: &backendComputeCommand);
143
144 // THEN
145 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
146 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
147
148 {
149 // WHEN
150 const bool newValue = false;
151 computeCommand.setEnabled(newValue);
152 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
153
154 // THEN
155 QCOMPARE(backendComputeCommand.isEnabled(), newValue);
156 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
157 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
158 }
159 {
160 // WHEN
161 const int newValue = 128;
162 computeCommand.setWorkGroupX(newValue);
163 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
164
165 // THEN
166 QCOMPARE(backendComputeCommand.x(), newValue);
167 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
168 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
169 }
170 {
171 // WHEN
172 const int newValue = 64;
173 computeCommand.setWorkGroupY(newValue);
174 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
175
176 // THEN
177 QCOMPARE(backendComputeCommand.y(), newValue);
178 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
179 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
180 }
181 {
182 // WHEN
183 const int newValue = 32;
184 computeCommand.setWorkGroupZ(newValue);
185 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
186
187 // THEN
188 QCOMPARE(backendComputeCommand.z(), newValue);
189 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
190 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
191 }
192 {
193 // WHEN
194 const Qt3DRender::QComputeCommand::RunType newValue = Qt3DRender::QComputeCommand::Manual;
195 computeCommand.setRunType(newValue);
196 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
197
198 // THEN
199 QCOMPARE(backendComputeCommand.runType(), newValue);
200 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
201 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
202 }
203 {
204 // WHEN
205 const int newValue = 32;
206 computeCommand.trigger(frameCount: newValue);
207 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
208
209 // THEN
210 QCOMPARE(backendComputeCommand.frameCount(), newValue);
211 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
212 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
213 }
214 }
215
216 void checkUpdateFrameCount()
217 {
218 // GIVEN
219 TestRenderer renderer;
220 TestArbiter arbiter;
221
222 Qt3DRender::QComputeCommand computeCommand;
223 Qt3DRender::Render::ComputeCommand backendComputeCommand;
224
225 computeCommand.setWorkGroupX(256);
226 computeCommand.setWorkGroupY(512);
227 computeCommand.setWorkGroupZ(128);
228 computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
229 computeCommand.trigger(frameCount: 6);
230
231
232 Qt3DCore::QBackendNodePrivate::get(n: &backendComputeCommand)->setArbiter(&arbiter);
233
234 backendComputeCommand.setRenderer(&renderer);
235 simulateInitializationSync(frontend: &computeCommand, backend: &backendComputeCommand);
236
237 for (int i = 0; i < 5; ++i) {
238 // WHEN
239 backendComputeCommand.updateFrameCount();
240
241 // THEN
242 QCOMPARE(backendComputeCommand.frameCount(), 6 - (i + 1));
243 QCOMPARE(backendComputeCommand.isEnabled(), true);
244 QCOMPARE(backendComputeCommand.hasReachedFrameCount(), false);
245 QCOMPARE(arbiter.events.size(), 0);
246 }
247
248 // WHEN
249 backendComputeCommand.updateFrameCount();
250
251 // THEN
252 QCOMPARE(backendComputeCommand.hasReachedFrameCount(), true);
253 QCOMPARE(backendComputeCommand.frameCount(), 0);
254 // Backend stays with enabled == true, frontend will be updated
255 // to be disabled and backend should be disabled on the next sync
256
257 // WHEN
258 computeCommand.setEnabled(false);
259 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
260
261 // THEN
262 QCOMPARE(backendComputeCommand.isEnabled(), false);
263 QCOMPARE(backendComputeCommand.frameCount(), 0);
264
265 // WHEN
266 computeCommand.trigger(frameCount: 1);
267 backendComputeCommand.syncFromFrontEnd(frontEnd: &computeCommand, firstTime: false);
268
269 // THEN
270 QCOMPARE(computeCommand.isEnabled(), true);
271 QCOMPARE(backendComputeCommand.isEnabled(), true);
272 QCOMPARE(backendComputeCommand.hasReachedFrameCount(), false);
273 QCOMPARE(backendComputeCommand.frameCount(), 1);
274 }
275};
276
277QTEST_MAIN(tst_ComputeCommand)
278
279#include "tst_computecommand.moc"
280

source code of qt3d/tests/auto/render/computecommand/tst_computecommand.cpp