backends/drm: fixes for bitmask drm properties
This commit is contained in:
parent
420358709a
commit
b5873ef792
7 changed files with 123 additions and 82 deletions
|
@ -32,7 +32,7 @@ bool DrmObject::initProps()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (KWIN_DRM().isDebugEnabled()) {
|
if (KWIN_DRM().isDebugEnabled()) {
|
||||||
auto debug = QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, KWIN_DRM().categoryName()).debug().nospace();
|
auto debug = QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, KWIN_DRM().categoryName()).debug().nospace().noquote();
|
||||||
switch (m_objectType) {
|
switch (m_objectType) {
|
||||||
case DRM_MODE_OBJECT_CONNECTOR:
|
case DRM_MODE_OBJECT_CONNECTOR:
|
||||||
debug << "Connector ";
|
debug << "Connector ";
|
||||||
|
@ -53,16 +53,7 @@ bool DrmObject::initProps()
|
||||||
}
|
}
|
||||||
const auto &prop = m_props[i];
|
const auto &prop = m_props[i];
|
||||||
if (prop) {
|
if (prop) {
|
||||||
debug << prop->name() << "=";
|
debug << prop->name() << "=" << prop->valueString(prop->current());
|
||||||
if (m_propertyDefinitions[i].enumNames.isEmpty()) {
|
|
||||||
debug << prop->current();
|
|
||||||
} else {
|
|
||||||
if (prop->hasEnum(prop->current())) {
|
|
||||||
debug << prop->enumNames().at(prop->enumForValue<uint32_t>(prop->current()));
|
|
||||||
} else {
|
|
||||||
debug << "invalid value: " << prop->current();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
debug << m_propertyDefinitions[i].name << " not found";
|
debug << m_propertyDefinitions[i].name << " not found";
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool propHasEnum(T prop, uint64_t value) const
|
|
||||||
{
|
|
||||||
const auto &property = m_props.at(static_cast<uint32_t>(prop));
|
|
||||||
return property ? property->hasEnum(value) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
DrmProperty *getProp(T propIndex) const
|
DrmProperty *getProp(T propIndex) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -266,9 +266,13 @@ void DrmPipeline::prepareAtomicModeset()
|
||||||
m_pending.crtc->setPending(DrmCrtc::PropertyIndex::ModeId, m_pending.mode->blobId());
|
m_pending.crtc->setPending(DrmCrtc::PropertyIndex::ModeId, m_pending.mode->blobId());
|
||||||
|
|
||||||
m_pending.crtc->primaryPlane()->setPending(DrmPlane::PropertyIndex::CrtcId, m_pending.crtc->id());
|
m_pending.crtc->primaryPlane()->setPending(DrmPlane::PropertyIndex::CrtcId, m_pending.crtc->id());
|
||||||
m_pending.crtc->primaryPlane()->setTransformation(m_pending.bufferOrientation);
|
if (const auto rotation = m_pending.crtc->primaryPlane()->getProp(DrmPlane::PropertyIndex::Rotation)) {
|
||||||
|
rotation->setEnum(m_pending.bufferOrientation);
|
||||||
|
}
|
||||||
if (m_pending.crtc->cursorPlane()) {
|
if (m_pending.crtc->cursorPlane()) {
|
||||||
m_pending.crtc->cursorPlane()->setTransformation(DrmPlane::Transformation::Rotate0);
|
if (const auto rotation = m_pending.crtc->cursorPlane()->getProp(DrmPlane::PropertyIndex::Rotation)) {
|
||||||
|
rotation->setEnum(DrmPlane::Transformation::Rotate0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +300,7 @@ void DrmPipeline::checkHardwareRotation()
|
||||||
if (m_pending.crtc && m_pending.crtc->primaryPlane()) {
|
if (m_pending.crtc && m_pending.crtc->primaryPlane()) {
|
||||||
const bool supported = (m_pending.bufferOrientation & m_pending.crtc->primaryPlane()->supportedTransformations());
|
const bool supported = (m_pending.bufferOrientation & m_pending.crtc->primaryPlane()->supportedTransformations());
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
m_pending.bufferOrientation = DrmPlane::Transformations(DrmPlane::Transformation::Rotate0);
|
m_pending.bufferOrientation = DrmPlane::Transformation::Rotate0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_pending.bufferOrientation = DrmPlane::Transformation::Rotate0;
|
m_pending.bufferOrientation = DrmPlane::Transformation::Rotate0;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
This file is part of the KDE project.
|
This file is part of the KDE project.
|
||||||
|
|
||||||
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
@ -53,18 +54,22 @@ bool DrmPlane::init()
|
||||||
|
|
||||||
bool success = initProps();
|
bool success = initProps();
|
||||||
if (success) {
|
if (success) {
|
||||||
m_supportedTransformations = Transformations();
|
if (const auto prop = getProp(PropertyIndex::Rotation)) {
|
||||||
auto checkSupport = [this](uint64_t value, Transformation t) {
|
m_supportedTransformations = Transformations();
|
||||||
if (propHasEnum(PropertyIndex::Rotation, value)) {
|
auto checkSupport = [this, prop](Transformation t) {
|
||||||
m_supportedTransformations |= t;
|
if (prop->hasEnum(t)) {
|
||||||
}
|
m_supportedTransformations |= t;
|
||||||
};
|
}
|
||||||
checkSupport(0, Transformation::Rotate0);
|
};
|
||||||
checkSupport(1, Transformation::Rotate90);
|
checkSupport(Transformation::Rotate0);
|
||||||
checkSupport(2, Transformation::Rotate180);
|
checkSupport(Transformation::Rotate90);
|
||||||
checkSupport(3, Transformation::Rotate270);
|
checkSupport(Transformation::Rotate180);
|
||||||
checkSupport(4, Transformation::ReflectX);
|
checkSupport(Transformation::Rotate270);
|
||||||
checkSupport(5, Transformation::ReflectY);
|
checkSupport(Transformation::ReflectX);
|
||||||
|
checkSupport(Transformation::ReflectY);
|
||||||
|
} else {
|
||||||
|
m_supportedTransformations = Transformation::Rotate0;
|
||||||
|
}
|
||||||
|
|
||||||
// read formats from blob if available and if modifiers are supported, and from the plane object if not
|
// read formats from blob if available and if modifiers are supported, and from the plane object if not
|
||||||
if (const auto formatProp = getProp(PropertyIndex::In_Formats); formatProp && formatProp->immutableBlob() && gpu()->addFB2ModifiersSupported()) {
|
if (const auto formatProp = getProp(PropertyIndex::In_Formats); formatProp && formatProp->immutableBlob() && gpu()->addFB2ModifiersSupported()) {
|
||||||
|
@ -96,15 +101,6 @@ void DrmPlane::setNext(const std::shared_ptr<DrmFramebuffer> &b)
|
||||||
m_next = b;
|
m_next = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DrmPlane::setTransformation(Transformations t)
|
|
||||||
{
|
|
||||||
if (m_supportedTransformations & t) {
|
|
||||||
return setPending(PropertyIndex::Rotation, t);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DrmPlane::Transformations DrmPlane::transformation()
|
DrmPlane::Transformations DrmPlane::transformation()
|
||||||
{
|
{
|
||||||
if (auto property = getProp(PropertyIndex::Rotation)) {
|
if (auto property = getProp(PropertyIndex::Rotation)) {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
This file is part of the KDE project.
|
This file is part of the KDE project.
|
||||||
|
|
||||||
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
@ -81,7 +82,6 @@ public:
|
||||||
void setBuffer(DrmFramebuffer *buffer);
|
void setBuffer(DrmFramebuffer *buffer);
|
||||||
void set(const QPoint &srcPos, const QSize &srcSize, const QPoint &dstPos, const QSize &dstSize);
|
void set(const QPoint &srcPos, const QSize &srcSize, const QPoint &dstPos, const QSize &dstSize);
|
||||||
|
|
||||||
bool setTransformation(Transformations t);
|
|
||||||
Transformations transformation();
|
Transformations transformation();
|
||||||
Transformations supportedTransformations() const;
|
Transformations supportedTransformations() const;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This file is part of the KDE project.
|
This file is part of the KDE project.
|
||||||
|
|
||||||
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
||||||
SPDX-FileCopyrightText: 2021 Xaver Hugl <xaver.hugl@gmail.com>
|
SPDX-FileCopyrightText: 2021-2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,7 @@ DrmProperty::DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val,
|
||||||
, m_current(val)
|
, m_current(val)
|
||||||
, m_immutable(prop->flags & DRM_MODE_PROP_IMMUTABLE)
|
, m_immutable(prop->flags & DRM_MODE_PROP_IMMUTABLE)
|
||||||
, m_isBlob(prop->flags & DRM_MODE_PROP_BLOB)
|
, m_isBlob(prop->flags & DRM_MODE_PROP_BLOB)
|
||||||
|
, m_isBitmask(prop->flags & DRM_MODE_PROP_BITMASK)
|
||||||
, m_obj(obj)
|
, m_obj(obj)
|
||||||
{
|
{
|
||||||
if (!enumNames.isEmpty()) {
|
if (!enumNames.isEmpty()) {
|
||||||
|
@ -39,8 +40,6 @@ DrmProperty::DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val,
|
||||||
updateBlob();
|
updateBlob();
|
||||||
}
|
}
|
||||||
|
|
||||||
DrmProperty::~DrmProperty() = default;
|
|
||||||
|
|
||||||
void DrmProperty::commit()
|
void DrmProperty::commit()
|
||||||
{
|
{
|
||||||
if (m_immutable || m_current == m_pending) {
|
if (m_immutable || m_current == m_pending) {
|
||||||
|
@ -77,18 +76,17 @@ bool DrmProperty::setPropertyLegacy(uint64_t value)
|
||||||
|
|
||||||
void DrmProperty::initEnumMap(drmModePropertyRes *prop)
|
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++) {
|
for (int i = 0; i < prop->count_enums; i++) {
|
||||||
struct drm_mode_property_enum *en = &prop->enums[i];
|
struct drm_mode_property_enum *en = &prop->enums[i];
|
||||||
int j = m_enumNames.indexOf(QByteArray(en->name));
|
int j = m_enumNames.indexOf(QByteArray(en->name));
|
||||||
if (j >= 0) {
|
if (j >= 0) {
|
||||||
m_enumMap[j] = en->value;
|
if (m_isBitmask) {
|
||||||
|
m_enumToPropertyMap[1 << j] = 1 << en->value;
|
||||||
|
m_propertyToEnumMap[1 << en->value] = 1 << j;
|
||||||
|
} else {
|
||||||
|
m_enumToPropertyMap[j] = en->value;
|
||||||
|
m_propertyToEnumMap[en->value] = j;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(KWIN_DRM, "%s has unrecognized enum '%s'", qPrintable(m_propName), en->name);
|
qCWarning(KWIN_DRM, "%s has unrecognized enum '%s'", qPrintable(m_propName), en->name);
|
||||||
}
|
}
|
||||||
|
@ -121,19 +119,9 @@ uint64_t DrmProperty::current() const
|
||||||
return m_current;
|
return m_current;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QByteArray> DrmProperty::enumNames() const
|
|
||||||
{
|
|
||||||
return m_enumNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DrmProperty::hasEnum(uint64_t value) const
|
|
||||||
{
|
|
||||||
return m_enumMap.contains(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DrmProperty::hasAllEnums() const
|
bool DrmProperty::hasAllEnums() const
|
||||||
{
|
{
|
||||||
return m_enumMap.count() == m_enumNames.count();
|
return m_enumToPropertyMap.count() == m_enumNames.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DrmProperty::propId() const
|
uint32_t DrmProperty::propId() const
|
||||||
|
@ -151,6 +139,11 @@ bool DrmProperty::isImmutable() const
|
||||||
return m_immutable;
|
return m_immutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DrmProperty::isBitmask() const
|
||||||
|
{
|
||||||
|
return m_isBitmask;
|
||||||
|
}
|
||||||
|
|
||||||
bool DrmProperty::isLegacy() const
|
bool DrmProperty::isLegacy() const
|
||||||
{
|
{
|
||||||
return m_legacy;
|
return m_legacy;
|
||||||
|
@ -189,4 +182,43 @@ drmModePropertyBlobRes *DrmProperty::immutableBlob() const
|
||||||
{
|
{
|
||||||
return m_immutableBlob.get();
|
return m_immutableBlob.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DrmProperty::valueString(uint64_t value) const
|
||||||
|
{
|
||||||
|
if (m_isBitmask) {
|
||||||
|
QString ret;
|
||||||
|
bool first = true;
|
||||||
|
for (uint64_t mask = 1; mask >= value && mask != 0; mask <<= 1) {
|
||||||
|
if (value & mask) {
|
||||||
|
if (!first) {
|
||||||
|
ret += " | ";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
uint64_t enumValue = enumForValue<uint64_t>(mask);
|
||||||
|
int enumIndex = 0;
|
||||||
|
while (!(enumValue & (1ull << enumIndex)) && enumIndex < 64) {
|
||||||
|
enumIndex++;
|
||||||
|
}
|
||||||
|
if (enumIndex < m_enumNames.size()) {
|
||||||
|
ret += m_enumNames[enumIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} else if (!m_enumNames.isEmpty()) {
|
||||||
|
if (const uint64_t index = enumForValue<uint64_t>(value); index < (uint)m_enumNames.size()) {
|
||||||
|
return m_enumNames[index];
|
||||||
|
} else {
|
||||||
|
return QStringLiteral("invalid value: %d").arg(value);
|
||||||
|
}
|
||||||
|
} else if (m_propName == QStringLiteral("SRC_X") || m_propName == QStringLiteral("SRC_Y") || m_propName == QStringLiteral("SRC_W") || m_propName == QStringLiteral("SRC_H")) {
|
||||||
|
QString ret;
|
||||||
|
ret.setNum(value / (float)(1ul << 16));
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
QString ret;
|
||||||
|
ret.setNum(value);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
This file is part of the KDE project.
|
This file is part of the KDE project.
|
||||||
|
|
||||||
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
SPDX-FileCopyrightText: 2016 Roman Gilg <subdiff@gmail.com>
|
||||||
SPDX-FileCopyrightText: 2021 Xaver Hugl <xaver.hugl@gmail.com>
|
SPDX-FileCopyrightText: 2021-2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "drm_pointer.h"
|
#include "drm_pointer.h"
|
||||||
|
#include "drm_logging.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
@ -26,31 +27,50 @@ class DrmProperty
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector<QByteArray> &enumNames);
|
DrmProperty(DrmObject *obj, drmModePropertyRes *prop, uint64_t val, const QVector<QByteArray> &enumNames);
|
||||||
virtual ~DrmProperty();
|
|
||||||
|
|
||||||
void initEnumMap(drmModePropertyRes *prop);
|
|
||||||
|
|
||||||
QVector<QByteArray> enumNames() const;
|
|
||||||
bool hasEnum(uint64_t value) const;
|
|
||||||
bool hasAllEnums() const;
|
bool hasAllEnums() const;
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
bool hasEnum(Enum value) const
|
||||||
|
{
|
||||||
|
return m_enumToPropertyMap.contains(static_cast<uint64_t>(value));
|
||||||
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T enumForValue(uint64_t value) const
|
T enumForValue(uint64_t value) const
|
||||||
{
|
{
|
||||||
return static_cast<T>(m_enumMap[value]);
|
if (m_isBitmask) {
|
||||||
}
|
uint64_t ret = 0;
|
||||||
template<typename T>
|
for (uint64_t mask = 1; value >= mask && mask != 0; mask <<= 1) {
|
||||||
bool setEnum(T index)
|
if (value & mask) {
|
||||||
{
|
ret |= m_propertyToEnumMap[mask];
|
||||||
if (hasEnum(static_cast<uint64_t>(index))) {
|
}
|
||||||
setPending(m_enumMap[static_cast<uint32_t>(index)]);
|
}
|
||||||
return true;
|
return static_cast<T>(ret);
|
||||||
|
} else {
|
||||||
|
return static_cast<T>(m_propertyToEnumMap[value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename Enum>
|
||||||
|
void setEnum(Enum value)
|
||||||
|
{
|
||||||
|
const uint64_t integer = static_cast<uint64_t>(value);
|
||||||
|
if (m_isBitmask) {
|
||||||
|
uint64_t set = 0;
|
||||||
|
for (uint64_t mask = 1; integer >= mask && mask != 0; mask <<= 1) {
|
||||||
|
if (integer & mask) {
|
||||||
|
set |= m_enumToPropertyMap[mask];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setPending(set);
|
||||||
|
} else {
|
||||||
|
setPending(m_enumToPropertyMap[integer]);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t propId() const;
|
uint32_t propId() const;
|
||||||
const QByteArray &name() const;
|
const QByteArray &name() const;
|
||||||
bool isImmutable() const;
|
bool isImmutable() const;
|
||||||
|
bool isBitmask() const;
|
||||||
bool isLegacy() const;
|
bool isLegacy() const;
|
||||||
/**
|
/**
|
||||||
* Makes this property be ignored by DrmObject::atomicPopulate
|
* Makes this property be ignored by DrmObject::atomicPopulate
|
||||||
|
@ -77,12 +97,15 @@ public:
|
||||||
bool setEnumLegacy(T value)
|
bool setEnumLegacy(T value)
|
||||||
{
|
{
|
||||||
if (hasEnum(static_cast<uint64_t>(value))) {
|
if (hasEnum(static_cast<uint64_t>(value))) {
|
||||||
return setPropertyLegacy(m_enumMap[static_cast<uint32_t>(value)]);
|
return setPropertyLegacy(m_enumToPropertyMap[static_cast<uint32_t>(value)]);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString valueString(uint64_t value) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initEnumMap(drmModePropertyRes *prop);
|
||||||
void updateBlob();
|
void updateBlob();
|
||||||
|
|
||||||
uint32_t m_propId = 0;
|
uint32_t m_propId = 0;
|
||||||
|
@ -101,10 +124,12 @@ private:
|
||||||
uint64_t m_minValue = -1;
|
uint64_t m_minValue = -1;
|
||||||
uint64_t m_maxValue = -1;
|
uint64_t m_maxValue = -1;
|
||||||
|
|
||||||
QMap<uint32_t, uint64_t> m_enumMap;
|
QMap<uint64_t, uint64_t> m_enumToPropertyMap;
|
||||||
|
QMap<uint64_t, uint64_t> m_propertyToEnumMap;
|
||||||
QVector<QByteArray> m_enumNames;
|
QVector<QByteArray> m_enumNames;
|
||||||
const bool m_immutable;
|
const bool m_immutable;
|
||||||
const bool m_isBlob;
|
const bool m_isBlob;
|
||||||
|
const bool m_isBitmask;
|
||||||
bool m_legacy = false;
|
bool m_legacy = false;
|
||||||
const DrmObject *m_obj;
|
const DrmObject *m_obj;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue