add ResourceManager
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 14 Jun 2016 19:20:08 +0000 (22:20 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 16 Jun 2016 18:45:26 +0000 (21:45 +0300)
kms++util/inc/kms++util/kms++util.h
kms++util/inc/kms++util/resourcemanager.h [new file with mode: 0644]
kms++util/src/resourcemanager.cpp [new file with mode: 0644]
py/pykmsutil.cpp

index ca3c4069f855b34990ff987e56f45beb80f0a4b2..10a1f0af5a13badb0e27db55abe946d23dcc17a3 100644 (file)
@@ -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 (file)
index 0000000..92e7b93
--- /dev/null
@@ -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 (file)
index 0000000..cdd3e40
--- /dev/null
@@ -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);
+}
index 5ee1d4e7445311bb01dd4d7b18303de666583ce9..ab9f5a8d0be8e58cabdc4860f2255509a3971563 100644 (file)
@@ -20,6 +20,24 @@ void init_pykmstest(py::module &m)
                        .def_property_readonly("rgb565", &RGB::rgb565)
                        ;
 
+       py::class_<ResourceManager>(m, "ResourceManager")
+                       .def(py::init<Card&>())
+                       .def("reset", &ResourceManager::reset)
+                       .def("reserve_connector", &ResourceManager::reserve_connector,
+                            py::arg("name") = string())
+                       .def("reserve_crtc", &ResourceManager::reserve_crtc)
+                       .def("reserve_plane", &ResourceManager::reserve_plane,
+                            py::arg("crtc"),
+                            py::arg("type"),
+                            py::arg("format") = PixelFormat::Undefined)
+                       .def("reserve_primary_plane", &ResourceManager::reserve_primary_plane,
+                            py::arg("crtc"),
+                            py::arg("format") = PixelFormat::Undefined)
+                       .def("reserve_overlay_plane", &ResourceManager::reserve_overlay_plane,
+                            py::arg("crtc"),
+                            py::arg("format") = PixelFormat::Undefined)
+                       ;
+
        // Use lambdas to handle IMappedFramebuffer
        m.def("draw_test_pattern", [](DumbFramebuffer& fb) { draw_test_pattern(fb); } );
        m.def("draw_color_bar", [](DumbFramebuffer& fb, int old_xpos, int xpos, int width) {