You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
6.6 KiB
192 lines
6.6 KiB
/* |
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> |
|
|
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
|
*/ |
|
|
|
#include <QSignalSpy> |
|
#include <QTest> |
|
#include <QThread> |
|
|
|
#include "wayland/compositor.h" |
|
#include "wayland/display.h" |
|
#include "wayland/surface.h" |
|
#include "wayland/viewporter.h" |
|
|
|
#include "KWayland/Client/compositor.h" |
|
#include "KWayland/Client/connection_thread.h" |
|
#include "KWayland/Client/event_queue.h" |
|
#include "KWayland/Client/registry.h" |
|
#include "KWayland/Client/shm_pool.h" |
|
#include "KWayland/Client/surface.h" |
|
|
|
#include "qwayland-viewporter.h" |
|
|
|
using namespace KWin; |
|
|
|
class Viewporter : public QtWayland::wp_viewporter |
|
{ |
|
}; |
|
|
|
class Viewport : public QtWayland::wp_viewport |
|
{ |
|
}; |
|
|
|
class TestViewporterInterface : public QObject |
|
{ |
|
Q_OBJECT |
|
|
|
public: |
|
~TestViewporterInterface() override; |
|
|
|
private Q_SLOTS: |
|
void initTestCase(); |
|
void testCropScale(); |
|
|
|
private: |
|
KWayland::Client::ConnectionThread *m_connection; |
|
KWayland::Client::EventQueue *m_queue; |
|
KWayland::Client::Compositor *m_clientCompositor; |
|
KWayland::Client::ShmPool *m_shm; |
|
|
|
QThread *m_thread; |
|
KWin::Display m_display; |
|
CompositorInterface *m_serverCompositor; |
|
Viewporter *m_viewporter; |
|
}; |
|
|
|
static const QString s_socketName = QStringLiteral("kwin-wayland-server-viewporter-test-0"); |
|
|
|
void TestViewporterInterface::initTestCase() |
|
{ |
|
m_display.addSocketName(s_socketName); |
|
m_display.start(); |
|
QVERIFY(m_display.isRunning()); |
|
|
|
m_display.createShm(); |
|
new ViewporterInterface(&m_display); |
|
|
|
m_serverCompositor = new CompositorInterface(&m_display, this); |
|
|
|
m_connection = new KWayland::Client::ConnectionThread; |
|
QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected); |
|
m_connection->setSocketName(s_socketName); |
|
|
|
m_thread = new QThread(this); |
|
m_connection->moveToThread(m_thread); |
|
m_thread->start(); |
|
|
|
m_connection->initConnection(); |
|
QVERIFY(connectedSpy.wait()); |
|
QVERIFY(!m_connection->connections().isEmpty()); |
|
|
|
m_queue = new KWayland::Client::EventQueue(this); |
|
QVERIFY(!m_queue->isValid()); |
|
m_queue->setup(m_connection); |
|
QVERIFY(m_queue->isValid()); |
|
|
|
auto registry = new KWayland::Client::Registry(this); |
|
connect(registry, &KWayland::Client::Registry::interfaceAnnounced, this, [this, registry](const QByteArray &interface, quint32 id, quint32 version) { |
|
if (interface == QByteArrayLiteral("wp_viewporter")) { |
|
m_viewporter = new Viewporter(); |
|
m_viewporter->init(*registry, id, version); |
|
} |
|
}); |
|
QSignalSpy allAnnouncedSpy(registry, &KWayland::Client::Registry::interfaceAnnounced); |
|
QSignalSpy compositorSpy(registry, &KWayland::Client::Registry::compositorAnnounced); |
|
QSignalSpy shmSpy(registry, &KWayland::Client::Registry::shmAnnounced); |
|
registry->setEventQueue(m_queue); |
|
registry->create(m_connection->display()); |
|
QVERIFY(registry->isValid()); |
|
registry->setup(); |
|
QVERIFY(allAnnouncedSpy.wait()); |
|
|
|
m_clientCompositor = registry->createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this); |
|
QVERIFY(m_clientCompositor->isValid()); |
|
|
|
m_shm = registry->createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this); |
|
QVERIFY(m_shm->isValid()); |
|
} |
|
|
|
TestViewporterInterface::~TestViewporterInterface() |
|
{ |
|
if (m_viewporter) { |
|
delete m_viewporter; |
|
m_viewporter = nullptr; |
|
} |
|
if (m_shm) { |
|
delete m_shm; |
|
m_shm = nullptr; |
|
} |
|
if (m_queue) { |
|
delete m_queue; |
|
m_queue = nullptr; |
|
} |
|
if (m_thread) { |
|
m_thread->quit(); |
|
m_thread->wait(); |
|
delete m_thread; |
|
m_thread = nullptr; |
|
} |
|
m_connection->deleteLater(); |
|
m_connection = nullptr; |
|
} |
|
|
|
void TestViewporterInterface::testCropScale() |
|
{ |
|
// Create a test surface. |
|
QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); |
|
std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); |
|
QVERIFY(serverSurfaceCreatedSpy.wait()); |
|
SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); |
|
QVERIFY(serverSurface); |
|
|
|
QSignalSpy serverSurfaceMappedSpy(serverSurface, &SurfaceInterface::mapped); |
|
QSignalSpy serverSurfaceSizeChangedSpy(serverSurface, &SurfaceInterface::sizeChanged); |
|
QSignalSpy surfaceToBufferMatrixChangedSpy(serverSurface, &SurfaceInterface::surfaceToBufferMatrixChanged); |
|
|
|
// Map the surface. |
|
QImage image(QSize(200, 100), QImage::Format_ARGB32_Premultiplied); |
|
image.fill(Qt::black); |
|
KWayland::Client::Buffer::Ptr buffer = m_shm->createBuffer(image); |
|
clientSurface->attachBuffer(buffer); |
|
clientSurface->setScale(2); |
|
clientSurface->damage(image.rect()); |
|
clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); |
|
QVERIFY(serverSurfaceMappedSpy.wait()); |
|
QCOMPARE(surfaceToBufferMatrixChangedSpy.count(), 1); |
|
QCOMPARE(serverSurface->size(), QSize(100, 50)); |
|
QCOMPARE(serverSurface->mapToBuffer(QPointF(0, 0)), QPointF(0, 0)); |
|
|
|
// Create a viewport for the surface. |
|
std::unique_ptr<Viewport> clientViewport(new Viewport); |
|
clientViewport->init(m_viewporter->get_viewport(*clientSurface)); |
|
|
|
// Crop the surface. |
|
clientViewport->set_source(wl_fixed_from_double(10), wl_fixed_from_double(10), wl_fixed_from_double(30), wl_fixed_from_double(20)); |
|
clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); |
|
QVERIFY(serverSurfaceSizeChangedSpy.wait()); |
|
QCOMPARE(surfaceToBufferMatrixChangedSpy.count(), 2); |
|
QCOMPARE(serverSurface->size(), QSize(30, 20)); |
|
QCOMPARE(serverSurface->mapToBuffer(QPointF(0, 0)), QPointF(20, 20)); |
|
|
|
// Scale the surface. |
|
clientViewport->set_destination(500, 250); |
|
clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); |
|
QVERIFY(serverSurfaceSizeChangedSpy.wait()); |
|
QCOMPARE(surfaceToBufferMatrixChangedSpy.count(), 3); |
|
QCOMPARE(serverSurface->size(), QSize(500, 250)); |
|
QCOMPARE(serverSurface->mapToBuffer(QPointF(0, 0)), QPointF(20, 20)); |
|
|
|
// If the viewport is destroyed, the crop and scale state will be unset on a next commit. |
|
clientViewport->destroy(); |
|
clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); |
|
QVERIFY(serverSurfaceSizeChangedSpy.wait()); |
|
QCOMPARE(surfaceToBufferMatrixChangedSpy.count(), 4); |
|
QCOMPARE(serverSurface->size(), QSize(100, 50)); |
|
QCOMPARE(serverSurface->mapToBuffer(QPointF(0, 0)), QPointF(0, 0)); |
|
} |
|
|
|
QTEST_GUILESS_MAIN(TestViewporterInterface) |
|
|
|
#include "test_viewporter_interface.moc"
|
|
|