1/****************************************************************************
2**
3** Copyright (C) 2015 Paul Lemire
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
31#include <Qt3DRender/private/vsyncframeadvanceservice_p.h>
32
33class FakeRenderThread final : public QThread
34{
35public:
36 FakeRenderThread(Qt3DRender::Render::VSyncFrameAdvanceService *tickService)
37 : m_tickService(tickService)
38 , m_running(1)
39 , m_submitCount(0)
40 {
41 }
42
43 int submitCount() const { return m_submitCount; }
44
45 void stopRunning()
46 {
47 m_running.fetchAndStoreOrdered(newValue: 0);
48 m_submitSemaphore.release(n: 1);
49 }
50
51 void enqueueRenderView()
52 {
53 m_submitSemaphore.release(n: 1);
54 }
55
56protected:
57 // QThread interface
58 void run() final
59 {
60 m_tickService->proceedToNextFrame();
61
62 while (true) {
63 if (!isReadyToSubmit())
64 break;
65 ++m_submitCount;
66 m_tickService->proceedToNextFrame();
67 }
68 }
69
70private:
71 bool isReadyToSubmit()
72 {
73 m_submitSemaphore.acquire(n: 1);
74 return m_running.loadRelaxed() == 1;
75 }
76
77 Qt3DRender::Render::VSyncFrameAdvanceService *m_tickService;
78 QAtomicInt m_running;
79 QSemaphore m_submitSemaphore;
80 int m_submitCount;
81};
82
83class tst_VSyncFrameAdvanceService : public QObject
84{
85 Q_OBJECT
86
87private Q_SLOTS:
88
89 void checkSynchronisation()
90 {
91 // GIVEN
92 Qt3DRender::Render::VSyncFrameAdvanceService tickService(true);
93 FakeRenderThread renderThread(&tickService);
94
95 // WHEN
96 renderThread.start();
97
98 for (int i = 0; i < 10; ++i) {
99 tickService.waitForNextFrame();
100 renderThread.enqueueRenderView();
101 }
102
103 tickService.waitForNextFrame();
104
105 renderThread.stopRunning();
106 renderThread.wait();
107
108 // THEN
109 QCOMPARE(renderThread.submitCount(), 10);
110 }
111};
112
113QTEST_MAIN(tst_VSyncFrameAdvanceService)
114
115#include "tst_vsyncframeadvanceservice.moc"
116

source code of qt3d/tests/auto/render/vsyncframeadvanceservice/tst_vsyncframeadvanceservice.cpp