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 }