| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #ifndef MYTHDRMFRAMEBUFFER_H | ||
| #define MYTHDRMFRAMEBUFFER_H | ||
|
|
||
| // MythTV | ||
| #include "platforms/drm/mythdrmresources.h" | ||
|
|
||
| using DRMFb = std::shared_ptr<class MythDRMFramebuffer>; | ||
| using DRMFbs = std::vector<DRMFb>; | ||
|
|
||
| class MythDRMFramebuffer | ||
| { | ||
| public: | ||
| DRMFb Create(int FD, uint32_t Id); | ||
|
|
||
| uint32_t m_id { 0 }; | ||
| uint32_t m_width { 0 }; | ||
| uint32_t m_height { 0 }; | ||
| uint32_t m_format { 0 }; | ||
| uint64_t m_modifiers { 0 }; | ||
| DRMArray m_handles { 0 }; | ||
| DRMArray m_pitches { 0 }; | ||
| DRMArray m_offsets { 0 }; | ||
|
|
||
| protected: | ||
| MythDRMFramebuffer(int FD, uint32_t Id); | ||
|
|
||
| private: | ||
| Q_DISABLE_COPY(MythDRMFramebuffer) | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // MythTV | ||
| #include "platforms/drm/mythdrmmode.h" | ||
|
|
||
| /*! \class MythDRMMode | ||
| * \brief A simple object representing a DRM video mode. | ||
| */ | ||
| DRMMode MythDRMMode::Create(drmModeModeInfoPtr Mode, int Index) | ||
| { | ||
| if (auto mode = std::shared_ptr<MythDRMMode>(new MythDRMMode(Mode, Index)); mode && mode->m_rate > 1.0) | ||
| return mode; | ||
| return nullptr; | ||
| } | ||
|
|
||
| MythDRMMode::MythDRMMode(drmModeModeInfoPtr Mode, int Index) | ||
| { | ||
| if (Mode) | ||
| { | ||
| m_index = Index; | ||
| m_rate = (Mode->clock * 1000.0) / (Mode->htotal * Mode->vtotal); | ||
| m_width = Mode->hdisplay; | ||
| m_height = Mode->vdisplay; | ||
| m_flags = Mode->flags; | ||
| m_name = Mode->name; | ||
| if (Mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| m_rate *= 2.0; | ||
| if (Mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
| m_rate /= 2.0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #ifndef MYTHDRMMODE_H | ||
| #define MYTHDRMMODE_H | ||
|
|
||
| // MythTV | ||
| #include "platforms/drm/mythdrmresources.h" | ||
|
|
||
| using DRMMode = std::shared_ptr<class MythDRMMode>; | ||
| using DRMModes = std::vector<DRMMode>; | ||
|
|
||
| class MUI_PUBLIC MythDRMMode | ||
| { | ||
| public: | ||
| static DRMMode Create(drmModeModeInfoPtr Mode, int Index); | ||
|
|
||
| int m_index { 0 }; | ||
| double m_rate { 0.0 }; | ||
| uint16_t m_width { 0 }; | ||
| uint16_t m_height { 0 }; | ||
| uint32_t m_flags { 0 }; | ||
| QString m_name; | ||
|
|
||
| protected: | ||
| explicit MythDRMMode(drmModeModeInfoPtr Mode, int Index); | ||
|
|
||
| private: | ||
| Q_DISABLE_COPY(MythDRMMode) | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| // MythTV | ||
| #include "mythlogging.h" | ||
| #include "platforms/drm/mythdrmplane.h" | ||
|
|
||
| // libdrm | ||
| extern "C" { | ||
| #include <drm_fourcc.h> | ||
| } | ||
|
|
||
| #define LOC QString("DRMPlane: ") | ||
|
|
||
| /*! \class MythDRMPlane | ||
| * \brief A wrapper around a DRM plane object. | ||
| * | ||
| * The full list of available planes can be retrieved with GetPlanes. | ||
| */ | ||
| QString MythDRMPlane::PlaneTypeToString(uint64_t Type) | ||
| { | ||
| if (Type == DRM_PLANE_TYPE_OVERLAY) return "Overlay"; | ||
| if (Type == DRM_PLANE_TYPE_CURSOR) return "Cursor"; | ||
| if (Type == DRM_PLANE_TYPE_PRIMARY) return "Primary"; | ||
| return "Unknown"; | ||
| } | ||
|
|
||
| DRMPlane MythDRMPlane::Create(int FD, uint32_t Id, uint32_t Index) | ||
| { | ||
| if (FD && Id) | ||
| if (auto plane = std::shared_ptr<MythDRMPlane>(new MythDRMPlane(FD, Id, Index)); plane && plane->m_id) | ||
| return plane; | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| MythDRMPlane::MythDRMPlane(int FD, uint32_t Id, uint32_t Index) | ||
| { | ||
| if (auto plane = drmModeGetPlane(FD, Id); plane) | ||
| { | ||
| auto id = plane->plane_id; | ||
| m_index = Index; | ||
| m_id = id; | ||
| m_fbId = plane->fb_id; | ||
| m_crtcId = plane->crtc_id; | ||
| m_possibleCrtcs = plane->possible_crtcs; | ||
|
|
||
| for (uint32_t j = 0; j < plane->count_formats; ++j) | ||
| { | ||
| m_formats.emplace_back(plane->formats[j]); | ||
| if (FormatIsVideo(plane->formats[j])) | ||
| m_videoFormats.emplace_back(plane->formats[j]); | ||
| } | ||
|
|
||
| m_properties = MythDRMProperty::GetProperties(FD, m_id, DRM_MODE_OBJECT_PLANE); | ||
|
|
||
| // Add generic properties | ||
| if (auto type = MythDRMProperty::GetProperty("type", m_properties); type) | ||
| if (auto enumt = dynamic_cast<MythDRMEnumProperty*>(type.get()); enumt) | ||
| m_type = enumt->m_value; | ||
|
|
||
| // Add video specific properties | ||
| if (!m_videoFormats.empty()) | ||
| { | ||
| m_fbIdProp = MythDRMProperty::GetProperty("FB_ID", m_properties); | ||
| m_crtcIdProp = MythDRMProperty::GetProperty("CRTC_ID", m_properties); | ||
| m_srcXProp = MythDRMProperty::GetProperty("SRC_X", m_properties); | ||
| m_srcYProp = MythDRMProperty::GetProperty("SRC_Y", m_properties); | ||
| m_srcWProp = MythDRMProperty::GetProperty("SRC_W", m_properties); | ||
| m_srcHProp = MythDRMProperty::GetProperty("SRC_H", m_properties); | ||
| m_crtcXProp = MythDRMProperty::GetProperty("CRTC_X", m_properties); | ||
| m_crtcYProp = MythDRMProperty::GetProperty("CRTC_Y", m_properties); | ||
| m_crtcWProp = MythDRMProperty::GetProperty("CRTC_W", m_properties); | ||
| m_crtcHProp = MythDRMProperty::GetProperty("CRTC_H", m_properties); | ||
| } | ||
|
|
||
| drmModeFreePlane(plane); | ||
| } | ||
| } | ||
|
|
||
| DRMPlanes MythDRMPlane::GetPlanes(int FD, int CRTCFilter) | ||
| { | ||
| DRMPlanes result; | ||
| auto planes = drmModeGetPlaneResources(FD); | ||
| if (!planes) | ||
| { | ||
| LOG(VB_GENERAL, LOG_ERR, QString(drmGetDeviceNameFromFd2(FD)) + ": Failed to retrieve planes"); | ||
| return result; | ||
| } | ||
|
|
||
| for (uint32_t index = 0; index < planes->count_planes; ++index) | ||
| { | ||
| if (auto plane = MythDRMPlane::Create(FD, planes->planes[index], index); plane) | ||
| { | ||
| if ((CRTCFilter > -1) && !(plane->m_possibleCrtcs & (1 << CRTCFilter))) | ||
| continue; | ||
| result.emplace_back(plane); | ||
| } | ||
| } | ||
|
|
||
| drmModeFreePlaneResources(planes); | ||
| return result; | ||
| } | ||
|
|
||
| DRMPlanes MythDRMPlane::FilterPrimaryPlanes(const DRMPlanes &Planes) | ||
| { | ||
| DRMPlanes result; | ||
| for (const auto & plane : Planes) | ||
| if ((plane->m_type == DRM_PLANE_TYPE_PRIMARY) && !plane->m_videoFormats.empty()) | ||
| result.emplace_back(plane); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| DRMPlanes MythDRMPlane::FilterOverlayPlanes(const DRMPlanes &Planes) | ||
| { | ||
| DRMPlanes result; | ||
| for (const auto & plane : Planes) | ||
| if ((plane->m_type == DRM_PLANE_TYPE_OVERLAY) && HasOverlayFormat(plane->m_formats)) | ||
| result.emplace_back(plane); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| QString MythDRMPlane::FormatToString(uint32_t Format) | ||
| { | ||
| switch (Format) | ||
| { | ||
| // Note: These match the string literals in QKmsDevice config parsing (but | ||
| // must be used lower case in the KMS config file) | ||
| case DRM_FORMAT_RGB565: return "RGB565"; | ||
| case DRM_FORMAT_XRGB8888: return "XRGB8888"; | ||
| case DRM_FORMAT_XBGR8888: return "XBGR8888"; | ||
| case DRM_FORMAT_ARGB8888: return "ARGB8888"; | ||
| case DRM_FORMAT_RGBA8888: return "RGBA8888"; | ||
| case DRM_FORMAT_ABGR8888: return "ABGR8888"; | ||
| case DRM_FORMAT_BGRA8888: return "BGRA8888"; | ||
| case DRM_FORMAT_XRGB2101010: return "XRGB2101010"; | ||
| case DRM_FORMAT_XBGR2101010: return "XBGR2101010"; | ||
| case DRM_FORMAT_ARGB2101010: return "ARGB2101010"; | ||
| case DRM_FORMAT_ABGR2101010: return "ABGR2101010"; | ||
| // Not supported by Qt as overlay formats | ||
| case DRM_FORMAT_XRGB16161616F: return "XRGB16F"; | ||
| case DRM_FORMAT_XBGR16161616F: return "XBGR16F"; | ||
| case DRM_FORMAT_ARGB16161616F: return "ARGB16F"; | ||
| case DRM_FORMAT_ABGR16161616F: return "ABGR16F"; | ||
| default: break; | ||
| } | ||
| return QString::asprintf("%c%c%c%c", Format, Format >> 8, Format >> 16, Format >> 24); | ||
| } | ||
|
|
||
| QString MythDRMPlane::FormatsToString(FOURCCVec Formats) | ||
| { | ||
| QStringList formats; | ||
| for (auto format : Formats) | ||
| formats.append(FormatToString(format)); | ||
| return formats.join(","); | ||
| } | ||
|
|
||
| bool MythDRMPlane::FormatIsVideo(uint32_t Format) | ||
| { | ||
| static const FOURCCVec s_yuvFormats = | ||
| { | ||
| // Bi-planar | ||
| DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_NV16, DRM_FORMAT_NV61, | ||
| DRM_FORMAT_NV24, DRM_FORMAT_NV42, DRM_FORMAT_P210, DRM_FORMAT_P010, | ||
| DRM_FORMAT_P012, DRM_FORMAT_P016, DRM_FORMAT_P030, DRM_FORMAT_NV15, | ||
| DRM_FORMAT_NV20, | ||
| // Tri-planar formats | ||
| DRM_FORMAT_YUV410, DRM_FORMAT_YVU410, DRM_FORMAT_YUV411, DRM_FORMAT_YVU411, | ||
| DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422, DRM_FORMAT_YVU422, | ||
| DRM_FORMAT_YUV444, DRM_FORMAT_YVU444, | ||
| // Packed formats | ||
| DRM_FORMAT_YUYV, DRM_FORMAT_YVYU, DRM_FORMAT_UYVY, DRM_FORMAT_VYUY | ||
| }; | ||
|
|
||
| return std::find(s_yuvFormats.cbegin(), s_yuvFormats.cend(), Format) != s_yuvFormats.cend(); | ||
| } | ||
|
|
||
| /*! \brief Enusure list of supplied formats contains a format that is suitable for OpenGL/Vulkan. | ||
| */ | ||
| bool MythDRMPlane::HasOverlayFormat(FOURCCVec Formats) | ||
| { | ||
| // Formats as deemed suitable by QKmsDevice | ||
| static const FOURCCVec s_rgbFormats = | ||
| { | ||
| DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888, | ||
| DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888, DRM_FORMAT_RGB565, | ||
| DRM_FORMAT_BGR565, DRM_FORMAT_XRGB2101010, DRM_FORMAT_XBGR2101010, | ||
| DRM_FORMAT_ARGB2101010, DRM_FORMAT_ABGR2101010 | ||
| }; | ||
|
|
||
| for (auto format : Formats) | ||
| if (std::any_of(s_rgbFormats.cbegin(), s_rgbFormats.cend(), [&format](auto Format) { return Format == format; })) | ||
| return true; | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| uint32_t MythDRMPlane::GetAlphaFormat(FOURCCVec Formats) | ||
| { | ||
| // N.B. Prioritised list | ||
| static const FOURCCVec s_alphaFormats = | ||
| { | ||
| DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, DRM_FORMAT_ABGR2101010 | ||
| }; | ||
|
|
||
| for (auto format : s_alphaFormats) | ||
| if (std::any_of(Formats.cbegin(), Formats.cend(), [&format](auto Format) { return Format == format; })) | ||
| return format; | ||
|
|
||
| return DRM_FORMAT_INVALID; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| #ifndef MYTHDRMPLANE_H | ||
| #define MYTHDRMPLANE_H | ||
|
|
||
| // MythTV | ||
| #include "platforms/drm/mythdrmproperty.h" | ||
|
|
||
| #ifndef DRM_FORMAT_NV15 | ||
| #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') | ||
| #endif | ||
|
|
||
| #ifndef DRM_FORMAT_NV20 | ||
| #define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') | ||
| #endif | ||
|
|
||
| #ifndef DRM_FORMAT_P030 | ||
| #define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0') | ||
| #endif | ||
|
|
||
| using FOURCCVec = std::vector<uint32_t>; | ||
| using DRMPlane = std::shared_ptr<class MythDRMPlane>; | ||
| using DRMPlanes = std::vector<DRMPlane>; | ||
|
|
||
| class MUI_PUBLIC MythDRMPlane | ||
| { | ||
| public: | ||
| static DRMPlane Create(int FD, uint32_t Id, uint32_t Index); | ||
| static DRMPlanes GetPlanes(int FD, int CRTCFilter = -1); | ||
|
|
||
| static QString PlaneTypeToString (uint64_t Type); | ||
| static DRMPlanes FilterPrimaryPlanes (const DRMPlanes& Planes); | ||
| static DRMPlanes FilterOverlayPlanes (const DRMPlanes& Planes); | ||
| static QString FormatToString (uint32_t Format); | ||
| static QString FormatsToString (FOURCCVec Formats); | ||
| static bool FormatIsVideo (uint32_t Format); | ||
| static bool HasOverlayFormat (FOURCCVec Formats); | ||
| static uint32_t GetAlphaFormat (FOURCCVec Formats); | ||
|
|
||
| uint32_t m_id { 0 }; | ||
| uint32_t m_index { 0 }; | ||
| uint64_t m_type { DRM_PLANE_TYPE_PRIMARY }; | ||
| uint32_t m_possibleCrtcs { 0 }; | ||
| uint32_t m_fbId { 0 }; | ||
| uint32_t m_crtcId { 0 }; | ||
| DRMProps m_properties; | ||
|
|
||
| DRMProp m_fbIdProp { nullptr }; | ||
| DRMProp m_crtcIdProp { nullptr }; | ||
| DRMProp m_srcXProp { nullptr }; | ||
| DRMProp m_srcYProp { nullptr }; | ||
| DRMProp m_srcWProp { nullptr }; | ||
| DRMProp m_srcHProp { nullptr }; | ||
| DRMProp m_crtcXProp { nullptr }; | ||
| DRMProp m_crtcYProp { nullptr }; | ||
| DRMProp m_crtcWProp { nullptr }; | ||
| DRMProp m_crtcHProp { nullptr }; | ||
|
|
||
| FOURCCVec m_formats; | ||
| FOURCCVec m_videoFormats; | ||
|
|
||
| protected: | ||
| MythDRMPlane(int FD, uint32_t Id, uint32_t Index); | ||
|
|
||
| private: | ||
| Q_DISABLE_COPY(MythDRMPlane) | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| // MythTV | ||
| #include "platforms/drm/mythdrmproperty.h" | ||
|
|
||
| // Qt | ||
| #include <QStringList> | ||
|
|
||
| /*! \class MythDRMProperty | ||
| * \brief A wrapper around a DRM object property. | ||
| * | ||
| * Retrieve a list of the properties available for an object with GetProperties | ||
| * and retrieve a single, named property from a given list with GetProperty. | ||
| * | ||
| * \note Property values represent the initial property state and will not reflect | ||
| * subsequent changes unless explicitly updated. | ||
| */ | ||
| MythDRMProperty::MythDRMProperty(Type mType, uint32_t Id, uint32_t Flags, const char * Name) | ||
| : m_type(mType), | ||
| m_id(Id), | ||
| m_readOnly(Flags & DRM_MODE_PROP_IMMUTABLE), | ||
| m_name(Name) | ||
| { | ||
| } | ||
|
|
||
| DRMProps MythDRMProperty::GetProperties(int FD, const uint32_t ObjectId, uint32_t ObjectType) | ||
| { | ||
| DRMProps result; | ||
| if (auto props = drmModeObjectGetProperties(FD, ObjectId, ObjectType); props) | ||
| { | ||
| for (uint32_t index = 0; index < props->count_props; ++index) | ||
| { | ||
| if (auto prop = drmModeGetProperty(FD, props->props[index]); prop) | ||
| { | ||
| auto key = QString(prop->name); | ||
| auto value = props->prop_values[index]; | ||
| if (prop->flags & DRM_MODE_PROP_RANGE) | ||
| result.emplace_back(std::shared_ptr<MythDRMProperty>(new MythDRMRangeProperty(value, prop))); | ||
| else if (prop->flags & DRM_MODE_PROP_ENUM) | ||
| result.emplace_back(std::shared_ptr<MythDRMProperty>(new MythDRMEnumProperty(value, prop))); | ||
| else if (prop->flags & DRM_MODE_PROP_BITMASK) | ||
| result.emplace_back(std::shared_ptr<MythDRMProperty>(new MythDRMBitmaskProperty(value, prop))); | ||
| else if (prop->flags & DRM_MODE_PROP_BLOB) | ||
| result.emplace_back(std::shared_ptr<MythDRMProperty>(new MythDRMBlobProperty(FD, value, prop))); | ||
| else if (prop->flags & DRM_MODE_PROP_OBJECT) | ||
| result.emplace_back(std::shared_ptr<MythDRMProperty>(new MythDRMObjectProperty(prop))); | ||
| else if (prop->flags & DRM_MODE_PROP_SIGNED_RANGE) | ||
| result.emplace_back(std::shared_ptr<MythDRMProperty>(new MythDRMSignedRangeProperty(value, prop))); | ||
| drmModeFreeProperty(prop); | ||
| } | ||
| } | ||
| drmModeFreeObjectProperties(props); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| DRMProp MythDRMProperty::GetProperty(const QString& Name, const DRMProps &Properties) | ||
| { | ||
| for (const auto & prop : Properties) | ||
| if (Name.compare(prop->m_name, Qt::CaseInsensitive) == 0) | ||
| return prop; | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| MythDRMRangeProperty::MythDRMRangeProperty(uint64_t Value, drmModePropertyPtr Property) | ||
| : MythDRMProperty(Range, Property->prop_id, Property->flags, Property->name), | ||
| m_value(Value) | ||
| { | ||
| for (int i = 0; i < Property->count_values; ++i) | ||
| { | ||
| auto value = Property->values[i]; | ||
| if (value < m_min) | ||
| m_min = value; | ||
| if (value > m_max) | ||
| m_max = value; | ||
| } | ||
| } | ||
|
|
||
| QString MythDRMRangeProperty::ToString() | ||
| { | ||
| return QString("%1 Value: %2 Range: %3<->%4").arg(m_name).arg(m_value).arg(m_min).arg(m_max); | ||
| } | ||
|
|
||
| MythDRMSignedRangeProperty::MythDRMSignedRangeProperty(uint64_t Value, drmModePropertyPtr Property) | ||
| : MythDRMProperty(SignedRange, Property->prop_id, Property->flags, Property->name), | ||
| m_value(static_cast<int64_t>(Value)) | ||
| { | ||
| for (int i = 0; i < Property->count_values; ++i) | ||
| { | ||
| auto value = static_cast<int64_t>(Property->values[i]); | ||
| if (value < m_min) | ||
| m_min = value; | ||
| if (value > m_max) | ||
| m_max = value; | ||
| } | ||
| } | ||
|
|
||
| QString MythDRMSignedRangeProperty::ToString() | ||
| { | ||
| return QString("%1 Value: %2 Range: %3<->%4").arg(m_name).arg(m_value).arg(m_min).arg(m_max); | ||
| } | ||
|
|
||
| MythDRMEnumProperty::MythDRMEnumProperty(uint64_t Value, drmModePropertyPtr Property) | ||
| : MythDRMProperty(Enum, Property->prop_id, Property->flags, Property->name), | ||
| m_value(Value) | ||
| { | ||
| for (int i = 0; i < Property->count_enums; ++i) | ||
| m_enums.emplace(Property->enums[i].value, Property->enums[i].name); | ||
| } | ||
|
|
||
| QString MythDRMEnumProperty::ToString() | ||
| { | ||
| QStringList values; | ||
| for (const auto & value : m_enums) | ||
| values.append(QString("%1(%2)").arg(value.first).arg(value.second)); | ||
| return QString("%1 Value: %2 Values: %3").arg(m_name).arg(m_value).arg(values.join(", ")); | ||
| } | ||
|
|
||
| MythDRMBitmaskProperty::MythDRMBitmaskProperty(uint64_t Value, drmModePropertyPtr Property) | ||
| : MythDRMEnumProperty(Value, Property) | ||
| { | ||
| m_type = Bitmask; | ||
| } | ||
|
|
||
| MythDRMBlobProperty::MythDRMBlobProperty(int FD, uint64_t Value, drmModePropertyPtr Property) | ||
| : MythDRMProperty(Blob, Property->prop_id, Property->flags, Property->name) | ||
| { | ||
| if (auto blob = drmModeGetPropertyBlob(FD, static_cast<uint32_t>(Value)); blob) | ||
| { | ||
| m_blob = QByteArray(reinterpret_cast<const char *>(blob->data), static_cast<int>(blob->length)); | ||
| drmModeFreePropertyBlob(blob); | ||
| } | ||
| } | ||
|
|
||
| MythDRMObjectProperty::MythDRMObjectProperty(drmModePropertyPtr Property) | ||
| : MythDRMProperty(Object, Property->prop_id, Property->flags, Property->name) | ||
| { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| #ifndef MYTHDRMPROPERTY_H | ||
| #define MYTHDRMPROPERTY_H | ||
|
|
||
| // MythTV | ||
| #include "platforms/drm/mythdrmresources.h" | ||
|
|
||
| using DRMProp = std::shared_ptr<class MythDRMProperty>; | ||
| using DRMProps = std::vector<DRMProp>; | ||
|
|
||
| class MUI_PUBLIC MythDRMProperty | ||
| { | ||
| public: | ||
| enum Type | ||
| { | ||
| Invalid = 0, | ||
| Range, | ||
| Enum, | ||
| Bitmask, | ||
| Blob, | ||
| Object, | ||
| SignedRange | ||
| }; | ||
|
|
||
| static DRMProps GetProperties(int FD, uint32_t ObjectId, uint32_t ObjectType); | ||
| static DRMProp GetProperty (const QString& Name, const DRMProps& Properties); | ||
| virtual ~MythDRMProperty() = default; | ||
| virtual QString ToString() { return ""; } | ||
|
|
||
| Type m_type { Invalid }; | ||
| uint32_t m_id { 0 }; | ||
| bool m_readOnly { true }; | ||
| QString m_name; | ||
|
|
||
| protected: | ||
| MythDRMProperty(Type mType, uint32_t Id, uint32_t Flags, const char * Name); | ||
|
|
||
| private: | ||
| Q_DISABLE_COPY(MythDRMProperty) | ||
| }; | ||
|
|
||
| class MUI_PUBLIC MythDRMRangeProperty : public MythDRMProperty | ||
| { | ||
| public: | ||
| MythDRMRangeProperty(uint64_t Value, drmModePropertyPtr Property); | ||
| QString ToString() override; | ||
| uint64_t m_value { 0 }; | ||
| uint64_t m_min { 0 }; | ||
| uint64_t m_max { 0 }; | ||
| }; | ||
|
|
||
| class MUI_PUBLIC MythDRMSignedRangeProperty : public MythDRMProperty | ||
| { | ||
| public: | ||
| MythDRMSignedRangeProperty(uint64_t Value, drmModePropertyPtr Property); | ||
| QString ToString() override; | ||
| int64_t m_value { 0 }; | ||
| int64_t m_min { 0 }; | ||
| int64_t m_max { 0 }; | ||
| }; | ||
|
|
||
| class MUI_PUBLIC MythDRMEnumProperty : public MythDRMProperty | ||
| { | ||
| public: | ||
| MythDRMEnumProperty(uint64_t Value, drmModePropertyPtr Property); | ||
| QString ToString() override; | ||
| uint64_t m_value { 0 }; | ||
| std::map<uint64_t,QString> m_enums; | ||
| }; | ||
|
|
||
| class MUI_PUBLIC MythDRMBitmaskProperty : public MythDRMEnumProperty | ||
| { | ||
| public: | ||
| MythDRMBitmaskProperty(uint64_t Value, drmModePropertyPtr Property); | ||
| }; | ||
|
|
||
| class MUI_PUBLIC MythDRMBlobProperty : public MythDRMProperty | ||
| { | ||
| public: | ||
| MythDRMBlobProperty(int FD, uint64_t Value, drmModePropertyPtr Property); | ||
| QByteArray m_blob; | ||
| }; | ||
|
|
||
| class MUI_PUBLIC MythDRMObjectProperty : public MythDRMProperty | ||
| { | ||
| public: | ||
| MythDRMObjectProperty(drmModePropertyPtr Property); | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // MythTV | ||
| #include "platforms/drm/mythdrmresources.h" | ||
|
|
||
| /*! \class MythDRMResources | ||
| * \brief A simple wrapper around a drmModeResPtr that ensures proper cleanup. | ||
| */ | ||
| MythDRMResources::MythDRMResources(int FD) | ||
| : m_resources(drmModeGetResources(FD)) | ||
| { | ||
| } | ||
|
|
||
| MythDRMResources::~MythDRMResources() | ||
| { | ||
| if (m_resources) | ||
| drmModeFreeResources(m_resources); | ||
| } | ||
|
|
||
| drmModeResPtr MythDRMResources::operator->() const | ||
| { | ||
| return m_resources; | ||
| } | ||
|
|
||
| drmModeResPtr MythDRMResources::operator*() const | ||
| { | ||
| return m_resources; | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #ifndef MYTHDRMRESOURCES_H | ||
| #define MYTHDRMRESOURCES_H | ||
|
|
||
| // Qt | ||
| #include <QString> | ||
|
|
||
| // MythTV | ||
| #include "mythuiexp.h" | ||
|
|
||
| // libdrm | ||
| extern "C" { | ||
| #include <xf86drm.h> | ||
| #include <xf86drmMode.h> | ||
| } | ||
|
|
||
| // Std | ||
| #include <map> | ||
| #include <vector> | ||
| #include <memory> | ||
|
|
||
| using DRMArray = std::array<uint32_t,4>; | ||
|
|
||
| class MUI_PUBLIC MythDRMResources | ||
| { | ||
| public: | ||
| MythDRMResources(int FD); | ||
| ~MythDRMResources(); | ||
| drmModeResPtr operator->() const; | ||
| drmModeResPtr operator*() const; | ||
|
|
||
| private: | ||
| drmModeResPtr m_resources { nullptr }; | ||
| }; | ||
|
|
||
| #endif |