diff --git a/plugins/platforms/drm/drm_object.cpp b/plugins/platforms/drm/drm_object.cpp index d2b7bb0d9..1932bf76e 100644 --- a/plugins/platforms/drm/drm_object.cpp +++ b/plugins/platforms/drm/drm_object.cpp @@ -1,155 +1,156 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Roman Gilg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "drm_object.h" +#include "drm_pointer.h" #include "logging.h" namespace KWin { /* * Definitions for class DrmObject */ DrmObject::DrmObject(uint32_t object_id, int fd) : m_fd(fd) , m_id(object_id) { } DrmObject::~DrmObject() { foreach(Property* p, m_props) delete p; } void DrmObject::setPropertyNames(QVector &&vector) { m_propsNames = std::move(vector); m_props.fill(nullptr, m_propsNames.size()); } void DrmObject::initProp(int n, drmModeObjectProperties *properties, QVector enumNames) { for (unsigned int i = 0; i < properties->count_props; ++i) { - drmModePropertyRes *prop = drmModeGetProperty(fd(), properties->props[i]); + ScopedDrmPointer prop( + drmModeGetProperty(fd(), properties->props[i])); if (!prop) { continue; } if (prop->name == m_propsNames[n]) { qCDebug(KWIN_DRM).nospace() << m_id << ": " << prop->name << "' (id " << prop->prop_id << "): " << properties->prop_values[i]; - m_props[n] = new Property(prop, properties->prop_values[i], enumNames); + m_props[n] = new Property(prop.data(), properties->prop_values[i], enumNames); } - drmModeFreeProperty(prop); } } bool DrmObject::atomicAddProperty(drmModeAtomicReq *req, Property *property) { if (drmModeAtomicAddProperty(req, m_id, property->propId(), property->value()) <= 0) { qCWarning(KWIN_DRM) << "Adding property" << property->name() << "to atomic commit failed for object" << this; return false; } return true; } bool DrmObject::atomicPopulate(drmModeAtomicReq *req) { bool ret = true; for (int i = 0; i < m_props.size(); i++) { auto property = m_props.at(i); if (!property) { continue; } ret &= atomicAddProperty(req, property); } if (!ret) { qCWarning(KWIN_DRM) << "Failed to populate atomic plane" << m_id; return false; } return true; } /* * Definitions for struct Prop */ DrmObject::Property::Property(drmModePropertyRes *prop, uint64_t val, QVector enumNames) : m_propId(prop->prop_id) , m_propName(prop->name) , m_value(val) { if (!enumNames.isEmpty()) { qCDebug(KWIN_DRM) << m_propName << " has enums:" << enumNames; m_enumNames = enumNames; initEnumMap(prop); } } DrmObject::Property::~Property() = default; 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; } int nameCount = m_enumNames.size(); m_enumMap.resize(nameCount); qCDebug(KWIN_DRM).nospace() << "Test all " << prop->count_enums << " possible enums" <<":"; for (int i = 0; i < prop->count_enums; i++) { struct drm_mode_property_enum *en = &prop->enums[i]; int j = 0; while (QByteArray(en->name) != m_enumNames[j]) { j++; if (j == nameCount) { break; } } if (j == nameCount) { qCWarning(KWIN_DRM).nospace() << m_propName << " has unrecognized enum '" << en->name << "'"; } else { qCDebug(KWIN_DRM).nospace() << "Enum '" << en->name << "': runtime-value = " << en->value; m_enumMap[j] = en->value; } } if (KWIN_DRM().isDebugEnabled()) { for (int i = 0; i < m_enumMap.size(); i++) { if (m_value == m_enumMap[i]) { qCDebug(KWIN_DRM) << "=>" << m_propName << "with mapped enum value" << m_enumNames[i]; } } } } } diff --git a/plugins/platforms/drm/drm_object_connector.cpp b/plugins/platforms/drm/drm_object_connector.cpp index 30b6e584a..27acff431 100644 --- a/plugins/platforms/drm/drm_object_connector.cpp +++ b/plugins/platforms/drm/drm_object_connector.cpp @@ -1,80 +1,81 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Roman Gilg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "drm_object_connector.h" #include "drm_pointer.h" #include "logging.h" namespace KWin { DrmConnector::DrmConnector(uint32_t connector_id, int fd) : DrmObject(connector_id, fd) { ScopedDrmPointer<_drmModeConnector, &drmModeFreeConnector> con(drmModeGetConnector(fd, connector_id)); if (!con) { return; } for (int i = 0; i < con->count_encoders; ++i) { m_encoders << con->encoders[i]; } } DrmConnector::~DrmConnector() = default; bool DrmConnector::atomicInit() { qCDebug(KWIN_DRM) << "Creating connector" << m_id; if (!initProps()) { return false; } return true; } bool DrmConnector::initProps() { setPropertyNames( { QByteArrayLiteral("CRTC_ID"), }); - drmModeObjectProperties *properties = drmModeObjectGetProperties(fd(), m_id, DRM_MODE_OBJECT_CONNECTOR); + ScopedDrmPointer properties( + drmModeObjectGetProperties(fd(), m_id, DRM_MODE_OBJECT_CONNECTOR)); if (!properties) { qCWarning(KWIN_DRM) << "Failed to get properties for connector " << m_id ; return false; } int propCount = int(PropertyIndex::Count); for (int j = 0; j < propCount; ++j) { - initProp(j, properties); + initProp(j, properties.data()); } - drmModeFreeObjectProperties(properties); + return true; } bool DrmConnector::isConnected() { ScopedDrmPointer<_drmModeConnector, &drmModeFreeConnector> con(drmModeGetConnector(fd(), m_id)); if (!con) { return false; } return con->connection == DRM_MODE_CONNECTED; } } diff --git a/plugins/platforms/drm/drm_object_crtc.cpp b/plugins/platforms/drm/drm_object_crtc.cpp index 85f2e654e..341d80a07 100644 --- a/plugins/platforms/drm/drm_object_crtc.cpp +++ b/plugins/platforms/drm/drm_object_crtc.cpp @@ -1,121 +1,123 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Roman Gilg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "drm_object_crtc.h" #include "drm_backend.h" #include "drm_output.h" #include "drm_buffer.h" +#include "drm_pointer.h" #include "logging.h" #include namespace KWin { DrmCrtc::DrmCrtc(uint32_t crtc_id, DrmBackend *backend, int resIndex) : DrmObject(crtc_id, backend->fd()), m_resIndex(resIndex), m_backend(backend) { ScopedDrmPointer<_drmModeCrtc, &drmModeFreeCrtc> modeCrtc(drmModeGetCrtc(backend->fd(), crtc_id)); if (modeCrtc) { m_gammaRampSize = modeCrtc->gamma_size; } } DrmCrtc::~DrmCrtc() { } bool DrmCrtc::atomicInit() { qCDebug(KWIN_DRM) << "Atomic init for CRTC:" << resIndex() << "id:" << m_id; if (!initProps()) { return false; } return true; } bool DrmCrtc::initProps() { setPropertyNames({ QByteArrayLiteral("MODE_ID"), QByteArrayLiteral("ACTIVE"), }); - drmModeObjectProperties *properties = drmModeObjectGetProperties(fd(), m_id, DRM_MODE_OBJECT_CRTC); + ScopedDrmPointer properties( + drmModeObjectGetProperties(fd(), m_id, DRM_MODE_OBJECT_CRTC)); if (!properties) { qCWarning(KWIN_DRM) << "Failed to get properties for crtc " << m_id ; return false; } int propCount = int(PropertyIndex::Count); for (int j = 0; j < propCount; ++j) { - initProp(j, properties); + initProp(j, properties.data()); } - drmModeFreeObjectProperties(properties); + return true; } void DrmCrtc::flipBuffer() { if (m_currentBuffer && m_backend->deleteBufferAfterPageFlip() && m_currentBuffer != m_nextBuffer) { delete m_currentBuffer; } m_currentBuffer = m_nextBuffer; m_nextBuffer = nullptr; delete m_blackBuffer; m_blackBuffer = nullptr; } bool DrmCrtc::blank() { if (!m_output) { return false; } if (!m_blackBuffer) { DrmDumbBuffer *blackBuffer = m_backend->createBuffer(m_output->pixelSize()); if (!blackBuffer->map()) { delete blackBuffer; return false; } blackBuffer->image()->fill(Qt::black); m_blackBuffer = blackBuffer; } if (m_output->setModeLegacy(m_blackBuffer)) { if (m_currentBuffer && m_backend->deleteBufferAfterPageFlip()) { delete m_currentBuffer; delete m_nextBuffer; } m_currentBuffer = nullptr; m_nextBuffer = nullptr; return true; } return false; } bool DrmCrtc::setGammaRamp(const ColorCorrect::GammaRamp &gamma) { bool isError = drmModeCrtcSetGamma(m_backend->fd(), m_id, gamma.size, gamma.red, gamma.green, gamma.blue); return !isError; } } diff --git a/plugins/platforms/drm/drm_object_plane.cpp b/plugins/platforms/drm/drm_object_plane.cpp index 929d27d72..19d8abaa9 100644 --- a/plugins/platforms/drm/drm_object_plane.cpp +++ b/plugins/platforms/drm/drm_object_plane.cpp @@ -1,200 +1,200 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2016 Roman Gilg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "drm_object_plane.h" #include "drm_buffer.h" #include "drm_pointer.h" #include "logging.h" namespace KWin { DrmPlane::DrmPlane(uint32_t plane_id, int fd) : DrmObject(plane_id, fd) { } DrmPlane::~DrmPlane() { delete m_current; delete m_next; } bool DrmPlane::atomicInit() { qCDebug(KWIN_DRM) << "Atomic init for plane:" << m_id; ScopedDrmPointer<_drmModePlane, &drmModeFreePlane> p(drmModeGetPlane(fd(), m_id)); if (!p) { qCWarning(KWIN_DRM) << "Failed to get kernel plane" << m_id; return false; } m_possibleCrtcs = p->possible_crtcs; int count_formats = p->count_formats; m_formats.resize(count_formats); for (int i = 0; i < count_formats; i++) { m_formats[i] = p->formats[i]; } if (!initProps()) { return false; } return true; } bool DrmPlane::initProps() { setPropertyNames( { QByteArrayLiteral("type"), QByteArrayLiteral("SRC_X"), QByteArrayLiteral("SRC_Y"), QByteArrayLiteral("SRC_W"), QByteArrayLiteral("SRC_H"), QByteArrayLiteral("CRTC_X"), QByteArrayLiteral("CRTC_Y"), QByteArrayLiteral("CRTC_W"), QByteArrayLiteral("CRTC_H"), QByteArrayLiteral("FB_ID"), QByteArrayLiteral("CRTC_ID"), QByteArrayLiteral("rotation") }); QVector typeNames = { QByteArrayLiteral("Primary"), QByteArrayLiteral("Cursor"), QByteArrayLiteral("Overlay"), }; const QVector rotationNames{ QByteArrayLiteral("rotate-0"), QByteArrayLiteral("rotate-90"), QByteArrayLiteral("rotate-180"), QByteArrayLiteral("rotate-270"), QByteArrayLiteral("reflect-x"), QByteArrayLiteral("reflect-y") }; - drmModeObjectProperties *properties = drmModeObjectGetProperties(fd(), m_id, DRM_MODE_OBJECT_PLANE); + ScopedDrmPointer properties( + drmModeObjectGetProperties(fd(), m_id, DRM_MODE_OBJECT_PLANE)); if (!properties){ qCWarning(KWIN_DRM) << "Failed to get properties for plane " << m_id ; return false; } int propCount = int(PropertyIndex::Count); for (int j = 0; j < propCount; ++j) { if (j == int(PropertyIndex::Type)) { - initProp(j, properties, typeNames); + initProp(j, properties.data(), typeNames); } else if (j == int(PropertyIndex::Rotation)) { - initProp(j, properties, rotationNames); + initProp(j, properties.data(), rotationNames); m_supportedTransformations = Transformations(); auto testTransform = [j, this] (uint64_t value, Transformation t) { if (propHasEnum(j, value)) { m_supportedTransformations |= t; } }; testTransform(0, Transformation::Rotate0); testTransform(1, Transformation::Rotate90); testTransform(2, Transformation::Rotate180); testTransform(3, Transformation::Rotate270); testTransform(4, Transformation::ReflectX); testTransform(5, Transformation::ReflectY); qCDebug(KWIN_DRM) << "Supported Transformations: " << m_supportedTransformations << " on plane " << m_id; } else { - initProp(j, properties); + initProp(j, properties.data()); } } - drmModeFreeObjectProperties(properties); return true; } DrmPlane::TypeIndex DrmPlane::type() { auto property = m_props.at(int(PropertyIndex::Type)); if (!property) { return TypeIndex::Overlay; } int typeCount = int(TypeIndex::Count); for (int i = 0; i < typeCount; i++) { if (property->enumMap(i) == property->value()) { return TypeIndex(i); } } return TypeIndex::Overlay; } void DrmPlane::setNext(DrmBuffer *b) { if (auto property = m_props.at(int(PropertyIndex::FbId))) { property->setValue(b ? b->bufferId() : 0); } m_next = b; } void DrmPlane::setTransformation(Transformations t) { if (auto property = m_props.at(int(PropertyIndex::Rotation))) { property->setValue(int(t)); } } DrmPlane::Transformations DrmPlane::transformation() { if (auto property = m_props.at(int(PropertyIndex::Rotation))) { return Transformations(int(property->value())); } return Transformations(Transformation::Rotate0); } bool DrmPlane::atomicPopulate(drmModeAtomicReq *req) { bool ret = true; for (int i = 1; i < m_props.size(); i++) { auto property = m_props.at(i); if (!property) { continue; } ret &= atomicAddProperty(req, property); } if (!ret) { qCWarning(KWIN_DRM) << "Failed to populate atomic plane" << m_id; return false; } return true; } void DrmPlane::flipBuffer() { m_current = m_next; m_next = nullptr; } void DrmPlane::flipBufferWithDelete() { if (m_current != m_next) { delete m_current; } flipBuffer(); } }