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/qrendertarget.h> |
32 | #include <Qt3DRender/qrendertargetoutput.h> |
33 | #include <Qt3DRender/private/qrendertarget_p.h> |
34 | #include <Qt3DRender/private/rendertarget_p.h> |
35 | #include <Qt3DRender/private/managers_p.h> |
36 | #include "qbackendnodetester.h" |
37 | #include "testrenderer.h" |
38 | |
39 | class tst_RenderTarget : public Qt3DCore::QBackendNodeTester |
40 | { |
41 | Q_OBJECT |
42 | |
43 | private Q_SLOTS: |
44 | |
45 | void checkInitialState() |
46 | { |
47 | // GIVEN |
48 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
49 | |
50 | // THEN |
51 | QCOMPARE(backendRenderTarget.isEnabled(), false); |
52 | QVERIFY(backendRenderTarget.peerId().isNull()); |
53 | QVERIFY(backendRenderTarget.renderOutputs().empty()); |
54 | } |
55 | |
56 | void checkCleanupState() |
57 | { |
58 | // GIVEN |
59 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
60 | |
61 | // WHEN |
62 | backendRenderTarget.setEnabled(true); |
63 | backendRenderTarget.appendRenderOutput(outputId: Qt3DCore::QNodeId::createId()); |
64 | backendRenderTarget.appendRenderOutput(outputId: Qt3DCore::QNodeId::createId()); |
65 | |
66 | backendRenderTarget.cleanup(); |
67 | |
68 | // THEN |
69 | QCOMPARE(backendRenderTarget.isEnabled(), false); |
70 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 0); |
71 | } |
72 | |
73 | void checkInitializeFromPeer() |
74 | { |
75 | // GIVEN |
76 | TestRenderer renderer; |
77 | Qt3DRender::QRenderTarget renderTarget; |
78 | Qt3DRender::QRenderTargetOutput renderTargetOuput; |
79 | renderTarget.addOutput(output: &renderTargetOuput); |
80 | |
81 | { |
82 | // WHEN |
83 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
84 | backendRenderTarget.setRenderer(&renderer); |
85 | simulateInitializationSync(frontend: &renderTarget, backend: &backendRenderTarget); |
86 | // THEN |
87 | QCOMPARE(backendRenderTarget.isEnabled(), true); |
88 | QCOMPARE(backendRenderTarget.peerId(), renderTarget.id()); |
89 | QCOMPARE(backendRenderTarget.renderOutputs(), QVector<Qt3DCore::QNodeId>() << renderTargetOuput.id()); |
90 | } |
91 | { |
92 | // WHEN |
93 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
94 | renderTarget.setEnabled(false); |
95 | backendRenderTarget.setRenderer(&renderer); |
96 | simulateInitializationSync(frontend: &renderTarget, backend: &backendRenderTarget); |
97 | |
98 | // THEN |
99 | QCOMPARE(backendRenderTarget.peerId(), renderTarget.id()); |
100 | QCOMPARE(backendRenderTarget.isEnabled(), false); |
101 | } |
102 | } |
103 | |
104 | void checkAddNoDuplicateOutput() |
105 | { |
106 | // GIVEN |
107 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
108 | |
109 | // THEN |
110 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 0); |
111 | |
112 | // WHEN |
113 | Qt3DCore::QNodeId renderTargetOutputId = Qt3DCore::QNodeId::createId(); |
114 | backendRenderTarget.appendRenderOutput(outputId: renderTargetOutputId); |
115 | |
116 | // THEN |
117 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 1); |
118 | |
119 | // WHEN |
120 | backendRenderTarget.appendRenderOutput(outputId: renderTargetOutputId); |
121 | |
122 | // THEN |
123 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 1); |
124 | } |
125 | |
126 | void checkAddRemoveOutput() |
127 | { |
128 | // GIVEN |
129 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
130 | |
131 | // THEN |
132 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 0); |
133 | |
134 | // WHEN |
135 | Qt3DCore::QNodeId renderTargetOutputId1 = Qt3DCore::QNodeId::createId(); |
136 | Qt3DCore::QNodeId renderTargetOutputId2 = Qt3DCore::QNodeId::createId(); |
137 | backendRenderTarget.appendRenderOutput(outputId: renderTargetOutputId1); |
138 | backendRenderTarget.appendRenderOutput(outputId: renderTargetOutputId2); |
139 | |
140 | // THEN |
141 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 2); |
142 | |
143 | // WHEN |
144 | backendRenderTarget.removeRenderOutput(outputId: Qt3DCore::QNodeId()); |
145 | |
146 | // THEN |
147 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 2); |
148 | |
149 | // WHEN |
150 | backendRenderTarget.removeRenderOutput(outputId: renderTargetOutputId1); |
151 | |
152 | // THEN |
153 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 1); |
154 | |
155 | // WHEN |
156 | backendRenderTarget.removeRenderOutput(outputId: renderTargetOutputId1); |
157 | |
158 | // THEN |
159 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 1); |
160 | |
161 | // WHEN |
162 | backendRenderTarget.removeRenderOutput(outputId: renderTargetOutputId2); |
163 | |
164 | // THEN |
165 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 0); |
166 | } |
167 | |
168 | void checkSceneChangeEvents() |
169 | { |
170 | // GIVEN |
171 | Qt3DRender::QRenderTarget renderTarget; |
172 | Qt3DRender::Render::RenderTarget backendRenderTarget; |
173 | TestRenderer renderer; |
174 | backendRenderTarget.setRenderer(&renderer); |
175 | simulateInitializationSync(frontend: &renderTarget, backend: &backendRenderTarget); |
176 | |
177 | { |
178 | // WHEN |
179 | const bool newValue = false; |
180 | renderTarget.setEnabled(newValue); |
181 | backendRenderTarget.syncFromFrontEnd(frontEnd: &renderTarget, firstTime: false); |
182 | |
183 | // THEN |
184 | QCOMPARE(backendRenderTarget.isEnabled(), newValue); |
185 | } |
186 | { |
187 | // WHEN |
188 | Qt3DRender::QRenderTargetOutput targetOutput; |
189 | renderTarget.addOutput(output: &targetOutput); |
190 | backendRenderTarget.syncFromFrontEnd(frontEnd: &renderTarget, firstTime: false); |
191 | |
192 | // THEN |
193 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 1); |
194 | QCOMPARE(backendRenderTarget.renderOutputs().first(), targetOutput.id()); |
195 | QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); |
196 | renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty); |
197 | |
198 | // WHEN |
199 | renderTarget.removeOutput(output: &targetOutput); |
200 | backendRenderTarget.syncFromFrontEnd(frontEnd: &renderTarget, firstTime: false); |
201 | |
202 | // THEN |
203 | QCOMPARE(backendRenderTarget.renderOutputs().size(), 0); |
204 | QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); |
205 | renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty); |
206 | } |
207 | } |
208 | |
209 | void checkRenderTargetManager() |
210 | { |
211 | // GIVEN |
212 | Qt3DRender::QRenderTarget renderTarget; |
213 | TestRenderer renderer; |
214 | Qt3DRender::Render::RenderTargetManager manager; |
215 | Qt3DRender::Render::RenderTargetFunctor creationFunctor(&renderer, &manager); |
216 | |
217 | // THEN |
218 | QVERIFY(manager.renderTargetIdsToCleanup().isEmpty()); |
219 | |
220 | // WHEN |
221 | Qt3DCore::QNodeCreatedChangeBase changeObj(&renderTarget); |
222 | Qt3DCore::QNodeCreatedChangeBasePtr changePtr(&changeObj, [](Qt3DCore::QNodeCreatedChangeBase *) {}); |
223 | auto backend = creationFunctor.create(change: changePtr); |
224 | |
225 | // THEN |
226 | QVERIFY(backend != nullptr); |
227 | QVERIFY(manager.renderTargetIdsToCleanup().isEmpty()); |
228 | |
229 | { |
230 | // WHEN |
231 | auto sameBackend = creationFunctor.get(id: renderTarget.id()); |
232 | // THEN |
233 | QCOMPARE(backend, sameBackend); |
234 | } |
235 | |
236 | // WHEN |
237 | creationFunctor.destroy(id: renderTarget.id()); |
238 | |
239 | // THEN -> Should be in list of ids to remove and return null on get |
240 | QVERIFY(manager.renderTargetIdsToCleanup().contains(renderTarget.id())); |
241 | QVERIFY(creationFunctor.get(renderTarget.id()) == nullptr); |
242 | |
243 | // WHEN -> Should be removed from list of ids to remove |
244 | creationFunctor.create(change: changePtr); |
245 | |
246 | // THEN |
247 | QVERIFY(manager.renderTargetIdsToCleanup().isEmpty()); |
248 | QVERIFY(creationFunctor.get(renderTarget.id()) != nullptr); |
249 | } |
250 | }; |
251 | |
252 | QTEST_MAIN(tst_RenderTarget) |
253 | |
254 | #include "tst_rendertarget.moc" |
255 | |