scene: add the presentation hint to Item

With this, the RenderLoop can use the Item instead of having to directly
deal with Wayland surfaces
This commit is contained in:
Xaver Hugl 2023-12-20 02:20:15 +01:00
parent a4283a2437
commit e1373ae2e1
11 changed files with 45 additions and 19 deletions

View file

@ -167,11 +167,10 @@ void Compositor::composite(RenderLoop *renderLoop)
prePaintPass(superLayer, &surfaceDamage);
SurfaceItem *scanoutCandidate = superLayer->delegate()->scanoutCandidate();
const SurfaceItemWayland *scanoutCandidateWayland = qobject_cast<SurfaceItemWayland *>(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 {

View file

@ -46,7 +46,6 @@ public:
Item *fullscreenItem = nullptr;
PresentationMode presentationMode = PresentationMode::VSync;
bool canDoTearing = false;
};
} // namespace KWin

View file

@ -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)

View file

@ -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"

View file

@ -7,6 +7,7 @@
#pragma once
#include "core/colorspace.h"
#include "effect/globals.h"
#include "scene/itemgeometry.h"
#include <QList>
@ -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<WindowQuadList> m_quads;
mutable std::optional<QList<Item *>> m_sortedChildItems;
ColorDescription m_colorDescription = ColorDescription::sRGB;
PresentationModeHint m_presentationHint = PresentationModeHint::VSync;
};
} // namespace KWin

View file

@ -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)

View file

@ -48,6 +48,7 @@ private Q_SLOTS:
void handleSubSurfacePositionChanged();
void handleSubSurfaceMappedChanged();
void handleColorDescriptionChanged();
void handlePresentationModeHintChanged();
protected:
std::unique_ptr<SurfacePixmap> createPixmap() override;

View file

@ -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;
}

View file

@ -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.

View file

@ -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<ContrastInterface> contrast;
QPointer<SlideInterface> slide;
ContentType contentType = ContentType::None;
PresentationHint presentationHint = PresentationHint::VSync;
PresentationModeHint presentationHint = PresentationModeHint::VSync;
ColorDescription colorDescription = ColorDescription::sRGB;
std::unique_ptr<PresentationTimeFeedback> presentationFeedback;

View file

@ -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;
}
}