[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
This commit is contained in:
Martin Gräßlin 2016-03-29 12:05:05 +02:00
parent 0551a39ab6
commit d44b2ee30d
4 changed files with 37 additions and 0 deletions

View file

@ -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);

View file

@ -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>(), 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<QRegion>(), 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();

View file

@ -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<Private*>(d.data());

View file

@ -152,6 +152,17 @@ public:
**/
QPointer<ContrastInterface> 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.
**/