2020-08-02 22:22:19 +00:00
|
|
|
/*
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
2016-08-31 12:00:31 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
2016-08-31 12:00:31 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2019-12-11 16:50:07 +00:00
|
|
|
#pragma once
|
2016-08-31 12:00:31 +00:00
|
|
|
|
|
|
|
#include <QVector>
|
|
|
|
#include <QByteArray>
|
2021-08-31 01:40:18 +00:00
|
|
|
#include <QMap>
|
2016-08-31 12:00:31 +00:00
|
|
|
|
|
|
|
// drm
|
|
|
|
#include <xf86drmMode.h>
|
|
|
|
|
2021-03-10 21:04:32 +00:00
|
|
|
#include "drm_pointer.h"
|
2016-08-31 12:00:31 +00:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2017-05-09 19:29:10 +00:00
|
|
|
class DrmBackend;
|
2021-04-01 11:15:42 +00:00
|
|
|
class DrmGpu;
|
2016-08-31 12:00:31 +00:00
|
|
|
class DrmOutput;
|
|
|
|
|
|
|
|
class DrmObject
|
|
|
|
{
|
|
|
|
public:
|
2017-11-12 20:00:02 +00:00
|
|
|
virtual ~DrmObject();
|
2016-08-31 12:00:31 +00:00
|
|
|
|
2019-12-11 16:50:07 +00:00
|
|
|
/**
|
|
|
|
* Must be called to query necessary data directly after creation.
|
|
|
|
* @return true when initializing was successful
|
|
|
|
*/
|
2021-01-26 20:23:44 +00:00
|
|
|
virtual bool init() = 0;
|
2016-08-31 12:00:31 +00:00
|
|
|
|
|
|
|
uint32_t id() const {
|
|
|
|
return m_id;
|
|
|
|
}
|
|
|
|
|
2021-04-01 11:15:42 +00:00
|
|
|
DrmGpu *gpu() const {
|
|
|
|
return m_gpu;
|
2017-11-12 20:00:02 +00:00
|
|
|
}
|
|
|
|
|
2019-12-11 16:50:07 +00:00
|
|
|
/**
|
|
|
|
* Populate an atomic request with data of this object.
|
|
|
|
* @param req the atomic request
|
|
|
|
* @return true when the request was successfully populated
|
|
|
|
*/
|
2021-03-10 21:04:32 +00:00
|
|
|
bool atomicPopulate(drmModeAtomicReq *req) const;
|
2019-12-11 16:50:07 +00:00
|
|
|
|
2021-03-10 21:04:32 +00:00
|
|
|
template <typename T>
|
2021-05-25 22:05:17 +00:00
|
|
|
bool setPending(T prop, uint64_t new_value)
|
2021-03-10 21:04:32 +00:00
|
|
|
{
|
|
|
|
if (auto &property = m_props.at(static_cast<uint32_t>(prop))) {
|
2021-05-25 22:05:17 +00:00
|
|
|
property->setPending(new_value);
|
|
|
|
return true;
|
2021-03-10 21:04:32 +00:00
|
|
|
}
|
2021-05-25 22:05:17 +00:00
|
|
|
return false;
|
2021-03-10 21:04:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2021-05-25 22:05:17 +00:00
|
|
|
bool setPendingBlob(T prop, void *data, size_t length)
|
2021-03-10 21:04:32 +00:00
|
|
|
{
|
2021-05-25 22:05:17 +00:00
|
|
|
if (auto &property = m_props.at(static_cast<uint32_t>(prop))) {
|
|
|
|
return property->setPendingBlob(data, length);
|
2021-03-10 21:04:32 +00:00
|
|
|
}
|
2021-05-25 22:05:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-12-11 16:50:07 +00:00
|
|
|
|
2021-03-10 21:04:32 +00:00
|
|
|
template <typename T>
|
2021-05-25 22:05:17 +00:00
|
|
|
bool propHasEnum(T prop, uint64_t value) const
|
2021-03-10 21:04:32 +00:00
|
|
|
{
|
2021-05-25 22:05:17 +00:00
|
|
|
const auto &property = m_props.at(static_cast<uint32_t>(prop));
|
|
|
|
return property ? property->hasEnum(value) : false;
|
2021-03-10 21:04:32 +00:00
|
|
|
}
|
2019-12-11 16:50:07 +00:00
|
|
|
|
2016-08-31 12:00:31 +00:00
|
|
|
class Property
|
|
|
|
{
|
|
|
|
public:
|
2021-09-16 11:53:31 +00:00
|
|
|
Property(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector<QByteArray> &enumNames, drmModePropertyBlobRes *blob);
|
2016-08-31 12:00:31 +00:00
|
|
|
virtual ~Property();
|
|
|
|
|
|
|
|
void initEnumMap(drmModePropertyRes *prop);
|
|
|
|
|
2021-08-22 20:25:03 +00:00
|
|
|
QVector<QByteArray> enumNames() const {
|
|
|
|
return m_enumNames;
|
|
|
|
}
|
2017-11-03 17:35:13 +00:00
|
|
|
bool hasEnum(uint64_t value) const {
|
|
|
|
return m_enumMap.contains(value);
|
|
|
|
}
|
2021-08-31 01:40:18 +00:00
|
|
|
bool hasAllEnums() const {
|
|
|
|
return m_enumMap.count() == m_enumNames.count();
|
|
|
|
}
|
|
|
|
template <typename T>
|
|
|
|
T enumForValue(uint64_t value) const {
|
|
|
|
return static_cast<T>(m_enumMap[value]);
|
|
|
|
}
|
2021-06-22 21:28:08 +00:00
|
|
|
template <typename T>
|
|
|
|
bool setEnum(T index) {
|
|
|
|
if (hasEnum(static_cast<uint64_t>(index))) {
|
2021-05-25 22:05:17 +00:00
|
|
|
setPending(m_enumMap[static_cast<uint32_t>(index)]);
|
2021-06-22 21:28:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-31 12:00:31 +00:00
|
|
|
|
2017-11-10 19:38:33 +00:00
|
|
|
uint32_t propId() const {
|
2016-08-31 12:00:31 +00:00
|
|
|
return m_propId;
|
|
|
|
}
|
2017-11-10 19:38:33 +00:00
|
|
|
const QByteArray &name() const {
|
|
|
|
return m_propName;
|
|
|
|
}
|
2020-10-25 19:18:06 +00:00
|
|
|
bool isImmutable() const {
|
|
|
|
return m_immutable;
|
|
|
|
}
|
2021-04-19 22:42:37 +00:00
|
|
|
bool isLegacy() const {
|
|
|
|
return m_legacy;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Makes this property be ignored by DrmObject::atomicPopulate
|
|
|
|
*/
|
|
|
|
void setLegacy() {
|
|
|
|
m_legacy = true;
|
|
|
|
}
|
2016-08-31 12:00:31 +00:00
|
|
|
|
2021-05-25 22:05:17 +00:00
|
|
|
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;
|
|
|
|
|
2021-09-16 11:53:31 +00:00
|
|
|
bool setPropertyLegacy(uint64_t value);
|
|
|
|
|
2016-08-31 12:00:31 +00:00
|
|
|
private:
|
|
|
|
uint32_t m_propId = 0;
|
|
|
|
QByteArray m_propName;
|
|
|
|
|
2021-05-25 22:05:17 +00:00
|
|
|
// 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;
|
|
|
|
|
2021-08-31 01:40:18 +00:00
|
|
|
QMap<uint32_t, uint64_t> m_enumMap;
|
2016-08-31 12:00:31 +00:00
|
|
|
QVector<QByteArray> m_enumNames;
|
2021-04-14 15:51:13 +00:00
|
|
|
const bool m_immutable;
|
2021-04-19 22:42:37 +00:00
|
|
|
bool m_legacy = false;
|
2021-09-16 11:53:31 +00:00
|
|
|
const DrmObject *m_obj;
|
2016-08-31 12:00:31 +00:00
|
|
|
};
|
2017-11-10 19:38:33 +00:00
|
|
|
|
2021-05-25 22:05:17 +00:00
|
|
|
template <typename T>
|
|
|
|
Property *getProp(T propIndex) const {
|
|
|
|
return m_props[static_cast<uint32_t>(propIndex)];
|
|
|
|
}
|
|
|
|
|
|
|
|
QVector<Property*> properties();
|
|
|
|
void commit();
|
|
|
|
void commitPending();
|
|
|
|
void rollbackPending();
|
|
|
|
|
|
|
|
bool needsCommit() const;
|
|
|
|
virtual bool needsModeset() const = 0;
|
|
|
|
|
2021-06-03 13:50:37 +00:00
|
|
|
virtual bool updateProperties();
|
|
|
|
|
2021-05-25 22:05:17 +00:00
|
|
|
protected:
|
2021-08-27 16:56:05 +00:00
|
|
|
enum class Requirement {
|
|
|
|
Required,
|
2021-09-16 12:03:10 +00:00
|
|
|
RequiredForLegacy,
|
|
|
|
Optional,
|
2021-08-27 16:56:05 +00:00
|
|
|
};
|
2021-05-25 22:05:17 +00:00
|
|
|
struct PropertyDefinition
|
|
|
|
{
|
2021-08-27 16:56:05 +00:00
|
|
|
PropertyDefinition(const QByteArray &name, Requirement requirement, const QVector<QByteArray> &&enumNames = {})
|
|
|
|
: name(name)
|
|
|
|
, requirement(requirement)
|
|
|
|
, enumNames(enumNames)
|
2021-05-25 22:05:17 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
QByteArray name;
|
2021-08-27 16:56:05 +00:00
|
|
|
Requirement requirement;
|
2021-05-25 22:05:17 +00:00
|
|
|
QVector<QByteArray> enumNames;
|
|
|
|
};
|
2021-06-03 13:50:37 +00:00
|
|
|
|
|
|
|
DrmObject(DrmGpu *gpu, uint32_t objectId, const QVector<PropertyDefinition> &&vector, uint32_t objectType);
|
|
|
|
|
|
|
|
bool initProps();
|
2021-05-25 22:05:17 +00:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void deleteProp(T prop)
|
|
|
|
{
|
|
|
|
delete m_props[static_cast<uint32_t>(prop)];
|
|
|
|
m_props[static_cast<uint32_t>(prop)] = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVector<Property *> m_props;
|
|
|
|
|
2017-11-10 19:38:33 +00:00
|
|
|
private:
|
2021-04-01 11:15:42 +00:00
|
|
|
DrmGpu *m_gpu;
|
2021-04-01 11:19:48 +00:00
|
|
|
const uint32_t m_id;
|
2021-06-03 13:50:37 +00:00
|
|
|
const uint32_t m_objectType;
|
|
|
|
const QVector<PropertyDefinition> m_propertyDefinitions;
|
2016-08-31 12:00:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-08-16 01:11:30 +00:00
|
|
|
QDebug operator<<(QDebug stream, const KWin::DrmObject*);
|