1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
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// TODO Remove in Qt6
30#include <QtCore/qcompilerdetection.h>
31QT_WARNING_DISABLE_DEPRECATED
32
33#include <QtTest/QTest>
34#include <QtTest/QSignalSpy>
35#include <Qt3DCore/qpropertyupdatedchange.h>
36#include <Qt3DCore/private/qnode_p.h>
37#include <Qt3DCore/private/qscene_p.h>
38#include <Qt3DRender/QRenderCapture>
39#include <Qt3DRender/private/qrendercapture_p.h>
40
41#include <QPointer>
42
43#include "testpostmanarbiter.h"
44
45class MyRenderCapture : public Qt3DRender::QRenderCapture
46{
47 Q_OBJECT
48public:
49 MyRenderCapture(Qt3DCore::QNode *parent = nullptr)
50 : Qt3DRender::QRenderCapture(parent)
51 {}
52
53 void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) final
54 {
55 Qt3DRender::QRenderCapture::sceneChangeEvent(change);
56 }
57
58private:
59 friend class tst_QRenderCapture;
60};
61
62class tst_QRenderCapture : public Qt3DCore::QNode
63{
64 Q_OBJECT
65
66private Q_SLOTS:
67
68 void checkCaptureRequest()
69 {
70 // GIVEN
71 TestArbiter arbiter;
72 QScopedPointer<Qt3DRender::QRenderCapture> renderCapture(new Qt3DRender::QRenderCapture());
73 arbiter.setArbiterOnNode(renderCapture.data());
74
75 // WHEN
76 QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture(rect: QRect(10, 15, 20, 50)));
77
78 // THEN
79 QCOMPARE(arbiter.events.size(), 0);
80 QCOMPARE(arbiter.dirtyNodes.size(), 1);
81 QCOMPARE(arbiter.dirtyNodes.front(), renderCapture.data());
82
83 arbiter.dirtyNodes.clear();
84 }
85
86 void checkRenderCaptureReply()
87 {
88 // GIVEN
89 QScopedPointer<MyRenderCapture> renderCapture(new MyRenderCapture());
90 QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture());
91 QImage img = QImage(20, 20, QImage::Format_ARGB32);
92
93 // WHEN
94 Qt3DRender::RenderCaptureDataPtr data = Qt3DRender::RenderCaptureDataPtr::create();
95 data.data()->captureId = 2;
96 data.data()->image = img;
97
98 auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(arguments: renderCapture->id());
99 e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
100 e->setPropertyName("renderCaptureData");
101 e->setValue(QVariant::fromValue(value: data));
102
103 renderCapture->sceneChangeEvent(change: e);
104
105 // THEN
106 QCOMPARE(reply->isComplete(), true);
107 QCOMPARE(reply->image().width(), 20);
108 QCOMPARE(reply->image().height(), 20);
109 QCOMPARE(reply->image().format(), QImage::Format_ARGB32);
110 }
111
112 void checkRenderCaptureDestroy()
113 {
114 // GIVEN
115 QScopedPointer<MyRenderCapture> renderCapture(new MyRenderCapture());
116 QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture());
117 QImage img = QImage(20, 20, QImage::Format_ARGB32);
118 Qt3DRender::RenderCaptureDataPtr data = Qt3DRender::RenderCaptureDataPtr::create();
119 data.data()->captureId = 2;
120 data.data()->image = img;
121 auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(arguments: renderCapture->id());
122 e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
123 e->setPropertyName("renderCaptureData");
124 e->setValue(QVariant::fromValue(value: data));
125
126 // WHEN
127 reply.reset();
128
129 // THEN
130 renderCapture->sceneChangeEvent(change: e); // Should not reset
131 }
132
133 void crashOnRenderCaptureDeletion()
134 {
135 // GIVEN
136 QScopedPointer<Qt3DRender::QRenderCapture> renderCapture(new Qt3DRender::QRenderCapture());
137 QPointer<Qt3DRender::QRenderCaptureReply> renderCaptureReply(renderCapture->requestCapture());
138
139 // THEN
140 QVERIFY(renderCaptureReply);
141
142 // WHEN
143 renderCapture.reset();
144
145 // THEN (Should not crash and delete reply)
146 QVERIFY(!renderCaptureReply);
147 }
148
149};
150
151QTEST_MAIN(tst_QRenderCapture)
152
153#include "tst_qrendercapture.moc"
154

source code of qt3d/tests/auto/render/qrendercapture/tst_qrendercapture.cpp