summaryrefslogtreecommitdiffstats
path: root/src/compositor
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2022-02-11 09:11:00 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2022-02-17 07:53:46 +0100
commit00323844defd67b0edc76db1c56ba32433a232bf (patch)
treeb7470038435703fdf9dc3f8e44df78b4d24ea169 /src/compositor
parent824ac51444e7df1420e9d35b94fd3efd204f9cc9 (diff)
Use opaque render list when client content is opaque
If the client says it's fully opaque through the set_opaque_region request, we can disable blending for the item and potentially improve performance a little bit. [ChangeLog][QtWaylandCompositor] The compositor now respects the opaque region set by the client and no longer applies blending or overdraw for fully opaque windows. Fixes: QTBUG-100373 Change-Id: Iaa68fbf1f086d926c9c1867d981a63810f4ca855 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp4
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp34
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h3
-rw-r--r--src/compositor/compositor_api/qwaylandsurface_p.h1
4 files changed, 37 insertions, 5 deletions
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
index bf1d0a447..07130a8a6 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
@@ -372,7 +372,7 @@ void QWaylandBufferMaterial::setBufferRef(QWaylandQuickItem *surfaceItem, const
if (auto texture = ref.toOpenGLTexture(plane)) {
QQuickWindow::CreateTextureOptions opt;
QWaylandQuickSurface *waylandSurface = qobject_cast<QWaylandQuickSurface *>(surfaceItem->surface());
- if (waylandSurface != nullptr && waylandSurface->useTextureAlpha())
+ if (waylandSurface != nullptr && waylandSurface->useTextureAlpha() && !waylandSurface->isOpaque())
opt |= QQuickWindow::TextureHasAlphaChannel;
QSGTexture *scenegraphTexture;
if (ref.bufferFormatEgl() == QWaylandBufferRef::BufferFormatEgl_EXTERNAL_OES) {
@@ -422,7 +422,7 @@ public:
#if QT_CONFIG(opengl)
QQuickWindow::CreateTextureOptions opt;
QWaylandQuickSurface *surface = qobject_cast<QWaylandQuickSurface *>(surfaceItem->surface());
- if (surface && surface->useTextureAlpha()) {
+ if (surface && surface->useTextureAlpha() && !surface->isOpaque()) {
opt |= QQuickWindow::TextureHasAlphaChannel;
}
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index b07a93e91..4523080b2 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -257,6 +257,7 @@ void QWaylandSurfacePrivate::surface_commit(Resource *)
QSize surfaceSize = bufferSize / bufferScale;
sourceGeometry = !pending.sourceGeometry.isValid() ? QRect(QPoint(), surfaceSize) : pending.sourceGeometry;
destinationSize = pending.destinationSize.isEmpty() ? sourceGeometry.size().toSize() : pending.destinationSize;
+ QRect destinationRect(QPoint(), destinationSize);
if (!pending.damageInBufferCoordinates || pending.bufferScale == 1) {
// pending.damage is already in surface coordinates
damage = pending.damage.intersected(QRect(QPoint(), destinationSize));
@@ -272,13 +273,19 @@ void QWaylandSurfacePrivate::surface_commit(Resource *)
};
damage = {};
for (const QRect &r : pending.damage) {
- damage |= xform(r, bufferScale).intersected(QRect{{}, destinationSize});
+ damage |= xform(r, bufferScale).intersected(destinationRect);
}
}
hasContent = bufferRef.hasContent();
frameCallbacks << pendingFrameCallbacks;
- inputRegion = pending.inputRegion.intersected(QRect(QPoint(), destinationSize));
- opaqueRegion = pending.opaqueRegion.intersected(QRect(QPoint(), destinationSize));
+ inputRegion = pending.inputRegion.intersected(destinationRect);
+ opaqueRegion = pending.opaqueRegion.intersected(destinationRect);
+ bool becameOpaque = opaqueRegion.boundingRect().contains(destinationRect);
+ if (becameOpaque != isOpaque) {
+ isOpaque = becameOpaque;
+ emit q->isOpaqueChanged();
+ }
+
QPoint offsetForNextFrame = pending.offset;
if (viewport)
@@ -857,6 +864,27 @@ bool QWaylandSurface::inhibitsIdle() const
return !d->idleInhibitors.isEmpty();
}
+/*!
+ * \qmlproperty bool QtWaylandCompositor::WaylandSurface::isOpaque
+ * \since 6.4
+ *
+ * This property holds whether the surface is fully opaque, as reported by the
+ * client through the set_opaque_region request.
+ */
+
+/*!
+ * \property bool QWaylandSurface::isOpaque
+ * \since 6.4
+ *
+ * This property holds whether the surface is fully opaque, as reported by the
+ * client through the set_opaque_region request.
+ */
+bool QWaylandSurface::isOpaque() const
+{
+ Q_D(const QWaylandSurface);
+ return d->isOpaque;
+}
+
#if QT_CONFIG(im)
QWaylandInputMethodControl *QWaylandSurface::inputMethodControl() const
{
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index 61ba570fc..8b377c9bc 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -78,6 +78,7 @@ class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject
Q_PROPERTY(bool hasContent READ hasContent NOTIFY hasContentChanged)
Q_PROPERTY(bool cursorSurface READ isCursorSurface WRITE markAsCursorSurface NOTIFY cursorSurfaceChanged)
Q_PROPERTY(bool inhibitsIdle READ inhibitsIdle NOTIFY inhibitsIdleChanged REVISION(1, 14))
+ Q_PROPERTY(bool isOpaque READ isOpaque NOTIFY isOpaqueChanged REVISION(6, 4))
Q_MOC_INCLUDE("qwaylanddrag.h")
Q_MOC_INCLUDE("qwaylandcompositor.h")
@@ -138,6 +139,7 @@ public:
bool isCursorSurface() const;
bool inhibitsIdle() const;
+ bool isOpaque() const;
#if QT_CONFIG(im)
QWaylandInputMethodControl *inputMethodControl() const;
@@ -170,6 +172,7 @@ Q_SIGNALS:
void dragStarted(QWaylandDrag *drag);
void cursorSurfaceChanged();
Q_REVISION(14) void inhibitsIdleChanged();
+ Q_REVISION(6, 4) void isOpaqueChanged();
void configure(bool hasBuffer);
void redraw();
diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h
index 6cf8121ff..fe8e1207b 100644
--- a/src/compositor/compositor_api/qwaylandsurface_p.h
+++ b/src/compositor/compositor_api/qwaylandsurface_p.h
@@ -172,6 +172,7 @@ public: //member variables
bool destroyed = false;
bool hasContent = false;
bool isInitialized = false;
+ bool isOpaque = false;
Qt::ScreenOrientation contentOrientation = Qt::PrimaryOrientation;
QWindow::Visibility visibility;
#if QT_CONFIG(im)