summaryrefslogtreecommitdiff
path: root/kms++util
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2016-06-14 22:20:08 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2016-06-16 21:45:26 +0300
commit84d89b1659b6eb3e7707f2fe107b9cada516f053 (patch)
tree8120c41cd8fdeb7f583c2432b5422deb5cd0a30d /kms++util
parent34e63f641195019e903104c8b9e6eb855efeee2c (diff)
add ResourceManager
Diffstat (limited to 'kms++util')
-rw-r--r--kms++util/inc/kms++util/kms++util.h1
-rw-r--r--kms++util/inc/kms++util/resourcemanager.h27
-rw-r--r--kms++util/src/resourcemanager.cpp147
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);
+}