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

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #include "drm_crtc.h"
0010 #include "drm_backend.h"
0011 #include "drm_buffer.h"
0012 #include "drm_gpu.h"
0013 #include "drm_logging.h"
0014 #include "drm_output.h"
0015 #include "drm_pointer.h"
0016 #include <cerrno>
0017 
0018 namespace KWin
0019 {
0020 
0021 DrmCrtc::DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex, DrmPlane *primaryPlane, DrmPlane *cursorPlane)
0022     : DrmObject(gpu, crtcId, {PropertyDefinition(QByteArrayLiteral("MODE_ID"), Requirement::Required), PropertyDefinition(QByteArrayLiteral("ACTIVE"), Requirement::Required), PropertyDefinition(QByteArrayLiteral("VRR_ENABLED"), Requirement::Optional), PropertyDefinition(QByteArrayLiteral("GAMMA_LUT"), Requirement::Optional), PropertyDefinition(QByteArrayLiteral("GAMMA_LUT_SIZE"), Requirement::Optional), PropertyDefinition(QByteArrayLiteral("CTM"), Requirement::Optional)}, DRM_MODE_OBJECT_CRTC)
0023     , m_crtc(drmModeGetCrtc(gpu->fd(), crtcId))
0024     , m_pipeIndex(pipeIndex)
0025     , m_primaryPlane(primaryPlane)
0026     , m_cursorPlane(cursorPlane)
0027 {
0028 }
0029 
0030 bool DrmCrtc::init()
0031 {
0032     if (!m_crtc) {
0033         return false;
0034     }
0035     return initProps();
0036 }
0037 
0038 void DrmCrtc::flipBuffer()
0039 {
0040     m_currentBuffer = m_nextBuffer;
0041     m_nextBuffer = nullptr;
0042 }
0043 
0044 drmModeModeInfo DrmCrtc::queryCurrentMode()
0045 {
0046     m_crtc.reset(drmModeGetCrtc(gpu()->fd(), id()));
0047     return m_crtc->mode;
0048 }
0049 
0050 int DrmCrtc::pipeIndex() const
0051 {
0052     return m_pipeIndex;
0053 }
0054 
0055 std::shared_ptr<DrmFramebuffer> DrmCrtc::current() const
0056 {
0057     return m_currentBuffer;
0058 }
0059 
0060 std::shared_ptr<DrmFramebuffer> DrmCrtc::next() const
0061 {
0062     return m_nextBuffer;
0063 }
0064 
0065 void DrmCrtc::setCurrent(const std::shared_ptr<DrmFramebuffer> &buffer)
0066 {
0067     m_currentBuffer = buffer;
0068 }
0069 
0070 void DrmCrtc::setNext(const std::shared_ptr<DrmFramebuffer> &buffer)
0071 {
0072     m_nextBuffer = buffer;
0073 }
0074 
0075 int DrmCrtc::gammaRampSize() const
0076 {
0077     if (gpu()->atomicModeSetting()) {
0078         // limit atomic gamma ramp to 4096 to work around https://gitlab.freedesktop.org/drm/intel/-/issues/3916
0079         if (auto prop = getProp(PropertyIndex::Gamma_LUT_Size); prop && prop->current() <= 4096) {
0080             return prop->current();
0081         }
0082     }
0083     return m_crtc->gamma_size;
0084 }
0085 
0086 DrmPlane *DrmCrtc::primaryPlane() const
0087 {
0088     return m_primaryPlane;
0089 }
0090 
0091 DrmPlane *DrmCrtc::cursorPlane() const
0092 {
0093     return m_cursorPlane;
0094 }
0095 
0096 void DrmCrtc::disable()
0097 {
0098     setPending(PropertyIndex::Active, 0);
0099     setPending(PropertyIndex::ModeId, 0);
0100 }
0101 
0102 void DrmCrtc::releaseBuffers()
0103 {
0104     if (m_nextBuffer) {
0105         m_nextBuffer->releaseBuffer();
0106     }
0107     if (m_currentBuffer) {
0108         m_currentBuffer->releaseBuffer();
0109     }
0110 }
0111 }