1/****************************************************************************
2**
3** Copyright (C) 2020 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/QtTest>
30#include <QMutex>
31#include <QWaitCondition>
32#include <QThread>
33#include <Qt3DRender/qrenderaspect.h>
34#include <Qt3DRender/private/offscreensurfacehelper_p.h>
35#include <Qt3DRender/private/rendersettings_p.h>
36#include <Qt3DRender/private/viewportnode_p.h>
37#include <Qt3DRender/private/job_common_p.h>
38#include <Qt3DRender/private/entity_p.h>
39
40#include "testaspect.h"
41#include "testrenderer.h"
42
43class TestRendererAspect : public Qt3DRender::TestAspect {
44public:
45 TestRendererAspect(Qt3DCore::QEntity *root) : Qt3DRender::TestAspect(root) {
46 auto d = Qt3DCore::QAbstractAspectPrivate::get(aspect: this);
47 d->m_rootId = root->id();
48 }
49
50 void replaceWithTestRenderer() {
51 auto daspect = Qt3DRender::QRenderAspectPrivate::get(q: this);
52
53 auto sceneRoot = daspect->m_renderer->sceneRoot();
54 daspect->m_renderer->shutdown();
55 delete daspect->m_renderer;
56 daspect->m_renderer = new TestRenderer();
57 daspect->m_renderer->setNodeManagers(daspect->m_nodeManagers);
58 daspect->m_renderer->setOffscreenSurfaceHelper(daspect->m_offscreenHelper);
59 sceneRoot->setRenderer(daspect->m_renderer);
60 daspect->m_renderer->setSceneRoot(sceneRoot);
61
62 // Give it a setting instance
63 Qt3DRender::Render::RenderSettings settings;
64 // owned by FG manager
65 Qt3DRender::Render::ViewportNode *fgRoot = new Qt3DRender::Render::ViewportNode();
66 const Qt3DCore::QNodeId fgRootId = Qt3DCore::QNodeId::createId();
67
68 daspect->m_nodeManagers->frameGraphManager()->appendNode(id: fgRootId, node: fgRoot);
69 settings.setActiveFrameGraphId(fgRootId);
70
71 daspect->m_renderer->setSettings(&settings);
72 }
73};
74
75class tst_Aspect : public QObject
76{
77 Q_OBJECT
78public :
79 tst_Aspect() = default;
80 ~tst_Aspect() = default;
81
82private Q_SLOTS:
83
84 void checkJobs()
85 {
86 // GIVEN
87 Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
88 QScopedPointer<TestRendererAspect> aspect(new TestRendererAspect(rootEntity));
89 auto daspect = Qt3DRender::QRenderAspectPrivate::get(q: aspect.data());
90 daspect->m_renderAfterJobs = true;
91 aspect->onEngineStartup();
92
93 // replace with empty renderer
94 aspect->replaceWithTestRenderer();
95
96 // WHEN
97 daspect->m_renderer->markDirty(changes: Qt3DRender::Render::AbstractRenderer::AllDirty, node: nullptr);
98
99 auto jobs = daspect->jobsToExecute(time: 1.);
100// qDebug() << jobs.size();
101// for (auto job: jobs)
102// qDebug() << Qt3DCore::QAspectJobPrivate::get(job.data())->m_jobName;
103
104 // THEN -> AllDirty
105 QCOMPARE(jobs.size(),
106 1 + // UpdateTreeEnabled
107 1 + // UpdateTransform
108 1 + // UpdateWorldBoundingVolume
109 1 + // CalcBoundingVolume
110 1 + // ExpandBoundingVolume
111 1 + // SyncLoadingJobs
112 1 + // UpdateSkinningPalette
113 1 + // UpdateLevelOfDetail
114 1 + // UpdateLayerEntity
115 1 + // PickBoundingVolume
116 1 + // RayCasting
117 0 // No skeleton, no scene loading, no geometry, no buffers
118 );
119
120 // WHEN
121 daspect->m_renderer->clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
122 jobs = daspect->jobsToExecute(time: 1.);
123
124 // THEN -> Nothing dirty
125 QCOMPARE(jobs.size(),
126 1 + // SyncLoadingJobs
127 1 + // UpdateSkinningPalette
128 1 + // UpdateLevelOfDetail
129 1 + // PickBoundingVolume
130 1 + // RayCasting
131 0 // No skeleton, no scene loading, no geometry, no buffers
132 );
133
134 // WHEN
135 daspect->m_renderer->clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
136 daspect->m_renderer->markDirty(changes: Qt3DRender::Render::AbstractRenderer::EntityEnabledDirty, node: nullptr);
137 jobs = daspect->jobsToExecute(time: 1.);
138
139 // THEN -> enabled dirty
140 QCOMPARE(jobs.size(),
141 1 + // UpdateTreeEnabled
142 1 + // UpdateTransform
143 1 + // UpdateWorldBoundingVolume
144 1 + // CalcBoundingVolume
145 1 + // ExpandBoundingVolume
146 1 + // SyncLoadingJobs
147 1 + // UpdateSkinningPalette
148 1 + // UpdateLevelOfDetail
149 1 + // PickBoundingVolume
150 1 + // RayCasting
151 0 // No skeleton, no scene loading, no geometry, no buffers
152 );
153
154 // WHEN
155 daspect->m_renderer->clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
156 daspect->m_renderer->markDirty(changes: Qt3DRender::Render::AbstractRenderer::TransformDirty, node: nullptr);
157 jobs = daspect->jobsToExecute(time: 1.);
158
159 // THEN -> transform dirty
160 QCOMPARE(jobs.size(),
161 1 + // UpdateTransform
162 1 + // UpdateWorldBoundingVolume
163 1 + // ExpandBoundingVolume
164 1 + // SyncLoadingJobs
165 1 + // UpdateSkinningPalette
166 1 + // UpdateLevelOfDetail
167 1 + // PickBoundingVolume
168 1 + // RayCasting
169 0 // No skeleton, no scene loading, no geometry, no buffers
170 );
171
172 // WHEN
173 daspect->m_renderer->clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
174 daspect->m_renderer->markDirty(changes: Qt3DRender::Render::AbstractRenderer::GeometryDirty, node: nullptr);
175 jobs = daspect->jobsToExecute(time: 1.);
176
177 // THEN -> geometry dirty
178 QCOMPARE(jobs.size(),
179 1 + // CalcBoundingVolume
180 1 + // ExpandBoundingVolume
181 1 + // SyncLoadingJobs
182 1 + // UpdateSkinningPalette
183 1 + // UpdateLevelOfDetail
184 1 + // PickBoundingVolume
185 1 + // RayCasting
186 0 // No skeleton, no scene loading, no geometry, no buffers
187 );
188 }
189};
190
191QTEST_MAIN(tst_Aspect)
192
193#include "tst_aspect.moc"
194

source code of qt3d/tests/auto/render/aspect/tst_aspect.cpp