From a70321c592f241618fda8e3fb6deaa2b7510e13f Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Wed, 22 Sep 2021 14:01:01 +0200 Subject: [PATCH] platforms/drm: split DrmObject::Property out in its own files --- src/plugins/platforms/drm/CMakeLists.txt | 1 + src/plugins/platforms/drm/drm_object.cpp | 163 +--------------- src/plugins/platforms/drm/drm_object.h | 96 +-------- src/plugins/platforms/drm/drm_property.cpp | 215 +++++++++++++++++++++ src/plugins/platforms/drm/drm_property.h | 97 ++++++++++ 5 files changed, 322 insertions(+), 250 deletions(-) create mode 100644 src/plugins/platforms/drm/drm_property.cpp create mode 100644 src/plugins/platforms/drm/drm_property.h diff --git a/src/plugins/platforms/drm/CMakeLists.txt b/src/plugins/platforms/drm/CMakeLists.txt index 5594a189d5..651532eed6 100644 --- a/src/plugins/platforms/drm/CMakeLists.txt +++ b/src/plugins/platforms/drm/CMakeLists.txt @@ -1,6 +1,7 @@ set(DRM_SOURCES drm_backend.cpp drm_object.cpp + drm_property.cpp drm_object_connector.cpp drm_object_crtc.cpp drm_object_plane.cpp diff --git a/src/plugins/platforms/drm/drm_object.cpp b/src/plugins/platforms/drm/drm_object.cpp index e4b58fd04c..c8bec5ae6d 100644 --- a/src/plugins/platforms/drm/drm_object.cpp +++ b/src/plugins/platforms/drm/drm_object.cpp @@ -17,10 +17,6 @@ namespace KWin { -/* - * Definitions for class DrmObject - */ - DrmObject::DrmObject(DrmGpu *gpu, uint32_t objectId, const QVector &&vector, uint32_t objectType) : m_gpu(gpu) , m_id(objectId) @@ -94,7 +90,7 @@ bool DrmObject::atomicPopulate(drmModeAtomicReq *req) const return true; } -QVector DrmObject::properties() +QVector DrmObject::properties() { return m_props; } @@ -156,7 +152,7 @@ bool DrmObject::updateProperties() if (m_props[propIndex]) { m_props[propIndex]->setCurrent(properties->prop_values[drmPropIndex]); } else { - m_props[propIndex] = new Property(this, prop.data(), properties->prop_values[drmPropIndex], def.enumNames); + m_props[propIndex] = new DrmProperty(this, prop.data(), properties->prop_values[drmPropIndex], def.enumNames); } found = true; break; @@ -187,160 +183,9 @@ DrmGpu *DrmObject::gpu() const return m_gpu; } -/* - * Definitions for DrmObject::Property - */ - -DrmObject::Property::Property(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector &enumNames) - : m_propId(prop->prop_id) - , m_propName(prop->name) - , m_pending(val) - , m_next(val) - , m_current(val) - , m_immutable(prop->flags & DRM_MODE_PROP_IMMUTABLE) - , m_obj(obj) +uint32_t DrmObject::type() const { - if (!enumNames.isEmpty()) { - m_enumNames = enumNames; - initEnumMap(prop); - } -} - -DrmObject::Property::~Property() = default; - -void DrmObject::Property::setPending(uint64_t value) -{ - m_pending = value; -} - -uint64_t DrmObject::Property::pending() const -{ - return m_pending; -} - -bool DrmObject::Property::setPendingBlob(void *blob, size_t length) -{ - if (!blob && !m_pendingBlob) { - return true; - } - if (blob && m_pendingBlob && length == m_pendingBlob->length && memcmp(blob, m_pendingBlob->data, length) == 0) { - return true; - } - uint32_t id = 0; - if (blob != nullptr) { - if (drmModeCreatePropertyBlob(m_obj->m_gpu->fd(), blob, length, &id) != 0) { - qCWarning(KWIN_DRM) << "Creating property blob failed!" << strerror(errno); - return false; - } - } - if (m_pendingBlob && m_pendingBlob != m_currentBlob && m_pendingBlob != m_nextBlob) { - drmModeDestroyPropertyBlob(m_obj->m_gpu->fd(), m_pendingBlob->id); - drmModeFreePropertyBlob(m_pendingBlob); - } - m_pending = id; - m_pendingBlob = drmModeGetPropertyBlob(m_obj->m_gpu->fd(), m_pending); - return true; -} - -void DrmObject::Property::setCurrent(uint64_t value) -{ - m_current = value; -} - -uint64_t DrmObject::Property::current() const -{ - return m_current; -} - -void DrmObject::Property::setCurrentBlob(drmModePropertyBlobRes *blob) -{ - if (m_currentBlob && m_currentBlob != m_pendingBlob && m_currentBlob != m_nextBlob && m_currentBlob != blob) { - drmModeDestroyPropertyBlob(m_obj->m_gpu->fd(), m_currentBlob->id); - drmModeFreePropertyBlob(m_currentBlob); - } - m_currentBlob = blob; - m_current = blob ? blob->id : 0; -} - -void DrmObject::Property::commit() -{ - if (m_immutable || m_current == m_pending) { - return; - } - if (m_pendingBlob || m_currentBlob) { - setCurrentBlob(m_pendingBlob); - } else { - setCurrent(m_pending); - } -} - -void DrmObject::Property::commitPending() -{ - if (m_immutable || m_next == m_pending) { - return; - } - if (m_pendingBlob || m_nextBlob) { - if (m_nextBlob && m_nextBlob != m_currentBlob) { - drmModeDestroyPropertyBlob(m_obj->m_gpu->fd(), m_nextBlob->id); - drmModeFreePropertyBlob(m_nextBlob); - } - m_next = m_pending; - m_nextBlob = m_pendingBlob; - } else { - m_next = m_pending; - } -} - -void DrmObject::Property::rollbackPending() -{ - if (m_immutable || m_next == m_pending) { - return; - } - if (m_pendingBlob || m_nextBlob) { - if (m_pendingBlob && m_pendingBlob != m_currentBlob) { - drmModeDestroyPropertyBlob(m_obj->m_gpu->fd(), m_pendingBlob->id); - drmModeFreePropertyBlob(m_pendingBlob); - } - m_pending = m_next; - m_pendingBlob = m_nextBlob; - } else { - m_pending = m_next; - } -} - -bool DrmObject::Property::needsCommit() const -{ - return m_pending != m_current; -} - -bool DrmObject::Property::setPropertyLegacy(uint64_t value) -{ - if (drmModeObjectSetProperty(m_obj->m_gpu->fd(), m_obj->id(), m_obj->m_objectType, m_propId, value) == 0) { - m_current = m_next = m_pending = value; - return true; - } else { - return false; - } -} - -void DrmObject::Property::initEnumMap(drmModePropertyRes *prop) -{ - if ( ( !(prop->flags & DRM_MODE_PROP_ENUM) && !(prop->flags & DRM_MODE_PROP_BITMASK) ) - || prop->count_enums < 1 ) { - qCWarning(KWIN_DRM) << "Property '" << prop->name << "' ( id =" - << m_propId << ") should be enum valued, but it is not."; - return; - } - - for (int i = 0; i < prop->count_enums; i++) { - struct drm_mode_property_enum *en = &prop->enums[i]; - int j = m_enumNames.indexOf(QByteArray(en->name)); - if (j >= 0) { - m_enumMap[j] = en->value; - } else { - qCWarning(KWIN_DRM, "%s has unrecognized enum '%s'", qPrintable(m_propName), en->name); - } - } + return m_objectType; } } diff --git a/src/plugins/platforms/drm/drm_object.h b/src/plugins/platforms/drm/drm_object.h index f889064313..5ba450fa41 100644 --- a/src/plugins/platforms/drm/drm_object.h +++ b/src/plugins/platforms/drm/drm_object.h @@ -16,6 +16,7 @@ #include #include "drm_pointer.h" +#include "drm_property.h" namespace KWin { @@ -37,6 +38,8 @@ public: uint32_t id() const; DrmGpu *gpu() const; + uint32_t type() const; + QVector properties(); void commit(); void commitPending(); @@ -72,100 +75,11 @@ public: return property ? property->hasEnum(value) : false; } - class Property - { - public: - Property(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector &enumNames); - virtual ~Property(); - - void initEnumMap(drmModePropertyRes *prop); - - QVector enumNames() const { - return m_enumNames; - } - bool hasEnum(uint64_t value) const { - return m_enumMap.contains(value); - } - bool hasAllEnums() const { - return m_enumMap.count() == m_enumNames.count(); - } - template - T enumForValue(uint64_t value) const { - return static_cast(m_enumMap[value]); - } - template - bool setEnum(T index) { - if (hasEnum(static_cast(index))) { - setPending(m_enumMap[static_cast(index)]); - return true; - } - return false; - } - - uint32_t propId() const { - return m_propId; - } - const QByteArray &name() const { - return m_propName; - } - bool isImmutable() const { - return m_immutable; - } - bool isLegacy() const { - return m_legacy; - } - /** - * Makes this property be ignored by DrmObject::atomicPopulate - */ - void setLegacy() { - m_legacy = true; - } - - void setPending(uint64_t value); - uint64_t pending() const; - bool setPendingBlob(void *blob, size_t length); - - void setCurrent(uint64_t value); - uint64_t current() const; - void setCurrentBlob(drmModePropertyBlobRes *blob); - - void commit(); - void commitPending(); - void rollbackPending(); - bool needsCommit() const; - - bool setPropertyLegacy(uint64_t value); - - private: - uint32_t m_propId = 0; - QByteArray m_propName; - - // the value that will be m_next after the property has been committed - // has not necessarily been tested to work - uint64_t m_pending = 0; - drmModePropertyBlobRes *m_pendingBlob = nullptr; - // the value that will be m_current after the next atomic commit - // and has been tested to work - uint64_t m_next = 0; - drmModePropertyBlobRes *m_nextBlob = nullptr; - // the value currently set for or by the kernel - uint64_t m_current = 0; - drmModePropertyBlobRes *m_currentBlob = nullptr; - - QMap m_enumMap; - QVector m_enumNames; - const bool m_immutable; - bool m_legacy = false; - const DrmObject *m_obj; - }; - template - Property *getProp(T propIndex) const { + DrmProperty *getProp(T propIndex) const { return m_props[static_cast(propIndex)]; } - QVector properties(); - protected: enum class Requirement { Required, @@ -196,7 +110,7 @@ protected: m_props[static_cast(prop)] = nullptr; } - QVector m_props; + QVector m_props; private: DrmGpu *m_gpu; diff --git a/src/plugins/platforms/drm/drm_property.cpp b/src/plugins/platforms/drm/drm_property.cpp new file mode 100644 index 0000000000..fb813d97cc --- /dev/null +++ b/src/plugins/platforms/drm/drm_property.cpp @@ -0,0 +1,215 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2016 Roman Gilg + SPDX-FileCopyrightText: 2021 Xaver Hugl + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "drm_property.h" +#include "drm_object.h" +#include "drm_gpu.h" +#include "logging.h" + +namespace KWin +{ + +DrmProperty::DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector &enumNames) + : m_propId(prop->prop_id) + , m_propName(prop->name) + , m_pending(val) + , m_next(val) + , m_current(val) + , m_immutable(prop->flags & DRM_MODE_PROP_IMMUTABLE) + , m_obj(obj) +{ + if (!enumNames.isEmpty()) { + m_enumNames = enumNames; + initEnumMap(prop); + } +} + +DrmProperty::~DrmProperty() = default; + +bool DrmProperty::setPendingBlob(void *blob, size_t length) +{ + if (!blob && !m_pendingBlob) { + return true; + } + if (blob && m_pendingBlob && length == m_pendingBlob->length && memcmp(blob, m_pendingBlob->data, length) == 0) { + return true; + } + uint32_t id = 0; + if (blob != nullptr) { + if (drmModeCreatePropertyBlob(m_obj->gpu()->fd(), blob, length, &id) != 0) { + qCWarning(KWIN_DRM) << "Creating property blob failed!" << strerror(errno); + return false; + } + } + if (m_pendingBlob && m_pendingBlob != m_currentBlob && m_pendingBlob != m_nextBlob) { + drmModeDestroyPropertyBlob(m_obj->gpu()->fd(), m_pendingBlob->id); + drmModeFreePropertyBlob(m_pendingBlob); + } + m_pending = id; + m_pendingBlob = drmModeGetPropertyBlob(m_obj->gpu()->fd(), m_pending); + return true; +} + +void DrmProperty::setCurrentBlob(drmModePropertyBlobRes *blob) +{ + if (m_currentBlob && m_currentBlob != m_pendingBlob && m_currentBlob != m_nextBlob && m_currentBlob != blob) { + drmModeDestroyPropertyBlob(m_obj->gpu()->fd(), m_currentBlob->id); + drmModeFreePropertyBlob(m_currentBlob); + } + m_currentBlob = blob; + m_current = blob ? blob->id : 0; +} + + +void DrmProperty::commit() +{ + if (m_immutable || m_current == m_pending) { + return; + } + if (m_pendingBlob || m_currentBlob) { + setCurrentBlob(m_pendingBlob); + } else { + setCurrent(m_pending); + } +} + +void DrmProperty::commitPending() +{ + if (m_immutable || m_next == m_pending) { + return; + } + if (m_pendingBlob || m_nextBlob) { + if (m_nextBlob && m_nextBlob != m_currentBlob) { + drmModeDestroyPropertyBlob(m_obj->gpu()->fd(), m_nextBlob->id); + drmModeFreePropertyBlob(m_nextBlob); + } + m_next = m_pending; + m_nextBlob = m_pendingBlob; + } else { + m_next = m_pending; + } +} + +void DrmProperty::rollbackPending() +{ + if (m_immutable || m_next == m_pending) { + return; + } + if (m_pendingBlob || m_nextBlob) { + if (m_pendingBlob && m_pendingBlob != m_currentBlob) { + drmModeDestroyPropertyBlob(m_obj->gpu()->fd(), m_pendingBlob->id); + drmModeFreePropertyBlob(m_pendingBlob); + } + m_pending = m_next; + m_pendingBlob = m_nextBlob; + } else { + m_pending = m_next; + } +} + +bool DrmProperty::setPropertyLegacy(uint64_t value) +{ + return drmModeObjectSetProperty(m_obj->gpu()->fd(), m_obj->id(), m_obj->type(), m_propId, value) == 0; +} + +void DrmProperty::initEnumMap(drmModePropertyRes *prop) +{ + if ( ( !(prop->flags & DRM_MODE_PROP_ENUM) && !(prop->flags & DRM_MODE_PROP_BITMASK) ) + || prop->count_enums < 1 ) { + qCWarning(KWIN_DRM) << "Property '" << prop->name << "' ( id =" + << m_propId << ") should be enum valued, but it is not."; + return; + } + + for (int i = 0; i < prop->count_enums; i++) { + struct drm_mode_property_enum *en = &prop->enums[i]; + int j = m_enumNames.indexOf(QByteArray(en->name)); + if (j >= 0) { + m_enumMap[j] = en->value; + } else { + qCWarning(KWIN_DRM, "%s has unrecognized enum '%s'", qPrintable(m_propName), en->name); + } + } +} + +void DrmProperty::setPending(uint64_t value) +{ + m_pending = value; +} + +uint64_t DrmProperty::pending() const +{ + return m_pending; +} + +bool DrmProperty::needsCommit() const +{ + return m_pending != m_current; +} + +drmModePropertyBlobRes *DrmProperty::currentBlob() const +{ + return m_currentBlob; +} + +drmModePropertyBlobRes *DrmProperty::pendingBlob() const +{ + return m_pendingBlob; +} + +void DrmProperty::setCurrent(uint64_t value) +{ + m_current = value; +} + +uint64_t DrmProperty::current() const +{ + return m_current; +} + +QVector DrmProperty::enumNames() const +{ + return m_enumNames; +} +bool DrmProperty::hasEnum(uint64_t value) const +{ + return m_enumMap.contains(value); +} +bool DrmProperty::hasAllEnums() const +{ + return m_enumMap.count() == m_enumNames.count(); +} + +uint32_t DrmProperty::propId() const +{ + return m_propId; +} + +const QByteArray &DrmProperty::name() const +{ + return m_propName; +} + +bool DrmProperty::isImmutable() const +{ + return m_immutable; +} + +bool DrmProperty::isLegacy() const +{ + return m_legacy; +} + +void DrmProperty::setLegacy() +{ + m_legacy = true; +} + +} diff --git a/src/plugins/platforms/drm/drm_property.h b/src/plugins/platforms/drm/drm_property.h new file mode 100644 index 0000000000..b0411e8be9 --- /dev/null +++ b/src/plugins/platforms/drm/drm_property.h @@ -0,0 +1,97 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2016 Roman Gilg + SPDX-FileCopyrightText: 2021 Xaver Hugl + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include + +#include +#include +#include + +namespace KWin +{ + +class DrmObject; + +class DrmProperty +{ +public: + DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector &enumNames); + virtual ~DrmProperty(); + + void initEnumMap(drmModePropertyRes *prop); + + QVector enumNames() const; + bool hasEnum(uint64_t value) const; + bool hasAllEnums() const; + template + T enumForValue(uint64_t value) const { + return static_cast(m_enumMap[value]); + } + template + bool setEnum(T index) { + if (hasEnum(static_cast(index))) { + setPending(m_enumMap[static_cast(index)]); + return true; + } + return false; + } + + uint32_t propId() const; + const QByteArray &name() const; + bool isImmutable() const; + bool isLegacy() const; + /** + * Makes this property be ignored by DrmObject::atomicPopulate + */ + void setLegacy(); + + void setPending(uint64_t value); + uint64_t pending() const; + bool setPendingBlob(void *blob, size_t length); + drmModePropertyBlobRes *pendingBlob() const; + + void setCurrent(uint64_t value); + uint64_t current() const; + void setCurrentBlob(drmModePropertyBlobRes *blob); + drmModePropertyBlobRes *currentBlob() const; + + void commit(); + void commitPending(); + void rollbackPending(); + bool needsCommit() const; + + bool setPropertyLegacy(uint64_t value); + +private: + uint32_t m_propId = 0; + QByteArray m_propName; + + // the value that will be m_next after the property has been committed + // has not necessarily been tested to work + uint64_t m_pending = 0; + drmModePropertyBlobRes *m_pendingBlob = nullptr; + // the value that will be m_current after the next atomic commit + // and has been tested to work + uint64_t m_next = 0; + drmModePropertyBlobRes *m_nextBlob = nullptr; + // the value currently set for or by the kernel + uint64_t m_current = 0; + drmModePropertyBlobRes *m_currentBlob = nullptr; + + QMap m_enumMap; + QVector m_enumNames; + const bool m_immutable; + bool m_legacy = false; + const DrmObject *m_obj; +}; + +}