client: implement support for the color management protocol
This uses an "experimental" tag of the proposed protocol, which has been implemented by several compositors. Once the protocol gets merged upstream, this should be updated to use the final version from that as well. Change-Id: I8653489fea44f404b759b046cd3fa910dc92479b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
8a6d564a64
commit
412b1ecd5c
11
src/3rdparty/wayland/protocols/color-management/REUSE.toml
vendored
Normal file
11
src/3rdparty/wayland/protocols/color-management/REUSE.toml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
version = 1
|
||||
|
||||
[[annotations]]
|
||||
path = "xx-color-management-v4.xml"
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = ["Copyright 2019 Sebastian Wick",
|
||||
"Copyright 2019 Erwin Burema",
|
||||
"Copyright 2020 AMD",
|
||||
"Copyright 2020-2024 Collabora, Ltd.",
|
||||
"Copyright 2024 Xaver Hugl"]
|
||||
SPDX-License-Identifier = "MIT"
|
18
src/3rdparty/wayland/protocols/color-management/qt_attribution.json
vendored
Normal file
18
src/3rdparty/wayland/protocols/color-management/qt_attribution.json
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"Id": "wayland-color-management-protocol",
|
||||
"Name": "Wayland Color Management Protocol",
|
||||
"QDocModule": "qtwaylandcompositor",
|
||||
"QtUsage": "Used in the Qt Wayland platform plugin.",
|
||||
"Files": "xx-color-management-v4.xml",
|
||||
|
||||
"Description": "An extension to use different colorspaces from sRGB",
|
||||
"Homepage": "https://wayland.freedesktop.org",
|
||||
"Version": "experimental v4",
|
||||
"DownloadLocation": "https://gitlab.freedesktop.org/swick/wayland-protocols/-/blob/708a8b4119d4072820158a115166598733d378f4/staging/color-management/xx-color-management-v4.xml",
|
||||
"LicenseId": "MIT",
|
||||
"License": "MIT License",
|
||||
"LicenseFile": "../MIT_LICENSE.txt",
|
||||
"Copyright": "Copyright 2019 Sebastian Wick\nCopyright 2019 Erwin Burema\nCopyright 2020 AMD\nCopyright 2020-2024 Collabora, Ltd.\nCopyright 2024 Xaver Hugl"
|
||||
}
|
||||
]
|
1453
src/3rdparty/wayland/protocols/color-management/xx-color-management-v4.xml
vendored
Normal file
1453
src/3rdparty/wayland/protocols/color-management/xx-color-management-v4.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ qt_internal_add_module(WaylandClient
|
||||
qwaylandabstractdecoration.cpp qwaylandabstractdecoration_p.h
|
||||
qwaylandappmenu.cpp qwaylandappmenu_p.h
|
||||
qwaylandbuffer.cpp qwaylandbuffer_p.h
|
||||
qwaylandcolormanagement.cpp qwaylandcolormanagement_p.h
|
||||
qwaylanddatacontrolv1.cpp qwaylanddatacontrolv1_p.h
|
||||
qwaylanddecorationfactory.cpp qwaylanddecorationfactory_p.h
|
||||
qwaylanddecorationplugin.cpp qwaylanddecorationplugin_p.h
|
||||
@ -121,6 +122,7 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../extensions/touch-extension.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardwareintegration/../../extensions/hardware-integration.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardwareintegration/../../extensions/server-buffer-extension.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/protocol/color-management/xx-color-management-v4.xml
|
||||
)
|
||||
|
||||
#### Keys ignored in scope 1:.:.:client.pro:<TRUE>:
|
||||
|
252
src/plugins/platforms/wayland/qwaylandcolormanagement.cpp
Normal file
252
src/plugins/platforms/wayland/qwaylandcolormanagement.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#include "qwaylandcolormanagement_p.h"
|
||||
#include "qwaylanddisplay_p.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
ColorManager::ColorManager(struct ::wl_registry *registry, uint32_t id, int version)
|
||||
: QtWayland::xx_color_manager_v4(registry, id, version)
|
||||
{
|
||||
}
|
||||
|
||||
ColorManager::~ColorManager()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void ColorManager::xx_color_manager_v4_supported_feature(uint32_t feature)
|
||||
{
|
||||
switch (feature) {
|
||||
case feature_icc_v2_v4:
|
||||
mFeatures |= Feature::ICC;
|
||||
break;
|
||||
case feature_parametric:
|
||||
mFeatures |= Feature::Parametric;
|
||||
break;
|
||||
case feature_set_primaries:
|
||||
mFeatures |= Feature::SetPrimaries;
|
||||
break;
|
||||
case feature_set_tf_power:
|
||||
mFeatures |= Feature::PowerTransferFunction;
|
||||
break;
|
||||
case feature_set_luminances:
|
||||
mFeatures |= Feature::SetLuminances;
|
||||
break;
|
||||
case feature_set_mastering_display_primaries:
|
||||
mFeatures |= Feature::SetMasteringDisplayPrimaries;
|
||||
break;
|
||||
case feature_extended_target_volume:
|
||||
mFeatures |= Feature::ExtendedTargetVolume;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ColorManager::xx_color_manager_v4_supported_primaries_named(uint32_t primaries)
|
||||
{
|
||||
mPrimaries.push_back(QtWayland::xx_color_manager_v4::primaries(primaries));
|
||||
}
|
||||
|
||||
void ColorManager::xx_color_manager_v4_supported_tf_named(uint32_t transferFunction)
|
||||
{
|
||||
mTransferFunctions.push_back(QtWayland::xx_color_manager_v4::transfer_function(transferFunction));
|
||||
}
|
||||
|
||||
ColorManager::Features ColorManager::supportedFeatures() const
|
||||
{
|
||||
return mFeatures;
|
||||
}
|
||||
|
||||
bool ColorManager::supportsNamedPrimary(QtWayland::xx_color_manager_v4::primaries primaries) const
|
||||
{
|
||||
return mPrimaries.contains(primaries);
|
||||
}
|
||||
|
||||
bool ColorManager::supportsTransferFunction(QtWayland::xx_color_manager_v4::transfer_function transferFunction) const
|
||||
{
|
||||
return mTransferFunctions.contains(transferFunction);
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageDescription> ColorManager::createImageDescription(const QColorSpace &colorspace)
|
||||
{
|
||||
if (!(mFeatures & Feature::Parametric))
|
||||
return nullptr;
|
||||
|
||||
constexpr std::array primaryMapping = {
|
||||
std::make_pair(QColorSpace::Primaries::SRgb, primaries_srgb),
|
||||
std::make_pair(QColorSpace::Primaries::AdobeRgb, primaries_adobe_rgb),
|
||||
std::make_pair(QColorSpace::Primaries::DciP3D65, primaries_display_p3),
|
||||
std::make_pair(QColorSpace::Primaries::Bt2020, primaries_bt2020),
|
||||
};
|
||||
const auto primary = std::find_if(primaryMapping.begin(), primaryMapping.end(), [&colorspace](const auto &pair) {
|
||||
return pair.first == colorspace.primaries();
|
||||
});
|
||||
if (!(supportedFeatures() & Feature::SetPrimaries) && (primary != primaryMapping.end() || !supportsNamedPrimary(primary->second)))
|
||||
return nullptr;
|
||||
|
||||
constexpr std::array tfMapping = {
|
||||
std::make_pair(QColorSpace::TransferFunction::Linear, transfer_function_linear),
|
||||
std::make_pair(QColorSpace::TransferFunction::SRgb, transfer_function_srgb),
|
||||
std::make_pair(QColorSpace::TransferFunction::St2084, transfer_function_st2084_pq),
|
||||
std::make_pair(QColorSpace::TransferFunction::Hlg, transfer_function_hlg),
|
||||
};
|
||||
const auto tfIt = std::find_if(tfMapping.begin(), tfMapping.end(), [&colorspace](const auto &pair) {
|
||||
return pair.first == colorspace.transferFunction();
|
||||
});
|
||||
auto transferFunction = tfIt == tfMapping.end() ? std::nullopt : std::make_optional(tfIt->second);
|
||||
if (colorspace.transferFunction() == QColorSpace::TransferFunction::Gamma) {
|
||||
if (qFuzzyCompare(colorspace.gamma(), 2.2f) && supportsTransferFunction(transfer_function_gamma22))
|
||||
transferFunction = transfer_function_gamma22;
|
||||
else if (qFuzzyCompare(colorspace.gamma(), 2.8f) && supportsTransferFunction(transfer_function_gamma28))
|
||||
transferFunction = transfer_function_gamma28;
|
||||
if (!transferFunction && !(mFeatures & Feature::PowerTransferFunction))
|
||||
return nullptr;
|
||||
} else if (!transferFunction) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto creator = new_parametric_creator();
|
||||
if (primary != primaryMapping.end()) {
|
||||
xx_image_description_creator_params_v4_set_primaries_named(creator, primary->second);
|
||||
} else {
|
||||
const auto primaries = colorspace.primaryPoints();
|
||||
xx_image_description_creator_params_v4_set_primaries(creator,
|
||||
std::round(10'000 * primaries.redPoint.x()), std::round(10'000 * primaries.redPoint.y()),
|
||||
std::round(10'000 * primaries.greenPoint.x()), std::round(10'000 * primaries.greenPoint.y()),
|
||||
std::round(10'000 * primaries.bluePoint.x()), std::round(10'000 * primaries.bluePoint.y()),
|
||||
std::round(10'000 * primaries.whitePoint.x()), std::round(10'000 * primaries.whitePoint.y())
|
||||
);
|
||||
}
|
||||
if (transferFunction) {
|
||||
xx_image_description_creator_params_v4_set_tf_named(creator, *transferFunction);
|
||||
} else {
|
||||
Q_ASSERT(colorspace.transferFunction() == QColorSpace::TransferFunction::Gamma);
|
||||
xx_image_description_creator_params_v4_set_tf_power(creator, std::round(colorspace.gamma() * 10'000));
|
||||
}
|
||||
return std::make_unique<ImageDescription>(xx_image_description_creator_params_v4_create(creator));
|
||||
}
|
||||
|
||||
ImageDescriptionInfo::ImageDescriptionInfo(ImageDescription *descr)
|
||||
: QtWayland::xx_image_description_info_v4(descr->get_information())
|
||||
{
|
||||
}
|
||||
|
||||
ImageDescriptionInfo::~ImageDescriptionInfo()
|
||||
{
|
||||
xx_image_description_info_v4_destroy(object());
|
||||
}
|
||||
|
||||
void ImageDescriptionInfo::xx_image_description_info_v4_done()
|
||||
{
|
||||
Q_EMIT done();
|
||||
}
|
||||
|
||||
void ImageDescriptionInfo::xx_image_description_info_v4_primaries(int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y)
|
||||
{
|
||||
mContainerRed = QPointF(r_x, r_y) / 10'000.0;
|
||||
mContainerGreen = QPointF(g_x, g_y) / 10'000.0;
|
||||
mContainerBlue = QPointF(b_x, b_y) / 10'000.0;
|
||||
mContainerWhite = QPointF(w_x, w_y) / 10'000.0;
|
||||
}
|
||||
|
||||
void ImageDescriptionInfo::xx_image_description_info_v4_tf_named(uint32_t transferFunction)
|
||||
{
|
||||
mTransferFunction = transferFunction;
|
||||
}
|
||||
|
||||
void ImageDescriptionInfo::xx_image_description_info_v4_luminances(uint32_t min_lum, uint32_t max_lum, uint32_t reference_lum)
|
||||
{
|
||||
mMinLuminance = min_lum / 10'000.0;
|
||||
mMaxLuminance = max_lum;
|
||||
mReferenceLuminance = reference_lum;
|
||||
}
|
||||
|
||||
void ImageDescriptionInfo::xx_image_description_info_v4_target_primaries(int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y)
|
||||
{
|
||||
mTargetRed = QPointF(r_x, r_y) / 10'000.0;
|
||||
mTargetGreen = QPointF(g_x, g_y) / 10'000.0;
|
||||
mTargetBlue = QPointF(b_x, b_y) / 10'000.0;
|
||||
mTargetWhite = QPointF(w_x, w_y) / 10'000.0;
|
||||
}
|
||||
|
||||
void ImageDescriptionInfo::xx_image_description_info_v4_target_luminance(uint32_t min_lum, uint32_t max_lum)
|
||||
{
|
||||
mTargetMinLuminance = min_lum / 10'000.0;
|
||||
mTargetMaxLuminance = max_lum;
|
||||
}
|
||||
|
||||
ImageDescription::ImageDescription(::xx_image_description_v4 *descr)
|
||||
: QtWayland::xx_image_description_v4(descr)
|
||||
{
|
||||
}
|
||||
|
||||
ImageDescription::~ImageDescription()
|
||||
{
|
||||
xx_image_description_v4_destroy(object());
|
||||
}
|
||||
|
||||
void ImageDescription::xx_image_description_v4_failed(uint32_t cause, const QString &msg)
|
||||
{
|
||||
Q_UNUSED(cause);
|
||||
qCWarning(lcQpaWayland) << "image description failed!" << msg;
|
||||
// TODO handle this, somehow
|
||||
// maybe fall back to the previous or preferred image description
|
||||
}
|
||||
|
||||
void ImageDescription::xx_image_description_v4_ready(uint32_t identity)
|
||||
{
|
||||
Q_UNUSED(identity);
|
||||
Q_EMIT ready();
|
||||
}
|
||||
|
||||
ColorManagementFeedback::ColorManagementFeedback(::xx_color_management_feedback_surface_v4 *obj)
|
||||
: QtWayland::xx_color_management_feedback_surface_v4(obj)
|
||||
, mPreferred(std::make_unique<ImageDescription>(get_preferred()))
|
||||
{
|
||||
}
|
||||
|
||||
ColorManagementFeedback::~ColorManagementFeedback()
|
||||
{
|
||||
xx_color_management_feedback_surface_v4_destroy(object());
|
||||
}
|
||||
|
||||
void ColorManagementFeedback::xx_color_management_feedback_surface_v4_preferred_changed()
|
||||
{
|
||||
mPreferred = std::make_unique<ImageDescription>(get_preferred());
|
||||
mPendingPreferredInfo = std::make_unique<ImageDescriptionInfo>(mPreferred.get());
|
||||
connect(mPendingPreferredInfo.get(), &ImageDescriptionInfo::done, this, &ColorManagementFeedback::preferredChanged);
|
||||
}
|
||||
|
||||
void ColorManagementFeedback::handlePreferredDone()
|
||||
{
|
||||
mPreferredInfo = std::move(mPendingPreferredInfo);
|
||||
}
|
||||
|
||||
ColorManagementSurface::ColorManagementSurface(::xx_color_management_surface_v4 *obj)
|
||||
: QtWayland::xx_color_management_surface_v4(obj)
|
||||
{
|
||||
}
|
||||
|
||||
ColorManagementSurface::~ColorManagementSurface()
|
||||
{
|
||||
xx_color_management_surface_v4_destroy(object());
|
||||
}
|
||||
|
||||
void ColorManagementSurface::setImageDescription(ImageDescription *descr)
|
||||
{
|
||||
if (descr)
|
||||
xx_color_management_surface_v4_set_image_description(object(), descr->object(), QtWayland::xx_color_manager_v4::render_intent::render_intent_perceptual);
|
||||
else
|
||||
xx_color_management_surface_v4_unset_image_description(object());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qwaylandcolormanagement_p.cpp"
|
147
src/plugins/platforms/wayland/qwaylandcolormanagement_p.h
Normal file
147
src/plugins/platforms/wayland/qwaylandcolormanagement_p.h
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QWAYLANDCOLORMANAGEMENT_H
|
||||
#define QWAYLANDCOLORMANAGEMENT_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointF>
|
||||
#include <QColorSpace>
|
||||
#include <QList>
|
||||
|
||||
#include "qwayland-xx-color-management-v4.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
class ImageDescription;
|
||||
|
||||
class ColorManager : public QObject, public QtWayland::xx_color_manager_v4
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class Feature {
|
||||
ICC = 1 << 0,
|
||||
Parametric = 1 << 1,
|
||||
SetPrimaries = 1 << 2,
|
||||
PowerTransferFunction = 1 << 3,
|
||||
SetLuminances = 1 << 4,
|
||||
SetMasteringDisplayPrimaries = 1 << 5,
|
||||
ExtendedTargetVolume = 1 << 6,
|
||||
};
|
||||
Q_ENUM(Feature);
|
||||
Q_DECLARE_FLAGS(Features, Feature);
|
||||
|
||||
explicit ColorManager(struct ::wl_registry *registry, uint32_t id, int version);
|
||||
~ColorManager() override;
|
||||
|
||||
Features supportedFeatures() const;
|
||||
bool supportsNamedPrimary(QtWayland::xx_color_manager_v4::primaries primaries) const;
|
||||
bool supportsTransferFunction(QtWayland::xx_color_manager_v4::transfer_function transferFunction) const;
|
||||
|
||||
std::unique_ptr<ImageDescription> createImageDescription(const QColorSpace &colorspace);
|
||||
|
||||
private:
|
||||
void xx_color_manager_v4_supported_feature(uint32_t feature) override;
|
||||
void xx_color_manager_v4_supported_primaries_named(uint32_t primaries) override;
|
||||
void xx_color_manager_v4_supported_tf_named(uint32_t transferFunction) override;
|
||||
|
||||
Features mFeatures;
|
||||
QList<QtWayland::xx_color_manager_v4::primaries> mPrimaries;
|
||||
QList<QtWayland::xx_color_manager_v4::transfer_function> mTransferFunctions;
|
||||
};
|
||||
|
||||
class ImageDescriptionInfo : public QObject, public QtWayland::xx_image_description_info_v4
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImageDescriptionInfo(ImageDescription *descr);
|
||||
~ImageDescriptionInfo();
|
||||
|
||||
Q_SIGNAL void done();
|
||||
|
||||
uint32_t mTransferFunction = 0;
|
||||
QPointF mContainerRed;
|
||||
QPointF mContainerGreen;
|
||||
QPointF mContainerBlue;
|
||||
QPointF mContainerWhite;
|
||||
QPointF mTargetRed;
|
||||
QPointF mTargetGreen;
|
||||
QPointF mTargetBlue;
|
||||
QPointF mTargetWhite;
|
||||
double mMinLuminance;
|
||||
double mMaxLuminance;
|
||||
double mReferenceLuminance;
|
||||
double mTargetMinLuminance;
|
||||
double mTargetMaxLuminance;
|
||||
|
||||
private:
|
||||
void xx_image_description_info_v4_done() override;
|
||||
void xx_image_description_info_v4_primaries(int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y) override;
|
||||
void xx_image_description_info_v4_tf_named(uint32_t transferFunction) override;
|
||||
void xx_image_description_info_v4_luminances(uint32_t min_lum, uint32_t max_lum, uint32_t reference_lum) override;
|
||||
void xx_image_description_info_v4_target_primaries(int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y) override;
|
||||
void xx_image_description_info_v4_target_luminance(uint32_t min_lum, uint32_t max_lum) override;
|
||||
};
|
||||
|
||||
class ImageDescription : public QObject, public QtWayland::xx_image_description_v4
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImageDescription(::xx_image_description_v4 *descr);
|
||||
~ImageDescription();
|
||||
|
||||
Q_SIGNAL void ready();
|
||||
|
||||
private:
|
||||
void xx_image_description_v4_failed(uint32_t cause, const QString &msg) override;
|
||||
void xx_image_description_v4_ready(uint32_t identity) override;
|
||||
};
|
||||
|
||||
class ColorManagementFeedback : public QObject, public QtWayland::xx_color_management_feedback_surface_v4
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ColorManagementFeedback(::xx_color_management_feedback_surface_v4 *obj);
|
||||
~ColorManagementFeedback();
|
||||
|
||||
Q_SIGNAL void preferredChanged();
|
||||
|
||||
std::unique_ptr<ImageDescriptionInfo> mPreferredInfo;
|
||||
|
||||
private:
|
||||
void xx_color_management_feedback_surface_v4_preferred_changed() override;
|
||||
void handlePreferredDone();
|
||||
|
||||
std::unique_ptr<ImageDescription> mPreferred;
|
||||
std::unique_ptr<ImageDescriptionInfo> mPendingPreferredInfo;
|
||||
|
||||
};
|
||||
|
||||
class ColorManagementSurface : public QObject, public QtWayland::xx_color_management_surface_v4
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ColorManagementSurface(::xx_color_management_surface_v4 *obj);
|
||||
~ColorManagementSurface();
|
||||
|
||||
void setImageDescription(ImageDescription *descr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -45,6 +45,8 @@
|
||||
#endif
|
||||
#include "qwaylandqtkey_p.h"
|
||||
|
||||
#include "qwaylandcolormanagement_p.h"
|
||||
|
||||
#include <QtWaylandClient/private/qwayland-text-input-unstable-v1.h>
|
||||
#include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h>
|
||||
#include <QtWaylandClient/private/qwayland-text-input-unstable-v3.h>
|
||||
@ -813,6 +815,10 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||
inputDevice->setDataControlDevice(mGlobals.dataControlManager->createDevice(inputDevice));
|
||||
}
|
||||
#endif
|
||||
} else if (interface == QLatin1String(QtWayland::xx_color_manager_v4::interface()->name)) {
|
||||
mGlobals.colorManager = std::make_unique<ColorManager>(registry, id, 1);
|
||||
// we need a roundtrip to receive the features the compositor supports
|
||||
forceRoundTrip();
|
||||
}
|
||||
|
||||
mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry));
|
||||
|
@ -92,6 +92,7 @@ class QWaylandShellIntegration;
|
||||
class QWaylandCursor;
|
||||
class QWaylandCursorTheme;
|
||||
class EventThread;
|
||||
class ColorManager;
|
||||
|
||||
typedef void (*RegistryListener)(void *data,
|
||||
struct wl_registry *registry,
|
||||
@ -226,6 +227,10 @@ public:
|
||||
{
|
||||
return mGlobals.appMenuManager.get();
|
||||
}
|
||||
ColorManager *colorManager() const
|
||||
{
|
||||
return mGlobals.colorManager.get();
|
||||
}
|
||||
|
||||
struct RegistryGlobal {
|
||||
uint32_t id;
|
||||
@ -363,6 +368,7 @@ private:
|
||||
std::unique_ptr<QtWayland::xdg_toplevel_drag_manager_v1> xdgToplevelDragManager;
|
||||
std::unique_ptr<QWaylandWindowManagerIntegration> windowManagerIntegration;
|
||||
std::unique_ptr<QWaylandAppMenuManager> appMenuManager;
|
||||
std::unique_ptr<ColorManager> colorManager;
|
||||
} mGlobals;
|
||||
|
||||
int mFd = -1;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qwaylandshmbackingstore_p.h"
|
||||
#include "qwaylandshellintegration_p.h"
|
||||
#include "qwaylandviewport_p.h"
|
||||
#include "qwaylandcolormanagement_p.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QPointer>
|
||||
@ -213,6 +214,11 @@ void QWaylandWindow::initWindow()
|
||||
mSurface->commit();
|
||||
}
|
||||
|
||||
void QWaylandWindow::setPendingImageDescription()
|
||||
{
|
||||
mColorManagementSurface->setImageDescription(mPendingImageDescription.get());
|
||||
}
|
||||
|
||||
void QWaylandWindow::initializeWlSurface()
|
||||
{
|
||||
Q_ASSERT(!mSurface);
|
||||
@ -240,6 +246,27 @@ void QWaylandWindow::initializeWlSurface()
|
||||
if (display()->viewporter() && display()->fractionalScaleManager()) {
|
||||
mViewport.reset(new QWaylandViewport(display()->createViewport(this)));
|
||||
}
|
||||
|
||||
QColorSpace requestedColorSpace = window()->requestedFormat().colorSpace();
|
||||
if (requestedColorSpace != QColorSpace{} && mDisplay->colorManager()) {
|
||||
// TODO try a similar (same primaries + supported transfer function) color space if this fails?
|
||||
mPendingImageDescription = mDisplay->colorManager()->createImageDescription(requestedColorSpace);
|
||||
if (mPendingImageDescription) {
|
||||
if (!mColorManagementSurface)
|
||||
mColorManagementSurface = std::make_unique<ColorManagementSurface>(mDisplay->colorManager()->get_surface(surface()));
|
||||
connect(mPendingImageDescription.get(), &ImageDescription::ready, this, &QWaylandWindow::setPendingImageDescription, Qt::SingleShotConnection);
|
||||
mSurfaceFormat.setColorSpace(requestedColorSpace);
|
||||
} else {
|
||||
qCWarning(lcQpaWayland) << "couldn't create image description for requested color space" << requestedColorSpace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandWindow::setFormat(const QSurfaceFormat &format)
|
||||
{
|
||||
const auto colorSpace = mSurfaceFormat.colorSpace();
|
||||
mSurfaceFormat = format;
|
||||
mSurfaceFormat.setColorSpace(colorSpace);
|
||||
}
|
||||
|
||||
void QWaylandWindow::setShellIntegration(QWaylandShellIntegration *shellIntegration)
|
||||
@ -297,6 +324,8 @@ void QWaylandWindow::reset()
|
||||
mSurface.reset();
|
||||
mViewport.reset();
|
||||
mFractionalScale.reset();
|
||||
mColorManagementSurface.reset();
|
||||
mPendingImageDescription.reset();
|
||||
}
|
||||
emit wlSurfaceDestroyed();
|
||||
}
|
||||
@ -1851,6 +1880,11 @@ bool QWaylandWindow::windowEvent(QEvent *event)
|
||||
return QPlatformWindow::windowEvent(event);
|
||||
}
|
||||
|
||||
QSurfaceFormat QWaylandWindow::format() const
|
||||
{
|
||||
return mSurfaceFormat;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -60,6 +60,8 @@ class QWaylandPointerGesturePinchEvent;
|
||||
class QWaylandSurface;
|
||||
class QWaylandFractionalScale;
|
||||
class QWaylandViewport;
|
||||
class ColorManagementSurface;
|
||||
class ImageDescription;
|
||||
|
||||
class Q_WAYLANDCLIENT_EXPORT QWaylandWindow : public QNativeInterface::Private::QWaylandWindow,
|
||||
public QPlatformWindow
|
||||
@ -246,6 +248,8 @@ public:
|
||||
|
||||
bool windowEvent(QEvent *event) override;
|
||||
|
||||
QSurfaceFormat format() const override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void applyConfigure();
|
||||
|
||||
@ -256,6 +260,7 @@ Q_SIGNALS:
|
||||
protected:
|
||||
virtual void doHandleFrameCallback();
|
||||
virtual QRect defaultGeometry() const;
|
||||
void setFormat(const QSurfaceFormat &format);
|
||||
|
||||
// this should be called directly for buffer size changes only
|
||||
// use updateExposure for anything affecting the on/off state
|
||||
@ -345,6 +350,9 @@ protected:
|
||||
|
||||
Qt::ScreenOrientation mLastReportedContentOrientation = Qt::PrimaryOrientation;
|
||||
|
||||
std::unique_ptr<ColorManagementSurface> mColorManagementSurface;
|
||||
QSurfaceFormat mSurfaceFormat;
|
||||
|
||||
private:
|
||||
void setGeometry_helper(const QRect &rect);
|
||||
void initWindow();
|
||||
@ -357,6 +365,7 @@ private:
|
||||
void updateInputRegion();
|
||||
void updateViewport();
|
||||
bool calculateExposure() const;
|
||||
void setPendingImageDescription();
|
||||
|
||||
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||
void handleScreensChanged();
|
||||
@ -370,6 +379,7 @@ private:
|
||||
bool mInResizeFromApplyConfigure = false;
|
||||
bool lastVisible = false;
|
||||
QRect mLastExposeGeometry;
|
||||
std::unique_ptr<ImageDescription> mPendingImageDescription;
|
||||
|
||||
static const wl_callback_listener callbackListener;
|
||||
void handleFrameCallback(struct ::wl_callback* callback);
|
||||
|
Loading…
x
Reference in New Issue
Block a user