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/qtechnique.h>
32#include <Qt3DRender/qparameter.h>
33#include <Qt3DRender/qfilterkey.h>
34#include <Qt3DRender/qrenderpass.h>
35#include <Qt3DRender/qgraphicsapifilter.h>
36#include <Qt3DRender/private/qgraphicsapifilter_p.h>
37#include <Qt3DRender/private/qtechnique_p.h>
38#include <QObject>
39#include <QSignalSpy>
40#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
41#include <Qt3DCore/qnodecreatedchange.h>
42#include "testpostmanarbiter.h"
43
44class tst_QTechnique : public QObject
45{
46 Q_OBJECT
47
48private Q_SLOTS:
49
50 void checkDefaultConstruction()
51 {
52 // GIVEN
53 Qt3DRender::QTechnique technique;
54
55 // THEN
56 QCOMPARE(technique.graphicsApiFilter()->profile(), Qt3DRender::QGraphicsApiFilter::NoProfile);
57 QCOMPARE(technique.graphicsApiFilter()->majorVersion(), 0);
58 QCOMPARE(technique.graphicsApiFilter()->minorVersion(), 0);
59 QVERIFY(technique.renderPasses().empty());
60 QVERIFY(technique.parameters().empty());
61 QVERIFY(technique.filterKeys().empty());
62 }
63
64 void checkPropertyChanges()
65 {
66 // GIVEN
67 Qt3DRender::QTechnique technique;
68
69 {
70 // WHEN
71 Qt3DRender::QRenderPass pass;
72
73 technique.addRenderPass(pass: &pass);
74
75 // THEN
76 QCOMPARE(technique.renderPasses().size(), 1);
77
78 // WHEN
79 technique.addRenderPass(pass: &pass);
80
81 // THEN
82 QCOMPARE(technique.renderPasses().size(), 1);
83
84 // WHEN
85 technique.removeRenderPass(pass: &pass);
86
87 // THEN
88 QCOMPARE(technique.renderPasses().size(), 0);
89 }
90 {
91 // WHEN
92 Qt3DRender::QParameter parameter;
93
94 technique.addParameter(p: &parameter);
95
96 // THEN
97 QCOMPARE(technique.parameters().size(), 1);
98
99 // WHEN
100 technique.addParameter(p: &parameter);
101
102 // THEN
103 QCOMPARE(technique.parameters().size(), 1);
104
105 // WHEN
106 technique.removeParameter(p: &parameter);
107
108 // THEN
109 QCOMPARE(technique.parameters().size(), 0);
110 }
111 {
112 // WHEN
113 Qt3DRender::QFilterKey filterKey;
114
115 technique.addFilterKey(filterKey: &filterKey);
116
117 // THEN
118 QCOMPARE(technique.filterKeys().size(), 1);
119
120 // WHEN
121 technique.addFilterKey(filterKey: &filterKey);
122
123 // THEN
124 QCOMPARE(technique.filterKeys().size(), 1);
125
126 // WHEN
127 technique.removeFilterKey(filterKey: &filterKey);
128
129 // THEN
130 QCOMPARE(technique.filterKeys().size(), 0);
131 }
132 {
133 // WHEN
134 QSignalSpy spy(technique.graphicsApiFilter(), SIGNAL(graphicsApiFilterChanged()));
135 technique.graphicsApiFilter()->setMajorVersion(3);
136
137 // THEN
138 QVERIFY(spy.isValid());
139 QCOMPARE(technique.graphicsApiFilter()->majorVersion(), 3);
140 QCOMPARE(spy.count(), 1);
141
142 // WHEN
143 spy.clear();
144 technique.graphicsApiFilter()->setMajorVersion(3);
145
146 // THEN
147 QCOMPARE(technique.graphicsApiFilter()->majorVersion(), 3);
148 QCOMPARE(spy.count(), 0);
149
150 // WHEN
151 technique.graphicsApiFilter()->setMinorVersion(2);
152
153 // THEN
154 QCOMPARE(technique.graphicsApiFilter()->minorVersion(), 2);
155 QCOMPARE(spy.count(), 1);
156
157 // WHEN
158 spy.clear();
159 technique.graphicsApiFilter()->setMinorVersion(2);
160
161 // THEN
162 QCOMPARE(technique.graphicsApiFilter()->minorVersion(), 2);
163 QCOMPARE(spy.count(), 0);
164
165 // WHEN
166 technique.graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
167
168 // THEN
169 QCOMPARE(technique.graphicsApiFilter()->profile(), Qt3DRender::QGraphicsApiFilter::CoreProfile);
170 QCOMPARE(spy.count(), 1);
171
172 // WHEN
173 spy.clear();
174 technique.graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
175
176 // THEN
177 QCOMPARE(technique.graphicsApiFilter()->profile(), Qt3DRender::QGraphicsApiFilter::CoreProfile);
178 QCOMPARE(spy.count(), 0);
179 }
180 }
181
182 void checkRenderPassBookkeeping()
183 {
184 // GIVEN
185 Qt3DRender::QTechnique technique;
186
187 {
188 // WHEN
189 Qt3DRender::QRenderPass pass;
190 technique.addRenderPass(pass: &pass);
191
192 // THEN
193 QCOMPARE(technique.renderPasses().size(), 1);
194 }
195
196 // THEN -> should not crash
197 QCOMPARE(technique.renderPasses().size(), 0);
198 }
199
200 void checkParameterBookkeeping()
201 {
202 // GIVEN
203 Qt3DRender::QTechnique technique;
204
205 {
206 // WHEN
207 Qt3DRender::QParameter parameter;
208 technique.addParameter(p: &parameter);
209
210 // THEN
211 QCOMPARE(technique.parameters().size(), 1);
212 }
213
214 // THEN -> should not crash
215 QCOMPARE(technique.parameters().size(), 0);
216 }
217
218 void checkFilterKeyBookkeeping()
219 {
220 // GIVEN
221 Qt3DRender::QTechnique technique;
222
223 {
224 // WHEN
225 Qt3DRender::QFilterKey filterKey;
226 technique.addFilterKey(filterKey: &filterKey);
227
228 // THEN
229 QCOMPARE(technique.filterKeys().size(), 1);
230 }
231
232 // THEN -> should not crash
233 QCOMPARE(technique.filterKeys().size(), 0);
234 }
235
236 void checkCreationData()
237 {
238 // GIVEN
239 Qt3DRender::QTechnique technique;
240 Qt3DRender::QRenderPass pass;
241 Qt3DRender::QParameter parameter;
242 Qt3DRender::QFilterKey filterKey;
243
244 technique.addRenderPass(pass: &pass);
245 technique.addParameter(p: &parameter);
246 technique.addFilterKey(filterKey: &filterKey);
247
248 // WHEN
249 QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
250
251 {
252 Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&technique);
253 creationChanges = creationChangeGenerator.creationChanges();
254 }
255
256 // THEN
257 {
258 QCOMPARE(creationChanges.size(), 4); // Technique + Pass + Parameter + FilterKey
259
260 const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QTechniqueData>>(src: creationChanges.first());
261 const Qt3DRender::QTechniqueData cloneData = creationChangeData->data;
262
263 QCOMPARE(technique.graphicsApiFilter()->minorVersion(), cloneData.graphicsApiFilterData.m_minor);
264 QCOMPARE(technique.graphicsApiFilter()->majorVersion(), cloneData.graphicsApiFilterData.m_major);
265 QCOMPARE(technique.graphicsApiFilter()->profile(), cloneData.graphicsApiFilterData.m_profile);
266 QCOMPARE(technique.graphicsApiFilter()->vendor(), cloneData.graphicsApiFilterData.m_vendor);
267 QCOMPARE(technique.graphicsApiFilter()->extensions(), cloneData.graphicsApiFilterData.m_extensions);
268 QCOMPARE(technique.graphicsApiFilter()->api(), cloneData.graphicsApiFilterData.m_api);
269 QCOMPARE(technique.id(), creationChangeData->subjectId());
270 QCOMPARE(technique.isEnabled(), true);
271 QCOMPARE(technique.isEnabled(), creationChangeData->isNodeEnabled());
272 QCOMPARE(technique.metaObject(), creationChangeData->metaObject());
273 QCOMPARE(technique.renderPasses().size(), cloneData.renderPassIds.size());
274 QCOMPARE(technique.parameters().size(), cloneData.parameterIds.size());
275 QCOMPARE(technique.filterKeys().size(), cloneData.filterKeyIds.size());
276 QCOMPARE(pass.id(), cloneData.renderPassIds.first());
277 QCOMPARE(parameter.id(), cloneData.parameterIds.first());
278 QCOMPARE(filterKey.id(), cloneData.filterKeyIds.first());
279 }
280
281 // WHEN
282 technique.setEnabled(false);
283
284 {
285 Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&technique);
286 creationChanges = creationChangeGenerator.creationChanges();
287 }
288
289 // THEN
290 {
291 QCOMPARE(creationChanges.size(), 4); // Technique + Pass + Parameter + FilterKey
292
293 const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QTechniqueData>>(src: creationChanges.first());
294 const Qt3DRender::QTechniqueData cloneData = creationChangeData->data;
295
296 QCOMPARE(technique.graphicsApiFilter()->minorVersion(), cloneData.graphicsApiFilterData.m_minor);
297 QCOMPARE(technique.graphicsApiFilter()->majorVersion(), cloneData.graphicsApiFilterData.m_major);
298 QCOMPARE(technique.graphicsApiFilter()->profile(), cloneData.graphicsApiFilterData.m_profile);
299 QCOMPARE(technique.graphicsApiFilter()->vendor(), cloneData.graphicsApiFilterData.m_vendor);
300 QCOMPARE(technique.graphicsApiFilter()->extensions(), cloneData.graphicsApiFilterData.m_extensions);
301 QCOMPARE(technique.graphicsApiFilter()->api(), cloneData.graphicsApiFilterData.m_api);
302 QCOMPARE(technique.id(), creationChangeData->subjectId());
303 QCOMPARE(technique.isEnabled(), false);
304 QCOMPARE(technique.isEnabled(), creationChangeData->isNodeEnabled());
305 QCOMPARE(technique.metaObject(), creationChangeData->metaObject());
306 QCOMPARE(technique.renderPasses().size(), cloneData.renderPassIds.size());
307 QCOMPARE(technique.parameters().size(), cloneData.parameterIds.size());
308 QCOMPARE(technique.filterKeys().size(), cloneData.filterKeyIds.size());
309 QCOMPARE(pass.id(), cloneData.renderPassIds.first());
310 QCOMPARE(parameter.id(), cloneData.parameterIds.first());
311 QCOMPARE(filterKey.id(), cloneData.filterKeyIds.first());
312 }
313 }
314
315 void checkRenderPassUpdate()
316 {
317 // GIVEN
318 TestArbiter arbiter;
319 Qt3DRender::QTechnique technique;
320 Qt3DRender::QRenderPass pass;
321 arbiter.setArbiterOnNode(&technique);
322
323 {
324 // WHEN
325 technique.addRenderPass(pass: &pass);
326 QCoreApplication::processEvents();
327
328 // THEN
329 QCOMPARE(arbiter.events.size(), 0);
330 QCOMPARE(arbiter.dirtyNodes.size(), 1);
331 QVERIFY(arbiter.dirtyNodes.contains(&technique));
332
333 arbiter.dirtyNodes.clear();
334 }
335 {
336 // WHEN
337 technique.removeRenderPass(pass: &pass);
338 QCoreApplication::processEvents();
339
340 // THEN
341 QCOMPARE(arbiter.events.size(), 0);
342 QCOMPARE(arbiter.dirtyNodes.size(), 1);
343 QVERIFY(arbiter.dirtyNodes.contains(&technique));
344 }
345 }
346
347 void checkParameterUpdate()
348 {
349 // GIVEN
350 TestArbiter arbiter;
351 Qt3DRender::QTechnique technique;
352 Qt3DRender::QParameter parameter;
353 arbiter.setArbiterOnNode(&technique);
354
355 {
356 // WHEN
357 technique.addParameter(p: &parameter);
358 QCoreApplication::processEvents();
359
360 // THEN
361 QCOMPARE(arbiter.events.size(), 0);
362 QCOMPARE(arbiter.dirtyNodes.size(), 1);
363 QVERIFY(arbiter.dirtyNodes.contains(&technique));
364
365 arbiter.dirtyNodes.clear();
366 }
367
368 {
369 // WHEN
370 technique.removeParameter(p: &parameter);
371 QCoreApplication::processEvents();
372
373 // THEN
374 QCOMPARE(arbiter.events.size(), 0);
375 QCOMPARE(arbiter.dirtyNodes.size(), 1);
376 QVERIFY(arbiter.dirtyNodes.contains(&technique));
377
378 arbiter.dirtyNodes.clear();
379 }
380 }
381
382 void checkFilterKeyUpdate()
383 {
384 // GIVEN
385 TestArbiter arbiter;
386 Qt3DRender::QTechnique technique;
387 Qt3DRender::QFilterKey filterKey;
388 arbiter.setArbiterOnNode(&technique);
389
390 {
391 // WHEN
392 technique.addFilterKey(filterKey: &filterKey);
393 QCoreApplication::processEvents();
394
395 // THEN
396 QCOMPARE(arbiter.events.size(), 0);
397 QCOMPARE(arbiter.dirtyNodes.size(), 1);
398 QVERIFY(arbiter.dirtyNodes.contains(&technique));
399
400 arbiter.dirtyNodes.clear();
401 }
402
403 {
404 // WHEN
405 technique.removeFilterKey(filterKey: &filterKey);
406 QCoreApplication::processEvents();
407
408 // THEN
409 QCOMPARE(arbiter.events.size(), 0);
410 QCOMPARE(arbiter.dirtyNodes.size(), 1);
411 QVERIFY(arbiter.dirtyNodes.contains(&technique));
412
413 arbiter.dirtyNodes.clear();
414 }
415 }
416
417 void checkGraphicsAPIFilterUpdate()
418 {
419 // GIVEN
420 TestArbiter arbiter;
421 Qt3DRender::QTechnique technique;
422 arbiter.setArbiterOnNode(&technique);
423
424 {
425 // WHEN
426 technique.graphicsApiFilter()->setMajorVersion(4);
427 QCoreApplication::processEvents();
428
429 // THEN
430 QCOMPARE(arbiter.events.size(), 0);
431 QCOMPARE(arbiter.dirtyNodes.size(), 1);
432 QVERIFY(arbiter.dirtyNodes.contains(&technique));
433
434 arbiter.dirtyNodes.clear();
435 }
436 {
437 // WHEN
438 technique.graphicsApiFilter()->setMinorVersion(5);
439 QCoreApplication::processEvents();
440
441 // THEN
442 QCOMPARE(arbiter.events.size(), 0);
443 QCOMPARE(arbiter.dirtyNodes.size(), 1);
444 QVERIFY(arbiter.dirtyNodes.contains(&technique));
445
446 arbiter.dirtyNodes.clear();
447 }
448 {
449 // WHEN
450 technique.graphicsApiFilter()->setVendor(QStringLiteral("AMD"));
451 QCoreApplication::processEvents();
452
453 // THEN
454 QCOMPARE(arbiter.events.size(), 0);
455 QCOMPARE(arbiter.dirtyNodes.size(), 1);
456 QVERIFY(arbiter.dirtyNodes.contains(&technique));
457
458 arbiter.dirtyNodes.clear();
459 }
460 {
461 // WHEN
462 technique.graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CompatibilityProfile);
463 QCoreApplication::processEvents();
464
465 // THEN
466 QCOMPARE(arbiter.events.size(), 0);
467 QCOMPARE(arbiter.dirtyNodes.size(), 1);
468 QVERIFY(arbiter.dirtyNodes.contains(&technique));
469
470 arbiter.dirtyNodes.clear();
471 }
472 }
473};
474
475QTEST_MAIN(tst_QTechnique)
476
477#include "tst_qtechnique.moc"
478

source code of qt3d/tests/auto/render/qtechnique/tst_qtechnique.cpp