From 75a6fd29fdeef8caefcfae1f58aae8265b851552 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 2 Feb 2021 19:27:46 +0200 Subject: [PATCH] Introduce SurfaceInterface::childSubSurfacesChanged Currently, the SurfaceInterface class has a signal that is emitted whenever any sub-surfaces in its sub-tree changes in a way that requires a repaint. It is emitted when a sub-surface is resized, moved, or damaged, etc. There is no way for the compositor to track changes in the stacking order of sub-surfaces efficiently. This change replaces the subTreeChanged signal with a less noisy signal that's emitted whenever the list of direct child sub-surfaces changes. --- .../client/test_wayland_subsurface.cpp | 50 ++++++------------- src/wayland/surface_interface.cpp | 18 ++----- src/wayland/surface_interface.h | 8 +-- 3 files changed, 23 insertions(+), 53 deletions(-) diff --git a/src/wayland/autotests/client/test_wayland_subsurface.cpp b/src/wayland/autotests/client/test_wayland_subsurface.cpp index c6244ff1db..d5ac9fe710 100644 --- a/src/wayland/autotests/client/test_wayland_subsurface.cpp +++ b/src/wayland/autotests/client/test_wayland_subsurface.cpp @@ -301,10 +301,6 @@ void TestSubSurface::testPosition() SubSurfaceInterface *serverSubSurface = subSurfaceCreatedSpy.first().first().value(); QVERIFY(serverSubSurface); - // create a signalspy - QSignalSpy subsurfaceTreeChanged(serverSubSurface->parentSurface(), &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(subsurfaceTreeChanged.isValid()); - // put the subsurface in the desired commit mode QFETCH(KWayland::Client::SubSurface::Mode, commitMode); subSurface->setMode(commitMode); @@ -332,13 +328,13 @@ void TestSubSurface::testPosition() QCOMPARE(serverSubSurface->position(), QPoint()); // committing the parent surface should update the position + QSignalSpy parentCommittedSpy(serverSubSurface->parentSurface(), &SurfaceInterface::committed); + QVERIFY(parentCommittedSpy.isValid()); parent->commit(Surface::CommitFlag::None); - QCOMPARE(subsurfaceTreeChanged.count(), 0); - QVERIFY(positionChangedSpy.wait()); + QVERIFY(parentCommittedSpy.wait()); QCOMPARE(positionChangedSpy.count(), 1); QCOMPARE(positionChangedSpy.first().first().toPoint(), QPoint(20, 30)); QCOMPARE(serverSubSurface->position(), QPoint(20, 30)); - QCOMPARE(subsurfaceTreeChanged.count(), 1); } void TestSubSurface::testPlaceAbove() @@ -606,12 +602,8 @@ void TestSubSurface::testSyncMode() QVERIFY(surfaceCreatedSpy.wait()); auto parentSurface = surfaceCreatedSpy.last().first().value(); QVERIFY(parentSurface); - QSignalSpy subSurfaceTreeChangedSpy(parentSurface, &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(subSurfaceTreeChangedSpy.isValid()); // create subSurface for surface of parent QScopedPointer subSurface(m_subCompositor->createSubSurface(QPointer(surface.data()), QPointer(parent.data()))); - QVERIFY(subSurfaceTreeChangedSpy.wait()); - QCOMPARE(subSurfaceTreeChangedSpy.count(), 1); // let's damage the child surface QSignalSpy childDamagedSpy(childSurface, &SurfaceInterface::damaged); @@ -637,7 +629,6 @@ void TestSubSurface::testSyncMode() parent->commit(); QVERIFY(childDamagedSpy.wait()); QCOMPARE(childDamagedSpy.count(), 1); - QCOMPARE(subSurfaceTreeChangedSpy.count(), 2); QCOMPARE(childSurface->buffer()->data(), image); QCOMPARE(parentSurface->buffer()->data(), image2); QVERIFY(childSurface->isMapped()); @@ -668,12 +659,8 @@ void TestSubSurface::testDeSyncMode() QVERIFY(surfaceCreatedSpy.wait()); auto parentSurface = surfaceCreatedSpy.last().first().value(); QVERIFY(parentSurface); - QSignalSpy subSurfaceTreeChangedSpy(parentSurface, &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(subSurfaceTreeChangedSpy.isValid()); // create subSurface for surface of parent QScopedPointer subSurface(m_subCompositor->createSubSurface(QPointer(surface.data()), QPointer(parent.data()))); - QVERIFY(subSurfaceTreeChangedSpy.wait()); - QCOMPARE(subSurfaceTreeChangedSpy.count(), 1); // let's damage the child surface QSignalSpy childDamagedSpy(childSurface, &SurfaceInterface::damaged); @@ -693,7 +680,6 @@ void TestSubSurface::testDeSyncMode() // 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()); @@ -704,7 +690,6 @@ void TestSubSurface::testDeSyncMode() surface->damage(QRect(0, 0, 200, 200)); surface->commit(Surface::CommitFlag::None); QVERIFY(childDamagedSpy.wait()); - QCOMPARE(subSurfaceTreeChangedSpy.count(), 3); QCOMPARE(childSurface->buffer()->data(), image); } @@ -734,15 +719,14 @@ void TestSubSurface::testMainSurfaceFromTree() auto childLevel3ServerSurface = surfaceCreatedSpy.last().first().value(); QVERIFY(childLevel3ServerSurface); - QSignalSpy subSurfaceTreeChangedSpy(parentServerSurface, &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(subSurfaceTreeChangedSpy.isValid()); - m_subCompositor->createSubSurface(childLevel1Surface.data(), parentSurface.data()); m_subCompositor->createSubSurface(childLevel2Surface.data(), childLevel1Surface.data()); m_subCompositor->createSubSurface(childLevel3Surface.data(), childLevel2Surface.data()); + QSignalSpy parentCommittedSpy(parentServerSurface, &SurfaceInterface::committed); + QVERIFY(parentCommittedSpy.isValid()); parentSurface->commit(Surface::CommitFlag::None); - QVERIFY(subSurfaceTreeChangedSpy.wait()); + QVERIFY(parentCommittedSpy.wait()); QCOMPARE(parentServerSurface->childSubSurfaces().count(), 1); auto child = parentServerSurface->childSubSurfaces().first(); @@ -777,18 +761,18 @@ void TestSubSurface::testRemoveSurface() auto childServerSurface = surfaceCreatedSpy.last().first().value(); QVERIFY(childServerSurface); - QSignalSpy subSurfaceTreeChangedSpy(parentServerSurface, &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(subSurfaceTreeChangedSpy.isValid()); + QSignalSpy childrenChangedSpy(parentServerSurface, &SurfaceInterface::childSubSurfacesChanged); + QVERIFY(childrenChangedSpy.isValid()); m_subCompositor->createSubSurface(childSurface.data(), parentSurface.data()); parentSurface->commit(Surface::CommitFlag::None); - QVERIFY(subSurfaceTreeChangedSpy.wait()); + QVERIFY(childrenChangedSpy.wait()); QCOMPARE(parentServerSurface->childSubSurfaces().count(), 1); // destroy surface, takes place immediately childSurface.reset(); - QVERIFY(subSurfaceTreeChangedSpy.wait()); + QVERIFY(childrenChangedSpy.wait()); QCOMPARE(parentServerSurface->childSubSurfaces().count(), 0); } @@ -817,15 +801,14 @@ void TestSubSurface::testMappingOfSurfaceTree() auto childLevel3ServerSurface = surfaceCreatedSpy.last().first().value(); QVERIFY(childLevel3ServerSurface); - QSignalSpy subSurfaceTreeChangedSpy(parentServerSurface, &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(subSurfaceTreeChangedSpy.isValid()); - auto subSurfaceLevel1 = m_subCompositor->createSubSurface(childLevel1Surface.data(), parentSurface.data()); auto subSurfaceLevel2 = m_subCompositor->createSubSurface(childLevel2Surface.data(), childLevel1Surface.data()); auto subSurfaceLevel3 = m_subCompositor->createSubSurface(childLevel3Surface.data(), childLevel2Surface.data()); + QSignalSpy parentCommittedSpy(parentServerSurface, &SurfaceInterface::committed); + QVERIFY(parentCommittedSpy.isValid()); parentSurface->commit(Surface::CommitFlag::None); - QVERIFY(subSurfaceTreeChangedSpy.wait()); + QVERIFY(parentCommittedSpy.wait()); QCOMPARE(parentServerSurface->childSubSurfaces().count(), 1); auto child = parentServerSurface->childSubSurfaces().first(); @@ -982,6 +965,8 @@ void TestSubSurface::testSurfaceAt() childFor1->commit(Surface::CommitFlag::None); partImage.fill(Qt::blue); + QSignalSpy childFor2CommittedSpy(childFor2ServerSurface, &SurfaceInterface::committed); + QVERIFY(childFor2CommittedSpy.isValid()); childFor2->attachBuffer(m_shm->createBuffer(partImage)); // child for 2's input region is subdivided into quadrants, with input mask on the top left and bottom right QRegion region; @@ -990,10 +975,7 @@ void TestSubSurface::testSurfaceAt() childFor2->setInputRegion(m_compositor->createRegion(region).get()); childFor2->damage(QRect(0, 0, 50, 50)); childFor2->commit(Surface::CommitFlag::None); - - QSignalSpy treeChangedSpy(parentServerSurface, &SurfaceInterface::subSurfaceTreeChanged); - QVERIFY(treeChangedSpy.isValid()); - QVERIFY(treeChangedSpy.wait()); + QVERIFY(childFor2CommittedSpy.wait()); QCOMPARE(directChild1ServerSurface->subSurface()->parentSurface(), parentServerSurface); QCOMPARE(directChild2ServerSurface->subSurface()->parentSurface(), parentServerSurface); diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index c29bf4952a..1e992ad41d 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -83,15 +83,9 @@ void SurfaceInterfacePrivate::addChild(SubSurfaceInterface *child) pending.children.append(child); cached.children.append(child); current.children.append(child); - child->surface()->setOutputs(outputs); - emit q->childSubSurfaceAdded(child); - emit q->subSurfaceTreeChanged(); - QObject::connect(child, &SubSurfaceInterface::positionChanged, q, &SurfaceInterface::subSurfaceTreeChanged); - QObject::connect(child->surface(), &SurfaceInterface::damaged, q, &SurfaceInterface::subSurfaceTreeChanged); - QObject::connect(child->surface(), &SurfaceInterface::unmapped, q, &SurfaceInterface::subSurfaceTreeChanged); - QObject::connect(child->surface(), &SurfaceInterface::subSurfaceTreeChanged, q, &SurfaceInterface::subSurfaceTreeChanged); + emit q->childSubSurfacesChanged(); } void SurfaceInterfacePrivate::removeChild(SubSurfaceInterface *child) @@ -101,13 +95,7 @@ void SurfaceInterfacePrivate::removeChild(SubSurfaceInterface *child) cached.children.removeAll(child); current.children.removeAll(child); emit q->childSubSurfaceRemoved(child); - emit q->subSurfaceTreeChanged(); - QObject::disconnect(child, &SubSurfaceInterface::positionChanged, q, &SurfaceInterface::subSurfaceTreeChanged); - if (child->surface()) { - QObject::disconnect(child->surface(), &SurfaceInterface::damaged, q, &SurfaceInterface::subSurfaceTreeChanged); - QObject::disconnect(child->surface(), &SurfaceInterface::unmapped, q, &SurfaceInterface::subSurfaceTreeChanged); - QObject::disconnect(child->surface(), &SurfaceInterface::subSurfaceTreeChanged, q, &SurfaceInterface::subSurfaceTreeChanged); - } + emit q->childSubSurfacesChanged(); } bool SurfaceInterfacePrivate::raiseChild(SubSurfaceInterface *subsurface, SurfaceInterface *sibling) @@ -681,7 +669,7 @@ void SurfaceInterfacePrivate::swapStates(State *source, State *target, bool emit emit q->slideOnShowHideChanged(); } if (childrenChanged) { - emit q->subSurfaceTreeChanged(); + emit q->childSubSurfacesChanged(); } } diff --git a/src/wayland/surface_interface.h b/src/wayland/surface_interface.h index d26a7e2c86..da566e49a5 100644 --- a/src/wayland/surface_interface.h +++ b/src/wayland/surface_interface.h @@ -407,10 +407,6 @@ Q_SIGNALS: void blurChanged(); void slideOnShowHideChanged(); void contrastChanged(); - /** - * Emitted whenever the tree of sub-surfaces changes in a way which requires a repaint. - */ - void subSurfaceTreeChanged(); /** * Emitted whenever a new child sub-surface @p subSurface is added. */ @@ -419,6 +415,10 @@ Q_SIGNALS: * Emitted whenver the child sub-surface @p subSurface is removed. */ void childSubSurfaceRemoved(SubSurfaceInterface *subSurface); + /** + * This signal is emitted when the list of child subsurfaces changes. + */ + void childSubSurfacesChanged(); /** * Emitted whenever a pointer constraint get (un)installed on this SurfaceInterface.