scene/workspacescene: do occlusion testing for direct scanout
Some clients have two or more completely opaque surfaces stacked on top of each other, optimizing the lower ones out makes direct scanout happen more often and more efficiently when multiple planes are involved
This commit is contained in:
parent
4ebb8530e6
commit
def0bde5e9
1 changed files with 14 additions and 6 deletions
|
@ -151,12 +151,15 @@ Item *WorkspaceScene::overlayItem() const
|
||||||
return m_overlayItem.get();
|
return m_overlayItem.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool addCandidates(SurfaceItem *item, QList<SurfaceItem *> &candidates, ssize_t maxCount)
|
static bool addCandidates(SurfaceItem *item, QList<SurfaceItem *> &candidates, ssize_t maxCount, QRegion &occluded)
|
||||||
{
|
{
|
||||||
const QList<Item *> children = item->sortedChildItems();
|
const QList<Item *> children = item->sortedChildItems();
|
||||||
for (const auto &child : children | std::views::reverse) {
|
for (const auto &child : children | std::views::reverse) {
|
||||||
if (child->z() >= 0 && child->isVisible()) {
|
if (child->z() < 0) {
|
||||||
if (!addCandidates(static_cast<SurfaceItem *>(child), candidates, maxCount)) {
|
break;
|
||||||
|
}
|
||||||
|
if (child->isVisible() && !occluded.contains(child->mapToScene(child->boundingRect()).toAlignedRect())) {
|
||||||
|
if (!addCandidates(static_cast<SurfaceItem *>(child), candidates, maxCount, occluded)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,9 +168,13 @@ static bool addCandidates(SurfaceItem *item, QList<SurfaceItem *> &candidates, s
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
candidates.push_back(item);
|
candidates.push_back(item);
|
||||||
|
occluded += item->mapToScene(item->opaque());
|
||||||
for (const auto &child : children | std::views::reverse) {
|
for (const auto &child : children | std::views::reverse) {
|
||||||
if (child->z() < 0 && child->isVisible()) {
|
if (child->z() >= 0) {
|
||||||
if (!addCandidates(static_cast<SurfaceItem *>(child), candidates, maxCount)) {
|
continue;
|
||||||
|
}
|
||||||
|
if (child->isVisible() && !occluded.contains(child->mapToScene(child->boundingRect()).toAlignedRect())) {
|
||||||
|
if (!addCandidates(static_cast<SurfaceItem *>(child), candidates, maxCount, occluded)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +199,8 @@ QList<SurfaceItem *> WorkspaceScene::scanoutCandidates(ssize_t maxCount) const
|
||||||
if (!windowItem->surfaceItem()) {
|
if (!windowItem->surfaceItem()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!addCandidates(windowItem->surfaceItem(), ret, maxCount)) {
|
QRegion occlusion;
|
||||||
|
if (!addCandidates(windowItem->surfaceItem(), ret, maxCount, occlusion)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue