Added testing of QBackingStore backend in wayland plugin.
authorSamuel Rødal <samuel.rodal@nokia.com>
Wed, 7 Mar 2012 12:52:50 +0000 (13:52 +0100)
committerLaszlo Agocs <laszlo.p.agocs@nokia.com>
Wed, 7 Mar 2012 14:51:39 +0000 (15:51 +0100)
Change-Id: I4db26cbee88f329a926914ff878e6efa9b0c8395
Reviewed-by: Laszlo Agocs <laszlo.p.agocs@nokia.com>
tests/auto/client/client.pro
tests/auto/client/mockcompositor.h
tests/auto/client/mockshm.cpp
tests/auto/client/mocksurface.cpp
tests/auto/client/mocksurface.h
tests/auto/client/tst_client.cpp

index 5d1f43d..12dad35 100644 (file)
@@ -31,4 +31,6 @@ SOURCES += tst_client.cpp \
            mockshm.cpp \
            mocksurface.cpp \
            mockoutput.cpp
-HEADERS += mockcompositor.h mocksurface.h
+HEADERS += mockcompositor.h \
+           mockshm.h \
+           mocksurface.h
index 18de0e6..2d1e418 100644 (file)
@@ -46,8 +46,9 @@
 #include <qglobal.h>
 #include <wayland-server.h>
 
-#include <QRect>
+#include <QImage>
 #include <QMutex>
+#include <QRect>
 #include <QSharedPointer>
 #include <QVariant>
 #include <QVector>
@@ -119,6 +120,8 @@ class MockSurface
 public:
     Impl::Surface *handle() const { return m_surface; }
 
+    QImage image;
+
 private:
     MockSurface(Impl::Surface *surface);
     friend class Impl::Compositor;
index 9deceeb..5c0ba38 100644 (file)
 ****************************************************************************/
 
 #include "mockcompositor.h"
-
-#include <QImage>
+#include "mockshm.h"
 
 namespace Impl {
 
-class ShmBuffer
+ShmBuffer::ShmBuffer(wl_buffer *buffer)
+    : m_buffer(buffer)
 {
-public:
-    ShmBuffer(wl_buffer *buffer)
-        : m_buffer(buffer)
-    {
-        refresh();
-    }
+    refresh();
+}
 
-    void refresh()
-    {
-        m_image = QImage(static_cast<uint8_t *>(wl_shm_buffer_get_data(m_buffer)),
-                         m_buffer->width, m_buffer->height,
-                         wl_shm_buffer_get_stride(m_buffer),
-                         QImage::Format_ARGB32_Premultiplied);
-    }
+void ShmBuffer::refresh()
+{
+    m_image = QImage(static_cast<uint8_t *>(wl_shm_buffer_get_data(m_buffer)),
+                     m_buffer->width, m_buffer->height,
+                     wl_shm_buffer_get_stride(m_buffer),
+                     QImage::Format_ARGB32_Premultiplied);
+}
 
-private:
-    wl_buffer *m_buffer;
-    QImage m_image;
-};
+QImage ShmBuffer::image() const
+{
+    return m_image;
+}
 
 static void shm_buffer_created(wl_buffer *buffer)
 {
index 38fc955..68c18ba 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "mocksurface.h"
 #include "mockcompositor.h"
+#include "mockshm.h"
 
 namespace Impl {
 
@@ -57,39 +58,54 @@ static void surface_destroy(wl_client *, wl_resource *surfaceResource)
     wl_resource_destroy(surfaceResource, surface->compositor()->time());
 }
 
-void surface_attach(wl_client *client, wl_resource *surface,
+void surface_attach(wl_client *client, wl_resource *surfaceResource,
                     wl_resource *buffer, int x, int y)
 {
     Q_UNUSED(client);
-    Q_UNUSED(surface);
-    Q_UNUSED(buffer);
     Q_UNUSED(x);
     Q_UNUSED(y);
-    //resolve<Surface>(surface)->attach(buffer ? reinterpret_cast<wl_buffer *>(buffer->data) : 0);
+
+    Surface *surface = static_cast<Surface *>(surfaceResource->data);
+    surface->m_buffer = buffer ? static_cast<wl_buffer *>(buffer->data) : 0;
+
+    if (!buffer)
+        surface->m_mockSurface->image = QImage();
 }
 
-void surface_damage(wl_client *client, wl_resource *surface,
+void surface_damage(wl_client *client, wl_resource *surfaceResource,
                     int32_t x, int32_t y, int32_t width, int32_t height)
 {
     Q_UNUSED(client);
-    Q_UNUSED(surface);
     Q_UNUSED(x);
     Q_UNUSED(y);
     Q_UNUSED(width);
     Q_UNUSED(height);
-    //resolve<Surface>(surface)->damage(QRect(x, y, width, height));
+
+    Surface *surface = static_cast<Surface *>(surfaceResource->data);
+    wl_buffer *buffer = surface->m_buffer;
+
+    if (!buffer)
+        return;
+
+    if (wl_buffer_is_shm(buffer))
+        surface->m_mockSurface->image = static_cast<ShmBuffer *>(buffer->user_data)->image();
+
+    wl_resource *frameCallback;
+    wl_list_for_each(frameCallback, &surface->m_frameCallbackList, link) {
+        wl_callback_send_done(frameCallback, surface->m_compositor->time());
+        wl_resource_destroy(frameCallback, surface->m_compositor->time());
+    }
+
+    wl_list_init(&surface->m_frameCallbackList);
 }
 
 void surface_frame(wl_client *client,
-                   wl_resource *surface,
+                   wl_resource *surfaceResource,
                    uint32_t callback)
 {
-    Q_UNUSED(client);
-    Q_UNUSED(surface);
-    Q_UNUSED(callback);
-//    Surface *surface = resolve<Surface>(resource);
-//    wl_resource *frame_callback = wl_client_add_object(client, &wl_callback_interface, 0, callback, surface);
-//    wl_list_insert(&surface->m_frame_callback_list, &frame_callback->link);
+    Surface *surface = static_cast<Surface *>(surfaceResource->data);
+    wl_resource *frameCallback = wl_client_add_object(client, &wl_callback_interface, 0, callback, surface);
+    wl_list_insert(&surface->m_frameCallbackList, &frameCallback->link);
 }
 
 void surface_set_opaque_region(wl_client *client, wl_resource *surfaceResource,
@@ -130,6 +146,7 @@ Surface::Surface(wl_client *client, uint32_t id, Compositor *compositor)
 
     wl_client_add_resource(client, &m_surface.resource);
 
+    wl_list_init(&m_frameCallbackList);
 }
 
 Surface::~Surface()
index 69ae802..da77b36 100644 (file)
@@ -59,9 +59,18 @@ public:
 
 private:
     wl_surface m_surface;
+    wl_buffer *m_buffer;
 
     Compositor *m_compositor;
     QSharedPointer<MockSurface> m_mockSurface;
+
+    wl_list m_frameCallbackList;
+
+    friend void surface_attach(wl_client *client, wl_resource *surface,
+                               wl_resource *buffer, int x, int y);
+    friend void surface_damage(wl_client *client, wl_resource *surface,
+                               int32_t x, int32_t y, int32_t width, int32_t height);
+    friend void surface_frame(wl_client *client, wl_resource *surface, uint32_t callback);
 };
 
 }
index 9b63337..b6d434f 100644 (file)
@@ -41,6 +41,9 @@
 
 #include "mockcompositor.h"
 
+#include <QBackingStore>
+#include <QPainter>
+
 #include <QtTest/QtTest>
 
 static const QSize screenSize(1600, 1200);
@@ -123,10 +126,18 @@ public slots:
         compositor->processWaylandEvents();
     }
 
+    void cleanup()
+    {
+        // make sure the surfaces from the last test are properly cleaned up
+        // and don't show up as false positives in the next test
+        QTRY_VERIFY(!compositor->surface());
+    }
+
 private slots:
     void screen();
     void createDestroyWindow();
     void events();
+    void backingStore();
 
 private:
     MockCompositor *compositor;
@@ -192,6 +203,42 @@ void tst_WaylandClient::events()
     QTRY_COMPARE(window.mouseReleaseEventCount, 1);
 }
 
+void tst_WaylandClient::backingStore()
+{
+    TestWindow window;
+    window.show();
+
+    QSharedPointer<MockSurface> surface;
+    QTRY_VERIFY(surface = compositor->surface());
+
+    QRect rect(QPoint(), window.size());
+
+    QBackingStore backingStore(&window);
+    backingStore.resize(rect.size());
+
+    backingStore.beginPaint(rect);
+
+    QColor color = Qt::magenta;
+
+    QPainter p(backingStore.paintDevice());
+    p.fillRect(rect, color);
+    p.end();
+
+    backingStore.endPaint();
+
+    QVERIFY(surface->image.isNull());
+
+    backingStore.flush(rect);
+
+    QTRY_COMPARE(surface->image.size(), rect.size());
+    QTRY_COMPARE(surface->image.pixel(0, 0), color.rgba());
+
+    window.hide();
+
+    // hiding the window should detach the buffer
+    QTRY_VERIFY(surface->image.isNull());
+}
+
 int main(int argc, char **argv)
 {
     setenv("XDG_RUNTIME_DIR", ".", 1);