File indexing completed on 2024-11-10 04:56:17
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 // Qt 0007 #include <QImage> 0008 #include <QSignalSpy> 0009 #include <QTest> 0010 // KWin 0011 #include "wayland/compositor.h" 0012 #include "wayland/display.h" 0013 #include "wayland/surface.h" 0014 0015 #include "KWayland/Client/compositor.h" 0016 #include "KWayland/Client/connection_thread.h" 0017 #include "KWayland/Client/registry.h" 0018 #include "KWayland/Client/shm_pool.h" 0019 #include "KWayland/Client/surface.h" 0020 0021 class TestShmPool : public QObject 0022 { 0023 Q_OBJECT 0024 public: 0025 explicit TestShmPool(QObject *parent = nullptr); 0026 private Q_SLOTS: 0027 void init(); 0028 void cleanup(); 0029 0030 void testCreateBufferNullImage(); 0031 void testCreateBufferNullSize(); 0032 void testCreateBufferInvalidSize(); 0033 void testCreateBufferFromImage(); 0034 void testCreateBufferFromImageWithAlpha(); 0035 void testCreateBufferFromData(); 0036 void testReuseBuffer(); 0037 0038 private: 0039 KWin::Display *m_display; 0040 KWayland::Client::ConnectionThread *m_connection; 0041 KWayland::Client::Compositor *m_compositor; 0042 KWayland::Client::ShmPool *m_shmPool; 0043 QThread *m_thread; 0044 }; 0045 0046 static const QString s_socketName = QStringLiteral("kwin-test-wayland-surface-0"); 0047 0048 TestShmPool::TestShmPool(QObject *parent) 0049 : QObject(parent) 0050 , m_display(nullptr) 0051 , m_connection(nullptr) 0052 , m_compositor(nullptr) 0053 , m_shmPool(nullptr) 0054 , m_thread(nullptr) 0055 { 0056 } 0057 0058 void TestShmPool::init() 0059 { 0060 using namespace KWin; 0061 delete m_display; 0062 m_display = new KWin::Display(this); 0063 m_display->addSocketName(s_socketName); 0064 m_display->start(); 0065 QVERIFY(m_display->isRunning()); 0066 0067 // setup connection 0068 m_connection = new KWayland::Client::ConnectionThread; 0069 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected); 0070 m_connection->setSocketName(s_socketName); 0071 0072 m_thread = new QThread(this); 0073 m_connection->moveToThread(m_thread); 0074 m_thread->start(); 0075 0076 m_connection->initConnection(); 0077 QVERIFY(connectedSpy.wait()); 0078 0079 KWayland::Client::Registry registry; 0080 QSignalSpy shmSpy(®istry, &KWayland::Client::Registry::shmAnnounced); 0081 registry.create(m_connection->display()); 0082 QVERIFY(registry.isValid()); 0083 registry.setup(); 0084 0085 // here we need a shm pool 0086 m_display->createShm(); 0087 0088 QVERIFY(shmSpy.wait()); 0089 m_shmPool = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this); 0090 } 0091 0092 void TestShmPool::cleanup() 0093 { 0094 if (m_compositor) { 0095 delete m_compositor; 0096 m_compositor = nullptr; 0097 } 0098 if (m_shmPool) { 0099 delete m_shmPool; 0100 m_shmPool = nullptr; 0101 } 0102 if (m_thread) { 0103 m_thread->quit(); 0104 m_thread->wait(); 0105 delete m_thread; 0106 m_thread = nullptr; 0107 } 0108 delete m_connection; 0109 m_connection = nullptr; 0110 0111 delete m_display; 0112 m_display = nullptr; 0113 } 0114 0115 void TestShmPool::testCreateBufferNullImage() 0116 { 0117 QVERIFY(m_shmPool->isValid()); 0118 QImage img; 0119 QVERIFY(img.isNull()); 0120 QVERIFY(!m_shmPool->createBuffer(img)); 0121 } 0122 0123 void TestShmPool::testCreateBufferNullSize() 0124 { 0125 QVERIFY(m_shmPool->isValid()); 0126 QSize size(0, 0); 0127 QVERIFY(size.isNull()); 0128 QVERIFY(!m_shmPool->createBuffer(size, 0, nullptr)); 0129 } 0130 0131 void TestShmPool::testCreateBufferInvalidSize() 0132 { 0133 QVERIFY(m_shmPool->isValid()); 0134 QSize size; 0135 QVERIFY(!size.isValid()); 0136 QVERIFY(!m_shmPool->createBuffer(size, 0, nullptr)); 0137 } 0138 0139 void TestShmPool::testCreateBufferFromImage() 0140 { 0141 QVERIFY(m_shmPool->isValid()); 0142 QImage img(24, 24, QImage::Format_RGB32); 0143 img.fill(Qt::black); 0144 QVERIFY(!img.isNull()); 0145 auto buffer = m_shmPool->createBuffer(img).toStrongRef(); 0146 QVERIFY(buffer); 0147 QCOMPARE(buffer->size(), img.size()); 0148 QImage img2(buffer->address(), img.width(), img.height(), QImage::Format_RGB32); 0149 QCOMPARE(img2, img); 0150 } 0151 0152 void TestShmPool::testCreateBufferFromImageWithAlpha() 0153 { 0154 QVERIFY(m_shmPool->isValid()); 0155 QImage img(24, 24, QImage::Format_ARGB32_Premultiplied); 0156 img.fill(QColor(255, 0, 0, 100)); // red with alpha 0157 QVERIFY(!img.isNull()); 0158 auto buffer = m_shmPool->createBuffer(img).toStrongRef(); 0159 QVERIFY(buffer); 0160 QCOMPARE(buffer->size(), img.size()); 0161 QImage img2(buffer->address(), img.width(), img.height(), QImage::Format_ARGB32_Premultiplied); 0162 QCOMPARE(img2, img); 0163 } 0164 0165 void TestShmPool::testCreateBufferFromData() 0166 { 0167 QVERIFY(m_shmPool->isValid()); 0168 QImage img(24, 24, QImage::Format_ARGB32_Premultiplied); 0169 img.fill(Qt::black); 0170 QVERIFY(!img.isNull()); 0171 auto buffer = m_shmPool->createBuffer(img.size(), img.bytesPerLine(), img.constBits()).toStrongRef(); 0172 QVERIFY(buffer); 0173 QCOMPARE(buffer->size(), img.size()); 0174 QImage img2(buffer->address(), img.width(), img.height(), QImage::Format_ARGB32_Premultiplied); 0175 QCOMPARE(img2, img); 0176 } 0177 0178 void TestShmPool::testReuseBuffer() 0179 { 0180 QVERIFY(m_shmPool->isValid()); 0181 QImage img(24, 24, QImage::Format_ARGB32_Premultiplied); 0182 img.fill(Qt::black); 0183 QVERIFY(!img.isNull()); 0184 auto buffer = m_shmPool->createBuffer(img).toStrongRef(); 0185 QVERIFY(buffer); 0186 buffer->setReleased(true); 0187 buffer->setUsed(false); 0188 0189 // same image should get the same buffer 0190 auto buffer2 = m_shmPool->createBuffer(img).toStrongRef(); 0191 QCOMPARE(buffer, buffer2); 0192 buffer2->setReleased(true); 0193 buffer2->setUsed(false); 0194 0195 // image with different size should get us a new buffer 0196 auto buffer3 = m_shmPool->getBuffer(QSize(10, 10), 8); 0197 QVERIFY(buffer3 != buffer2); 0198 0199 // image with a different format should get us a new buffer 0200 QImage img2(24, 24, QImage::Format_RGB32); 0201 img2.fill(Qt::black); 0202 QVERIFY(!img2.isNull()); 0203 auto buffer4 = m_shmPool->createBuffer(img2).toStrongRef(); 0204 QVERIFY(buffer4); 0205 QVERIFY(buffer4 != buffer2); 0206 QVERIFY(buffer4 != buffer3); 0207 } 0208 0209 QTEST_GUILESS_MAIN(TestShmPool) 0210 #include "test_shm_pool.moc"