KWin
Loading...
Searching...
No Matches
test_shm_pool.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6// Qt
7#include <QImage>
8#include <QSignalSpy>
9#include <QTest>
10// KWin
11#include "wayland/compositor.h"
12#include "wayland/display.h"
13#include "wayland/surface.h"
14
15#include "KWayland/Client/compositor.h"
16#include "KWayland/Client/connection_thread.h"
17#include "KWayland/Client/registry.h"
18#include "KWayland/Client/shm_pool.h"
19#include "KWayland/Client/surface.h"
20
21class TestShmPool : public QObject
22{
23 Q_OBJECT
24public:
25 explicit TestShmPool(QObject *parent = nullptr);
26private Q_SLOTS:
27 void init();
28 void cleanup();
29
30 void testCreateBufferNullImage();
31 void testCreateBufferNullSize();
32 void testCreateBufferInvalidSize();
33 void testCreateBufferFromImage();
34 void testCreateBufferFromImageWithAlpha();
35 void testCreateBufferFromData();
36 void testReuseBuffer();
37
38private:
39 KWin::Display *m_display;
40 KWayland::Client::ConnectionThread *m_connection;
41 KWayland::Client::Compositor *m_compositor;
42 KWayland::Client::ShmPool *m_shmPool;
43 QThread *m_thread;
44};
45
46static const QString s_socketName = QStringLiteral("kwin-test-wayland-surface-0");
47
49 : QObject(parent)
50 , m_display(nullptr)
51 , m_connection(nullptr)
52 , m_compositor(nullptr)
53 , m_shmPool(nullptr)
54 , m_thread(nullptr)
55{
56}
57
58void TestShmPool::init()
59{
60 using namespace KWin;
61 delete m_display;
62 m_display = new KWin::Display(this);
63 m_display->addSocketName(s_socketName);
64 m_display->start();
65 QVERIFY(m_display->isRunning());
66
67 // setup connection
68 m_connection = new KWayland::Client::ConnectionThread;
69 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
70 m_connection->setSocketName(s_socketName);
71
72 m_thread = new QThread(this);
73 m_connection->moveToThread(m_thread);
74 m_thread->start();
75
76 m_connection->initConnection();
77 QVERIFY(connectedSpy.wait());
78
79 KWayland::Client::Registry registry;
80 QSignalSpy shmSpy(&registry, &KWayland::Client::Registry::shmAnnounced);
81 registry.create(m_connection->display());
82 QVERIFY(registry.isValid());
83 registry.setup();
84
85 // here we need a shm pool
86 m_display->createShm();
87
88 QVERIFY(shmSpy.wait());
89 m_shmPool = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this);
90}
91
92void TestShmPool::cleanup()
93{
94 if (m_compositor) {
95 delete m_compositor;
96 m_compositor = nullptr;
97 }
98 if (m_shmPool) {
99 delete m_shmPool;
100 m_shmPool = nullptr;
101 }
102 if (m_thread) {
103 m_thread->quit();
104 m_thread->wait();
105 delete m_thread;
106 m_thread = nullptr;
107 }
108 delete m_connection;
109 m_connection = nullptr;
110
111 delete m_display;
112 m_display = nullptr;
113}
114
115void TestShmPool::testCreateBufferNullImage()
116{
117 QVERIFY(m_shmPool->isValid());
118 QImage img;
119 QVERIFY(img.isNull());
120 QVERIFY(!m_shmPool->createBuffer(img));
121}
122
123void TestShmPool::testCreateBufferNullSize()
124{
125 QVERIFY(m_shmPool->isValid());
126 QSize size(0, 0);
127 QVERIFY(size.isNull());
128 QVERIFY(!m_shmPool->createBuffer(size, 0, nullptr));
129}
130
131void TestShmPool::testCreateBufferInvalidSize()
132{
133 QVERIFY(m_shmPool->isValid());
134 QSize size;
135 QVERIFY(!size.isValid());
136 QVERIFY(!m_shmPool->createBuffer(size, 0, nullptr));
137}
138
139void TestShmPool::testCreateBufferFromImage()
140{
141 QVERIFY(m_shmPool->isValid());
142 QImage img(24, 24, QImage::Format_RGB32);
143 img.fill(Qt::black);
144 QVERIFY(!img.isNull());
145 auto buffer = m_shmPool->createBuffer(img).toStrongRef();
146 QVERIFY(buffer);
147 QCOMPARE(buffer->size(), img.size());
148 QImage img2(buffer->address(), img.width(), img.height(), QImage::Format_RGB32);
149 QCOMPARE(img2, img);
150}
151
152void TestShmPool::testCreateBufferFromImageWithAlpha()
153{
154 QVERIFY(m_shmPool->isValid());
155 QImage img(24, 24, QImage::Format_ARGB32_Premultiplied);
156 img.fill(QColor(255, 0, 0, 100)); // red with alpha
157 QVERIFY(!img.isNull());
158 auto buffer = m_shmPool->createBuffer(img).toStrongRef();
159 QVERIFY(buffer);
160 QCOMPARE(buffer->size(), img.size());
161 QImage img2(buffer->address(), img.width(), img.height(), QImage::Format_ARGB32_Premultiplied);
162 QCOMPARE(img2, img);
163}
164
165void TestShmPool::testCreateBufferFromData()
166{
167 QVERIFY(m_shmPool->isValid());
168 QImage img(24, 24, QImage::Format_ARGB32_Premultiplied);
169 img.fill(Qt::black);
170 QVERIFY(!img.isNull());
171 auto buffer = m_shmPool->createBuffer(img.size(), img.bytesPerLine(), img.constBits()).toStrongRef();
172 QVERIFY(buffer);
173 QCOMPARE(buffer->size(), img.size());
174 QImage img2(buffer->address(), img.width(), img.height(), QImage::Format_ARGB32_Premultiplied);
175 QCOMPARE(img2, img);
176}
177
178void TestShmPool::testReuseBuffer()
179{
180 QVERIFY(m_shmPool->isValid());
181 QImage img(24, 24, QImage::Format_ARGB32_Premultiplied);
182 img.fill(Qt::black);
183 QVERIFY(!img.isNull());
184 auto buffer = m_shmPool->createBuffer(img).toStrongRef();
185 QVERIFY(buffer);
186 buffer->setReleased(true);
187 buffer->setUsed(false);
188
189 // same image should get the same buffer
190 auto buffer2 = m_shmPool->createBuffer(img).toStrongRef();
191 QCOMPARE(buffer, buffer2);
192 buffer2->setReleased(true);
193 buffer2->setUsed(false);
194
195 // image with different size should get us a new buffer
196 auto buffer3 = m_shmPool->getBuffer(QSize(10, 10), 8);
197 QVERIFY(buffer3 != buffer2);
198
199 // image with a different format should get us a new buffer
200 QImage img2(24, 24, QImage::Format_RGB32);
201 img2.fill(Qt::black);
202 QVERIFY(!img2.isNull());
203 auto buffer4 = m_shmPool->createBuffer(img2).toStrongRef();
204 QVERIFY(buffer4);
205 QVERIFY(buffer4 != buffer2);
206 QVERIFY(buffer4 != buffer3);
207}
208
209QTEST_GUILESS_MAIN(TestShmPool)
210#include "test_shm_pool.moc"
Class holding the Wayland server display loop.
Definition display.h:34
void createShm()
Definition display.cpp:128
bool addSocketName(const QString &name=QString())
Definition display.cpp:68
bool isRunning() const
Definition display.cpp:144
bool start()
Definition display.cpp:92
TestShmPool(QObject *parent=nullptr)