File indexing completed on 2024-05-19 16:34:01

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 
0015 #include <QDebug>
0016 #include <QMatrix3x3>
0017 #include <QMatrix4x4>
0018 #include <QObject>
0019 #include <QRect>
0020 #include <QSize>
0021 #include <QUuid>
0022 #include <QVector>
0023 
0024 namespace KWin
0025 {
0026 
0027 class CursorSource;
0028 class EffectScreenImpl;
0029 class RenderLoop;
0030 class OutputConfiguration;
0031 class ColorTransformation;
0032 
0033 enum class ContentType {
0034     None = 0,
0035     Photo = 1,
0036     Video = 2,
0037     Game = 3,
0038 };
0039 
0040 class KWIN_EXPORT OutputMode
0041 {
0042 public:
0043     enum class Flag : uint {
0044         Preferred = 0x1,
0045     };
0046     Q_DECLARE_FLAGS(Flags, Flag)
0047 
0048     OutputMode(const QSize &size, uint32_t refreshRate, Flags flags = {});
0049     virtual ~OutputMode() = default;
0050 
0051     QSize size() const;
0052     uint32_t refreshRate() const;
0053     Flags flags() const;
0054 
0055 private:
0056     const QSize m_size;
0057     const uint32_t m_refreshRate;
0058     const Flags m_flags;
0059 };
0060 
0061 /**
0062  * Generic output representation.
0063  */
0064 class KWIN_EXPORT Output : public QObject
0065 {
0066     Q_OBJECT
0067 
0068 public:
0069     enum class DpmsMode {
0070         On,
0071         Standby,
0072         Suspend,
0073         Off,
0074     };
0075     Q_ENUM(DpmsMode)
0076 
0077     enum class Capability : uint {
0078         Dpms = 0x1,
0079         Overscan = 0x2,
0080         Vrr = 0x4,
0081         RgbRange = 0x8,
0082     };
0083     Q_DECLARE_FLAGS(Capabilities, Capability)
0084 
0085     enum class SubPixel {
0086         Unknown,
0087         None,
0088         Horizontal_RGB,
0089         Horizontal_BGR,
0090         Vertical_RGB,
0091         Vertical_BGR,
0092     };
0093     Q_ENUM(SubPixel)
0094 
0095     enum class RgbRange {
0096         Automatic = 0,
0097         Full = 1,
0098         Limited = 2,
0099     };
0100     Q_ENUM(RgbRange)
0101 
0102     explicit Output(QObject *parent = nullptr);
0103     ~Output() override;
0104 
0105     void ref();
0106     void unref();
0107 
0108     /**
0109      * Maps the specified @a rect from the global coordinate system to the output-local coords.
0110      */
0111     QRect mapFromGlobal(const QRect &rect) const;
0112 
0113     /**
0114      * Maps the specified @a rect from the global coordinate system to the output-local coords.
0115      */
0116     QRectF mapFromGlobal(const QRectF &rect) const;
0117 
0118     /**
0119      * Maps a @a rect in this output coordinates to the global coordinate system.
0120      */
0121     QRectF mapToGlobal(const QRectF &rect) const;
0122 
0123     /**
0124      * Returns a short identifiable name of this output.
0125      */
0126     QString name() const;
0127 
0128     /**
0129      * Returns the identifying uuid of this output.
0130      *
0131      * Default implementation returns an empty byte array.
0132      */
0133     QUuid uuid() const;
0134 
0135     /**
0136      * Returns @c true if the output is enabled; otherwise returns @c false.
0137      */
0138     bool isEnabled() const;
0139 
0140     /**
0141      * Returns geometry of this output in device independent pixels.
0142      */
0143     QRect geometry() const;
0144 
0145     /**
0146      * Returns geometry of this output in device independent pixels, without rounding
0147      */
0148     QRectF fractionalGeometry() const;
0149 
0150     /**
0151      * Equivalent to `QRect(QPoint(0, 0), geometry().size())`
0152      */
0153     QRect rect() const;
0154 
0155     /**
0156      * Returns the approximate vertical refresh rate of this output, in mHz.
0157      */
0158     int refreshRate() const;
0159 
0160     /**
0161      * Returns whether this output is connected through an internal connector,
0162      * e.g. LVDS, or eDP.
0163      */
0164     bool isInternal() const;
0165 
0166     /**
0167      * Returns the ratio between physical pixels and logical pixels.
0168      *
0169      * Default implementation returns 1.
0170      */
0171     qreal scale() const;
0172 
0173     /**
0174      * Returns the non-rotated physical size of this output, in millimeters.
0175      *
0176      * Default implementation returns an invalid QSize.
0177      */
0178     QSize physicalSize() const;
0179 
0180     /** Returns the resolution of the output.  */
0181     QSize pixelSize() const;
0182     QSize modeSize() const;
0183 
0184     QString eisaId() const;
0185 
0186     /**
0187      * Returns the manufacturer of the screen.
0188      */
0189     QString manufacturer() const;
0190     /**
0191      * Returns the model of the screen.
0192      */
0193     QString model() const;
0194     /**
0195      * Returns the serial number of the screen.
0196      */
0197     QString serialNumber() const;
0198 
0199     /**
0200      * Returns the RenderLoop for this output. If the platform does not support per screen
0201      * rendering, all outputs will share the same render loop.
0202      */
0203     virtual RenderLoop *renderLoop() const = 0;
0204 
0205     void inhibitDirectScanout();
0206     void uninhibitDirectScanout();
0207 
0208     bool directScanoutInhibited() const;
0209 
0210     /**
0211      * @returns the configured time for an output to dim
0212      *
0213      * This allows the backends to coordinate with the front-end the time they
0214      * allow to decorate the dimming until the display is turned off
0215      *
0216      * @see aboutToTurnOff
0217      */
0218     static std::chrono::milliseconds dimAnimationTime();
0219 
0220     enum class Transform {
0221         Normal,
0222         Rotated90,
0223         Rotated180,
0224         Rotated270,
0225         Flipped,
0226         Flipped90,
0227         Flipped180,
0228         Flipped270
0229     };
0230     Q_ENUM(Transform)
0231     Transform transform() const;
0232     QSize orientateSize(const QSize &size) const;
0233 
0234     void applyChanges(const OutputConfiguration &config);
0235 
0236     SubPixel subPixel() const;
0237     QString description() const;
0238     Capabilities capabilities() const;
0239     QByteArray edid() const;
0240     QList<std::shared_ptr<OutputMode>> modes() const;
0241     std::shared_ptr<OutputMode> currentMode() const;
0242     DpmsMode dpmsMode() const;
0243     virtual void setDpmsMode(DpmsMode mode);
0244 
0245     uint32_t overscan() const;
0246 
0247     /**
0248      * Returns a matrix that can translate into the display's coordinates system
0249      */
0250     static QMatrix4x4 logicalToNativeMatrix(const QRect &rect, qreal scale, Transform transform);
0251 
0252     void setVrrPolicy(RenderLoop::VrrPolicy policy);
0253     RenderLoop::VrrPolicy vrrPolicy() const;
0254     RgbRange rgbRange() const;
0255 
0256     ContentType contentType() const;
0257     void setContentType(ContentType contentType);
0258 
0259     bool isPlaceholder() const;
0260     bool isNonDesktop() const;
0261     Transform panelOrientation() const;
0262 
0263     virtual bool setGammaRamp(const std::shared_ptr<ColorTransformation> &transformation);
0264     virtual bool setCTM(const QMatrix3x3 &ctm);
0265 
0266     virtual bool setCursor(CursorSource *source);
0267     virtual bool moveCursor(const QPoint &position);
0268 
0269 Q_SIGNALS:
0270     /**
0271      * This signal is emitted when the geometry of this output has changed.
0272      */
0273     void geometryChanged();
0274     /**
0275      * This signal is emitted when the output has been enabled or disabled.
0276      */
0277     void enabledChanged();
0278     /**
0279      * This signal is emitted when the device pixel ratio of the output has changed.
0280      */
0281     void scaleChanged();
0282 
0283     /**
0284      * Notifies that the display will be dimmed in @p time ms. This allows
0285      * effects to plan for it and hopefully animate it
0286      */
0287     void aboutToTurnOff(std::chrono::milliseconds time);
0288 
0289     /**
0290      * Notifies that the output has been turned on and the wake can be decorated.
0291      */
0292     void wakeUp();
0293 
0294     /**
0295      * Notifies that the output is about to change configuration based on a
0296      * user interaction.
0297      *
0298      * Be it because it gets a transformation or moved around.
0299      *
0300      * Only to be used for effects
0301      */
0302     void aboutToChange();
0303 
0304     /**
0305      * Notifies that the output changed based on a user interaction.
0306      *
0307      * Be it because it gets a transformation or moved around.
0308      *
0309      * Only to be used for effects
0310      */
0311     void changed();
0312 
0313     void currentModeChanged();
0314     void modesChanged();
0315     void outputChange(const QRegion &damagedRegion);
0316     void transformChanged();
0317     void dpmsModeChanged();
0318     void capabilitiesChanged();
0319     void overscanChanged();
0320     void vrrPolicyChanged();
0321     void rgbRangeChanged();
0322 
0323 protected:
0324     struct Information
0325     {
0326         QString name;
0327         QString manufacturer;
0328         QString model;
0329         QString serialNumber;
0330         QString eisaId;
0331         QSize physicalSize;
0332         QByteArray edid;
0333         SubPixel subPixel = SubPixel::Unknown;
0334         Capabilities capabilities;
0335         Transform panelOrientation = Transform::Normal;
0336         bool internal = false;
0337         bool placeholder = false;
0338         bool nonDesktop = false;
0339     };
0340 
0341     struct State
0342     {
0343         QPoint position;
0344         qreal scale = 1;
0345         Transform transform = Transform::Normal;
0346         QList<std::shared_ptr<OutputMode>> modes;
0347         std::shared_ptr<OutputMode> currentMode;
0348         DpmsMode dpmsMode = DpmsMode::On;
0349         SubPixel subPixel = SubPixel::Unknown;
0350         bool enabled = false;
0351         uint32_t overscan = 0;
0352         RgbRange rgbRange = RgbRange::Automatic;
0353     };
0354 
0355     void setInformation(const Information &information);
0356     void setState(const State &state);
0357 
0358     EffectScreenImpl *m_effectScreen = nullptr;
0359     State m_state;
0360     Information m_information;
0361     QUuid m_uuid;
0362     int m_directScanoutCount = 0;
0363     int m_refCount = 1;
0364     ContentType m_contentType = ContentType::None;
0365     friend class EffectScreenImpl; // to access m_effectScreen
0366 };
0367 
0368 inline QRect Output::rect() const
0369 {
0370     return QRect(QPoint(0, 0), geometry().size());
0371 }
0372 
0373 KWIN_EXPORT QDebug operator<<(QDebug debug, const Output *output);
0374 
0375 } // namespace KWin
0376 
0377 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::Output::Capabilities)