diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2016-06-14 22:20:08 +0300 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2016-06-16 21:45:26 +0300 |
commit | 84d89b1659b6eb3e7707f2fe107b9cada516f053 (patch) | |
tree | 8120c41cd8fdeb7f583c2432b5422deb5cd0a30d /kms++util | |
parent | 34e63f641195019e903104c8b9e6eb855efeee2c (diff) |
add ResourceManager
Diffstat (limited to 'kms++util')
-rw-r--r-- | kms++util/inc/kms++util/kms++util.h | 1 | ||||
-rw-r--r-- | kms++util/inc/kms++util/resourcemanager.h | 27 | ||||
-rw-r--r-- | kms++util/src/resourcemanager.cpp | 147 |
3 files changed, 175 insertions, 0 deletions
diff --git a/kms++util/inc/kms++util/kms++util.h b/kms++util/inc/kms++util/kms++util.h index ca3c406..10a1f0a 100644 --- a/kms++util/inc/kms++util/kms++util.h +++ b/kms++util/inc/kms++util/kms++util.h @@ -8,6 +8,7 @@ #include <kms++util/extcpuframebuffer.h> #include <kms++util/stopwatch.h> #include <kms++util/opts.h> +#include <kms++util/resourcemanager.h> #include <cstdio> #include <cstdlib> diff --git a/kms++util/inc/kms++util/resourcemanager.h b/kms++util/inc/kms++util/resourcemanager.h new file mode 100644 index 0000000..92e7b93 --- /dev/null +++ b/kms++util/inc/kms++util/resourcemanager.h @@ -0,0 +1,27 @@ +#include <kms++/kms++.h> +#include <vector> +#include <string> + +namespace kms { + +class ResourceManager +{ +public: + ResourceManager(Card& card); + + void reset(); + + Connector* reserve_connector(const std::string& name = ""); + Crtc* reserve_crtc(Connector* conn); + Plane* reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format = PixelFormat::Undefined); + Plane* reserve_primary_plane(Crtc* crtc, PixelFormat format = PixelFormat::Undefined); + Plane* reserve_overlay_plane(Crtc* crtc, PixelFormat format = PixelFormat::Undefined); + +private: + Card& m_card; + std::vector<Connector*> m_reserved_connectors; + std::vector<Crtc*> m_reserved_crtcs; + std::vector<Plane*> m_reserved_planes; +}; + +} diff --git a/kms++util/src/resourcemanager.cpp b/kms++util/src/resourcemanager.cpp new file mode 100644 index 0000000..cdd3e40 --- /dev/null +++ b/kms++util/src/resourcemanager.cpp @@ -0,0 +1,147 @@ +#include <kms++util/resourcemanager.h> +#include <algorithm> +#include <kms++util/strhelpers.h> + +using namespace kms; +using namespace std; + +template<class C, class T> +auto contains(const C& v, const T& x) +-> decltype(end(v), true) +{ + return end(v) != std::find(begin(v), end(v), x); +} + +ResourceManager::ResourceManager(Card& card) + : m_card(card) +{ +} + +void ResourceManager::reset() +{ + m_reserved_connectors.clear(); + m_reserved_crtcs.clear(); + m_reserved_planes.clear(); +} + +static Connector* find_connector(Card& card, const vector<Connector*> reserved) +{ + for (Connector* conn : card.get_connectors()) { + if (!conn->connected()) + continue; + + if (contains(reserved, conn)) + continue; + + return conn; + } + + return nullptr; +} + +static Connector* resolve_connector(Card& card, const string& name, const vector<Connector*> reserved) +{ + auto connectors = card.get_connectors(); + + if (name[0] == '@') { + char* endptr; + unsigned id = strtoul(name.c_str() + 1, &endptr, 10); + if (*endptr == 0) { + Connector* c = card.get_connector(id); + + if (!c || contains(reserved, c)) + return nullptr; + + return c; + } + } else { + char* endptr; + unsigned idx = strtoul(name.c_str(), &endptr, 10); + if (*endptr == 0) { + if (idx >= connectors.size()) + return nullptr; + + Connector* c = connectors[idx]; + + if (contains(reserved, c)) + return nullptr; + + return c; + } + } + + for (Connector* conn : connectors) { + if (to_lower(conn->fullname()).find(to_lower(name)) == string::npos) + continue; + + if (contains(reserved, conn)) + continue; + + return conn; + } + + return nullptr; +} + +Connector* ResourceManager::reserve_connector(const string& name) +{ + Connector* conn; + + if (name.empty()) + conn = find_connector(m_card, m_reserved_connectors); + else + conn = resolve_connector(m_card, name, m_reserved_connectors); + + if (!conn) + return nullptr; + + m_reserved_connectors.push_back(conn); + return conn; +} + +Crtc* ResourceManager::reserve_crtc(Connector* conn) +{ + if (Crtc* crtc = conn->get_current_crtc()) { + m_reserved_crtcs.push_back(crtc); + return crtc; + } + + for (Crtc* crtc : conn->get_possible_crtcs()) { + if (contains(m_reserved_crtcs, crtc)) + continue; + + m_reserved_crtcs.push_back(crtc); + return crtc; + } + + return nullptr; +} + +Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format) +{ + for (Plane* plane : crtc->get_possible_planes()) { + if (plane->plane_type() != type) + continue; + + if (format != PixelFormat::Undefined && !plane->supports_format(format)) + continue; + + if (contains(m_reserved_planes, plane)) + continue; + + m_reserved_planes.push_back(plane); + return plane; + } + + return nullptr; +} + +Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format) +{ + return reserve_plane(crtc, PlaneType::Primary, format); +} + +Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format) +{ + return reserve_plane(crtc, PlaneType::Overlay, format); +} |