diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2022-02-11 09:11:00 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2022-02-17 07:53:46 +0100 |
commit | 00323844defd67b0edc76db1c56ba32433a232bf (patch) | |
tree | b7470038435703fdf9dc3f8e44df78b4d24ea169 | |
parent | 824ac51444e7df1420e9d35b94fd3efd204f9cc9 (diff) | |
download | qtwayland-00323844defd67b0edc76db1c56ba32433a232bf.tar.gz |
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>
4 files changed, 37 insertions, 5 deletions
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index bf1d0a44..07130a8a 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 b07a93e9..4523080b 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 61ba570f..8b377c9b 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 6cf8121f..fe8e1207 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) |