From cc779e0ed47ec4759dc3c23953dd02cfacc6885c Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Wed, 30 Sep 2020 13:37:12 +0200 Subject: 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. Change-Id: I4f7562467449eac7931f3011d4b835934212adad Reviewed-by: David Edmundson (cherry picked from commit 0db685834f8377e41b147d3367b8ec514841eff5) --- src/client/qwaylandwindow.cpp | 26 ++++++++++++++++++++++++++ src/client/qwaylandwindow_p.h | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 1e26ee91e..bc031ed5a 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -364,6 +364,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) @@ -463,10 +466,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(); @@ -1215,6 +1224,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 diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 35a2c0321..6cc1664b7 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -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(); -- cgit v1.2.3