From e1373ae2e12121f74e462bcddb239eb0d065de31 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Wed, 20 Dec 2023 02:20:15 +0100 Subject: [PATCH] scene: add the presentation hint to Item With this, the RenderLoop can use the Item instead of having to directly deal with Wayland surfaces --- src/compositor.cpp | 3 +-- src/core/renderloop_p.h | 1 - src/effect/globals.h | 6 ++++++ src/scene/item.cpp | 10 ++++++++++ src/scene/item.h | 4 ++++ src/scene/surfaceitem_wayland.cpp | 7 +++++++ src/scene/surfaceitem_wayland.h | 1 + src/wayland/surface.cpp | 10 +++++++--- src/wayland/surface.h | 8 ++------ src/wayland/surface_p.h | 4 ++-- src/wayland/tearingcontrol_v1.cpp | 10 +++++----- 11 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/compositor.cpp b/src/compositor.cpp index 0da61ed243..6f17399cd5 100644 --- a/src/compositor.cpp +++ b/src/compositor.cpp @@ -167,11 +167,10 @@ void Compositor::composite(RenderLoop *renderLoop) prePaintPass(superLayer, &surfaceDamage); SurfaceItem *scanoutCandidate = superLayer->delegate()->scanoutCandidate(); - const SurfaceItemWayland *scanoutCandidateWayland = qobject_cast(scanoutCandidate); renderLoop->setFullscreenSurface(scanoutCandidate); frame->setContentType(scanoutCandidate ? scanoutCandidate->contentType() : ContentType::None); const bool vrr = (output->capabilities() & Output::Capability::Vrr) && (output->vrrPolicy() == VrrPolicy::Always || (output->vrrPolicy() == VrrPolicy::Automatic && scanoutCandidate)); - const bool tearing = (output->capabilities() & Output::Capability::Tearing) && options->allowTearing() && scanoutCandidateWayland && scanoutCandidateWayland->surface()->presentationHint() == PresentationHint::Async; + const bool tearing = (output->capabilities() & Output::Capability::Tearing) && options->allowTearing() && scanoutCandidate && scanoutCandidate->presentationHint() == PresentationModeHint::Async; if (vrr) { frame->setPresentationMode(tearing ? PresentationMode::AdaptiveAsync : PresentationMode::AdaptiveSync); } else { diff --git a/src/core/renderloop_p.h b/src/core/renderloop_p.h index e49aa99ed8..cec1bfb0d4 100644 --- a/src/core/renderloop_p.h +++ b/src/core/renderloop_p.h @@ -46,7 +46,6 @@ public: Item *fullscreenItem = nullptr; PresentationMode presentationMode = PresentationMode::VSync; - bool canDoTearing = false; }; } // namespace KWin diff --git a/src/effect/globals.h b/src/effect/globals.h index 09bc8094a8..4ae1ecddc1 100644 --- a/src/effect/globals.h +++ b/src/effect/globals.h @@ -296,6 +296,12 @@ enum class VrrPolicy { }; Q_ENUM_NS(VrrPolicy); +enum class PresentationModeHint { + VSync, + Async +}; +Q_ENUM_NS(PresentationModeHint); + } // namespace Q_DECLARE_METATYPE(std::chrono::nanoseconds) diff --git a/src/scene/item.cpp b/src/scene/item.cpp index 839e245204..d5675677c4 100644 --- a/src/scene/item.cpp +++ b/src/scene/item.cpp @@ -452,6 +452,16 @@ void Item::setColorDescription(const ColorDescription &description) m_colorDescription = description; } +PresentationModeHint Item::presentationHint() const +{ + return m_presentationHint; +} + +void Item::setPresentationHint(PresentationModeHint hint) +{ + m_presentationHint = hint; +} + } // namespace KWin #include "moc_item.cpp" diff --git a/src/scene/item.h b/src/scene/item.h index 853c8f386d..5e9e4f1c92 100644 --- a/src/scene/item.h +++ b/src/scene/item.h @@ -7,6 +7,7 @@ #pragma once #include "core/colorspace.h" +#include "effect/globals.h" #include "scene/itemgeometry.h" #include @@ -112,6 +113,7 @@ public: WindowQuadList quads() const; virtual void preprocess(); const ColorDescription &colorDescription() const; + PresentationModeHint presentationHint() const; Q_SIGNALS: void childAdded(Item *item); @@ -134,6 +136,7 @@ protected: virtual WindowQuadList buildQuads() const; void discardQuads(); void setColorDescription(const ColorDescription &description); + void setPresentationHint(PresentationModeHint hint); private: void addChild(Item *item); @@ -162,6 +165,7 @@ private: mutable std::optional m_quads; mutable std::optional> m_sortedChildItems; ColorDescription m_colorDescription = ColorDescription::sRGB; + PresentationModeHint m_presentationHint = PresentationModeHint::VSync; }; } // namespace KWin diff --git a/src/scene/surfaceitem_wayland.cpp b/src/scene/surfaceitem_wayland.cpp index 670168e614..7cba52eef9 100644 --- a/src/scene/surfaceitem_wayland.cpp +++ b/src/scene/surfaceitem_wayland.cpp @@ -42,6 +42,8 @@ SurfaceItemWayland::SurfaceItemWayland(SurfaceInterface *surface, Scene *scene, this, &SurfaceItemWayland::handleChildSubSurfaceRemoved); connect(surface, &SurfaceInterface::colorDescriptionChanged, this, &SurfaceItemWayland::handleColorDescriptionChanged); + connect(surface, &SurfaceInterface::presentationModeHintChanged, + this, &SurfaceItemWayland::handlePresentationModeHintChanged); SubSurfaceInterface *subsurface = surface->subSurface(); if (subsurface) { @@ -189,6 +191,11 @@ void SurfaceItemWayland::handleColorDescriptionChanged() setColorDescription(m_surface->colorDescription()); } +void SurfaceItemWayland::handlePresentationModeHintChanged() +{ + setPresentationHint(m_surface->presentationModeHint()); +} + SurfacePixmapWayland::SurfacePixmapWayland(SurfaceItemWayland *item, QObject *parent) : SurfacePixmap(Compositor::self()->backend()->createSurfaceTextureWayland(this), parent) , m_item(item) diff --git a/src/scene/surfaceitem_wayland.h b/src/scene/surfaceitem_wayland.h index 26f6af9532..42ffd650a4 100644 --- a/src/scene/surfaceitem_wayland.h +++ b/src/scene/surfaceitem_wayland.h @@ -48,6 +48,7 @@ private Q_SLOTS: void handleSubSurfacePositionChanged(); void handleSubSurfaceMappedChanged(); void handleColorDescriptionChanged(); + void handlePresentationModeHintChanged(); protected: std::unique_ptr createPixmap() override; diff --git a/src/wayland/surface.cpp b/src/wayland/surface.cpp index 2e3107e0d5..adb10add48 100644 --- a/src/wayland/surface.cpp +++ b/src/wayland/surface.cpp @@ -641,9 +641,9 @@ void SurfaceState::mergeInto(SurfaceState *target) target->contentType = contentType; target->contentTypeIsSet = true; } - if (tearingIsSet) { + if (presentationModeHintIsSet) { target->presentationHint = presentationHint; - target->tearingIsSet = true; + target->presentationModeHintIsSet = true; } if (colorDescriptionIsSet) { target->colorDescription = colorDescription; @@ -671,6 +671,7 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) const bool subsurfaceOrderChanged = next->subsurfaceOrderChanged; const bool visibilityChanged = bufferChanged && bool(current->buffer) != bool(next->buffer); const bool colorDescriptionChanged = next->colorDescriptionIsSet; + const bool presentationModeHintChanged = next->presentationModeHintIsSet; const QSizeF oldSurfaceSize = surfaceSize; const QSize oldBufferSize = bufferSize; @@ -769,6 +770,9 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) if (colorDescriptionChanged) { Q_EMIT q->colorDescriptionChanged(); } + if (presentationModeHintChanged) { + Q_EMIT q->presentationModeHintChanged(); + } if (bufferChanged) { if (current->buffer && (!current->damage.isEmpty() || !current->bufferDamage.isEmpty())) { @@ -1154,7 +1158,7 @@ QPointF SurfaceInterface::toSurfaceLocal(const QPointF &point) const return QPointF(point.x() * d->scaleOverride, point.y() * d->scaleOverride); } -PresentationHint SurfaceInterface::presentationHint() const +PresentationModeHint SurfaceInterface::presentationModeHint() const { return d->current->presentationHint; } diff --git a/src/wayland/surface.h b/src/wayland/surface.h index 5557eaa514..b51ab52dc3 100644 --- a/src/wayland/surface.h +++ b/src/wayland/surface.h @@ -34,11 +34,6 @@ class SubSurfaceInterface; class SurfaceInterfacePrivate; class Transaction; -enum class PresentationHint { - VSync, - Async -}; - /** * The SurfaceRole class represents a role assigned to a wayland surface. */ @@ -347,7 +342,7 @@ public: /** * @returns if the client thinks the content of this surface is suitable for presentation with tearing */ - PresentationHint presentationHint() const; + PresentationModeHint presentationModeHint() const; /** * Sets a preferred buffer scale that clients should provide buffers in @@ -470,6 +465,7 @@ Q_SIGNALS: void inhibitsIdleChanged(); void colorDescriptionChanged(); + void presentationModeHintChanged(); /** * Emitted when the Surface has been committed. diff --git a/src/wayland/surface_p.h b/src/wayland/surface_p.h index ae31db4c1d..db5e4950e2 100644 --- a/src/wayland/surface_p.h +++ b/src/wayland/surface_p.h @@ -55,7 +55,7 @@ struct SurfaceState bool bufferScaleIsSet = false; bool bufferTransformIsSet = false; bool contentTypeIsSet = false; - bool tearingIsSet = false; + bool presentationModeHintIsSet = false; bool colorDescriptionIsSet = false; qint32 bufferScale = 1; OutputTransform bufferTransform = OutputTransform::Normal; @@ -67,7 +67,7 @@ struct SurfaceState QPointer contrast; QPointer slide; ContentType contentType = ContentType::None; - PresentationHint presentationHint = PresentationHint::VSync; + PresentationModeHint presentationHint = PresentationModeHint::VSync; ColorDescription colorDescription = ColorDescription::sRGB; std::unique_ptr presentationFeedback; diff --git a/src/wayland/tearingcontrol_v1.cpp b/src/wayland/tearingcontrol_v1.cpp index 9dad0ce463..12ca337d8b 100644 --- a/src/wayland/tearingcontrol_v1.cpp +++ b/src/wayland/tearingcontrol_v1.cpp @@ -74,8 +74,8 @@ TearingControlV1Interface::~TearingControlV1Interface() { if (m_surface) { SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface); - surfacePrivate->pending->presentationHint = PresentationHint::VSync; - surfacePrivate->pending->tearingIsSet = true; + surfacePrivate->pending->presentationHint = PresentationModeHint::VSync; + surfacePrivate->pending->presentationModeHintIsSet = true; surfacePrivate->tearing = nullptr; } } @@ -85,11 +85,11 @@ void TearingControlV1Interface::wp_tearing_control_v1_set_presentation_hint(Reso if (m_surface) { SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface); if (hint == presentation_hint::presentation_hint_async) { - surfacePrivate->pending->presentationHint = PresentationHint::Async; + surfacePrivate->pending->presentationHint = PresentationModeHint::Async; } else { - surfacePrivate->pending->presentationHint = PresentationHint::VSync; + surfacePrivate->pending->presentationHint = PresentationModeHint::VSync; } - surfacePrivate->pending->tearingIsSet = true; + surfacePrivate->pending->presentationModeHintIsSet = true; } }