Skip to content

Commit

Permalink
libmythui: Add DRM wrapper classes
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-kendall committed Jan 18, 2021
1 parent aa683ba commit c77ea53
Show file tree
Hide file tree
Showing 17 changed files with 1,014 additions and 1 deletion.
18 changes: 17 additions & 1 deletion mythtv/libs/libmythui/libmythui.pro
Expand Up @@ -12,7 +12,7 @@ CONFIG += thread dll
target.path = $${LIBDIR}
INSTALLS = target

DEPENDPATH += ./opengl ./platforms ./devices ./vulkan
DEPENDPATH += ./opengl ./platforms ./platforms/drm ./devices ./vulkan
INCLUDEPATH += $$DEPENDPATH
INCLUDEPATH += ../libmythbase
INCLUDEPATH += ../.. ../
Expand Down Expand Up @@ -130,9 +130,25 @@ using_drm {
HEADERS += platforms/mythdisplaydrm.h
HEADERS += platforms/mythscreensaverdrm.h
HEADERS += platforms/mythdrmdevice.h
HEADERS += platforms/drm/mythdrmresources.h
HEADERS += platforms/drm/mythdrmplane.h
HEADERS += platforms/drm/mythdrmmode.h
HEADERS += platforms/drm/mythdrmcrtc.h
HEADERS += platforms/drm/mythdrmproperty.h
HEADERS += platforms/drm/mythdrmconnector.h
HEADERS += platforms/drm/mythdrmencoder.h
HEADERS += platforms/drm/mythdrmframebuffer.h
SOURCES += platforms/mythdisplaydrm.cpp
SOURCES += platforms/mythscreensaverdrm.cpp
SOURCES += platforms/mythdrmdevice.cpp
SOURCES += platforms/drm/mythdrmresources.cpp
SOURCES += platforms/drm/mythdrmplane.cpp
SOURCES += platforms/drm/mythdrmmode.cpp
SOURCES += platforms/drm/mythdrmcrtc.cpp
SOURCES += platforms/drm/mythdrmproperty.cpp
SOURCES += platforms/drm/mythdrmconnector.cpp
SOURCES += platforms/drm/mythdrmencoder.cpp
SOURCES += platforms/drm/mythdrmframebuffer.cpp
QMAKE_CXXFLAGS += $${LIBDRM_CFLAGS}
}

Expand Down
81 changes: 81 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmconnector.cpp
@@ -0,0 +1,81 @@
// MythTV
#include "platforms/drm/mythdrmmode.h"
#include "platforms/drm/mythdrmconnector.h"

/*! \class MythDRMConnector
* \brief A wrapper around a DRM connector object.
*
* The full list of available connectors can be retrieved with GetConnectors and
* a single connector retrieved from a list with GetConnector.
*/
DRMConn MythDRMConnector::Create(int FD, uint32_t Id)
{
if (FD && Id)
if (auto c = std::shared_ptr<MythDRMConnector>(new MythDRMConnector(FD, Id)); c.get() && c->m_id)
return c;

return nullptr;
}

DRMConn MythDRMConnector::GetConnector(const DRMConns &Connectors, uint32_t Id)
{
auto match = [&Id](const auto & Conn) { return Conn->m_id == Id; };
if (auto found = std::find_if(Connectors.cbegin(), Connectors.cend(), match); found != Connectors.cend())
return *found;
return nullptr;
}

DRMConns MythDRMConnector::GetConnectors(int FD)
{
DRMConns result;
if (auto resources = MythDRMResources(FD); *resources)
for (auto i = 0; i < resources->count_connectors; ++i)
if (auto connector = Create(FD, resources->connectors[i]); connector.get())
result.emplace_back(connector);

return result;
}

MythDRMConnector::MythDRMConnector(int FD, uint32_t Id)
{
if (auto connector = drmModeGetConnector(FD, Id); connector)
{
m_id = connector->connector_id;
m_encoderId = connector->encoder_id;
m_type = connector->connector_type;
m_typeId = connector->connector_type_id;
m_name = GetConnectorName(m_type, m_typeId);
m_state = connector->connection;
m_mmWidth = connector->mmWidth;
m_mmHeight = connector->mmHeight;
m_properties = MythDRMProperty::GetProperties(FD, m_id, DRM_MODE_OBJECT_CONNECTOR);
for (auto i = 0; i < connector->count_modes; ++i)
m_modes.emplace_back(MythDRMMode::Create(&connector->modes[i], i));
drmModeFreeConnector(connector);
}
}

bool MythDRMConnector::Connected() const
{
return m_state == DRM_MODE_CONNECTED;
}

QString MythDRMConnector::GetConnectorName(uint32_t Type, uint32_t Id)
{
static const std::array<const std::string,DRM_MODE_CONNECTOR_DPI + 1> s_connectorNames =
{
"None", "VGA", "DVI", "DVI", "DVI", "Composite", "TV", "LVDS",
"CTV", "DIN", "DP", "HDMI", "HDMI", "TV", "eDP", "Virtual", "DSI", "DPI"
};
uint32_t type = qMin(Type, static_cast<uint32_t>(DRM_MODE_CONNECTOR_DPI));
return QString("%1%2").arg(QString::fromStdString(s_connectorNames[type])).arg(Id);
}

DRMConn MythDRMConnector::GetConnectorByName(const DRMConns& Connectors, const QString &Name)
{
for (const auto & connector : Connectors)
if (Name.compare(connector->m_name, Qt::CaseInsensitive) == 0)
return connector;

return nullptr;
}
41 changes: 41 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmconnector.h
@@ -0,0 +1,41 @@
#ifndef MYTHDRMCONNECTOR_H
#define MYTHDRMCONNECTOR_H

// MythTV
#include "platforms/drm/mythdrmproperty.h"
#include "platforms/drm/mythdrmmode.h"
#include "platforms/drm/mythdrmresources.h"

using Encoders = std::vector<uint32_t>;
using DRMConn = std::shared_ptr<class MythDRMConnector>;
using DRMConns = std::vector<DRMConn>;

class MUI_PUBLIC MythDRMConnector
{
public:
static DRMConn Create(int FD, uint32_t Id);
static DRMConn GetConnector(const DRMConns& Connectors, uint32_t Id);
static DRMConns GetConnectors(int FD);
static QString GetConnectorName(uint32_t Type, uint32_t Id);
static DRMConn GetConnectorByName(const DRMConns& Connectors, const QString& Name);
bool Connected() const;

uint32_t m_id { 0 };
uint32_t m_encoderId { 0 };
uint32_t m_type { DRM_MODE_CONNECTOR_Unknown };
uint32_t m_typeId { 0 };
QString m_name;
drmModeConnection m_state { DRM_MODE_UNKNOWNCONNECTION };
uint32_t m_mmWidth { 0 };
uint32_t m_mmHeight { 0 };
DRMModes m_modes;
DRMProps m_properties;

protected:
MythDRMConnector(int FD, uint32_t Id);

private:
Q_DISABLE_COPY(MythDRMConnector)
};

#endif
79 changes: 79 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmcrtc.cpp
@@ -0,0 +1,79 @@
// MythTV
#include "platforms/drm/mythdrmcrtc.h"

/*! \class MythDRMCrtc
* \brief A simple wrapper around a DRM CRTC object.
*
* The full list of available CRTCs can be retrieved with GetCrtcs. An individual
* CRTC can be retrieved from a given list with GetCrtc.
*/
DRMCrtc MythDRMCrtc::Create(int FD, uint32_t Id, int Index)
{
if (FD && Id)
if (auto crtc = std::shared_ptr<MythDRMCrtc>(new MythDRMCrtc(FD, Id, Index)); crtc.get() && crtc->m_id)
return crtc;

return nullptr;
}

DRMCrtc MythDRMCrtc::GetCrtc(const DRMCrtcs &Crtcs, uint32_t Id)
{
auto match = [&Id](const auto & Crtc) { return Crtc->m_id == Id; };
if (auto found = std::find_if(Crtcs.cbegin(), Crtcs.cend(), match); found != Crtcs.cend())
return *found;
return nullptr;
}

DRMCrtcs MythDRMCrtc::GetCrtcs(int FD)
{
DRMCrtcs result;
if (auto resources = MythDRMResources(FD); *resources)
for (auto i = 0; i < resources->count_crtcs; ++i)
if (auto crtc = Create(FD, resources->crtcs[i], i); crtc.get())
result.emplace_back(crtc);

return result;
}

MythDRMCrtc::MythDRMCrtc(int FD, uint32_t Id, int Index)
{
if (auto crtc = drmModeGetCrtc(FD, Id); crtc)
{
m_index = Index;
m_id = crtc->crtc_id;
m_fbId = crtc->buffer_id;
m_x = crtc->x;
m_y = crtc->y;
m_width = crtc->width;
m_height = crtc->height;
if (crtc->mode_valid)
m_mode = MythDRMMode::Create(&crtc->mode, 0);
m_properties = MythDRMProperty::GetProperties(FD, m_id, DRM_MODE_OBJECT_CRTC);
drmModeFreeCrtc(crtc);

if (m_index < 0)
m_index = RetrieveCRTCIndex(FD, Id);
}
}

int MythDRMCrtc::RetrieveCRTCIndex(int FD, uint32_t Id)
{
int result = -1;
if (auto resources = MythDRMResources(FD); *resources)
{
for (auto i = 0; i < resources->count_crtcs; ++i)
{
if (auto crtc = drmModeGetCrtc(FD, resources->crtcs[i]); crtc)
{
bool match = crtc->crtc_id == Id;
drmModeFreeCrtc(crtc);
if (match)
{
result = i;
break;
}
}
}
}
return result;
}
36 changes: 36 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmcrtc.h
@@ -0,0 +1,36 @@
#ifndef MYTHDRMCRTC_H
#define MYTHDRMCRTC_H

// MythTV
#include "platforms/drm/mythdrmproperty.h"
#include "platforms/drm/mythdrmmode.h"

using DRMCrtc = std::shared_ptr<class MythDRMCrtc>;
using DRMCrtcs = std::vector<DRMCrtc>;

class MUI_PUBLIC MythDRMCrtc
{
public:
static DRMCrtc Create(int FD, uint32_t Id, int Index = -1);
static DRMCrtc GetCrtc(const DRMCrtcs& Crtcs, uint32_t Id);
static DRMCrtcs GetCrtcs(int FD);

int m_index { -1 };
uint32_t m_id { 0 };
uint32_t m_fbId { 0 };
DRMMode m_mode { nullptr };
uint32_t m_x { 0 };
uint32_t m_y { 0 };
uint32_t m_width { 0 };
uint32_t m_height { 0 };
DRMProps m_properties;

protected:
MythDRMCrtc(int FD, uint32_t Id, int Index);
int RetrieveCRTCIndex(int FD, uint32_t Id);

private:
Q_DISABLE_COPY(MythDRMCrtc)
};

#endif
49 changes: 49 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmencoder.cpp
@@ -0,0 +1,49 @@
// MythTV
#include "platforms/drm/mythdrmencoder.h"

/*! \class MythDRMEncoder
* \brief A simple object representing a DRM encoder.
*
* The full list of available encoders can be retrieved with GetEncoders and a
* specific encoder retrieved from a list with GetEncoder.
*/
DRMEnc MythDRMEncoder::Create(int FD, uint32_t Id)
{
if (FD && Id)
if (auto e = std::shared_ptr<MythDRMEncoder>(new MythDRMEncoder(FD, Id)); e.get() && e->m_id)
return e;

return nullptr;
}

DRMEnc MythDRMEncoder::GetEncoder(const DRMEncs& Encoders, uint32_t Id)
{
auto match = [&Id](const auto & Enc) { return Enc->m_id == Id; };
if (auto found = std::find_if(Encoders.cbegin(), Encoders.cend(), match); found != Encoders.cend())
return *found;
return nullptr;
}

DRMEncs MythDRMEncoder::GetEncoders(int FD)
{
DRMEncs result;
if (auto resources = MythDRMResources(FD); *resources)
for (auto i = 0; i < resources->count_encoders; ++i)
if (auto encoder = Create(FD, resources->encoders[i]); encoder.get())
result.emplace_back(encoder);

return result;
}

MythDRMEncoder::MythDRMEncoder(int FD, uint32_t Id)
{
if (auto encoder = drmModeGetEncoder(FD, Id); encoder)
{
m_id = encoder->encoder_id;
m_type = encoder->encoder_type;
m_crtcId = encoder->crtc_id;
m_possibleCrtcs = encoder->possible_crtcs;
drmModeFreeEncoder(encoder);
}
}

29 changes: 29 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmencoder.h
@@ -0,0 +1,29 @@
#ifndef MYTHDRMENCODER_H
#define MYTHDRMENCODER_H

// MythTV
#include "platforms/drm/mythdrmresources.h"

using DRMEnc = std::shared_ptr<class MythDRMEncoder>;
using DRMEncs = std::vector<DRMEnc>;

class MUI_PUBLIC MythDRMEncoder
{
public:
static DRMEnc Create(int FD, uint32_t Id);
static DRMEnc GetEncoder(const DRMEncs& Encoders, uint32_t Id);
static DRMEncs GetEncoders(int FD);

uint32_t m_id { 0 };
uint32_t m_type { 0 };
uint32_t m_crtcId { 0 };
uint32_t m_possibleCrtcs { 0 };

protected:
explicit MythDRMEncoder(int FD, uint32_t Id);

private:
Q_DISABLE_COPY(MythDRMEncoder)
};

#endif
27 changes: 27 additions & 0 deletions mythtv/libs/libmythui/platforms/drm/mythdrmframebuffer.cpp
@@ -0,0 +1,27 @@
// MythTV
#include "platforms/drm/mythdrmframebuffer.h"

/*! \class MythDRMFramebuffer
* \brief A simple object representing a DRM Framebuffer object.
*/
DRMFb MythDRMFramebuffer::Create(int FD, uint32_t Id)
{
if (auto fb = std::shared_ptr<MythDRMFramebuffer>(new MythDRMFramebuffer(FD, Id)); fb.get() && fb->m_id)
return fb;
return nullptr;
}

MythDRMFramebuffer::MythDRMFramebuffer(int FD, uint32_t Id)
{
if (auto fb = drmModeGetFB2(FD, Id); fb)
{
m_id = fb->fb_id;
m_width = fb->width;
m_height = fb->height;
m_format = fb->pixel_format;
m_modifiers = fb->modifier;
std::copy(std::begin(fb->handles), std::end(fb->handles), std::begin(m_handles));
std::copy(std::begin(fb->pitches), std::end(fb->pitches), std::begin(m_pitches));
std::copy(std::begin(fb->offsets), std::end(fb->offsets), std::begin(m_offsets));
}
}

0 comments on commit c77ea53

Please sign in to comment.