From 1206dad079473cb2804f16707ffea06d898cfe10 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Wed, 4 Oct 2023 16:51:44 +0200 Subject: [PATCH] move icc profile handling into Output --- src/backends/drm/drm_output.cpp | 10 +++++- src/colors/colordevice.cpp | 32 ------------------- src/colors/colordevice.h | 14 -------- src/core/output.cpp | 12 +++++++ src/core/output.h | 4 +++ src/core/outputconfiguration.h | 3 ++ .../colord-integration/colorddevice.cpp | 9 +++--- 7 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index b32f0d328b..f9afab74ab 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -13,6 +13,8 @@ #include "drm_gpu.h" #include "drm_pipeline.h" +#include "core/colortransformation.h" +#include "core/iccprofile.h" #include "core/outputconfiguration.h" #include "core/renderloop.h" #include "core/renderloop_p.h" @@ -343,7 +345,10 @@ void DrmOutput::applyQueuedChanges(const std::shared_ptr &props next.sdrBrightness = props->sdrBrightness.value_or(m_state.sdrBrightness); next.wideColorGamut = props->wideColorGamut.value_or(m_state.wideColorGamut); next.autoRotatePolicy = props->autoRotationPolicy.value_or(m_state.autoRotatePolicy); - if (m_state.highDynamicRange != next.highDynamicRange || m_state.sdrBrightness != next.sdrBrightness || m_state.wideColorGamut != next.wideColorGamut) { + if (props->iccProfilePath) { + next.iccProfile = IccProfile::load(*props->iccProfilePath); + } + if (m_state.highDynamicRange != next.highDynamicRange || m_state.sdrBrightness != next.sdrBrightness || m_state.wideColorGamut != next.wideColorGamut || m_state.iccProfile != next.iccProfile) { m_renderLoop->scheduleRepaint(); } @@ -380,6 +385,9 @@ bool DrmOutput::setGammaRamp(const std::shared_ptr &transfo if (!m_pipeline->activePending() || needsColormanagement()) { return false; } + if (m_state.iccProfile && m_state.iccProfile->vcgt()) { + transformation->append(m_state.iccProfile->vcgt().get()); + } m_pipeline->setGammaRamp(transformation); m_pipeline->setCTM(QMatrix3x3()); if (DrmPipeline::commitPipelines({m_pipeline}, DrmPipeline::CommitMode::Test) == DrmPipeline::Error::None) { diff --git a/src/colors/colordevice.cpp b/src/colors/colordevice.cpp index f714b1ce2e..77d66c506f 100644 --- a/src/colors/colordevice.cpp +++ b/src/colors/colordevice.cpp @@ -7,7 +7,6 @@ #include "colordevice.h" #include "core/colorpipelinestage.h" #include "core/colortransformation.h" -#include "core/iccprofile.h" #include "core/output.h" #include "utils/common.h" @@ -37,7 +36,6 @@ public: enum DirtyToneCurveBit { DirtyTemperatureToneCurve = 0x1, DirtyBrightnessToneCurve = 0x2, - DirtyCalibrationToneCurve = 0x4, }; Q_DECLARE_FLAGS(DirtyToneCurves, DirtyToneCurveBit) @@ -45,12 +43,10 @@ public: void updateTemperatureToneCurves(); void updateBrightnessToneCurves(); - void updateCalibrationToneCurves(); Output *output; DirtyToneCurves dirtyCurves; QTimer *updateTimer; - QString profilePath; uint brightness = 100; uint temperature = 6500; @@ -58,7 +54,6 @@ public: QVector3D temperatureFactors = QVector3D(1, 1, 1); std::unique_ptr brightnessStage; QVector3D brightnessFactors = QVector3D(1, 1, 1); - std::unique_ptr iccProfile; std::shared_ptr transformation; // used if only limited per-channel multiplication is available @@ -67,9 +62,6 @@ public: void ColorDevicePrivate::rebuildPipeline() { - if (dirtyCurves & DirtyCalibrationToneCurve) { - updateCalibrationToneCurves(); - } if (dirtyCurves & DirtyBrightnessToneCurve) { updateBrightnessToneCurves(); } @@ -95,9 +87,6 @@ void ColorDevicePrivate::rebuildPipeline() } const auto tmp = std::make_shared(std::move(stages)); - if (iccProfile && iccProfile->vcgt()) { - tmp->append(iccProfile->vcgt().get()); - } if (tmp->valid()) { transformation = tmp; simpleTransformation = brightnessFactors * temperatureFactors; @@ -109,11 +98,6 @@ static qreal interpolate(qreal a, qreal b, qreal blendFactor) return (1 - blendFactor) * a + blendFactor * b; } -QString ColorDevice::profile() const -{ - return d->profilePath; -} - void ColorDevicePrivate::updateTemperatureToneCurves() { temperatureStage.reset(); @@ -205,11 +189,6 @@ void ColorDevicePrivate::updateBrightnessToneCurves() } } -void ColorDevicePrivate::updateCalibrationToneCurves() -{ - iccProfile = IccProfile::load(profilePath); -} - ColorDevice::ColorDevice(Output *output, QObject *parent) : QObject(parent) , d(new ColorDevicePrivate) @@ -276,17 +255,6 @@ void ColorDevice::setTemperature(uint temperature) Q_EMIT temperatureChanged(); } -void ColorDevice::setProfile(const QString &profile) -{ - if (d->profilePath == profile) { - return; - } - d->profilePath = profile; - d->dirtyCurves |= ColorDevicePrivate::DirtyCalibrationToneCurve; - scheduleUpdate(); - Q_EMIT profileChanged(); -} - void ColorDevice::update() { d->rebuildPipeline(); diff --git a/src/colors/colordevice.h b/src/colors/colordevice.h index 9e78fa4286..91a6649039 100644 --- a/src/colors/colordevice.h +++ b/src/colors/colordevice.h @@ -53,16 +53,6 @@ public: */ void setTemperature(uint temperature); - /** - * Returns the color profile for this device. - */ - QString profile() const; - - /** - * Sets the color profile for this device to @a profile. - */ - void setProfile(const QString &profile); - public Q_SLOTS: void update(); void scheduleUpdate(); @@ -76,10 +66,6 @@ Q_SIGNALS: * This signal is emitted when the color temperature of this device has changed. */ void temperatureChanged(); - /** - * This signal is emitted when the color profile of this device has changed. - */ - void profileChanged(); private: std::unique_ptr d; diff --git a/src/core/output.cpp b/src/core/output.cpp index 798a05c48e..1b9e2dc82c 100644 --- a/src/core/output.cpp +++ b/src/core/output.cpp @@ -8,6 +8,7 @@ */ #include "output.h" +#include "iccprofile.h" #include "outputconfiguration.h" #include @@ -334,6 +335,9 @@ void Output::applyChanges(const OutputConfiguration &config) next.scale = props->scale.value_or(m_state.scale); next.rgbRange = props->rgbRange.value_or(m_state.rgbRange); next.autoRotatePolicy = props->autoRotationPolicy.value_or(m_state.autoRotatePolicy); + if (props->iccProfilePath) { + next.iccProfile = IccProfile::load(*props->iccProfilePath); + } setState(next); setVrrPolicy(props->vrrPolicy.value_or(vrrPolicy())); @@ -410,6 +414,9 @@ void Output::setState(const State &state) if (oldState.autoRotatePolicy != state.autoRotatePolicy) { Q_EMIT autoRotationPolicyChanged(); } + if (oldState.iccProfile != state.iccProfile) { + Q_EMIT iccProfileChanged(); + } if (oldState.enabled != state.enabled) { Q_EMIT enabledChanged(); } @@ -558,6 +565,11 @@ Output::AutoRotationPolicy Output::autoRotationPolicy() const return m_state.autoRotatePolicy; } +std::shared_ptr Output::iccProfile() const +{ + return m_state.iccProfile; +} + bool Output::updateCursorLayer() { return false; diff --git a/src/core/output.h b/src/core/output.h index e374d0d199..ed95f122cc 100644 --- a/src/core/output.h +++ b/src/core/output.h @@ -29,6 +29,7 @@ class EffectScreenImpl; class RenderLoop; class OutputConfiguration; class ColorTransformation; +class IccProfile; enum class ContentType { None = 0, @@ -313,6 +314,7 @@ public: bool highDynamicRange() const; uint32_t sdrBrightness() const; AutoRotationPolicy autoRotationPolicy() const; + std::shared_ptr iccProfile() const; virtual bool setGammaRamp(const std::shared_ptr &transformation); virtual bool setChannelFactors(const QVector3D &rgb); @@ -376,6 +378,7 @@ Q_SIGNALS: void sdrBrightnessChanged(); void highDynamicRangeChanged(); void autoRotationPolicyChanged(); + void iccProfileChanged(); protected: struct Information @@ -412,6 +415,7 @@ protected: bool highDynamicRange = false; uint32_t sdrBrightness = 200; AutoRotationPolicy autoRotatePolicy = AutoRotationPolicy::InTabletMode; + std::shared_ptr iccProfile; }; void setInformation(const Information &information); diff --git a/src/core/outputconfiguration.h b/src/core/outputconfiguration.h index d4b87a5923..f5e4e6b19e 100644 --- a/src/core/outputconfiguration.h +++ b/src/core/outputconfiguration.h @@ -18,6 +18,8 @@ namespace KWin { +class IccProfile; + class KWIN_EXPORT OutputChangeSet { public: @@ -34,6 +36,7 @@ public: std::optional sdrBrightness; std::optional wideColorGamut; std::optional autoRotationPolicy; + std::optional iccProfilePath; }; class KWIN_EXPORT OutputConfiguration diff --git a/src/plugins/colord-integration/colorddevice.cpp b/src/plugins/colord-integration/colorddevice.cpp index 3dbe5d0e50..477ee82a9b 100644 --- a/src/plugins/colord-integration/colorddevice.cpp +++ b/src/plugins/colord-integration/colorddevice.cpp @@ -10,7 +10,9 @@ #include "colors/colordevice.h" #include "colors/colormanager.h" #include "core/output.h" +#include "core/outputconfiguration.h" #include "main.h" +#include "workspace.h" namespace KWin { @@ -55,10 +57,9 @@ void ColordDevice::updateProfile() return; } - ColorDevice *device = kwinApp()->colorManager()->findDevice(m_output); - if (device) { - device->setProfile(profile.filename()); - } + OutputConfiguration cfg; + cfg.changeSet(m_output)->iccProfilePath = profile.filename(); + workspace()->applyOutputConfiguration(cfg); } } // namespace KWin