From d44b2ee30d1e290efe7bf1b3fb240690716c23d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 29 Mar 2016 12:05:05 +0200 Subject: [PATCH] [server] Add a convenient method to check whether a Surface is mapped Summary: In a SubSurface tree a Surface is only considered mapped if the Surface has a buffer applied and the parent Surface is mapped. The added method implements this check. It's useful for the compositor to easily check this condition as it allows to easily figure out whether a SubSurface needs to be rendered and it's also useful for implementing the input handling as a not mapped sub-surface should not get any input events. Reviewers: #plasma Subscribers: plasma-devel Projects: #plasma Differential Revision: https://phabricator.kde.org/D1247 --- .../autotests/client/test_wayland_subsurface.cpp | 9 +++++++++ src/wayland/autotests/client/test_wayland_surface.cpp | 6 ++++++ src/wayland/surface_interface.cpp | 11 +++++++++++ src/wayland/surface_interface.h | 11 +++++++++++ 4 files changed, 37 insertions(+) diff --git a/src/wayland/autotests/client/test_wayland_subsurface.cpp b/src/wayland/autotests/client/test_wayland_subsurface.cpp index 7ddf1fd627..da9a820ad5 100644 --- a/src/wayland/autotests/client/test_wayland_subsurface.cpp +++ b/src/wayland/autotests/client/test_wayland_subsurface.cpp @@ -626,6 +626,9 @@ void TestSubSurface::testSyncMode() QVERIFY(!childDamagedSpy.wait(100)); QVERIFY(!childSurface->buffer()); + QVERIFY(!childSurface->isMapped()); + QVERIFY(!parentSurface->isMapped()); + QImage image2(QSize(400, 400), QImage::Format_ARGB32); image2.fill(Qt::red); parent->attachBuffer(m_shm->createBuffer(image2)); @@ -636,6 +639,8 @@ void TestSubSurface::testSyncMode() QCOMPARE(subSurfaceTreeChangedSpy.count(), 2); QCOMPARE(childSurface->buffer()->data(), image); QCOMPARE(parentSurface->buffer()->data(), image2); + QVERIFY(childSurface->isMapped()); + QVERIFY(parentSurface->isMapped()); // sending frame rendered to parent should also send it to child QSignalSpy frameRenderedSpy(surface.data(), &Surface::frameRendered); @@ -681,12 +686,16 @@ void TestSubSurface::testDeSyncMode() // state should be applied when the parent surface's state gets applied or when the subsurface switches to desync QVERIFY(!childDamagedSpy.wait(100)); + QVERIFY(!childSurface->isMapped()); + QVERIFY(!parentSurface->isMapped()); // setting to desync should apply the state directly subSurface->setMode(SubSurface::Mode::Desynchronized); QVERIFY(childDamagedSpy.wait()); QCOMPARE(subSurfaceTreeChangedSpy.count(), 2); QCOMPARE(childSurface->buffer()->data(), image); + QVERIFY(!childSurface->isMapped()); + QVERIFY(!parentSurface->isMapped()); // and damaging again, should directly be applied image.fill(Qt::red); diff --git a/src/wayland/autotests/client/test_wayland_surface.cpp b/src/wayland/autotests/client/test_wayland_surface.cpp index ff9e638e3f..1860f45179 100644 --- a/src/wayland/autotests/client/test_wayland_surface.cpp +++ b/src/wayland/autotests/client/test_wayland_surface.cpp @@ -231,6 +231,7 @@ void TestWaylandSurface::testDamage() QVERIFY(serverSurface); QCOMPARE(serverSurface->damage(), QRegion()); QVERIFY(serverSurface->parentResource()); + QVERIFY(!serverSurface->isMapped()); QSignalSpy damageSpy(serverSurface, SIGNAL(damaged(QRegion))); QVERIFY(damageSpy.isValid()); @@ -242,6 +243,7 @@ void TestWaylandSurface::testDamage() QCoreApplication::processEvents(); QCoreApplication::processEvents(); QVERIFY(damageSpy.isEmpty()); + QVERIFY(!serverSurface->isMapped()); QImage img(QSize(10, 10), QImage::Format_ARGB32); img.fill(Qt::black); @@ -252,6 +254,7 @@ void TestWaylandSurface::testDamage() QVERIFY(damageSpy.wait()); QCOMPARE(serverSurface->damage(), QRegion(0, 0, 10, 10)); QCOMPARE(damageSpy.first().first().value(), QRegion(0, 0, 10, 10)); + QVERIFY(serverSurface->isMapped()); // damage multiple times QRegion testRegion(5, 8, 3, 6); @@ -266,6 +269,7 @@ void TestWaylandSurface::testDamage() QVERIFY(damageSpy.wait()); QCOMPARE(serverSurface->damage(), testRegion); QCOMPARE(damageSpy.first().first().value(), testRegion); + QVERIFY(serverSurface->isMapped()); } void TestWaylandSurface::testFrameCallback() @@ -408,6 +412,7 @@ void TestWaylandSurface::testAttachBuffer() QCOMPARE(serverSurface->buffer(), buffer3); QVERIFY(damageSpy.isEmpty()); QVERIFY(unmappedSpy.isEmpty()); + QVERIFY(serverSurface->isMapped()); // clear the surface s->attachBuffer(blackBuffer); @@ -420,6 +425,7 @@ void TestWaylandSurface::testAttachBuffer() QVERIFY(!unmappedSpy.isEmpty()); QCOMPARE(unmappedSpy.count(), 1); QVERIFY(damageSpy.isEmpty()); + QVERIFY(!serverSurface->isMapped()); // TODO: add signal test on release buffer->unref(); diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index e9b4ffff4c..bc34af6bba 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -662,6 +662,17 @@ QPointer< SlideInterface > SurfaceInterface::slideOnShowHide() const return d->current.slide; } +bool SurfaceInterface::isMapped() const +{ + Q_D(); + if (d->subSurface) { + // from spec: + // "A sub-surface becomes mapped, when a non-NULL wl_buffer is applied and the parent surface is mapped." + return d->current.buffer && !d->subSurface->parentSurface().isNull() && d->subSurface->parentSurface()->isMapped(); + } + return d->current.buffer != nullptr; +} + SurfaceInterface::Private *SurfaceInterface::d_func() const { return reinterpret_cast(d.data()); diff --git a/src/wayland/surface_interface.h b/src/wayland/surface_interface.h index 11c77b667d..7cb88b8c73 100644 --- a/src/wayland/surface_interface.h +++ b/src/wayland/surface_interface.h @@ -152,6 +152,17 @@ public: **/ QPointer contrast() const; + /** + * Whether the SurfaceInterface is currently considered to be mapped. + * A SurfaceInterface is mapped if it has a non-null BufferInterface attached. + * If the SurfaceInterface references a SubSurfaceInterface it is only considered + * mapped if it has a BufferInterface attached and the parent SurfaceInterface is mapped. + * + * @returns Whether the SurfaceInterface is currently mapped + * @since 5.7 + **/ + bool isMapped() const; + /** * @returns The SurfaceInterface for the @p native resource. **/