move icc profile handling into Output

This commit is contained in:
Xaver Hugl 2023-10-04 16:51:44 +02:00
parent 44ae4ba004
commit 1206dad079
7 changed files with 33 additions and 51 deletions

View file

@ -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<OutputChangeSet> &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<ColorTransformation> &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) {

View file

@ -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<ColorPipelineStage> brightnessStage;
QVector3D brightnessFactors = QVector3D(1, 1, 1);
std::unique_ptr<IccProfile> iccProfile;
std::shared_ptr<ColorTransformation> 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<ColorTransformation>(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();

View file

@ -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<ColorDevicePrivate> d;

View file

@ -8,6 +8,7 @@
*/
#include "output.h"
#include "iccprofile.h"
#include "outputconfiguration.h"
#include <KConfigGroup>
@ -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<IccProfile> Output::iccProfile() const
{
return m_state.iccProfile;
}
bool Output::updateCursorLayer()
{
return false;

View file

@ -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> iccProfile() const;
virtual bool setGammaRamp(const std::shared_ptr<ColorTransformation> &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> iccProfile;
};
void setInformation(const Information &information);

View file

@ -18,6 +18,8 @@
namespace KWin
{
class IccProfile;
class KWIN_EXPORT OutputChangeSet
{
public:
@ -34,6 +36,7 @@ public:
std::optional<uint32_t> sdrBrightness;
std::optional<bool> wideColorGamut;
std::optional<Output::AutoRotationPolicy> autoRotationPolicy;
std::optional<QString> iccProfilePath;
};
class KWIN_EXPORT OutputConfiguration

View file

@ -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