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:
parent
a4283a2437
commit
e1373ae2e1
11 changed files with 45 additions and 19 deletions
|
@ -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 {
|
||||
|
|
|
@ -46,7 +46,6 @@ public:
|
|||
Item *fullscreenItem = nullptr;
|
||||
|
||||
PresentationMode presentationMode = PresentationMode::VSync;
|
||||
bool canDoTearing = false;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -48,6 +48,7 @@ private Q_SLOTS:
|
|||
void handleSubSurfacePositionChanged();
|
||||
void handleSubSurfaceMappedChanged();
|
||||
void handleColorDescriptionChanged();
|
||||
void handlePresentationModeHintChanged();
|
||||
|
||||
protected:
|
||||
std::unique_ptr<SurfacePixmap> createPixmap() override;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue