File indexing completed on 2024-06-23 05:25:13

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 <QList>
0015 #include <QPointer>
0016 #include <QSize>
0017 #include <QSocketNotifier>
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 class DrmOutput;
0028 class DrmObject;
0029 class DrmCrtc;
0030 class DrmConnector;
0031 class DrmPlane;
0032 class DrmBackend;
0033 class EglGbmBackend;
0034 class DrmAbstractOutput;
0035 class DrmRenderBackend;
0036 class DrmVirtualOutput;
0037 class EglDisplay;
0038 class GraphicsBuffer;
0039 class GraphicsBufferAllocator;
0040 
0041 class DrmLease : public QObject
0042 {
0043     Q_OBJECT
0044 public:
0045     DrmLease(DrmGpu *gpu, FileDescriptor &&fd, uint32_t lesseeId, const QList<DrmOutput *> &outputs);
0046     ~DrmLease();
0047 
0048     FileDescriptor &fd();
0049     uint32_t lesseeId() const;
0050 
0051 Q_SIGNALS:
0052     void revokeRequested();
0053 
0054 private:
0055     DrmGpu *const m_gpu;
0056     FileDescriptor m_fd;
0057     const uint32_t m_lesseeId;
0058     const QList<DrmOutput *> m_outputs;
0059 };
0060 
0061 class DrmGpu : public QObject
0062 {
0063     Q_OBJECT
0064 public:
0065     DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t deviceId);
0066     ~DrmGpu();
0067 
0068     int fd() const;
0069     dev_t deviceId() const;
0070     QString devNode() const;
0071 
0072     bool isRemoved() const;
0073     void setRemoved();
0074     void setActive(bool active);
0075     bool isActive() const;
0076 
0077     bool atomicModeSetting() const;
0078     bool addFB2ModifiersSupported() const;
0079     bool asyncPageflipSupported() const;
0080     bool isI915() const;
0081     bool isNVidia() const;
0082     gbm_device *gbmDevice() const;
0083     EglDisplay *eglDisplay() const;
0084     DrmBackend *platform() const;
0085     /**
0086      * Returns the clock from which presentation timestamps are sourced. The returned value
0087      * can be either CLOCK_MONOTONIC or CLOCK_REALTIME.
0088      */
0089     clockid_t presentationClock() const;
0090     QSize cursorSize() const;
0091 
0092     QList<DrmVirtualOutput *> virtualOutputs() const;
0093     QList<DrmOutput *> drmOutputs() const;
0094     const QList<DrmPipeline *> pipelines() const;
0095 
0096     void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
0097 
0098     bool updateOutputs();
0099     void removeOutputs();
0100 
0101     DrmVirtualOutput *createVirtualOutput(const QString &name, const QSize &size, double scale);
0102     void removeVirtualOutput(DrmVirtualOutput *output);
0103 
0104     DrmPipeline::Error testPendingConfiguration();
0105     bool needsModeset() const;
0106     bool maybeModeset();
0107 
0108     GraphicsBufferAllocator *graphicsBufferAllocator() const;
0109     std::shared_ptr<DrmFramebuffer> importBuffer(GraphicsBuffer *buffer, FileDescriptor &&explicitFence);
0110     void releaseBuffers();
0111     void recreateSurfaces();
0112 
0113     FileDescriptor createNonMasterFd() const;
0114     std::unique_ptr<DrmLease> leaseOutputs(const QList<DrmOutput *> &outputs);
0115     void waitIdle();
0116 
0117 Q_SIGNALS:
0118     void activeChanged(bool active);
0119     void outputAdded(DrmAbstractOutput *output);
0120     void outputRemoved(DrmAbstractOutput *output);
0121 
0122 private:
0123     void dispatchEvents();
0124     DrmOutput *findOutput(quint32 connector);
0125     void removeOutput(DrmOutput *output);
0126     void initDrmResources();
0127 
0128     DrmPipeline::Error checkCrtcAssignment(QList<DrmConnector *> connectors, const QList<DrmCrtc *> &crtcs);
0129     DrmPipeline::Error testPipelines();
0130     QList<DrmObject *> unusedObjects() const;
0131 
0132     static void pageFlipHandler(int fd, unsigned int sequence, unsigned int sec, unsigned int usec, unsigned int crtc_id, void *user_data);
0133 
0134     const int m_fd;
0135     const dev_t m_deviceId;
0136     const QString m_devNode;
0137     bool m_atomicModeSetting;
0138     bool m_addFB2ModifiersSupported = false;
0139     bool m_isNVidia;
0140     bool m_isI915;
0141     bool m_isVirtualMachine;
0142     bool m_supportsCursorPlaneHotspot = false;
0143     bool m_asyncPageflipSupported = false;
0144     bool m_isRemoved = false;
0145     bool m_isActive = true;
0146     clockid_t m_presentationClock;
0147     gbm_device *m_gbmDevice;
0148     FileDescriptor m_gbmFd;
0149     std::unique_ptr<GraphicsBufferAllocator> m_allocator;
0150     std::unique_ptr<EglDisplay> m_eglDisplay;
0151     DrmBackend *const m_platform;
0152 
0153     std::vector<std::unique_ptr<DrmPlane>> m_planes;
0154     std::vector<std::unique_ptr<DrmCrtc>> m_crtcs;
0155     std::vector<std::shared_ptr<DrmConnector>> m_connectors;
0156     QList<DrmObject *> m_allObjects;
0157     QList<DrmPipeline *> m_pipelines;
0158 
0159     QList<DrmOutput *> m_drmOutputs;
0160     QList<DrmVirtualOutput *> m_virtualOutputs;
0161 
0162     std::unique_ptr<QSocketNotifier> m_socketNotifier;
0163     QSize m_cursorSize;
0164 };
0165 
0166 }