From 4a328e3533f93ed65f9dc77f764b3cbe3c694266 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Wed, 17 Oct 2018 14:05:27 +0200 Subject: Compositor: Emit signals after applying pending surface state [ChangeLog][Compositor] Fixed a bug where some signals on QWaylandSurface were emitted before all double buffered state had been applied. Restructures QWaylandSurface::commit so no signals are emitted until all state mutations are completed. Adds a test to confirm that pending state is applied at once. Also fixes opaqueRegion, which is documented to be double buffered as well, but the old implementation set it immediately. Change-Id: I1c4dfea7c83dd9ee84dc8c03e6d92e2924bf2fad Reviewed-by: Paul Olav Tvete --- .../auto/compositor/compositor/tst_compositor.cpp | 74 +++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) (limited to 'tests/auto/compositor/compositor/tst_compositor.cpp') diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index c7661e8db..2c0e46b23 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -74,6 +74,7 @@ private slots: void modes(); void sizeFollowsWindow(); void mapSurface(); + void mapSurfaceHiDpi(); void frameCallback(); void removeOutput(); @@ -421,9 +422,78 @@ void tst_WaylandCompositor::mapSurface() wl_surface_damage(surface, 0, 0, size.width(), size.height()); wl_surface_commit(surface); - QTRY_COMPARE(waylandSurface->size(), size); - QTRY_COMPARE(waylandSurface->hasContent(), true); QTRY_COMPARE(hasContentSpy.count(), 1); + QCOMPARE(waylandSurface->hasContent(), true); + QCOMPARE(waylandSurface->size(), size); + + wl_surface_destroy(surface); +} + +void tst_WaylandCompositor::mapSurfaceHiDpi() +{ + TestCompositor compositor; + compositor.create(); + + MockClient client; + + wl_surface *surface = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + + constexpr int bufferScale = 2; + const QSize surfaceSize(128, 128); + const QSize bufferSize = surfaceSize * bufferScale; + const QPoint attachOffset(1, 2); // in surface-local coordinates + + client.createShellSurface(surface); + ShmBuffer buffer(bufferSize, client.shm); + wl_surface_attach(surface, buffer.handle, attachOffset.x(), attachOffset.y()); + wl_surface_set_buffer_scale(surface, bufferScale); + // wl_surface_damage is given in surface coordinates + wl_surface_damage(surface, 0, 0, surfaceSize.width(), surfaceSize.height()); + + auto verifyComittedState = [=]() { + QCOMPARE(waylandSurface->size(), bufferSize); + QCOMPARE(waylandSurface->bufferScale(), bufferScale); + QCOMPARE(waylandSurface->hasContent(), true); + }; + + QObject::connect(waylandSurface, &QWaylandSurface::damaged, [=] (const QRegion &damage) { + // Currently, QWaylandSurface::size returns the size in pixels. + // Should be fixed or removed for Qt 6. + QCOMPARE(damage, QRect(QPoint(), surfaceSize)); + verifyComittedState(); + }); + QSignalSpy damagedSpy(waylandSurface, SIGNAL(damaged(const QRegion &))); + + QObject::connect(waylandSurface, &QWaylandSurface::hasContentChanged, verifyComittedState); + QSignalSpy hasContentSpy(waylandSurface, SIGNAL(hasContentChanged())); + + QObject::connect(waylandSurface, &QWaylandSurface::sizeChanged, verifyComittedState); + QSignalSpy sizeSpy(waylandSurface, SIGNAL(sizeChanged())); + + QObject::connect(waylandSurface, &QWaylandSurface::bufferScaleChanged, verifyComittedState); + QSignalSpy bufferScaleSpy(waylandSurface, SIGNAL(bufferScaleChanged())); + + QObject::connect(waylandSurface, &QWaylandSurface::offsetForNextFrame, [=](const QPoint &offset) { + QCOMPARE(offset, attachOffset); + verifyComittedState(); + }); + QSignalSpy offsetSpy(waylandSurface, SIGNAL(offsetForNextFrame(const QPoint &))); + + // No state should be applied before the commit + QCOMPARE(waylandSurface->size(), QSize()); + QCOMPARE(waylandSurface->hasContent(), false); + QCOMPARE(waylandSurface->bufferScale(), 1); + QCOMPARE(offsetSpy.count(), 0); + + wl_surface_commit(surface); + + QTRY_COMPARE(hasContentSpy.count(), 1); + QTRY_COMPARE(sizeSpy.count(), 1); + QTRY_COMPARE(bufferScaleSpy.count(), 1); + QTRY_COMPARE(offsetSpy.count(), 1); wl_surface_destroy(surface); } -- cgit v1.2.3