KWin
Loading...
Searching...
No Matches
colordevice.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "colordevice.h"
10#include "core/output.h"
11#include "utils/common.h"
12
14
15#include <QTimer>
16
17#include <lcms2.h>
18
19namespace KWin
20{
21
23{
24public:
25 void recalculateFactors();
26
28 QTimer *updateTimer;
29 uint brightness = 100;
30 uint temperature = 6500;
31
32 QVector3D temperatureFactors = QVector3D(1, 1, 1);
33 QVector3D brightnessFactors = QVector3D(1, 1, 1);
34
35 std::shared_ptr<ColorTransformation> transformation;
36 // used if only limited per-channel multiplication is available
37 QVector3D simpleTransformation = QVector3D(1, 1, 1);
38};
39
40static qreal interpolate(qreal a, qreal b, qreal blendFactor)
41{
42 return (1 - blendFactor) * a + blendFactor * b;
43}
44
46{
47 brightnessFactors = QVector3D(brightness / 100.0, brightness / 100.0, brightness / 100.0);
48
49 if (temperature == 6500) {
50 temperatureFactors = QVector3D(1, 1, 1);
51 } else {
52 // Note that cmsWhitePointFromTemp() returns a slightly green-ish white point.
53 const int blackBodyColorIndex = ((temperature - 1000) / 100) * 3;
54 const qreal blendFactor = (temperature % 100) / 100.0;
55
56 const qreal xWhitePoint = interpolate(blackbodyColor[blackBodyColorIndex + 0],
57 blackbodyColor[blackBodyColorIndex + 3],
58 blendFactor);
59 const qreal yWhitePoint = interpolate(blackbodyColor[blackBodyColorIndex + 1],
60 blackbodyColor[blackBodyColorIndex + 4],
61 blendFactor);
62 const qreal zWhitePoint = interpolate(blackbodyColor[blackBodyColorIndex + 2],
63 blackbodyColor[blackBodyColorIndex + 5],
64 blendFactor);
65 // the values in the blackbodyColor array are "gamma corrected", but we need a linear value
66 temperatureFactors = ColorDescription::encodedToNits(QVector3D(xWhitePoint, yWhitePoint, zWhitePoint), NamedTransferFunction::gamma22, 1);
67 }
69}
70
71ColorDevice::ColorDevice(Output *output, QObject *parent)
72 : QObject(parent)
73 , d(new ColorDevicePrivate)
74{
75 d->updateTimer = new QTimer(this);
76 d->updateTimer->setSingleShot(true);
77 connect(d->updateTimer, &QTimer::timeout, this, &ColorDevice::update);
78
79 d->output = output;
81}
82
86
88{
89 return d->output;
90}
91
93{
94 return d->brightness;
95}
96
97void ColorDevice::setBrightness(uint brightness)
98{
99 if (brightness > 100) {
100 qCWarning(KWIN_CORE) << "Got invalid brightness value:" << brightness;
101 brightness = 100;
102 }
103 if (d->brightness == brightness) {
104 return;
105 }
106 d->brightness = brightness;
108 Q_EMIT brightnessChanged();
109}
110
112{
113 return d->temperature;
114}
115
116void ColorDevice::setTemperature(uint temperature)
117{
118 if (temperature > 6500) {
119 qCWarning(KWIN_CORE) << "Got invalid temperature value:" << temperature;
120 temperature = 6500;
121 }
122 if (d->temperature == temperature) {
123 return;
124 }
125 d->temperature = temperature;
127 Q_EMIT temperatureChanged();
128}
129
131{
132 d->recalculateFactors();
133 d->output->setChannelFactors(d->simpleTransformation);
134}
135
137{
138 d->updateTimer->start();
139}
140
141} // namespace KWin
142
143#include "moc_colordevice.cpp"
static QVector3D encodedToNits(const QVector3D &nits, NamedTransferFunction tf, double sdrBrightness)
ColorDevice(Output *output, QObject *parent=nullptr)
~ColorDevice() override
void brightnessChanged()
uint temperature() const
Output * output() const
uint brightness() const
void temperatureChanged()
void setBrightness(uint brightness)
void setTemperature(uint temperature)
std::shared_ptr< ColorTransformation > transformation