Added testing of QBackingStore backend in wayland plugin.

Change-Id: I4db26cbee88f329a926914ff878e6efa9b0c8395
Reviewed-by: Laszlo Agocs <laszlo.p.agocs@nokia.com>
This commit is contained in:
Samuel Rødal 2012-03-07 13:52:50 +01:00 committed by Laszlo Agocs
parent 54331754cb
commit 621af3b836
6 changed files with 110 additions and 36 deletions

View File

@ -31,4 +31,6 @@ SOURCES += tst_client.cpp \
mockshm.cpp \ mockshm.cpp \
mocksurface.cpp \ mocksurface.cpp \
mockoutput.cpp mockoutput.cpp
HEADERS += mockcompositor.h mocksurface.h HEADERS += mockcompositor.h \
mockshm.h \
mocksurface.h

View File

@ -46,8 +46,9 @@
#include <qglobal.h> #include <qglobal.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <QRect> #include <QImage>
#include <QMutex> #include <QMutex>
#include <QRect>
#include <QSharedPointer> #include <QSharedPointer>
#include <QVariant> #include <QVariant>
#include <QVector> #include <QVector>
@ -119,6 +120,8 @@ class MockSurface
public: public:
Impl::Surface *handle() const { return m_surface; } Impl::Surface *handle() const { return m_surface; }
QImage image;
private: private:
MockSurface(Impl::Surface *surface); MockSurface(Impl::Surface *surface);
friend class Impl::Compositor; friend class Impl::Compositor;

View File

@ -40,21 +40,17 @@
****************************************************************************/ ****************************************************************************/
#include "mockcompositor.h" #include "mockcompositor.h"
#include "mockshm.h"
#include <QImage>
namespace Impl { namespace Impl {
class ShmBuffer ShmBuffer::ShmBuffer(wl_buffer *buffer)
{
public:
ShmBuffer(wl_buffer *buffer)
: m_buffer(buffer) : m_buffer(buffer)
{ {
refresh(); refresh();
} }
void refresh() void ShmBuffer::refresh()
{ {
m_image = QImage(static_cast<uint8_t *>(wl_shm_buffer_get_data(m_buffer)), m_image = QImage(static_cast<uint8_t *>(wl_shm_buffer_get_data(m_buffer)),
m_buffer->width, m_buffer->height, m_buffer->width, m_buffer->height,
@ -62,10 +58,10 @@ public:
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
} }
private: QImage ShmBuffer::image() const
wl_buffer *m_buffer; {
QImage m_image; return m_image;
}; }
static void shm_buffer_created(wl_buffer *buffer) static void shm_buffer_created(wl_buffer *buffer)
{ {

View File

@ -41,6 +41,7 @@
#include "mocksurface.h" #include "mocksurface.h"
#include "mockcompositor.h" #include "mockcompositor.h"
#include "mockshm.h"
namespace Impl { namespace Impl {
@ -57,39 +58,54 @@ static void surface_destroy(wl_client *, wl_resource *surfaceResource)
wl_resource_destroy(surfaceResource, surface->compositor()->time()); 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) wl_resource *buffer, int x, int y)
{ {
Q_UNUSED(client); Q_UNUSED(client);
Q_UNUSED(surface);
Q_UNUSED(buffer);
Q_UNUSED(x); Q_UNUSED(x);
Q_UNUSED(y); 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) int32_t x, int32_t y, int32_t width, int32_t height)
{ {
Q_UNUSED(client); Q_UNUSED(client);
Q_UNUSED(surface);
Q_UNUSED(x); Q_UNUSED(x);
Q_UNUSED(y); Q_UNUSED(y);
Q_UNUSED(width); Q_UNUSED(width);
Q_UNUSED(height); 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, void surface_frame(wl_client *client,
wl_resource *surface, wl_resource *surfaceResource,
uint32_t callback) uint32_t callback)
{ {
Q_UNUSED(client); Surface *surface = static_cast<Surface *>(surfaceResource->data);
Q_UNUSED(surface); wl_resource *frameCallback = wl_client_add_object(client, &wl_callback_interface, 0, callback, surface);
Q_UNUSED(callback); wl_list_insert(&surface->m_frameCallbackList, &frameCallback->link);
// 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);
} }
void surface_set_opaque_region(wl_client *client, wl_resource *surfaceResource, 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_client_add_resource(client, &m_surface.resource);
wl_list_init(&m_frameCallbackList);
} }
Surface::~Surface() Surface::~Surface()

View File

@ -59,9 +59,18 @@ public:
private: private:
wl_surface m_surface; wl_surface m_surface;
wl_buffer *m_buffer;
Compositor *m_compositor; Compositor *m_compositor;
QSharedPointer<MockSurface> m_mockSurface; 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);
}; };
} }

View File

@ -41,6 +41,9 @@
#include "mockcompositor.h" #include "mockcompositor.h"
#include <QBackingStore>
#include <QPainter>
#include <QtTest/QtTest> #include <QtTest/QtTest>
static const QSize screenSize(1600, 1200); static const QSize screenSize(1600, 1200);
@ -123,10 +126,18 @@ public slots:
compositor->processWaylandEvents(); 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: private slots:
void screen(); void screen();
void createDestroyWindow(); void createDestroyWindow();
void events(); void events();
void backingStore();
private: private:
MockCompositor *compositor; MockCompositor *compositor;
@ -192,6 +203,42 @@ void tst_WaylandClient::events()
QTRY_COMPARE(window.mouseReleaseEventCount, 1); 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) int main(int argc, char **argv)
{ {
setenv("XDG_RUNTIME_DIR", ".", 1); setenv("XDG_RUNTIME_DIR", ".", 1);