/* KWin - the KDE window manager This file is part of the KDE project. SPDX-FileCopyrightText: 2020 Xaver Hugl SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "core/drmdevice.h" #include "drm_pipeline.h" #include "utils/filedescriptor.h" #include "utils/version.h" #include #include #include #include #include #include #include #include namespace KWin { class DrmOutput; class DrmObject; class DrmCrtc; class DrmConnector; class DrmPlane; class DrmBackend; class EglGbmBackend; class DrmAbstractOutput; class DrmRenderBackend; class DrmVirtualOutput; class EglDisplay; class GraphicsBuffer; class GraphicsBufferAllocator; class OutputFrame; class DrmLease : public QObject { Q_OBJECT public: DrmLease(DrmGpu *gpu, FileDescriptor &&fd, uint32_t lesseeId, const QList &outputs); ~DrmLease(); FileDescriptor &fd(); uint32_t lesseeId() const; Q_SIGNALS: void revokeRequested(); private: DrmGpu *const m_gpu; FileDescriptor m_fd; const uint32_t m_lesseeId; const QList m_outputs; }; class DrmGpu : public QObject { Q_OBJECT public: /** * This should always be longer than any real pageflip can take, even with PSR and modesets */ static constexpr std::chrono::milliseconds s_pageflipTimeout = std::chrono::seconds(1); DrmGpu(DrmBackend *backend, int fd, std::unique_ptr &&device); ~DrmGpu(); int fd() const; DrmDevice *drmDevice() const; bool isRemoved() const; void setRemoved(); void setActive(bool active); bool isActive() const; bool atomicModeSetting() const; bool addFB2ModifiersSupported() const; bool asyncPageflipSupported() const; bool isI915() const; bool isNVidia() const; bool isAmdgpu() const; bool isVmwgfx() const; bool isVirtualMachine() const; std::optional nvidiaDriverVersion() const; EglDisplay *eglDisplay() const; DrmBackend *platform() const; /** * Returns the clock from which presentation timestamps are sourced. The returned value * can be either CLOCK_MONOTONIC or CLOCK_REALTIME. */ clockid_t presentationClock() const; QSize cursorSize() const; QList drmOutputs() const; const QList pipelines() const; void setEglDisplay(std::unique_ptr &&display); bool updateOutputs(); void removeOutputs(); DrmPipeline::Error testPendingConfiguration(); bool needsModeset() const; bool maybeModeset(const std::shared_ptr &frame); std::shared_ptr importBuffer(GraphicsBuffer *buffer, FileDescriptor &&explicitFence); void releaseBuffers(); void recreateSurfaces(); FileDescriptor createNonMasterFd() const; std::unique_ptr leaseOutputs(const QList &outputs); void waitIdle(); Q_SIGNALS: void activeChanged(bool active); void outputAdded(DrmAbstractOutput *output); void outputRemoved(DrmAbstractOutput *output); private: void dispatchEvents(); DrmOutput *findOutput(quint32 connector); void removeOutput(DrmOutput *output); void initDrmResources(); DrmPipeline::Error checkCrtcAssignment(QList connectors, const QList &crtcs); DrmPipeline::Error testPipelines(); QList unusedObjects() const; static void pageFlipHandler(int fd, unsigned int sequence, unsigned int sec, unsigned int usec, unsigned int crtc_id, void *user_data); const int m_fd; const std::unique_ptr m_drmDevice; bool m_atomicModeSetting; bool m_addFB2ModifiersSupported = false; bool m_isNVidia; bool m_isI915; bool m_isAmdgpu; bool m_isVmwgfx; bool m_isVirtualMachine; bool m_supportsCursorPlaneHotspot = false; bool m_asyncPageflipSupported = false; bool m_isRemoved = false; bool m_isActive = true; bool m_forceModeset = false; clockid_t m_presentationClock; std::unique_ptr m_eglDisplay; DrmBackend *const m_platform; std::optional m_nvidiaDriverVersion; std::vector> m_planes; std::vector> m_crtcs; std::vector> m_connectors; QList m_allObjects; QList m_pipelines; QList m_drmOutputs; std::unique_ptr m_socketNotifier; QSize m_cursorSize; std::vector> m_pendingModesetFrames; }; } QDebug &operator<<(QDebug &s, const KWin::DrmGpu *gpu);