File indexing completed on 2025-02-09 06:37:18
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #pragma once 0010 0011 #include <kwin_export.h> 0012 0013 #include "renderloop.h" 0014 #include "utils/edid.h" 0015 0016 #include <QDebug> 0017 #include <QList> 0018 #include <QMatrix4x4> 0019 #include <QObject> 0020 #include <QRect> 0021 #include <QSize> 0022 #include <QUuid> 0023 0024 namespace KWin 0025 { 0026 0027 class RenderLoop; 0028 class OutputConfiguration; 0029 class ColorTransformation; 0030 class IccProfile; 0031 class OutputChangeSet; 0032 0033 /** 0034 * The OutputTransform type is used to describe the transform applied to the output content. 0035 */ 0036 class KWIN_EXPORT OutputTransform 0037 { 0038 public: 0039 enum Kind { 0040 Normal = 0, // no rotation 0041 Rotate90 = 1, // rotate 90 degrees counterclockwise 0042 Rotate180 = 2, // rotate 180 degrees counterclockwise 0043 Rotate270 = 3, // rotate 270 degrees counterclockwise 0044 FlipX = 4, // mirror horizontally 0045 FlipX90 = 5, // mirror horizontally, then rotate 90 degrees counterclockwise 0046 FlipX180 = 6, // mirror horizontally, then rotate 180 degrees counterclockwise 0047 FlipX270 = 7, // mirror horizontally, then rotate 270 degrees counterclockwise 0048 FlipY = FlipX180, // mirror vertically 0049 FlipY90 = FlipX270, // mirror vertically, then rotate 90 degrees counterclockwise 0050 FlipY180 = FlipX, // mirror vertically, then rotate 180 degrees counterclockwise 0051 FlipY270 = FlipX90, // mirror vertically, then rotate 270 degrees counterclockwise 0052 }; 0053 0054 OutputTransform() = default; 0055 OutputTransform(Kind kind) 0056 : m_kind(kind) 0057 { 0058 } 0059 0060 bool operator<=>(const OutputTransform &other) const = default; 0061 0062 /** 0063 * Returns the transform kind. 0064 */ 0065 Kind kind() const; 0066 0067 /** 0068 * Returns the inverse transform. The inverse transform can be used for mapping between 0069 * surface and buffer coordinate systems. 0070 */ 0071 OutputTransform inverted() const; 0072 0073 /** 0074 * Applies the output transform to the given @a size. 0075 */ 0076 QSizeF map(const QSizeF &size) const; 0077 QSize map(const QSize &size) const; 0078 0079 /** 0080 * Applies the output transform to the given @a rect within a buffer with dimensions @a bounds. 0081 */ 0082 QRectF map(const QRectF &rect, const QSizeF &bounds) const; 0083 QRect map(const QRect &rect, const QSize &bounds) const; 0084 0085 /** 0086 * Applies the output transform to the given @a point. 0087 */ 0088 QPointF map(const QPointF &point, const QSizeF &bounds) const; 0089 QPoint map(const QPoint &point, const QSize &bounds) const; 0090 0091 /** 0092 * Returns an output transform that is equivalent to applying this transform and @a other 0093 * transform sequentially. 0094 */ 0095 OutputTransform combine(OutputTransform other) const; 0096 0097 /** 0098 * Returns the matrix corresponding to this output transform. 0099 */ 0100 QMatrix4x4 toMatrix() const; 0101 0102 private: 0103 Kind m_kind = Kind::Normal; 0104 }; 0105 0106 class KWIN_EXPORT OutputMode 0107 { 0108 public: 0109 enum class Flag : uint { 0110 Preferred = 0x1, 0111 Generated = 0x2, 0112 }; 0113 Q_DECLARE_FLAGS(Flags, Flag) 0114 0115 OutputMode(const QSize &size, uint32_t refreshRate, Flags flags = {}); 0116 virtual ~OutputMode() = default; 0117 0118 QSize size() const; 0119 uint32_t refreshRate() const; 0120 Flags flags() const; 0121 0122 private: 0123 const QSize m_size; 0124 const uint32_t m_refreshRate; 0125 const Flags m_flags; 0126 }; 0127 0128 /** 0129 * Generic output representation. 0130 */ 0131 class KWIN_EXPORT Output : public QObject 0132 { 0133 Q_OBJECT 0134 Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged) 0135 Q_PROPERTY(qreal devicePixelRatio READ scale NOTIFY scaleChanged) 0136 Q_PROPERTY(QString name READ name CONSTANT) 0137 Q_PROPERTY(QString manufacturer READ manufacturer CONSTANT) 0138 Q_PROPERTY(QString model READ model CONSTANT) 0139 Q_PROPERTY(QString serialNumber READ serialNumber CONSTANT) 0140 0141 public: 0142 enum class DpmsMode { 0143 On, 0144 Standby, 0145 Suspend, 0146 Off, 0147 }; 0148 Q_ENUM(DpmsMode) 0149 0150 enum class Capability : uint { 0151 Dpms = 1, 0152 Overscan = 1 << 1, 0153 Vrr = 1 << 2, 0154 RgbRange = 1 << 3, 0155 HighDynamicRange = 1 << 4, 0156 WideColorGamut = 1 << 5, 0157 AutoRotation = 1 << 6, 0158 IccProfile = 1 << 7, 0159 Tearing = 1 << 8, 0160 }; 0161 Q_DECLARE_FLAGS(Capabilities, Capability) 0162 0163 enum class SubPixel { 0164 Unknown, 0165 None, 0166 Horizontal_RGB, 0167 Horizontal_BGR, 0168 Vertical_RGB, 0169 Vertical_BGR, 0170 }; 0171 Q_ENUM(SubPixel) 0172 0173 enum class RgbRange { 0174 Automatic = 0, 0175 Full = 1, 0176 Limited = 2, 0177 }; 0178 Q_ENUM(RgbRange) 0179 0180 enum class AutoRotationPolicy { 0181 Never = 0, 0182 InTabletMode, 0183 Always 0184 }; 0185 Q_ENUM(AutoRotationPolicy); 0186 0187 explicit Output(QObject *parent = nullptr); 0188 ~Output() override; 0189 0190 void ref(); 0191 void unref(); 0192 0193 /** 0194 * Maps the specified @a rect from the global coordinate system to the output-local coords. 0195 */ 0196 QRect mapFromGlobal(const QRect &rect) const; 0197 0198 /** 0199 * Maps the specified @a rect from the global coordinate system to the output-local coords. 0200 */ 0201 QRectF mapFromGlobal(const QRectF &rect) const; 0202 0203 /** 0204 * Maps a @a rect in this output coordinates to the global coordinate system. 0205 */ 0206 QRectF mapToGlobal(const QRectF &rect) const; 0207 0208 Q_INVOKABLE QPointF mapToGlobal(const QPointF &pos) const; 0209 Q_INVOKABLE QPointF mapFromGlobal(const QPointF &pos) const; 0210 0211 /** 0212 * Returns a short identifiable name of this output. 0213 */ 0214 QString name() const; 0215 0216 /** 0217 * Returns the identifying uuid of this output. 0218 */ 0219 QUuid uuid() const; 0220 0221 /** 0222 * Returns @c true if the output is enabled; otherwise returns @c false. 0223 */ 0224 bool isEnabled() const; 0225 0226 /** 0227 * Returns geometry of this output in device independent pixels. 0228 */ 0229 QRect geometry() const; 0230 0231 /** 0232 * Returns geometry of this output in device independent pixels, without rounding 0233 */ 0234 QRectF geometryF() const; 0235 0236 /** 0237 * Equivalent to `QRect(QPoint(0, 0), geometry().size())` 0238 */ 0239 QRect rect() const; 0240 0241 /** 0242 * Equivalent to `QRectF(QPointF(0, 0), geometryF().size())` 0243 */ 0244 QRectF rectF() const; 0245 0246 /** 0247 * Returns the approximate vertical refresh rate of this output, in mHz. 0248 */ 0249 uint32_t refreshRate() const; 0250 0251 /** 0252 * Returns whether this output is connected through an internal connector, 0253 * e.g. LVDS, or eDP. 0254 */ 0255 bool isInternal() const; 0256 0257 /** 0258 * Returns the ratio between physical pixels and logical pixels. 0259 */ 0260 qreal scale() const; 0261 0262 /** 0263 * Returns the non-rotated physical size of this output, in millimeters. 0264 */ 0265 QSize physicalSize() const; 0266 0267 /** Returns the resolution of the output. */ 0268 QSize pixelSize() const; 0269 QSize modeSize() const; 0270 0271 QString eisaId() const; 0272 0273 /** 0274 * Returns the manufacturer of the screen. 0275 */ 0276 QString manufacturer() const; 0277 /** 0278 * Returns the model of the screen. 0279 */ 0280 QString model() const; 0281 /** 0282 * Returns the serial number of the screen. 0283 */ 0284 QString serialNumber() const; 0285 0286 /** 0287 * Returns the RenderLoop for this output. If the platform does not support per screen 0288 * rendering, all outputs will share the same render loop. 0289 * FIXME: remove this and decouple RenderLoop from Output 0290 */ 0291 virtual RenderLoop *renderLoop() const = 0; 0292 0293 void inhibitDirectScanout(); 0294 void uninhibitDirectScanout(); 0295 0296 bool directScanoutInhibited() const; 0297 0298 /** 0299 * @returns the configured time for an output to dim 0300 * 0301 * This allows the backends to coordinate with the front-end the time they 0302 * allow to decorate the dimming until the display is turned off 0303 * 0304 * @see aboutToTurnOff 0305 */ 0306 static std::chrono::milliseconds dimAnimationTime(); 0307 0308 OutputTransform transform() const; 0309 /** 0310 * The transform that the user has configured, and which doesn't get changed 0311 * by automatic rotation 0312 */ 0313 OutputTransform manualTransform() const; 0314 QSize orientateSize(const QSize &size) const; 0315 0316 void applyChanges(const OutputConfiguration &config); 0317 0318 SubPixel subPixel() const; 0319 QString description() const; 0320 Capabilities capabilities() const; 0321 const Edid &edid() const; 0322 QList<std::shared_ptr<OutputMode>> modes() const; 0323 std::shared_ptr<OutputMode> currentMode() const; 0324 DpmsMode dpmsMode() const; 0325 virtual void setDpmsMode(DpmsMode mode); 0326 0327 uint32_t overscan() const; 0328 0329 VrrPolicy vrrPolicy() const; 0330 RgbRange rgbRange() const; 0331 0332 bool isPlaceholder() const; 0333 bool isNonDesktop() const; 0334 OutputTransform panelOrientation() const; 0335 bool wideColorGamut() const; 0336 bool highDynamicRange() const; 0337 uint32_t sdrBrightness() const; 0338 AutoRotationPolicy autoRotationPolicy() const; 0339 std::shared_ptr<IccProfile> iccProfile() const; 0340 QString iccProfilePath() const; 0341 /** 0342 * @returns the mst path of this output. Is empty if invalid 0343 */ 0344 QByteArray mstPath() const; 0345 0346 virtual bool setGammaRamp(const std::shared_ptr<ColorTransformation> &transformation); 0347 virtual bool setChannelFactors(const QVector3D &rgb); 0348 0349 virtual bool updateCursorLayer(); 0350 0351 std::optional<double> maxPeakBrightness() const; 0352 std::optional<double> maxAverageBrightness() const; 0353 double minBrightness() const; 0354 std::optional<double> maxPeakBrightnessOverride() const; 0355 std::optional<double> maxAverageBrightnessOverride() const; 0356 std::optional<double> minBrightnessOverride() const; 0357 0358 double sdrGamutWideness() const; 0359 0360 const ColorDescription &colorDescription() const; 0361 0362 Q_SIGNALS: 0363 /** 0364 * This signal is emitted when the geometry of this output has changed. 0365 */ 0366 void geometryChanged(); 0367 /** 0368 * This signal is emitted when the output has been enabled or disabled. 0369 */ 0370 void enabledChanged(); 0371 /** 0372 * This signal is emitted when the device pixel ratio of the output has changed. 0373 */ 0374 void scaleChanged(); 0375 0376 /** 0377 * Notifies that the display will be dimmed in @p time ms. This allows 0378 * effects to plan for it and hopefully animate it 0379 */ 0380 void aboutToTurnOff(std::chrono::milliseconds time); 0381 0382 /** 0383 * Notifies that the output has been turned on and the wake can be decorated. 0384 */ 0385 void wakeUp(); 0386 0387 /** 0388 * Notifies that the output is about to change configuration based on a 0389 * user interaction. 0390 * 0391 * Be it because it gets a transformation or moved around. 0392 * 0393 * Only to be used for effects 0394 */ 0395 void aboutToChange(OutputChangeSet *changeSet); 0396 0397 /** 0398 * Notifies that the output changed based on a user interaction. 0399 * 0400 * Be it because it gets a transformation or moved around. 0401 * 0402 * Only to be used for effects 0403 */ 0404 void changed(); 0405 0406 void currentModeChanged(); 0407 void modesChanged(); 0408 void outputChange(const QRegion &damagedRegion); 0409 void transformChanged(); 0410 void dpmsModeChanged(); 0411 void capabilitiesChanged(); 0412 void overscanChanged(); 0413 void vrrPolicyChanged(); 0414 void rgbRangeChanged(); 0415 void wideColorGamutChanged(); 0416 void sdrBrightnessChanged(); 0417 void highDynamicRangeChanged(); 0418 void autoRotationPolicyChanged(); 0419 void iccProfileChanged(); 0420 void iccProfilePathChanged(); 0421 void brightnessMetadataChanged(); 0422 void sdrGamutWidenessChanged(); 0423 void colorDescriptionChanged(); 0424 0425 protected: 0426 struct Information 0427 { 0428 QString name; 0429 QString manufacturer; 0430 QString model; 0431 QString serialNumber; 0432 QString eisaId; 0433 QSize physicalSize; 0434 Edid edid; 0435 SubPixel subPixel = SubPixel::Unknown; 0436 Capabilities capabilities; 0437 OutputTransform panelOrientation = OutputTransform::Normal; 0438 bool internal = false; 0439 bool placeholder = false; 0440 bool nonDesktop = false; 0441 QByteArray mstPath; 0442 std::optional<double> maxPeakBrightness; 0443 std::optional<double> maxAverageBrightness; 0444 double minBrightness = 0; 0445 }; 0446 0447 struct State 0448 { 0449 QPoint position; 0450 qreal scale = 1; 0451 OutputTransform transform = OutputTransform::Normal; 0452 OutputTransform manualTransform = OutputTransform::Normal; 0453 QList<std::shared_ptr<OutputMode>> modes; 0454 std::shared_ptr<OutputMode> currentMode; 0455 DpmsMode dpmsMode = DpmsMode::On; 0456 SubPixel subPixel = SubPixel::Unknown; 0457 bool enabled = false; 0458 uint32_t overscan = 0; 0459 RgbRange rgbRange = RgbRange::Automatic; 0460 bool wideColorGamut = false; 0461 bool highDynamicRange = false; 0462 uint32_t sdrBrightness = 200; 0463 AutoRotationPolicy autoRotatePolicy = AutoRotationPolicy::InTabletMode; 0464 QString iccProfilePath; 0465 std::shared_ptr<IccProfile> iccProfile; 0466 ColorDescription colorDescription = ColorDescription::sRGB; 0467 std::optional<double> maxPeakBrightnessOverride; 0468 std::optional<double> maxAverageBrightnessOverride; 0469 std::optional<double> minBrightnessOverride; 0470 double sdrGamutWideness = 0; 0471 VrrPolicy vrrPolicy = VrrPolicy::Automatic; 0472 }; 0473 0474 void setInformation(const Information &information); 0475 void setState(const State &state); 0476 0477 State m_state; 0478 Information m_information; 0479 QUuid m_uuid; 0480 int m_directScanoutCount = 0; 0481 int m_refCount = 1; 0482 }; 0483 0484 inline QRect Output::rect() const 0485 { 0486 return QRect(QPoint(0, 0), geometry().size()); 0487 } 0488 0489 inline QRectF Output::rectF() const 0490 { 0491 return QRectF(QPointF(0, 0), geometryF().size()); 0492 } 0493 0494 KWIN_EXPORT QDebug operator<<(QDebug debug, const Output *output); 0495 0496 } // namespace KWin 0497 0498 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::Output::Capabilities)