File indexing completed on 2025-04-20 10:57:36
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 SPDX-FileCopyrightText: 2021-2022 Xaver Hugl <xaver.hugl@gmail.com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #pragma once 0012 #include "drm_pointer.h" 0013 #include "drm_logging.h" 0014 0015 #include <QByteArray> 0016 #include <QMap> 0017 #include <QVector> 0018 0019 #include <xf86drmMode.h> 0020 0021 namespace KWin 0022 { 0023 0024 class DrmObject; 0025 0026 class DrmProperty 0027 { 0028 public: 0029 DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector<QByteArray> &enumNames); 0030 0031 bool hasAllEnums() const; 0032 0033 template<typename Enum> 0034 bool hasEnum(Enum value) const 0035 { 0036 return m_enumToPropertyMap.contains(static_cast<uint64_t>(value)); 0037 } 0038 template<typename T> 0039 T enumForValue(uint64_t value) const 0040 { 0041 if (m_isBitmask) { 0042 uint64_t ret = 0; 0043 for (uint64_t mask = 1; value >= mask && mask != 0; mask <<= 1) { 0044 if (value & mask) { 0045 ret |= m_propertyToEnumMap[mask]; 0046 } 0047 } 0048 return static_cast<T>(ret); 0049 } else { 0050 return static_cast<T>(m_propertyToEnumMap[value]); 0051 } 0052 } 0053 template<typename Enum> 0054 void setEnum(Enum value) 0055 { 0056 const uint64_t integer = static_cast<uint64_t>(value); 0057 if (m_isBitmask) { 0058 uint64_t set = 0; 0059 for (uint64_t mask = 1; integer >= mask && mask != 0; mask <<= 1) { 0060 if (integer & mask) { 0061 set |= m_enumToPropertyMap[mask]; 0062 } 0063 } 0064 setPending(set); 0065 } else { 0066 setPending(m_enumToPropertyMap[integer]); 0067 } 0068 } 0069 0070 uint32_t propId() const; 0071 const QByteArray &name() const; 0072 bool isImmutable() const; 0073 bool isBitmask() const; 0074 bool isLegacy() const; 0075 /** 0076 * Makes this property be ignored by DrmObject::atomicPopulate 0077 */ 0078 void setLegacy(); 0079 0080 void setPending(uint64_t value); 0081 uint64_t pending() const; 0082 0083 void setCurrent(uint64_t value); 0084 uint64_t current() const; 0085 drmModePropertyBlobRes *immutableBlob() const; 0086 0087 uint64_t minValue() const; 0088 uint64_t maxValue() const; 0089 0090 void commit(); 0091 void commitPending(); 0092 void rollbackPending(); 0093 bool needsCommit() const; 0094 0095 bool setPropertyLegacy(uint64_t value); 0096 template<typename T> 0097 bool setEnumLegacy(T value) 0098 { 0099 if (hasEnum(static_cast<uint64_t>(value))) { 0100 return setPropertyLegacy(m_enumToPropertyMap[static_cast<uint32_t>(value)]); 0101 } 0102 return false; 0103 } 0104 0105 QString valueString(uint64_t value) const; 0106 0107 private: 0108 void initEnumMap(drmModePropertyRes *prop); 0109 void updateBlob(); 0110 0111 uint32_t m_propId = 0; 0112 QByteArray m_propName; 0113 0114 // the value that will be m_next after the property has been committed 0115 // has not necessarily been tested to work 0116 uint64_t m_pending = 0; 0117 // the value that will be m_current after the next atomic commit 0118 // and has been tested to work 0119 uint64_t m_next = 0; 0120 // the value currently set for or by the kernel 0121 uint64_t m_current = 0; 0122 DrmUniquePtr<drmModePropertyBlobRes> m_immutableBlob; 0123 0124 uint64_t m_minValue = -1; 0125 uint64_t m_maxValue = -1; 0126 0127 QMap<uint64_t, uint64_t> m_enumToPropertyMap; 0128 QMap<uint64_t, uint64_t> m_propertyToEnumMap; 0129 QVector<QByteArray> m_enumNames; 0130 const bool m_immutable; 0131 const bool m_isBlob; 0132 const bool m_isBitmask; 0133 bool m_legacy = false; 0134 const DrmObject *m_obj; 0135 }; 0136 0137 }