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 }