wayland: implement tearing_control_v1
This commit is contained in:
parent
1a97d384f1
commit
b261050be1
9 changed files with 168 additions and 1 deletions
|
@ -205,7 +205,7 @@ find_package(Wayland 1.21 REQUIRED COMPONENTS
|
|||
Server
|
||||
)
|
||||
|
||||
find_package(WaylandProtocols 1.27)
|
||||
find_package(WaylandProtocols 1.30)
|
||||
set_package_properties(WaylandProtocols PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Collection of Wayland protocols that add functionality not available in the Wayland core protocol"
|
||||
|
|
|
@ -184,6 +184,10 @@ ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
|||
PROTOCOL ${WaylandProtocols_DATADIR}/staging/ext-idle-notify/ext-idle-notify-v1.xml
|
||||
BASENAME ext-idle-notify-v1
|
||||
)
|
||||
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
||||
PROTOCOL ${WaylandProtocols_DATADIR}/staging/tearing-control/tearing-control-v1.xml
|
||||
BASENAME tearing-control-v1
|
||||
)
|
||||
|
||||
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
||||
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
|
||||
|
@ -256,6 +260,7 @@ target_sources(kwin PRIVATE
|
|||
surface_interface.cpp
|
||||
surfacerole.cpp
|
||||
tablet_v2_interface.cpp
|
||||
tearingcontrol_v1_interface.cpp
|
||||
textinput.cpp
|
||||
textinput_v2_interface.cpp
|
||||
textinput_v3_interface.cpp
|
||||
|
|
|
@ -536,6 +536,10 @@ void SurfaceState::mergeInto(SurfaceState *target)
|
|||
target->contentType = contentType;
|
||||
target->contentTypeIsSet = true;
|
||||
}
|
||||
if (tearingIsSet) {
|
||||
target->presentationHint = presentationHint;
|
||||
target->tearingIsSet = true;
|
||||
}
|
||||
|
||||
*this = SurfaceState{};
|
||||
below = target->below;
|
||||
|
@ -1097,4 +1101,9 @@ QPointF SurfaceInterface::toSurfaceLocal(const QPointF &point) const
|
|||
return QPointF(point.x() * d->scaleOverride, point.y() * d->scaleOverride);
|
||||
}
|
||||
|
||||
PresentationHint SurfaceInterface::presentationHint() const
|
||||
{
|
||||
return d->current.presentationHint;
|
||||
}
|
||||
|
||||
} // namespace KWaylandServer
|
||||
|
|
|
@ -28,6 +28,11 @@ class SubSurfaceInterface;
|
|||
class SurfaceInterfacePrivate;
|
||||
class LinuxDmaBufV1Feedback;
|
||||
|
||||
enum class PresentationHint {
|
||||
VSync,
|
||||
Async
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Resource representing a wl_surface.
|
||||
*
|
||||
|
@ -336,6 +341,11 @@ public:
|
|||
*/
|
||||
QPointF toSurfaceLocal(const QPointF &point) const;
|
||||
|
||||
/**
|
||||
* @returns if the client thinks the content of this surface is suitable for presentation with tearing
|
||||
*/
|
||||
PresentationHint presentationHint() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when the underlying wl_surface resource is about to be freed.
|
||||
|
|
|
@ -20,6 +20,7 @@ class IdleInhibitorV1Interface;
|
|||
class SurfaceRole;
|
||||
class ViewportInterface;
|
||||
class ContentTypeV1Interface;
|
||||
class TearingControlV1Interface;
|
||||
|
||||
struct SurfaceState
|
||||
{
|
||||
|
@ -40,6 +41,7 @@ struct SurfaceState
|
|||
bool bufferScaleIsSet = false;
|
||||
bool bufferTransformIsSet = false;
|
||||
bool contentTypeIsSet = false;
|
||||
bool tearingIsSet = false;
|
||||
qint32 bufferScale = 1;
|
||||
KWin::Output::Transform bufferTransform = KWin::Output::Transform::Normal;
|
||||
wl_list frameCallbacks;
|
||||
|
@ -50,6 +52,7 @@ struct SurfaceState
|
|||
QPointer<ContrastInterface> contrast;
|
||||
QPointer<SlideInterface> slide;
|
||||
KWin::ContentType contentType = KWin::ContentType::None;
|
||||
PresentationHint presentationHint = PresentationHint::VSync;
|
||||
|
||||
// Subsurfaces are stored in two lists. The below list contains subsurfaces that
|
||||
// are below their parent surface; the above list contains subsurfaces that are
|
||||
|
@ -139,6 +142,7 @@ public:
|
|||
std::unique_ptr<LinuxDmaBufV1Feedback> dmabufFeedbackV1;
|
||||
QPointer<ContentTypeV1Interface> contentTypeInterface;
|
||||
ClientConnection *client = nullptr;
|
||||
TearingControlV1Interface *tearing = nullptr;
|
||||
|
||||
protected:
|
||||
void surface_destroy_resource(Resource *resource) override;
|
||||
|
|
104
src/wayland/tearingcontrol_v1_interface.cpp
Normal file
104
src/wayland/tearingcontrol_v1_interface.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
#include "tearingcontrol_v1_interface.h"
|
||||
#include "display.h"
|
||||
#include "surface_interface_p.h"
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
static constexpr uint32_t s_version = 1;
|
||||
|
||||
class TearingControlManagerV1InterfacePrivate : public QtWaylandServer::wp_tearing_control_manager_v1
|
||||
{
|
||||
public:
|
||||
TearingControlManagerV1InterfacePrivate(Display *display);
|
||||
|
||||
private:
|
||||
void wp_tearing_control_manager_v1_destroy(Resource *resource) override;
|
||||
void wp_tearing_control_manager_v1_get_tearing_control(Resource *resource, uint32_t id, struct ::wl_resource *surface) override;
|
||||
};
|
||||
|
||||
class TearingControlV1Interface : private QtWaylandServer::wp_tearing_control_v1
|
||||
{
|
||||
public:
|
||||
TearingControlV1Interface(SurfaceInterface *surface, wl_client *client, uint32_t id);
|
||||
~TearingControlV1Interface();
|
||||
|
||||
private:
|
||||
void wp_tearing_control_v1_set_presentation_hint(Resource *resource, uint32_t hint) override;
|
||||
void wp_tearing_control_v1_destroy(Resource *resource) override;
|
||||
void wp_tearing_control_v1_destroy_resource(Resource *resource) override;
|
||||
|
||||
const QPointer<SurfaceInterface> m_surface;
|
||||
};
|
||||
|
||||
TearingControlManagerV1Interface::TearingControlManagerV1Interface(Display *display, QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TearingControlManagerV1Interface::~TearingControlManagerV1Interface() = default;
|
||||
|
||||
TearingControlManagerV1InterfacePrivate::TearingControlManagerV1InterfacePrivate(Display *display)
|
||||
: QtWaylandServer::wp_tearing_control_manager_v1(*display, s_version)
|
||||
{
|
||||
}
|
||||
|
||||
void TearingControlManagerV1InterfacePrivate::wp_tearing_control_manager_v1_destroy(Resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void TearingControlManagerV1InterfacePrivate::wp_tearing_control_manager_v1_get_tearing_control(Resource *resource, uint32_t id, struct ::wl_resource *wlSurface)
|
||||
{
|
||||
SurfaceInterface *surface = SurfaceInterface::get(wlSurface);
|
||||
if (SurfaceInterfacePrivate::get(surface)->tearing) {
|
||||
wl_resource_post_error(resource->handle, QtWaylandServer::wp_tearing_control_manager_v1::error_tearing_control_exists, "Surface already has a wp_surface_tearing_control_v1");
|
||||
return;
|
||||
}
|
||||
SurfaceInterfacePrivate::get(surface)->tearing = new TearingControlV1Interface(surface, resource->client(), id);
|
||||
}
|
||||
|
||||
TearingControlV1Interface::TearingControlV1Interface(SurfaceInterface *surface, wl_client *client, uint32_t id)
|
||||
: QtWaylandServer::wp_tearing_control_v1(client, id, s_version)
|
||||
, m_surface(surface)
|
||||
{
|
||||
}
|
||||
|
||||
TearingControlV1Interface::~TearingControlV1Interface()
|
||||
{
|
||||
if (m_surface) {
|
||||
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface);
|
||||
surfacePrivate->pending.presentationHint = PresentationHint::VSync;
|
||||
surfacePrivate->pending.tearingIsSet = true;
|
||||
surfacePrivate->tearing = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TearingControlV1Interface::wp_tearing_control_v1_set_presentation_hint(Resource *resource, uint32_t hint)
|
||||
{
|
||||
if (m_surface) {
|
||||
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface);
|
||||
if (hint == presentation_hint::presentation_hint_async) {
|
||||
surfacePrivate->pending.presentationHint = PresentationHint::Async;
|
||||
} else {
|
||||
surfacePrivate->pending.presentationHint = PresentationHint::VSync;
|
||||
}
|
||||
surfacePrivate->pending.tearingIsSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TearingControlV1Interface::wp_tearing_control_v1_destroy(Resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void TearingControlV1Interface::wp_tearing_control_v1_destroy_resource(Resource *resource)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
31
src/wayland/tearingcontrol_v1_interface.h
Normal file
31
src/wayland/tearingcontrol_v1_interface.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "surface_interface.h"
|
||||
|
||||
#include "qwayland-server-tearing-control-v1.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
class TearingControlManagerV1InterfacePrivate;
|
||||
class TearingControlV1Interface;
|
||||
class Display;
|
||||
|
||||
class TearingControlManagerV1Interface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TearingControlManagerV1Interface(Display *display, QObject *parent = nullptr);
|
||||
~TearingControlManagerV1Interface() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<TearingControlManagerV1InterfacePrivate> d;
|
||||
};
|
||||
}
|
|
@ -59,6 +59,7 @@
|
|||
#include "wayland/shadow_interface.h"
|
||||
#include "wayland/subcompositor_interface.h"
|
||||
#include "wayland/tablet_v2_interface.h"
|
||||
#include "wayland/tearingcontrol_v1_interface.h"
|
||||
#include "wayland/viewporter_interface.h"
|
||||
#include "wayland/xdgactivation_v1_interface.h"
|
||||
#include "wayland/xdgdecoration_v1_interface.h"
|
||||
|
@ -487,6 +488,7 @@ bool WaylandServer::init(InitializationFlags flags)
|
|||
});
|
||||
|
||||
m_contentTypeManager = new KWaylandServer::ContentTypeManagerV1Interface(m_display, m_display);
|
||||
m_tearingControlInterface = new KWaylandServer::TearingControlManagerV1Interface(m_display, m_display);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ class XdgDecorationManagerV1Interface;
|
|||
class XWaylandKeyboardGrabManagerV1Interface;
|
||||
class ContentTypeManagerV1Interface;
|
||||
class DrmLeaseManagerV1;
|
||||
class TearingControlManagerV1Interface;
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
|
@ -290,6 +291,7 @@ private:
|
|||
XdgActivationV1Integration *m_xdgActivationIntegration = nullptr;
|
||||
KWaylandServer::XWaylandKeyboardGrabManagerV1Interface *m_xWaylandKeyboardGrabManager = nullptr;
|
||||
KWaylandServer::ContentTypeManagerV1Interface *m_contentTypeManager = nullptr;
|
||||
KWaylandServer::TearingControlManagerV1Interface *m_tearingControlInterface = nullptr;
|
||||
QList<Window *> m_windows;
|
||||
InitializationFlags m_initFlags;
|
||||
QHash<Output *, KWaylandServer::OutputInterface *> m_waylandOutputs;
|
||||
|
|
Loading…
Reference in a new issue