File indexing completed on 2025-04-20 10:57:35

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2020 Xaver Hugl <xaver.hugl@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include "drm_pipeline.h"
0012 #include "utils/filedescriptor.h"
0013 
0014 #include <QPointer>
0015 #include <QSize>
0016 #include <QSocketNotifier>
0017 #include <QVector>
0018 #include <qobject.h>
0019 
0020 #include <epoxy/egl.h>
0021 #include <sys/types.h>
0022 
0023 struct gbm_device;
0024 
0025 namespace KWin
0026 {
0027 
0028 class DrmOutput;
0029 class DrmObject;
0030 class DrmCrtc;
0031 class DrmConnector;
0032 class DrmPlane;
0033 class DrmBackend;
0034 class EglGbmBackend;
0035 class DrmAbstractOutput;
0036 class DrmRenderBackend;
0037 class DrmVirtualOutput;
0038 
0039 class DrmLease : public QObject
0040 {
0041     Q_OBJECT
0042 public:
0043     DrmLease(DrmGpu *gpu, FileDescriptor &&fd, uint32_t lesseeId, const QVector<DrmOutput *> &outputs);
0044     ~DrmLease();
0045 
0046     FileDescriptor &fd();
0047     uint32_t lesseeId() const;
0048 
0049 Q_SIGNALS:
0050     void revokeRequested();
0051 
0052 private:
0053     DrmGpu *const m_gpu;
0054     FileDescriptor m_fd;
0055     const uint32_t m_lesseeId;
0056     const QVector<DrmOutput *> m_outputs;
0057 };
0058 
0059 class DrmGpu : public QObject
0060 {
0061     Q_OBJECT
0062 public:
0063     DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t deviceId);
0064     ~DrmGpu();
0065 
0066     int fd() const;
0067     dev_t deviceId() const;
0068     QString devNode() const;
0069 
0070     bool isRemoved() const;
0071     void setRemoved();
0072 
0073     bool atomicModeSetting() const;
0074     bool addFB2ModifiersSupported() const;
0075     bool asyncPageflipSupported() const;
0076     bool isNVidia() const;
0077     gbm_device *gbmDevice() const;
0078     EGLDisplay eglDisplay() const;
0079     DrmBackend *platform() const;
0080     /**
0081      * Returns the clock from which presentation timestamps are sourced. The returned value
0082      * can be either CLOCK_MONOTONIC or CLOCK_REALTIME.
0083      */
0084     clockid_t presentationClock() const;
0085     QSize cursorSize() const;
0086 
0087     QVector<DrmVirtualOutput *> virtualOutputs() const;
0088     QVector<DrmOutput *> drmOutputs() const;
0089     const QVector<DrmPipeline *> pipelines() const;
0090 
0091     void setEglDisplay(EGLDisplay display);
0092 
0093     bool updateOutputs();
0094     void removeOutputs();
0095 
0096     DrmVirtualOutput *createVirtualOutput(const QString &name, const QSize &size, double scale);
0097     void removeVirtualOutput(DrmVirtualOutput *output);
0098 
0099     DrmPipeline::Error testPendingConfiguration();
0100     bool needsModeset() const;
0101     bool maybeModeset();
0102 
0103     void releaseBuffers();
0104     void recreateSurfaces();
0105 
0106     FileDescriptor createNonMasterFd() const;
0107     std::unique_ptr<DrmLease> leaseOutputs(const QVector<DrmOutput *> &outputs);
0108 
0109 Q_SIGNALS:
0110     void outputAdded(DrmAbstractOutput *output);
0111     void outputRemoved(DrmAbstractOutput *output);
0112 
0113 private:
0114     void dispatchEvents();
0115     DrmOutput *findOutput(quint32 connector);
0116     void removeOutput(DrmOutput *output);
0117     void initDrmResources();
0118     void waitIdle();
0119 
0120     DrmPipeline::Error checkCrtcAssignment(QVector<DrmConnector *> connectors, const QVector<DrmCrtc *> &crtcs);
0121     DrmPipeline::Error testPipelines();
0122     QVector<DrmObject *> unusedObjects() const;
0123 
0124     static void pageFlipHandler(int fd, unsigned int sequence, unsigned int sec, unsigned int usec, unsigned int crtc_id, void *user_data);
0125 
0126     const int m_fd;
0127     const dev_t m_deviceId;
0128     const QString m_devNode;
0129     bool m_atomicModeSetting;
0130     bool m_addFB2ModifiersSupported = false;
0131     bool m_isNVidia;
0132     bool m_isVirtualMachine;
0133     bool m_asyncPageflipSupported = false;
0134     bool m_isRemoved = false;
0135     clockid_t m_presentationClock;
0136     gbm_device *m_gbmDevice;
0137     EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
0138     DrmBackend *const m_platform;
0139 
0140     std::vector<std::unique_ptr<DrmPlane>> m_planes;
0141     std::vector<std::unique_ptr<DrmCrtc>> m_crtcs;
0142     std::vector<std::shared_ptr<DrmConnector>> m_connectors;
0143     QVector<DrmObject *> m_allObjects;
0144     QVector<DrmPipeline *> m_pipelines;
0145 
0146     QVector<DrmOutput *> m_drmOutputs;
0147     QVector<DrmVirtualOutput *> m_virtualOutputs;
0148 
0149     std::unique_ptr<QSocketNotifier> m_socketNotifier;
0150     QSize m_cursorSize;
0151 };
0152 
0153 }