From 70eab7e2428a4e8ebc8d4a263d87b6e01e6a93bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 28 Aug 2014 14:22:53 +0200 Subject: [PATCH] [kwin_wayland] Add support for shm buffers in server module The Display provides a method to create the shm pool and a BufferInterface class is added to the server module. It is created from the SurfaceInterface when a buffer gets attached to the surface. The BufferInterface can be referenced and once its unreferenced it sends a buffer release to the client and destroys itself. For the case that the buffer is a shm buffer the BufferInterface provides a convenience method to turn it into a QImage. The auto test for Surface is extended by attaching buffers to the surface and verifying that the content is correct. --- src/wayland/test_wayland_surface.cpp | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/wayland/test_wayland_surface.cpp b/src/wayland/test_wayland_surface.cpp index 1b480895f4..bb4a7291a3 100644 --- a/src/wayland/test_wayland_surface.cpp +++ b/src/wayland/test_wayland_surface.cpp @@ -19,11 +19,14 @@ along with this program. If not, see . *********************************************************************/ // Qt #include +#include // KWin #include "../../wayland_client/compositor.h" #include "../../wayland_client/connection_thread.h" #include "../../wayland_client/surface.h" #include "../../wayland_client/registry.h" +#include "../../wayland_client/shm_pool.h" +#include "../../wayland_server/buffer_interface.h" #include "../../wayland_server/compositor_interface.h" #include "../../wayland_server/display.h" #include "../../wayland_server/surface_interface.h" @@ -42,6 +45,7 @@ private Q_SLOTS: void testStaticAccessor(); void testDamage(); void testFrameCallback(); + void testAttachBuffer(); private: KWin::WaylandServer::Display *m_display; @@ -230,5 +234,69 @@ void TestWaylandSurface::testFrameCallback() QVERIFY(!frameRenderedSpy.isEmpty()); } +void TestWaylandSurface::testAttachBuffer() +{ + // here we need a shm pool + m_display->createShm(); + + KWin::Wayland::Registry registry; + QSignalSpy shmSpy(®istry, SIGNAL(shmAnnounced(quint32,quint32))); + registry.create(m_connection->display()); + QVERIFY(registry.isValid()); + registry.setup(); + QVERIFY(shmSpy.wait()); + + KWin::Wayland::ShmPool pool; + pool.setup(registry.bindShm(shmSpy.first().first().value(), shmSpy.first().last().value())); + QVERIFY(pool.isValid()); + + // create the surface + QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWin::WaylandServer::SurfaceInterface*))); + QVERIFY(serverSurfaceCreated.isValid()); + KWin::Wayland::Surface *s = m_compositor->createSurface(); + QVERIFY(serverSurfaceCreated.wait()); + KWin::WaylandServer::SurfaceInterface *serverSurface = serverSurfaceCreated.first().first().value(); + QVERIFY(serverSurface); + + // create two images + // TODO: test RGB32 + QImage black(24, 24, QImage::Format_ARGB32); + black.fill(Qt::black); + QImage red(24, 24, QImage::Format_ARGB32); + red.fill(QColor(255, 0, 0, 128)); + + wl_buffer *blackBuffer = pool.createBuffer(black); + wl_buffer *redBuffer = pool.createBuffer(red); + + s->attachBuffer(redBuffer); + s->attachBuffer(blackBuffer); + s->damage(QRect(0, 0, 24, 24)); + s->commit(KWin::Wayland::Surface::CommitFlag::None); + QSignalSpy damageSpy(serverSurface, SIGNAL(damaged(QRegion))); + QVERIFY(damageSpy.isValid()); + QVERIFY(damageSpy.wait()); + + // now the ServerSurface should have the black image attached as a buffer + KWin::WaylandServer::BufferInterface *buffer = serverSurface->buffer(); + buffer->ref(); + QVERIFY(buffer->shmBuffer()); + QCOMPARE(buffer->data(), black); + + // render another frame + s->attachBuffer(redBuffer); + s->damage(QRect(0, 0, 24, 24)); + s->commit(KWin::Wayland::Surface::CommitFlag::None); + damageSpy.clear(); + QVERIFY(damageSpy.wait()); + KWin::WaylandServer::BufferInterface *buffer2 = serverSurface->buffer(); + buffer2->ref(); + QVERIFY(buffer2->shmBuffer()); + QCOMPARE(buffer2->data(), red); + buffer2->unref(); + + // TODO: add signal test on release + buffer->unref(); +} + QTEST_MAIN(TestWaylandSurface) #include "test_wayland_surface.moc"