Issue set_opaque_region on opaque surfaces

The application will tell Qt whether the background is transparent
through either Qt::WA_TranslucentBackground or QQuickWindow::setColor.
These will set a QSurfaceFormat.
This change checks the QSurfaceFormat and issues the opacity information
so we can properly implement culling optimizations in the compositor.

Pick-to: 5.15
Change-Id: I4f7562467449eac7931f3011d4b835934212adad
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Aleix Pol 2020-09-30 13:37:12 +02:00
parent a0a17c1886
commit 108be7810d
2 changed files with 29 additions and 0 deletions

View File

@ -362,6 +362,9 @@ void QWaylandWindow::setGeometry(const QRect &rect)
if (mShellSurface)
mShellSurface->setWindowGeometry(windowContentGeometry());
if (isOpaque() && mMask.isEmpty())
setOpaqueArea(rect);
}
void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
@ -461,10 +464,16 @@ void QWaylandWindow::setMask(const QRegion &mask)
if (mMask.isEmpty()) {
mSurface->set_input_region(nullptr);
if (isOpaque())
setOpaqueArea(QRect(QPoint(0, 0), geometry().size()));
} else {
struct ::wl_region *region = mDisplay->createRegion(mMask);
mSurface->set_input_region(region);
wl_region_destroy(region);
if (isOpaque())
setOpaqueArea(mMask);
}
mSurface->commit();
@ -1223,6 +1232,23 @@ bool QtWaylandClient::QWaylandWindow::startSystemMove()
return false;
}
bool QWaylandWindow::isOpaque() const
{
return window()->requestedFormat().alphaBufferSize() <= 0;
}
void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea)
{
if (opaqueArea == mOpaqueArea || !mSurface)
return;
mOpaqueArea = opaqueArea;
struct ::wl_region *region = mDisplay->createRegion(opaqueArea);
mSurface->set_opaque_region(region);
wl_region_destroy(region);
}
}
QT_END_NAMESPACE

View File

@ -254,6 +254,7 @@ protected:
Qt::WindowFlags mFlags;
QRegion mMask;
QRegion mOpaqueArea;
Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
QWaylandShmBackingStore *mBackingStore = nullptr;
@ -270,6 +271,8 @@ private:
void sendExposeEvent(const QRect &rect);
static void closePopups(QWaylandWindow *parent);
QPlatformScreen *calculateScreenFromSurfaceEvents() const;
void setOpaqueArea(const QRegion &opaqueArea);
bool isOpaque() const;
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
void handleScreensChanged();