1/****************************************************************************
2**
3** Copyright (C) 2015 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#include <QtTest/QTest>
30#include <qbackendnodetester.h>
31#include <private/qframeallocator_p.h>
32#include <private/qframeallocator_p_p.h>
33#include <private/memorybarrier_p.h>
34#include <testpostmanarbiter.h>
35#include <testrenderer.h>
36#include <private/shader_p.h>
37#include <Qt3DRender/qshaderprogram.h>
38#include <renderview_p.h>
39#include <renderviewjobutils_p.h>
40#include <rendercommand_p.h>
41#include <renderer_p.h>
42#include <glresourcemanagers_p.h>
43#include <private/shader_p.h>
44
45QT_BEGIN_NAMESPACE
46
47namespace Qt3DRender {
48
49namespace Render {
50
51namespace OpenGL {
52
53namespace {
54
55void compareShaderParameterPacks(const ShaderParameterPack &t1,
56 const ShaderParameterPack &t2)
57{
58 const PackUniformHash hash1 = t1.uniforms();
59 const PackUniformHash hash2 = t2.uniforms();
60
61 QCOMPARE(hash1.keys.size(), hash2.keys.size());
62
63 for (int i = 0, m = hash1.keys.size(); i < m; ++i) {
64 const int key = hash1.keys.at(n: i);
65 QCOMPARE(hash1.value(key), hash2.value(key));
66 }
67}
68
69} // anonymous
70
71class tst_RenderViews : public Qt3DCore::QBackendNodeTester
72{
73 Q_OBJECT
74
75private Q_SLOTS:
76
77 void checkRenderViewSizeFitsWithAllocator()
78 {
79 QSKIP("Allocated Disabled");
80 QVERIFY(sizeof(RenderView) <= 192);
81 }
82
83 void checkRenderViewInitialState()
84 {
85 // GIVEN
86 RenderView renderView;
87
88 // THEN
89 QCOMPARE(renderView.memoryBarrier(), QMemoryBarrier::None);
90 }
91
92 void checkMemoryBarrierInitialization()
93 {
94 // GIVEN
95 RenderView renderView;
96
97 // THEN
98 QCOMPARE(renderView.memoryBarrier(), QMemoryBarrier::None);
99
100 // WHEN
101 const QMemoryBarrier::Operations barriers(QMemoryBarrier::BufferUpdate|QMemoryBarrier::ShaderImageAccess);
102 renderView.setMemoryBarrier(barriers);
103
104 // THEN
105 QCOMPARE(renderView.memoryBarrier(), barriers);
106 }
107
108 void checkSetRenderViewConfig()
109 {
110 TestRenderer renderer;
111 {
112 // GIVEN
113 const QMemoryBarrier::Operations barriers(QMemoryBarrier::AtomicCounter|QMemoryBarrier::ShaderStorage);
114 Qt3DRender::QMemoryBarrier frontendBarrier;
115 FrameGraphManager frameGraphManager;
116 MemoryBarrier backendBarrier;
117 RenderView renderView;
118 // setRenderViewConfigFromFrameGraphLeafNode assumes node has a manager
119 backendBarrier.setFrameGraphManager(&frameGraphManager);
120 backendBarrier.setRenderer(&renderer);
121
122 // WHEN
123 frontendBarrier.setWaitOperations(barriers);
124 simulateInitializationSync(frontend: &frontendBarrier, backend: &backendBarrier);
125
126 // THEN
127 QCOMPARE(renderView.memoryBarrier(), QMemoryBarrier::None);
128 QCOMPARE(backendBarrier.waitOperations(), barriers);
129
130 // WHEN
131 Qt3DRender::Render::OpenGL::setRenderViewConfigFromFrameGraphLeafNode(rv: &renderView, fgLeaf: &backendBarrier);
132
133 // THEN
134 QCOMPARE(backendBarrier.waitOperations(), renderView.memoryBarrier());
135 }
136 // TO DO: Complete tests for other framegraph node types
137 }
138
139 void checkDoesntCrashWhenNoCommandsToSort()
140 {
141 // GIVEN
142 Qt3DRender::Render::NodeManagers nodeManagers;
143 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
144 RenderView renderView;
145
146 renderer.setNodeManagers(&nodeManagers);
147 renderView.setRenderer(&renderer);
148
149 QVector<QSortPolicy::SortType> sortTypes;
150 sortTypes.push_back(t: QSortPolicy::BackToFront);
151
152 // WHEN
153 renderView.addSortType(sortTypes);
154
155 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
156 renderView.setRenderCommandDataView(view);
157
158 // THEN -> shouldn't crash
159 renderView.sort();
160
161 // RenderCommands are deleted by RenderView dtor
162 renderer.shutdown();
163 }
164
165 void checkRenderCommandBackToFrontSorting()
166 {
167 // GIVEN
168 Qt3DRender::Render::NodeManagers nodeManagers;
169 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
170 RenderView renderView;
171 std::vector<RenderCommand> rawCommands;
172
173 QVector<QSortPolicy::SortType> sortTypes;
174
175 renderer.setNodeManagers(&nodeManagers);
176 renderView.setRenderer(&renderer);
177
178 sortTypes.push_back(t: QSortPolicy::BackToFront);
179
180 for (int i = 0; i < 200; ++i) {
181 RenderCommand c;
182 c.m_depth = float(i);
183 rawCommands.push_back(x: c);
184 }
185
186 // WHEN
187 renderView.addSortType(sortTypes);
188
189 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
190 view->data.commands = rawCommands;
191 view->indices.resize(new_size: rawCommands.size());
192 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
193
194 renderView.setRenderCommandDataView(view);
195
196 renderView.sort();
197
198 // THEN
199 int j = 0;
200 RenderCommand previousRC;
201 renderView.forEachCommand(func: [&] (const RenderCommand &command) {
202 if (j > 0)
203 QVERIFY(previousRC.m_depth > command.m_depth);
204 previousRC = command;
205 ++j;
206 });
207
208 // RenderCommands are deleted by RenderView dtor
209 renderer.shutdown();
210 }
211
212 void checkRenderCommandMaterialSorting()
213 {
214 // GIVEN
215 Qt3DRender::Render::NodeManagers nodeManagers;
216 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
217 RenderView renderView;
218 std::vector<RenderCommand> rawCommands;
219
220 QVector<QSortPolicy::SortType> sortTypes;
221
222 renderer.setNodeManagers(&nodeManagers);
223 renderView.setRenderer(&renderer);
224
225 sortTypes.push_back(t: QSortPolicy::Material);
226
227 GLShader *dnas[5] = {
228 reinterpret_cast<GLShader *>(0x250),
229 reinterpret_cast<GLShader *>(0x500),
230 reinterpret_cast<GLShader *>(0x1000),
231 reinterpret_cast<GLShader *>(0x1500),
232 reinterpret_cast<GLShader *>(0x2000)
233 };
234
235 for (int i = 0; i < 20; ++i) {
236 RenderCommand c;
237 c.m_glShader = dnas[i % 5];
238 rawCommands.push_back(x: c);
239 }
240
241 // WHEN
242 renderView.addSortType(sortTypes);
243
244 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
245 view->data.commands = rawCommands;
246 view->indices.resize(new_size: rawCommands.size());
247 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
248
249 renderView.setRenderCommandDataView(view);
250
251 renderView.sort();
252
253 // THEN
254 int j = 0;
255 GLShader *targetShader;
256 RenderCommand previousRC;
257
258 renderView.forEachCommand(func: [&] (const RenderCommand &command) {
259 if (j % 4 == 0) {
260 targetShader = command.m_glShader;
261 if (j > 0)
262 QVERIFY(targetShader != previousRC.m_glShader);
263 }
264 QCOMPARE(targetShader, command.m_glShader);
265 previousRC = command;
266 ++j;
267 });
268
269 // RenderCommands are deleted by RenderView dtor
270 renderer.shutdown();
271 }
272
273 void checkRenderViewUniformMinification_data()
274 {
275 QTest::addColumn<QVector<QShaderProgram*>>(name: "shaders");
276 QTest::addColumn<QVector<ShaderParameterPack>>(name: "rawParameters");
277 QTest::addColumn<QVector<ShaderParameterPack>>(name: "expectedMinimizedParameters");
278
279 Qt3DCore::QNodeId fakeTextureNodeId = Qt3DCore::QNodeId::createId();
280
281 ShaderParameterPack pack1;
282 pack1.setUniform(glslNameId: 1, val: UniformValue(883));
283 pack1.setUniform(glslNameId: 2, val: UniformValue(1584.0f));
284 pack1.setTexture(glslNameId: 3, uniformArrayIndex: 0, id: fakeTextureNodeId);
285
286 QShaderProgram *shader1 = new QShaderProgram();
287 QShaderProgram *shader2 = new QShaderProgram();
288
289 shader1->setShaderCode(type: QShaderProgram::Vertex, QByteArrayLiteral("1"));
290 shader2->setShaderCode(type: QShaderProgram::Vertex, QByteArrayLiteral("2"));
291
292 ShaderParameterPack minifiedPack1;
293
294 QTest::newRow(dataTag: "NoMinification")
295 << (QVector<QShaderProgram*>() << shader1 << shader2)
296 << (QVector<ShaderParameterPack>() << pack1 << pack1)
297 << (QVector<ShaderParameterPack>() << pack1 << pack1);
298
299 QTest::newRow(dataTag: "SingleShaderMinified")
300 << (QVector<QShaderProgram*>() << shader1 << shader1 << shader1)
301 << (QVector<ShaderParameterPack>() << pack1 << pack1 << pack1)
302 << (QVector<ShaderParameterPack>() << pack1 << minifiedPack1 << minifiedPack1);
303
304 QTest::newRow(dataTag: "MultipleShadersMinified")
305 << (QVector<QShaderProgram*>() << shader1 << shader1 << shader1 << shader2 << shader2 << shader2)
306 << (QVector<ShaderParameterPack>() << pack1 << pack1 << pack1 << pack1 << pack1 << pack1)
307 << (QVector<ShaderParameterPack>() << pack1 << minifiedPack1 << minifiedPack1 << pack1 << minifiedPack1 << minifiedPack1);
308 }
309
310 void checkRenderViewUniformMinification()
311 {
312 QFETCH(QVector<QShaderProgram*>, shaders);
313 QFETCH(QVector<ShaderParameterPack>, rawParameters);
314 QFETCH(QVector<ShaderParameterPack>, expectedMinimizedParameters);
315
316 Qt3DRender::Render::NodeManagers nodeManagers;
317 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
318 renderer.setNodeManagers(&nodeManagers);
319
320 GLShaderManager *shaderManager = renderer.glResourceManagers()->glShaderManager();
321 for (int i = 0, m = shaders.size(); i < m; ++i) {
322 Shader* backend = new Shader();
323 backend->setRenderer(&renderer);
324 simulateInitializationSync(frontend: shaders.at(i), backend);
325 shaderManager->createOrAdoptExisting(shader: backend);
326 }
327
328 RenderView renderView;
329 std::vector<RenderCommand> rawCommands;
330
331 renderView.setRenderer(&renderer);
332
333 for (int i = 0, m = shaders.size(); i < m; ++i) {
334 RenderCommand c;
335 c.m_shaderId = shaders.at(i)->id();
336 c.m_glShader = shaderManager->lookupResource(shaderId: c.m_shaderId);
337 c.m_parameterPack = rawParameters.at(i);
338 rawCommands.push_back(x: c);
339 }
340
341 // WHEN
342 renderView.addSortType(sortTypes: (QVector<QSortPolicy::SortType>() << QSortPolicy::Uniform));
343
344 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
345 view->data.commands = rawCommands;
346 view->indices.resize(new_size: rawCommands.size());
347 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
348
349 renderView.setRenderCommandDataView(view);
350
351 renderView.sort();
352
353 // THEN
354 int j = 0;
355 renderView.forEachCommand(func: [&] (const RenderCommand &command) {
356 QCOMPARE(command.m_shaderId, shaders.at(j)->id());
357 compareShaderParameterPacks(t1: command.m_parameterPack, t2: expectedMinimizedParameters.at(i: j));
358 ++j;
359 });
360
361 renderer.shutdown();
362 }
363
364
365 void checkRenderCommandFrontToBackSorting()
366 {
367 // GIVEN
368 Qt3DRender::Render::NodeManagers nodeManagers;
369 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
370 RenderView renderView;
371 std::vector<RenderCommand> rawCommands;
372
373 QVector<QSortPolicy::SortType> sortTypes;
374
375 renderer.setNodeManagers(&nodeManagers);
376 renderView.setRenderer(&renderer);
377
378 sortTypes.push_back(t: QSortPolicy::FrontToBack);
379
380 for (int i = 0; i < 200; ++i) {
381 RenderCommand c;
382 c.m_depth = float(i);
383 rawCommands.push_back(x: c);
384 }
385
386 // WHEN
387 renderView.addSortType(sortTypes);
388
389 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
390 view->data.commands = rawCommands;
391 view->indices.resize(new_size: rawCommands.size());
392 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
393
394 renderView.setRenderCommandDataView(view);
395
396 renderView.sort();
397
398 // THEN
399 int j = 0;
400 RenderCommand previousRC;
401 renderView.forEachCommand(func: [&] (const RenderCommand &command) {
402 if (j > 0)
403 QVERIFY(previousRC.m_depth < command.m_depth);
404 previousRC = command;
405 ++j;
406 });
407
408 // RenderCommands are deleted by RenderView dtor
409 renderer.shutdown();
410 }
411
412 void checkRenderCommandStateCostSorting()
413 {
414 // GIVEN
415 Qt3DRender::Render::NodeManagers nodeManagers;
416 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
417 RenderView renderView;
418 std::vector<RenderCommand> rawCommands;
419
420 QVector<QSortPolicy::SortType> sortTypes;
421
422 renderer.setNodeManagers(&nodeManagers);
423 renderView.setRenderer(&renderer);
424
425 sortTypes.push_back(t: QSortPolicy::StateChangeCost);
426
427 for (int i = 0; i < 200; ++i) {
428 RenderCommand c;
429 c.m_changeCost = i;
430 rawCommands.push_back(x: c);
431 }
432
433 // WHEN
434 renderView.addSortType(sortTypes);
435
436 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
437 view->data.commands = rawCommands;
438 view->indices.resize(new_size: rawCommands.size());
439 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
440
441 renderView.setRenderCommandDataView(view);
442
443 renderView.sort();
444
445 // THEN
446 int j = 0;
447 RenderCommand previousRC;
448 renderView.forEachCommand(func: [&] (const RenderCommand &command) {
449 if (j > 0)
450 QVERIFY(previousRC.m_changeCost > command.m_changeCost);
451 previousRC = command;
452 ++j;
453 });
454
455
456 // RenderCommands are deleted by RenderView dtor
457 renderer.shutdown();
458 }
459
460 void checkRenderCommandCombinedStateMaterialDepthSorting()
461 {
462 // GIVEN
463 Qt3DRender::Render::NodeManagers nodeManagers;
464 Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
465 RenderView renderView;
466 std::vector<RenderCommand> rawCommands;
467
468 QVector<QSortPolicy::SortType> sortTypes;
469
470 renderer.setNodeManagers(&nodeManagers);
471 renderView.setRenderer(&renderer);
472
473 sortTypes.push_back(t: QSortPolicy::StateChangeCost);
474 sortTypes.push_back(t: QSortPolicy::Material);
475 sortTypes.push_back(t: QSortPolicy::BackToFront);
476
477 GLShader *dna[5] = {
478 reinterpret_cast<GLShader *>(0x250),
479 reinterpret_cast<GLShader *>(0x500),
480 reinterpret_cast<GLShader *>(0x1000),
481 reinterpret_cast<GLShader *>(0x1500),
482 reinterpret_cast<GLShader *>(0x2000)
483 };
484
485 float depth[3] = {
486 10.0f,
487 25.0f,
488 30.0f
489 };
490
491 int stateChangeCost[2] = {
492 100,
493 200
494 };
495
496 auto buildRC = [] (GLShader *dna, float depth, int changeCost) {
497 RenderCommand c;
498 c.m_glShader = dna;
499 c.m_depth = depth;
500 c.m_changeCost = changeCost;
501 return c;
502 };
503
504 RenderCommand c5 = buildRC(dna[3], depth[1], stateChangeCost[1]);
505 RenderCommand c3 = buildRC(dna[3], depth[0], stateChangeCost[1]);
506 RenderCommand c4 = buildRC(dna[2], depth[1], stateChangeCost[1]);
507 RenderCommand c8 = buildRC(dna[1], depth[1], stateChangeCost[1]);
508 RenderCommand c0 = buildRC(dna[0], depth[2], stateChangeCost[1]);
509
510 RenderCommand c2 = buildRC(dna[2], depth[2], stateChangeCost[0]);
511 RenderCommand c9 = buildRC(dna[2], depth[0], stateChangeCost[0]);
512 RenderCommand c1 = buildRC(dna[1], depth[0], stateChangeCost[0]);
513 RenderCommand c7 = buildRC(dna[0], depth[2], stateChangeCost[0]);
514 RenderCommand c6 = buildRC(dna[0], depth[1], stateChangeCost[0]);
515
516 rawCommands = { c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 };
517
518 // WHEN
519 renderView.addSortType(sortTypes);
520
521 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
522 view->data.commands = rawCommands;
523 view->indices.resize(new_size: rawCommands.size());
524 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
525
526 renderView.setRenderCommandDataView(view);
527
528
529 renderView.sort();
530
531 // THEN
532 const std::vector<RenderCommand> &sortedCommands = view->data.commands;
533 const std::vector<size_t> &sortedCommandIndices = view->indices;
534 QCOMPARE(rawCommands.size(), sortedCommands.size());
535
536 // Ordered by higher state, higher shaderDNA and higher depth
537 QCOMPARE(c0, sortedCommands.at(sortedCommandIndices[4]));
538 QCOMPARE(c3, sortedCommands.at(sortedCommandIndices[1]));
539 QCOMPARE(c4, sortedCommands.at(sortedCommandIndices[2]));
540 QCOMPARE(c5, sortedCommands.at(sortedCommandIndices[0]));
541 QCOMPARE(c8, sortedCommands.at(sortedCommandIndices[3]));
542
543 QCOMPARE(c1, sortedCommands.at(sortedCommandIndices[7]));
544 QCOMPARE(c2, sortedCommands.at(sortedCommandIndices[5]));
545 QCOMPARE(c6, sortedCommands.at(sortedCommandIndices[9]));
546 QCOMPARE(c7, sortedCommands.at(sortedCommandIndices[8]));
547 QCOMPARE(c9, sortedCommands.at(sortedCommandIndices[6]));
548
549 // RenderCommands are deleted by RenderView dtor
550 renderer.shutdown();
551 }
552
553 void checkRenderCommandTextureSorting()
554 {
555 // GIVEN
556 RenderView renderView;
557 QVector<QSortPolicy::SortType> sortTypes;
558
559 sortTypes.push_back(t: QSortPolicy::Texture);
560
561
562 Qt3DCore::QNodeId tex1 = Qt3DCore::QNodeId::createId();
563 Qt3DCore::QNodeId tex2 = Qt3DCore::QNodeId::createId();
564 Qt3DCore::QNodeId tex3 = Qt3DCore::QNodeId::createId();
565 Qt3DCore::QNodeId tex4 = Qt3DCore::QNodeId::createId();
566
567 RenderCommand a;
568 {
569 ShaderParameterPack pack;
570 pack.setTexture(glslNameId: 0, uniformArrayIndex: 0, id: tex1);
571 pack.setTexture(glslNameId: 1, uniformArrayIndex: 0, id: tex3);
572 pack.setTexture(glslNameId: 2, uniformArrayIndex: 0, id: tex4);
573 pack.setTexture(glslNameId: 3, uniformArrayIndex: 0, id: tex2);
574 a.m_parameterPack = pack;
575 }
576 RenderCommand b;
577 RenderCommand c;
578 {
579 ShaderParameterPack pack;
580 pack.setTexture(glslNameId: 0, uniformArrayIndex: 0, id: tex1);
581 pack.setTexture(glslNameId: 3, uniformArrayIndex: 0, id: tex2);
582 c.m_parameterPack = pack;
583 }
584 RenderCommand d;
585 {
586 ShaderParameterPack pack;
587 pack.setTexture(glslNameId: 1, uniformArrayIndex: 0, id: tex3);
588 pack.setTexture(glslNameId: 2, uniformArrayIndex: 0, id: tex4);
589 d.m_parameterPack = pack;
590 }
591 RenderCommand e;
592 {
593 ShaderParameterPack pack;
594 pack.setTexture(glslNameId: 3, uniformArrayIndex: 0, id: tex2);
595 e.m_parameterPack = pack;
596 }
597 RenderCommand f;
598 {
599 ShaderParameterPack pack;
600 pack.setTexture(glslNameId: 3, uniformArrayIndex: 0, id: tex2);
601 f.m_parameterPack = pack;
602 }
603 RenderCommand g;
604 {
605 ShaderParameterPack pack;
606 pack.setTexture(glslNameId: 0, uniformArrayIndex: 0, id: tex1);
607 pack.setTexture(glslNameId: 1, uniformArrayIndex: 0, id: tex3);
608 pack.setTexture(glslNameId: 2, uniformArrayIndex: 0, id: tex4);
609 pack.setTexture(glslNameId: 3, uniformArrayIndex: 0, id: tex2);
610 g.m_parameterPack = pack;
611 }
612
613 // WHEN
614 std::vector<RenderCommand> rawCommands = {a, b, c, d, e, f, g};
615 renderView.addSortType(sortTypes);
616
617 EntityRenderCommandDataViewPtr view = EntityRenderCommandDataViewPtr::create();
618 view->data.commands = rawCommands;
619 view->indices.resize(new_size: rawCommands.size());
620 std::iota(first: view->indices.begin(), last: view->indices.end(), value: 0);
621
622 renderView.setRenderCommandDataView(view);
623
624 renderView.sort();
625
626 // THEN
627 const std::vector<RenderCommand> &sortedCommands = view->data.commands;
628 const std::vector<size_t> &sortedCommandIndices = view->indices;
629 QCOMPARE(rawCommands.size(), sortedCommands.size());
630 QCOMPARE(sortedCommands.at(sortedCommandIndices[0]), a);
631 QCOMPARE(sortedCommands.at(sortedCommandIndices[1]), g);
632 QCOMPARE(sortedCommands.at(sortedCommandIndices[2]), d);
633 QCOMPARE(sortedCommands.at(sortedCommandIndices[3]), c);
634 QCOMPARE(sortedCommands.at(sortedCommandIndices[4]), e);
635 QCOMPARE(sortedCommands.at(sortedCommandIndices[5]), f);
636 QCOMPARE(sortedCommands.at(sortedCommandIndices[6]), b);
637 // RenderCommands are deleted by RenderView dtor
638 }
639private:
640};
641
642} // OpenGL
643
644} // Render
645
646} // Qt3DRender
647
648QT_END_NAMESPACE
649
650//APPLESS_
651QTEST_MAIN(Qt3DRender::Render::OpenGL::tst_RenderViews)
652
653#include "tst_renderviews.moc"
654

source code of qt3d/tests/auto/render/opengl/renderviews/tst_renderviews.cpp