1/****************************************************************************
2**
3** Copyright (C) 2014 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 <renderqueue_p.h>
34#include <renderview_p.h>
35
36class tst_RenderQueue : public QObject
37{
38 Q_OBJECT
39public :
40 tst_RenderQueue() {}
41 ~tst_RenderQueue() {}
42
43private Q_SLOTS:
44 void setRenderViewCount();
45 void circleQueues();
46 void checkOrder();
47 void checkTimeToSubmit();
48 void concurrentQueueAccess();
49 void resetQueue();
50};
51
52
53void tst_RenderQueue::setRenderViewCount()
54{
55 // GIVEN
56 Qt3DRender::Render::OpenGL::RenderQueue renderQueue;
57
58 // THEN
59 QCOMPARE(renderQueue.wasReset(), true);
60
61 // WHEN
62 renderQueue.setTargetRenderViewCount(7);
63
64 // THEN
65 QCOMPARE(renderQueue.wasReset(), false);
66 QVERIFY(renderQueue.targetRenderViewCount() == 7);
67 QVERIFY(renderQueue.currentRenderViewCount()== 0);
68}
69
70void tst_RenderQueue::circleQueues()
71{
72 // GIVEN
73 Qt3DRender::Render::OpenGL::RenderQueue renderQueue;
74 renderQueue.setTargetRenderViewCount(7);
75
76 // WHEN
77 for (int j = 0; j < 10; j++) {
78
79 // WHEN
80 renderQueue.reset();
81 renderQueue.setTargetRenderViewCount(7);
82
83 // THEN
84 QVERIFY(!renderQueue.isFrameQueueComplete());
85 QCOMPARE(renderQueue.currentRenderViewCount(), 0);
86
87 // WHEN
88 QList<Qt3DRender::Render::OpenGL::RenderView *> renderViews;
89 for (int i = 0; i < 7; i++) {
90 renderViews << new Qt3DRender::Render::OpenGL::RenderView();
91 renderQueue.queueRenderView(renderView: renderViews.at(i), submissionOrderIndex: i);
92 }
93
94 // THEN
95 QVERIFY(renderQueue.isFrameQueueComplete());
96 }
97}
98
99void tst_RenderQueue::checkOrder()
100{
101 // GIVEN
102 Qt3DRender::Render::OpenGL::RenderQueue renderQueue;
103 renderQueue.setTargetRenderViewCount(7);
104 QVector<Qt3DRender::Render::OpenGL::RenderView *> renderViews(7);
105
106 // WHEN
107 for (int i = 0; i < 7; ++i) {
108 int processingOrder = (i % 2 == 0) ? (6 - i) : i;
109 renderViews[processingOrder] = new Qt3DRender::Render::OpenGL::RenderView();
110 renderQueue.queueRenderView(renderView: renderViews[processingOrder], submissionOrderIndex: processingOrder);
111 }
112
113 // THEN
114 QVector<Qt3DRender::Render::OpenGL::RenderView *> frame = renderQueue.nextFrameQueue();
115 for (int i = 0; i < 7; ++i) {
116 QVERIFY(frame[i] == renderViews[i]);
117 }
118}
119
120void tst_RenderQueue::checkTimeToSubmit()
121{
122 // GIVEN
123 Qt3DRender::Render::OpenGL::RenderQueue renderQueue;
124 renderQueue.setTargetRenderViewCount(7);
125 QVector<Qt3DRender::Render::OpenGL::RenderView *> renderViews(7);
126
127 // WHEN
128 for (int i = 0; i < 7; i++) {
129 int processingOrder = (i % 2 == 0) ? (6 - i) : i;
130 renderViews[processingOrder] = new Qt3DRender::Render::OpenGL::RenderView();
131 renderQueue.queueRenderView(renderView: renderViews[processingOrder], submissionOrderIndex: processingOrder);
132
133 // THEN
134 if (i < 6)
135 QVERIFY(!renderQueue.isFrameQueueComplete());
136 else
137 QVERIFY(renderQueue.isFrameQueueComplete());
138 }
139}
140
141class SimpleWorker : public QThread
142{
143 Q_OBJECT
144public:
145 QSemaphore m_waitSubmit;
146 QSemaphore m_waitQueue;
147 Qt3DRender::Render::OpenGL::RenderQueue *m_renderQueues;
148
149public Q_SLOTS:
150
151 void run() final // In Thread
152 {
153 for (int i = 0; i < 5; i++) {
154 m_waitQueue.acquire();
155
156 QVERIFY(m_renderQueues->currentRenderViewCount() == 0);
157 QVERIFY(!m_renderQueues->isFrameQueueComplete());
158
159 for (int j = 0; j < 7; ++j) {
160 // THEN
161 QCOMPARE(m_renderQueues->currentRenderViewCount(), j);
162 // WHEN
163 m_renderQueues->queueRenderView(renderView: new Qt3DRender::Render::OpenGL::RenderView(), submissionOrderIndex: j);
164 // THEN
165 QVERIFY(m_renderQueues->targetRenderViewCount() == 7);
166 QCOMPARE(m_renderQueues->currentRenderViewCount(), j + 1);
167 QVERIFY(m_renderQueues->isFrameQueueComplete() == (j == 6));
168 QThread::msleep(20); // Simulates business
169 }
170
171 QVERIFY(m_renderQueues->isFrameQueueComplete());
172 m_waitSubmit.release();
173 }
174 }
175};
176
177
178void tst_RenderQueue::concurrentQueueAccess()
179{
180 // GIVEN
181 Qt3DRender::Render::OpenGL::RenderQueue *renderQueue = new Qt3DRender::Render::OpenGL::RenderQueue;
182
183 SimpleWorker *jobsThread = new SimpleWorker();
184 renderQueue->setTargetRenderViewCount(7);
185 jobsThread->m_renderQueues = renderQueue;
186
187 // THEN
188 QVERIFY(jobsThread->m_renderQueues->targetRenderViewCount() == renderQueue->targetRenderViewCount());
189 QVERIFY(jobsThread->m_renderQueues->currentRenderViewCount() == renderQueue->currentRenderViewCount());
190
191 // Start thread
192 jobsThread->start();
193
194 jobsThread->m_waitQueue.release();
195
196 for (int i = 0; i < 5; ++i) {
197 jobsThread->m_waitSubmit.acquire();
198
199 // WHEN unlocked
200 // THEN
201 QVERIFY (renderQueue->isFrameQueueComplete());
202 QCOMPARE(renderQueue->nextFrameQueue().size(), renderQueue->targetRenderViewCount());
203
204 // reset queue for next frame
205 renderQueue->reset();
206 renderQueue->setTargetRenderViewCount(7);
207 jobsThread->m_waitQueue.release();
208 }
209 jobsThread->wait();
210}
211
212void tst_RenderQueue::resetQueue()
213{
214 // GIVEN
215 Qt3DRender::Render::OpenGL::RenderQueue renderQueue;
216
217 for (int j = 0; j < 5; j++) {
218 // WHEN
219 renderQueue.setTargetRenderViewCount(5);
220 // THEN
221 QCOMPARE(renderQueue.wasReset(), false);
222 QVERIFY(renderQueue.currentRenderViewCount() == 0);
223
224 // WHEN
225 QVector<Qt3DRender::Render::OpenGL::RenderView *> renderViews(5);
226 for (int i = 0; i < 5; ++i) {
227 renderQueue.queueRenderView(renderView: renderViews.at(i), submissionOrderIndex: i);
228 }
229 // THEN
230 QCOMPARE(renderQueue.currentRenderViewCount(), 5);
231 QVERIFY(renderQueue.isFrameQueueComplete());
232
233 // WHEN
234 renderQueue.reset();
235 QCOMPARE(renderQueue.wasReset(), true);
236 // THEN
237 QVERIFY(renderQueue.currentRenderViewCount() == 0);
238 }
239}
240
241QTEST_APPLESS_MAIN(tst_RenderQueue)
242
243#include "tst_renderqueue.moc"
244

source code of qt3d/tests/auto/render/opengl/renderqueue/tst_renderqueue.cpp