implement the frog color management protocol

master
Xaver Hugl 11 months ago
parent 15d6d8c336
commit 9d4fe3adf1

@ -354,6 +354,7 @@ void DrmOutput::applyQueuedChanges(const std::shared_ptr<OutputChangeSet> &props
if (m_state.highDynamicRange != next.highDynamicRange || m_state.sdrBrightness != next.sdrBrightness || m_state.wideColorGamut != next.wideColorGamut || m_state.iccProfile != next.iccProfile) {
m_renderLoop->scheduleRepaint();
}
next.colorDescription = m_pipeline->colorDescription();
setState(next);
setVrrPolicy(props->vrrPolicy.value_or(vrrPolicy()));

@ -599,6 +599,11 @@ bool Output::updateCursorLayer()
return false;
}
const ColorDescription &Output::colorDescription() const
{
return m_state.colorDescription;
}
} // namespace KWin
#include "moc_output.cpp"

@ -335,6 +335,8 @@ public:
virtual bool updateCursorLayer();
const ColorDescription &colorDescription() const;
Q_SIGNALS:
/**
* This signal is emitted when the geometry of this output has changed.
@ -433,6 +435,7 @@ protected:
AutoRotationPolicy autoRotatePolicy = AutoRotationPolicy::InTabletMode;
QString iccProfilePath;
std::shared_ptr<IccProfile> iccProfile;
ColorDescription colorDescription = ColorDescription::sRGB;
};
void setInformation(const Information &information);

@ -41,6 +41,7 @@ void DragAndDropIconItem::setOutput(Output *output)
{
if (m_surfaceItem && output) {
m_surfaceItem->surface()->setPreferredBufferScale(output->scale());
m_surfaceItem->surface()->setPreferredColorDescription(output->colorDescription());
}
}

@ -216,6 +216,10 @@ ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
PROTOCOL protocols/qt-toplevel-drag-v1.xml
BASENAME qt-toplevel-drag-v1
)
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
PROTOCOL ${PROJECT_SOURCE_DIR}/src/wayland/protocols/frog-color-management-v1.xml
BASENAME frog-color-management-v1
)
target_sources(kwin PRIVATE
abstract_data_source.cpp
@ -239,8 +243,9 @@ target_sources(kwin PRIVATE
dpms.cpp
drmclientbuffer.cpp
drmlease_v1.cpp
fractionalscale_v1.cpp
filtered_display.cpp
fractionalscale_v1.cpp
frog_colormanagement_v1.cpp
idle.cpp
idleinhibit_v1.cpp
idlenotify_v1.cpp
@ -314,6 +319,7 @@ install(FILES
dpms.h
drmlease_v1.h
fractionalscale_v1.h
frog_colormanagement_v1.h
idle.h
idleinhibit_v1.h
idlenotify_v1.h

@ -0,0 +1,158 @@
/*
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "frog_colormanagement_v1.h"
#include "display.h"
#include "surface.h"
#include "surface_p.h"
namespace KWin
{
static constexpr uint32_t s_version = 1;
FrogColorManagementV1::FrogColorManagementV1(Display *display, QObject *parent)
: QObject(parent)
, QtWaylandServer::frog_color_management_factory_v1(*display, s_version)
{
}
FrogColorManagementV1::~FrogColorManagementV1()
{
}
void FrogColorManagementV1::frog_color_management_factory_v1_get_color_managed_surface(Resource *resource, wl_resource *surface, uint32_t callback)
{
SurfaceInterface *surf = SurfaceInterface::get(surface);
SurfaceInterfacePrivate::get(surf)->frogColorManagement = new FrogColorManagementSurfaceV1(surf, resource->client(), callback);
}
void FrogColorManagementV1::frog_color_management_factory_v1_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
FrogColorManagementSurfaceV1::FrogColorManagementSurfaceV1(SurfaceInterface *surface, wl_client *client, uint32_t id)
: QtWaylandServer::frog_color_managed_surface(client, id, s_version)
, m_surface(surface)
{
}
FrogColorManagementSurfaceV1::~FrogColorManagementSurfaceV1()
{
if (m_surface) {
const auto priv = SurfaceInterfacePrivate::get(m_surface);
priv->pending->colorDescription = ColorDescription::sRGB;
priv->pending->colorDescriptionIsSet = true;
priv->frogColorManagement = nullptr;
}
}
static QtWaylandServer::frog_color_managed_surface::transfer_function kwinToFrogTransferFunction(NamedTransferFunction tf)
{
switch (tf) {
case NamedTransferFunction::sRGB:
return QtWaylandServer::frog_color_managed_surface::transfer_function_srgb;
case NamedTransferFunction::PerceptualQuantizer:
return QtWaylandServer::frog_color_managed_surface::transfer_function_st2084_pq;
case NamedTransferFunction::scRGB:
return QtWaylandServer::frog_color_managed_surface::transfer_function_scrgb_linear;
case NamedTransferFunction::linear:
return QtWaylandServer::frog_color_managed_surface::transfer_function_scrgb_linear;
}
return QtWaylandServer::frog_color_managed_surface::transfer_function_undefined;
}
uint16_t encodePrimary(float primary)
{
return uint16_t(std::clamp<float>(std::round(primary / 0.00002), 0, 0xC350));
}
void FrogColorManagementSurfaceV1::setPreferredColorDescription(const ColorDescription &colorDescription)
{
const auto &color = colorDescription.colorimetry();
send_preferred_metadata(kwinToFrogTransferFunction(colorDescription.transferFunction()),
encodePrimary(color.red.x()), encodePrimary(color.red.y()),
encodePrimary(color.green.x()), encodePrimary(color.green.y()),
encodePrimary(color.blue.x()), encodePrimary(color.blue.y()),
encodePrimary(color.white.x()), encodePrimary(color.white.y()),
std::round(colorDescription.maxHdrHighlightBrightness()),
std::round(colorDescription.minHdrBrightness() / 0.0001),
std::round(colorDescription.maxFrameAverageBrightness()));
}
void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_known_transfer_function(Resource *resource, uint32_t transfer_function)
{
switch (transfer_function) {
case transfer_function_undefined:
case transfer_function_srgb:
case transfer_function_gamma_22:
m_transferFunction = NamedTransferFunction::sRGB;
break;
case transfer_function_st2084_pq:
m_transferFunction = NamedTransferFunction::PerceptualQuantizer;
break;
case transfer_function_scrgb_linear:
m_transferFunction = NamedTransferFunction::scRGB;
break;
}
updateColorDescription();
}
void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_known_container_color_volume(Resource *resource, uint32_t primaries)
{
switch (primaries) {
case primaries_undefined:
case primaries_rec709:
m_colorimetry = NamedColorimetry::BT709;
break;
case primaries_rec2020:
m_colorimetry = NamedColorimetry::BT2020;
break;
}
updateColorDescription();
}
void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_render_intent(Resource *resource, uint32_t render_intent)
{
// there's only perceptual right now, so this can be ignored
}
void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_hdr_metadata(Resource *resource,
uint32_t mastering_display_primary_red_x, uint32_t mastering_display_primary_red_y,
uint32_t mastering_display_primary_green_x, uint32_t mastering_display_primary_green_y,
uint32_t mastering_display_primary_blue_x, uint32_t mastering_display_primary_blue_y,
uint32_t mastering_white_point_x, uint32_t mastering_white_point_y,
uint32_t max_display_mastering_luminance, uint32_t min_display_mastering_luminance,
uint32_t max_cll, uint32_t max_fall)
{
m_maxPeakBrightness = max_cll;
m_maxFrameAverageBrightness = max_fall;
updateColorDescription();
}
void FrogColorManagementSurfaceV1::frog_color_managed_surface_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void FrogColorManagementSurfaceV1::frog_color_managed_surface_destroy_resource(Resource *resource)
{
delete this;
}
void FrogColorManagementSurfaceV1::updateColorDescription()
{
if (m_surface) {
// TODO make brightness values optional in ColorDescription
SurfaceInterfacePrivate *priv = SurfaceInterfacePrivate::get(m_surface);
priv->pending->colorDescription = ColorDescription(m_colorimetry, m_transferFunction, 0, 0, m_maxFrameAverageBrightness, m_maxPeakBrightness);
priv->pending->colorDescriptionIsSet = true;
}
}
}
#include "moc_frog_colormanagement_v1.cpp"

@ -0,0 +1,62 @@
/*
SPDX-FileCopyrightText: 2023 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 "libkwineffects/colorspace.h"
#include "qwayland-server-frog-color-management-v1.h"
#include <QObject>
#include <QPointer>
namespace KWin
{
class Display;
class SurfaceInterface;
class FrogColorManagementV1 : public QObject, private QtWaylandServer::frog_color_management_factory_v1
{
Q_OBJECT
public:
explicit FrogColorManagementV1(Display *display, QObject *parent);
~FrogColorManagementV1() override;
private:
void frog_color_management_factory_v1_get_color_managed_surface(Resource *resource, wl_resource *surface, uint32_t callback) override;
void frog_color_management_factory_v1_destroy(Resource *resource) override;
};
class FrogColorManagementSurfaceV1 : public QObject, private QtWaylandServer::frog_color_managed_surface
{
Q_OBJECT
public:
explicit FrogColorManagementSurfaceV1(SurfaceInterface *surface, wl_client *client, uint32_t id);
~FrogColorManagementSurfaceV1() override;
void setPreferredColorDescription(const ColorDescription &colorDescription);
private:
void frog_color_managed_surface_set_known_transfer_function(Resource *resource, uint32_t transfer_function) override;
void frog_color_managed_surface_set_known_container_color_volume(Resource *resource, uint32_t primaries) override;
void frog_color_managed_surface_set_render_intent(Resource *resource, uint32_t render_intent) override;
void frog_color_managed_surface_set_hdr_metadata(Resource *resource, uint32_t mastering_display_primary_red_x, uint32_t mastering_display_primary_red_y,
uint32_t mastering_display_primary_green_x, uint32_t mastering_display_primary_green_y,
uint32_t mastering_display_primary_blue_x, uint32_t mastering_display_primary_blue_y,
uint32_t mastering_white_point_x, uint32_t mastering_white_point_y,
uint32_t max_display_mastering_luminance, uint32_t min_display_mastering_luminance,
uint32_t max_cll, uint32_t max_fall) override;
void frog_color_managed_surface_destroy(Resource *resource) override;
void frog_color_managed_surface_destroy_resource(Resource *resource) override;
void updateColorDescription();
const QPointer<SurfaceInterface> m_surface;
NamedTransferFunction m_transferFunction = NamedTransferFunction::sRGB;
NamedColorimetry m_colorimetry = NamedColorimetry::BT709;
float m_maxFrameAverageBrightness = 0;
float m_maxPeakBrightness = 0;
};
}

@ -0,0 +1,356 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="frog_color_management_v1">
<copyright>
Copyright © 2023 Joshua Ashton for Valve Software
Copyright © 2023 Xaver Hugl
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="experimental color management protocol">
The aim of this color management extension is to get HDR games working quickly,
and have an easy way to test implementations in the wild before the upstream
protocol is ready to be merged.
For that purpose it's intentionally limited and cut down and does not serve
all uses cases.
</description>
<interface name="frog_color_management_factory_v1" version="1">
<description summary="color management factory">
The color management factory singleton creates color managed surface objects.
</description>
<request name="destroy" type="destructor"></request>
<request name="get_color_managed_surface">
<description summary="create color management interface for surface">
</description>
<arg name="surface" type="object" interface="wl_surface"
summary="target surface"/>
<arg name="callback" type="new_id" interface="frog_color_managed_surface"
summary="new color managed surface object"/>
</request>
</interface>
<interface name="frog_color_managed_surface" version="1">
<description summary="color managed surface">
Interface for changing surface color management and HDR state.
An implementation must: support every part of the version
of the frog_color_managed_surface interface it exposes.
Including all known enums associated with a given version.
</description>
<request name="destroy" type="destructor">
<description summary="destroy color managed surface">
Destroying the color managed surface resets all known color
state for the surface back to 'undefined' implementation-specific
values.
</description>
</request>
<enum name="transfer_function">
<description summary="known transfer functions">
Extended information on the transfer functions described
here can be found in the Khronos Data Format specification:
https://registry.khronos.org/DataFormat/specs/1.3/dataformat.1.3.html
</description>
<entry name="undefined" value="0" summary="specifies undefined, implementation-specific handling of the surface's transfer function."/>
<entry name="srgb" value="1" summary="specifies the sRGB non-linear EOTF. An implementation may: display this as Gamma 2.2 for the purposes of being consistent with content rendering across displays, rendering_intent and user expectations."/>
<entry name="gamma_22" value="2" summary="specifies gamma 2.2 power curve as the EOTF"/>
<entry name="st2084_pq" value="3" summary="specifies the SMPTE ST2084 Perceptual Quantizer (PQ) EOTF"/>
<entry name="scrgb_linear" value="4" summary="specifies the scRGB (extended sRGB) linear EOTF. Note: Primaries outside the gamut triangle specified can be expressed with negative values for this transfer function."/>
</enum>
<request name="set_known_transfer_function">
<description summary="sets a known transfer function for a surface"/>
<arg name="transfer_function" type="uint" enum="transfer_function" summary="transfer function for the surface"/>
</request>
<enum name="primaries">
<description summary="known primaries"/>
<entry name="undefined" value="0" summary="specifies undefined, implementation-specific handling"/>
<entry name="rec709" value="1" summary="specifies Rec.709/sRGB primaries with D65 white point"/>
<entry name="rec2020" value="2" summary="specifies Rec.2020/HDR10 primaries with D65 white point"/>
</enum>
<request name="set_known_container_color_volume">
<description summary="sets the container color volume (primaries) for a surface"/>
<arg name="primaries" type="uint" enum="primaries" summary="primaries for the surface"/>
</request>
<enum name="render_intent">
<description summary="known render intents">
Extended information on render intents described
here can be found in ICC.1:2022:
https://www.color.org/specification/ICC.1-2022-05.pdf
</description>
<entry name="perceptual" value="0" summary="perceptual"/>
</enum>
<request name="set_render_intent">
<description summary="sets the render intent for a surface">
NOTE: On a surface with "perceptual" (default) render intent, handling of the container's color volume
is implementation-specific, and may differ between different transfer functions it is paired with:
ie. sRGB + 709 rendering may have it's primaries widened to more of the available display's gamut
to be be more pleasing for the viewer.
Compared to scRGB Linear + 709 being treated faithfully as 709
(including utilizing negatives out of the 709 gamut triangle)
</description>
<arg name="render_intent" type="uint" enum="render_intent" summary="render intent for the surface"/>
</request>
<request name="set_hdr_metadata">
<description summary="set HDR metadata for a surface">
Forwards HDR metadata from the client to the compositor.
HDR Metadata Infoframe as per CTA 861.G spec.
Usage of this HDR metadata is implementation specific and
outside of the scope of this protocol.
</description>
<arg name="mastering_display_primary_red_x" type="uint">
<description summary="red primary x coordinate">
Mastering Red Color Primary X Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_display_primary_red_y" type="uint">
<description summary="red primary y coordinate">
Mastering Red Color Primary Y Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_display_primary_green_x" type="uint">
<description summary="green primary x coordinate">
Mastering Green Color Primary X Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_display_primary_green_y" type="uint">
<description summary="green primary y coordinate">
Mastering Green Color Primary Y Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_display_primary_blue_x" type="uint">
<description summary="blue primary x coordinate">
Mastering Blue Color Primary X Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_display_primary_blue_y" type="uint">
<description summary="blue primary y coordinate">
Mastering Blue Color Primary Y Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_white_point_x" type="uint">
<description summary="white point x coordinate">
Mastering White Point X Coordinate of the Data.
These are coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="mastering_white_point_y" type="uint">
<description summary="white point y coordinate">
Mastering White Point Y Coordinate of the Data.
These are coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="max_display_mastering_luminance" type="uint">
<description summary="max display mastering luminance">
Max Mastering Display Luminance.
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
</description>
</arg>
<arg name="min_display_mastering_luminance" type="uint">
<description summary="min display mastering luminance">
Min Mastering Display Luminance.
This value is coded as an unsigned 16-bit value in units of
0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
represents 6.5535 cd/m2.
</description>
</arg>
<arg name="max_cll" type="uint">
<description summary="max content light level">
Max Content Light Level.
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
</description>
</arg>
<arg name="max_fall" type="uint">
<description summary="max frame average light level">
Max Frame Average Light Level.
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
</description>
</arg>
</request>
<event name="preferred_metadata">
<description summary="preferred metadata for a surface">
Current preferred metadata for a surface.
The application should use this information to tone-map its buffers
to this target before committing.
This metadata does not necessarily correspond to any physical output, but
rather what the compositor thinks would be best for a given surface.
</description>
<arg name="transfer_function" type="uint" enum="transfer_function">
<description summary="output's current transfer function">
Specifies a known transfer function that corresponds to the
output the surface is targeting.
</description>
</arg>
<arg name="output_display_primary_red_x" type="uint">
<description summary="red primary x coordinate">
Output Red Color Primary X Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_display_primary_red_y" type="uint">
<description summary="red primary y coordinate">
Output Red Color Primary Y Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_display_primary_green_x" type="uint">
<description summary="green primary x coordinate">
Output Green Color Primary X Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_display_primary_green_y" type="uint">
<description summary="green primary y coordinate">
Output Green Color Primary Y Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_display_primary_blue_x" type="uint">
<description summary="blue primary x coordinate">
Output Blue Color Primary X Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_display_primary_blue_y" type="uint">
<description summary="blue primary y coordinate">
Output Blue Color Primary Y Coordinate of the Data.
Coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_white_point_x" type="uint">
<description summary="white point x coordinate">
Output White Point X Coordinate of the Data.
These are coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="output_white_point_y" type="uint">
<description summary="white point y coordinate">
Output White Point Y Coordinate of the Data.
These are coded as unsigned 16-bit values in units of
0.00002, where 0x0000 represents zero and 0xC350
represents 1.0000.
</description>
</arg>
<arg name="max_luminance" type="uint">
<description summary="maximum luminance">
Max Output Luminance
The max luminance in nits that the output is capable of rendering in small areas.
Content should: not exceed this value to avoid clipping.
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
</description>
</arg>
<arg name="min_luminance" type="uint">
<description summary="minimum luminance">
Min Output Luminance
The min luminance that the output is capable of rendering.
Content should: not exceed this value to avoid clipping.
This value is coded as an unsigned 16-bit value in units of
0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
represents 6.5535 cd/m2.
</description>
</arg>
<arg name="max_full_frame_luminance" type="uint">
<description summary="maximum full frame luminance">
Max Full Frame Luminance
The max luminance in nits that the output is capable of rendering for the
full frame sustained.
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
</description>
</arg>
</event>
</interface>
</protocol>

@ -11,6 +11,7 @@
#include "contrast.h"
#include "display.h"
#include "fractionalscale_v1_p.h"
#include "frog_colormanagement_v1.h"
#include "idleinhibit_v1_p.h"
#include "linuxdmabufv1clientbuffer.h"
#include "output.h"
@ -82,6 +83,9 @@ void SurfaceInterfacePrivate::addChild(SubSurfaceInterface *child)
if (preferredBufferTransform.has_value()) {
child->surface()->setPreferredBufferTransform(preferredBufferTransform.value());
}
if (preferredColorDescription) {
child->surface()->setPreferredColorDescription(preferredColorDescription.value());
}
Q_EMIT q->childSubSurfaceAdded(child);
Q_EMIT q->childSubSurfacesChanged();
@ -1152,6 +1156,20 @@ const ColorDescription &SurfaceInterface::colorDescription() const
return d->current->colorDescription;
}
void SurfaceInterface::setPreferredColorDescription(const ColorDescription &descr)
{
d->preferredColorDescription = descr;
if (d->frogColorManagement) {
d->frogColorManagement->setPreferredColorDescription(descr);
}
for (auto child : std::as_const(d->current->subsurface.below)) {
child->surface()->setPreferredColorDescription(descr);
}
for (auto child : std::as_const(d->current->subsurface.above)) {
child->surface()->setPreferredColorDescription(descr);
}
}
void SurfaceInterface::setPreferredBufferScale(qreal scale)
{
if (scale == d->preferredBufferScale) {

@ -374,6 +374,8 @@ public:
const ColorDescription &colorDescription() const;
void setPreferredColorDescription(const ColorDescription &descr);
Q_SIGNALS:
/**
* This signal is emitted when the underlying wl_surface resource is about to be freed.

@ -25,6 +25,7 @@ class ViewportInterface;
class ContentTypeV1Interface;
class TearingControlV1Interface;
class FractionalScaleV1Interface;
class FrogColorManagementSurfaceV1;
struct SurfaceState
{
@ -149,6 +150,7 @@ public:
OutputInterface *primaryOutput = nullptr;
std::optional<qreal> preferredBufferScale;
std::optional<OutputTransform> preferredBufferTransform;
std::optional<ColorDescription> preferredColorDescription;
LockedPointerV1Interface *lockedPointer = nullptr;
ConfinedPointerV1Interface *confinedPointer = nullptr;
@ -162,6 +164,7 @@ public:
FractionalScaleV1Interface *fractionalScaleExtension = nullptr;
ClientConnection *client = nullptr;
TearingControlV1Interface *tearing = nullptr;
FrogColorManagementSurfaceV1 *frogColorManagement = nullptr;
struct
{

@ -32,6 +32,7 @@
#include "wayland/drmlease_v1.h"
#include "wayland/filtered_display.h"
#include "wayland/fractionalscale_v1.h"
#include "wayland/frog_colormanagement_v1.h"
#include "wayland/idle.h"
#include "wayland/idleinhibit_v1.h"
#include "wayland/idlenotify_v1.h"
@ -521,6 +522,7 @@ bool WaylandServer::init(InitializationFlags flags)
}
});
new FrogColorManagementV1(m_display, m_display);
return true;
}

@ -161,6 +161,7 @@ void WaylandWindow::updateClientOutputs()
if (output()) {
surface()->setPreferredBufferScale(output()->scale());
surface()->setPreferredBufferTransform(output()->transform());
surface()->setPreferredColorDescription(output()->colorDescription());
}
}

Loading…
Cancel
Save