wayland: implement the alpha-modifier protocol
The alpha modifier protocol allows clients to set a multiplier for the opacity of a surface, which allows them to offload some operations to KWin, which in turn may offload them to KMS in the future
This commit is contained in:
parent
370c9c8953
commit
4759ec6089
11 changed files with 160 additions and 2 deletions
|
@ -211,7 +211,7 @@ else()
|
|||
set(HAVE_WL_DISPLAY_SET_DEFAULT_MAX_BUFFER_SIZE 0)
|
||||
endif()
|
||||
|
||||
find_package(WaylandProtocols 1.34)
|
||||
find_package(WaylandProtocols 1.36)
|
||||
set_package_properties(WaylandProtocols PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Collection of Wayland protocols that add functionality not available in the Wayland core protocol"
|
||||
|
|
|
@ -47,6 +47,7 @@ SurfaceItemWayland::SurfaceItemWayland(SurfaceInterface *surface, Item *parent)
|
|||
connect(surface, &SurfaceInterface::presentationModeHintChanged,
|
||||
this, &SurfaceItemWayland::handlePresentationModeHintChanged);
|
||||
connect(surface, &SurfaceInterface::bufferReleasePointChanged, this, &SurfaceItemWayland::handleReleasePointChanged);
|
||||
connect(surface, &SurfaceInterface::alphaMultiplierChanged, this, &SurfaceItemWayland::handleAlphaMultiplierChanged);
|
||||
|
||||
SubSurfaceInterface *subsurface = surface->subSurface();
|
||||
if (subsurface) {
|
||||
|
@ -66,6 +67,7 @@ SurfaceItemWayland::SurfaceItemWayland(SurfaceInterface *surface, Item *parent)
|
|||
setBufferSourceBox(surface->bufferSourceBox());
|
||||
setBufferSize(surface->bufferSize());
|
||||
setColorDescription(surface->colorDescription());
|
||||
setOpacity(surface->alphaMultiplier());
|
||||
}
|
||||
|
||||
QList<QRectF> SurfaceItemWayland::shape() const
|
||||
|
@ -216,6 +218,11 @@ void SurfaceItemWayland::handleReleasePointChanged()
|
|||
m_bufferReleasePoint = m_surface->bufferReleasePoint();
|
||||
}
|
||||
|
||||
void SurfaceItemWayland::handleAlphaMultiplierChanged()
|
||||
{
|
||||
setOpacity(m_surface->alphaMultiplier());
|
||||
}
|
||||
|
||||
SurfacePixmapWayland::SurfacePixmapWayland(SurfaceItemWayland *item, QObject *parent)
|
||||
: SurfacePixmap(Compositor::self()->backend()->createSurfaceTextureWayland(this), parent)
|
||||
, m_item(item)
|
||||
|
|
|
@ -50,6 +50,7 @@ private Q_SLOTS:
|
|||
void handleColorDescriptionChanged();
|
||||
void handlePresentationModeHintChanged();
|
||||
void handleReleasePointChanged();
|
||||
void handleAlphaMultiplierChanged();
|
||||
|
||||
protected:
|
||||
std::unique_ptr<SurfacePixmap> createPixmap() override;
|
||||
|
|
|
@ -315,10 +315,15 @@ ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
|||
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-external-brightness-v1.xml
|
||||
BASENAME kde-external-brightness-v1
|
||||
)
|
||||
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
|
||||
PROTOCOL ${WaylandProtocols_DATADIR}/staging/alpha-modifier/alpha-modifier-v1.xml
|
||||
BASENAME alpha-modifier-v1
|
||||
)
|
||||
|
||||
target_sources(kwin PRIVATE
|
||||
abstract_data_source.cpp
|
||||
abstract_drop_handler.cpp
|
||||
alphamodifier_v1.cpp
|
||||
appmenu.cpp
|
||||
blur.cpp
|
||||
clientconnection.cpp
|
||||
|
@ -403,6 +408,7 @@ target_sources(kwin PRIVATE
|
|||
)
|
||||
|
||||
install(FILES
|
||||
alphamodifier_v1.h
|
||||
appmenu.h
|
||||
blur.h
|
||||
clientconnection.h
|
||||
|
@ -478,12 +484,14 @@ install(FILES
|
|||
xwaylandshell_v1.h
|
||||
xx_colormanagement_v4.h
|
||||
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-alpha-modifier-v1.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-content-type-v1.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-frog-color-management-v1.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-kde-external-brightness-v1.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-linux-drm-syncobj-v1.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-presentation-time.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/qwayland-server-xx-color-management-v4.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wayland-alpha-modifier-v1-server-protocol.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wayland-content-type-v1-server-protocol.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wayland-frog-color-management-v1-server-protocol.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wayland-kde-external-brightness-v1-server-protocol.h
|
||||
|
|
75
src/wayland/alphamodifier_v1.cpp
Normal file
75
src/wayland/alphamodifier_v1.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
#include "alphamodifier_v1.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "surface.h"
|
||||
#include "surface_p.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
static constexpr uint32_t s_version = 1;
|
||||
|
||||
AlphaModifierManagerV1::AlphaModifierManagerV1(Display *display, QObject *parent)
|
||||
: QObject(parent)
|
||||
, QtWaylandServer::wp_alpha_modifier_v1(*display, s_version)
|
||||
{
|
||||
}
|
||||
|
||||
void AlphaModifierManagerV1::wp_alpha_modifier_v1_destroy(Resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void AlphaModifierManagerV1::wp_alpha_modifier_v1_get_surface(Resource *resource, uint32_t id, ::wl_resource *surface)
|
||||
{
|
||||
SurfaceInterface *surf = SurfaceInterface::get(surface);
|
||||
SurfaceInterfacePrivate *priv = SurfaceInterfacePrivate::get(surf);
|
||||
if (priv->alphaModifier) {
|
||||
wl_resource_post_error(surface, error_already_constructed, "wl_surface already has an alpha modifier surface");
|
||||
return;
|
||||
}
|
||||
new AlphaModifierSurfaceV1(resource->client(), id, resource->version(), surf);
|
||||
}
|
||||
|
||||
AlphaModifierSurfaceV1::AlphaModifierSurfaceV1(wl_client *client, uint32_t id, uint32_t version, SurfaceInterface *surface)
|
||||
: QtWaylandServer::wp_alpha_modifier_surface_v1(client, id, version)
|
||||
, m_surface(surface)
|
||||
{
|
||||
}
|
||||
|
||||
AlphaModifierSurfaceV1::~AlphaModifierSurfaceV1()
|
||||
{
|
||||
if (m_surface) {
|
||||
const auto priv = SurfaceInterfacePrivate::get(m_surface);
|
||||
priv->pending->alphaMultiplier = 1;
|
||||
priv->pending->alphaMultiplierIsSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaModifierSurfaceV1::wp_alpha_modifier_surface_v1_destroy_resource(Resource *resource)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void AlphaModifierSurfaceV1::wp_alpha_modifier_surface_v1_destroy(Resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
void AlphaModifierSurfaceV1::wp_alpha_modifier_surface_v1_set_multiplier(Resource *resource, uint32_t factor)
|
||||
{
|
||||
if (!m_surface) {
|
||||
wl_resource_post_error(resource->handle, error_no_surface, "wl_surface was destroyed before a set_multiplier request");
|
||||
return;
|
||||
}
|
||||
const auto priv = SurfaceInterfacePrivate::get(m_surface);
|
||||
priv->pending->alphaMultiplier = factor / double(std::numeric_limits<uint32_t>::max());
|
||||
priv->pending->alphaMultiplierIsSet = true;
|
||||
}
|
||||
|
||||
}
|
44
src/wayland/alphamodifier_v1.h
Normal file
44
src/wayland/alphamodifier_v1.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 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 "kwin_export.h"
|
||||
#include "wayland/qwayland-server-alpha-modifier-v1.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Display;
|
||||
class SurfaceInterface;
|
||||
|
||||
class KWIN_EXPORT AlphaModifierManagerV1 : public QObject, private QtWaylandServer::wp_alpha_modifier_v1
|
||||
{
|
||||
public:
|
||||
explicit AlphaModifierManagerV1(Display *display, QObject *parent);
|
||||
|
||||
private:
|
||||
void wp_alpha_modifier_v1_destroy(Resource *resource) override;
|
||||
void wp_alpha_modifier_v1_get_surface(Resource *resource, uint32_t id, ::wl_resource *surface) override;
|
||||
};
|
||||
|
||||
class AlphaModifierSurfaceV1 : private QtWaylandServer::wp_alpha_modifier_surface_v1
|
||||
{
|
||||
public:
|
||||
explicit AlphaModifierSurfaceV1(wl_client *client, uint32_t id, uint32_t version, SurfaceInterface *surface);
|
||||
~AlphaModifierSurfaceV1() override;
|
||||
|
||||
private:
|
||||
void wp_alpha_modifier_surface_v1_destroy_resource(Resource *resource) override;
|
||||
void wp_alpha_modifier_surface_v1_destroy(Resource *resource) override;
|
||||
void wp_alpha_modifier_surface_v1_set_multiplier(Resource *resource, uint32_t factor) override;
|
||||
|
||||
const QPointer<SurfaceInterface> m_surface;
|
||||
};
|
||||
|
||||
}
|
|
@ -589,6 +589,10 @@ void SurfaceState::mergeInto(SurfaceState *target)
|
|||
target->colorDescription = colorDescription;
|
||||
target->colorDescriptionIsSet = true;
|
||||
}
|
||||
if (alphaMultiplierIsSet) {
|
||||
target->alphaMultiplier = alphaMultiplier;
|
||||
target->alphaMultiplierIsSet = true;
|
||||
}
|
||||
target->presentationFeedback = std::move(presentationFeedback);
|
||||
|
||||
*this = SurfaceState{};
|
||||
|
@ -611,6 +615,7 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next)
|
|||
const bool colorDescriptionChanged = next->colorDescriptionIsSet;
|
||||
const bool presentationModeHintChanged = next->presentationModeHintIsSet;
|
||||
const bool bufferReleasePointChanged = next->bufferIsSet && current->releasePoint != next->releasePoint;
|
||||
const bool alphaMultiplierChanged = next->alphaMultiplierIsSet;
|
||||
|
||||
const QSizeF oldSurfaceSize = surfaceSize;
|
||||
const QSize oldBufferSize = bufferSize;
|
||||
|
@ -706,6 +711,9 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next)
|
|||
if (bufferReleasePointChanged) {
|
||||
Q_EMIT q->bufferReleasePointChanged();
|
||||
}
|
||||
if (alphaMultiplierChanged) {
|
||||
Q_EMIT q->alphaMultiplierChanged();
|
||||
}
|
||||
|
||||
if (bufferChanged) {
|
||||
if (current->buffer && (!current->damage.isEmpty() || !current->bufferDamage.isEmpty())) {
|
||||
|
@ -1210,6 +1218,11 @@ std::shared_ptr<SyncReleasePoint> SurfaceInterface::bufferReleasePoint() const
|
|||
return d->current->releasePoint;
|
||||
}
|
||||
|
||||
double SurfaceInterface::alphaMultiplier() const
|
||||
{
|
||||
return d->current->alphaMultiplier;
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
#include "moc_surface.cpp"
|
||||
|
|
|
@ -344,6 +344,8 @@ public:
|
|||
|
||||
void setPreferredColorDescription(const ColorDescription &descr);
|
||||
|
||||
double alphaMultiplier() const;
|
||||
|
||||
/**
|
||||
* Returns the current release point for the buffer on this surface. The buffer keeps the
|
||||
* release point referenced as long as it's referenced itself; for synchronization on the
|
||||
|
@ -437,6 +439,7 @@ Q_SIGNALS:
|
|||
void colorDescriptionChanged();
|
||||
void presentationModeHintChanged();
|
||||
void bufferReleasePointChanged();
|
||||
void alphaMultiplierChanged();
|
||||
|
||||
/**
|
||||
* Emitted when the Surface has been committed.
|
||||
|
|
|
@ -30,6 +30,7 @@ class PresentationTimeFeedback;
|
|||
class XXColorSurfaceV4;
|
||||
class XXColorFeedbackSurfaceV4;
|
||||
class LinuxDrmSyncObjSurfaceV1;
|
||||
class AlphaModifierSurfaceV1;
|
||||
|
||||
struct SurfaceState
|
||||
{
|
||||
|
@ -60,6 +61,7 @@ struct SurfaceState
|
|||
bool contentTypeIsSet = false;
|
||||
bool presentationModeHintIsSet = false;
|
||||
bool colorDescriptionIsSet = false;
|
||||
bool alphaMultiplierIsSet = false;
|
||||
qint32 bufferScale = 1;
|
||||
OutputTransform bufferTransform = OutputTransform::Normal;
|
||||
wl_list frameCallbacks;
|
||||
|
@ -80,6 +82,7 @@ struct SurfaceState
|
|||
uint64_t point = 0;
|
||||
} acquirePoint;
|
||||
std::shared_ptr<SyncReleasePoint> releasePoint;
|
||||
double alphaMultiplier = 1;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -181,6 +184,7 @@ public:
|
|||
XXColorSurfaceV4 *xxColorSurface = nullptr;
|
||||
QList<XXColorFeedbackSurfaceV4 *> xxColorFeedbacks;
|
||||
LinuxDrmSyncObjSurfaceV1 *syncObjV1 = nullptr;
|
||||
AlphaModifierSurfaceV1 *alphaModifier = nullptr;
|
||||
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "utils/kernel.h"
|
||||
#include "utils/serviceutils.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "wayland/alphamodifier_v1.h"
|
||||
#include "wayland/appmenu.h"
|
||||
#include "wayland/clientconnection.h"
|
||||
#include "wayland/compositor.h"
|
||||
|
@ -525,7 +526,7 @@ bool WaylandServer::init()
|
|||
});
|
||||
|
||||
m_externalBrightness = new ExternalBrightnessV1(m_display, m_display);
|
||||
|
||||
m_alphaModifierManager = new AlphaModifierManagerV1(m_display, m_display);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ class PresentationTime;
|
|||
class XXColorManagerV4;
|
||||
class LinuxDrmSyncObjV1Interface;
|
||||
class RenderBackend;
|
||||
class AlphaModifierManagerV1;
|
||||
|
||||
class KWIN_EXPORT WaylandServer : public QObject
|
||||
{
|
||||
|
@ -291,6 +292,7 @@ private:
|
|||
XXColorManagerV4 *m_xxColorManager = nullptr;
|
||||
XdgDialogWmV1Interface *m_xdgDialogWm = nullptr;
|
||||
ExternalBrightnessV1 *m_externalBrightness = nullptr;
|
||||
AlphaModifierManagerV1 *m_alphaModifierManager = nullptr;
|
||||
KWIN_SINGLETON(WaylandServer)
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue