465d817c6e1c6ca3155cce0fead5e2694ebd1ebb
[android/external-libkmsxx.git] / kms++util / src / resourcemanager.cpp
1 #include <kms++util/resourcemanager.h>
2 #include <algorithm>
3 #include <kms++util/strhelpers.h>
5 using namespace kms;
6 using namespace std;
8 template<class C, class T>
9 auto contains(const C& v, const T& x)
10 -> decltype(end(v), true)
11 {
12         return end(v) != std::find(begin(v), end(v), x);
13 }
15 ResourceManager::ResourceManager(Card& card)
16         : m_card(card)
17 {
18 }
20 void ResourceManager::reset()
21 {
22         m_reserved_connectors.clear();
23         m_reserved_crtcs.clear();
24         m_reserved_planes.clear();
25 }
27 static Connector* find_connector(Card& card, const vector<Connector*> reserved)
28 {
29         for (Connector* conn : card.get_connectors()) {
30                 if (!conn->connected())
31                         continue;
33                 if (contains(reserved, conn))
34                         continue;
36                 return conn;
37         }
39         return nullptr;
40 }
42 static Connector* resolve_connector(Card& card, const string& name, const vector<Connector*> reserved)
43 {
44         auto connectors = card.get_connectors();
46         if (name[0] == '@') {
47                 char* endptr;
48                 unsigned id = strtoul(name.c_str() + 1, &endptr, 10);
49                 if (*endptr == 0) {
50                         Connector* c = card.get_connector(id);
52                         if (!c || contains(reserved, c))
53                                 return nullptr;
55                         return c;
56                 }
57         } else {
58                 char* endptr;
59                 unsigned idx = strtoul(name.c_str(), &endptr, 10);
60                 if (*endptr == 0) {
61                         if (idx >= connectors.size())
62                                 return nullptr;
64                         Connector* c = connectors[idx];
66                         if (contains(reserved, c))
67                                 return nullptr;
69                         return c;
70                 }
71         }
73         for (Connector* conn : connectors) {
74                 if (to_lower(conn->fullname()).find(to_lower(name)) == string::npos)
75                         continue;
77                 if (contains(reserved, conn))
78                         continue;
80                 return conn;
81         }
83         return nullptr;
84 }
86 Connector* ResourceManager::reserve_connector(const string& name)
87 {
88         Connector* conn;
90         if (name.empty())
91                 conn = find_connector(m_card, m_reserved_connectors);
92         else
93                 conn = resolve_connector(m_card, name, m_reserved_connectors);
95         if (!conn)
96                 return nullptr;
98         m_reserved_connectors.push_back(conn);
99         return conn;
102 Connector* ResourceManager::reserve_connector(Connector* conn)
104         if (!conn)
105                 return nullptr;
107         if (contains(m_reserved_connectors, conn))
108                 return nullptr;
110         m_reserved_connectors.push_back(conn);
111         return conn;
114 Crtc* ResourceManager::reserve_crtc(Connector* conn)
116         if (!conn)
117                 return nullptr;
119         if (Crtc* crtc = conn->get_current_crtc()) {
120                 m_reserved_crtcs.push_back(crtc);
121                 return crtc;
122         }
124         for (Crtc* crtc : conn->get_possible_crtcs()) {
125                 if (contains(m_reserved_crtcs, crtc))
126                         continue;
128                 m_reserved_crtcs.push_back(crtc);
129                 return crtc;
130         }
132         return nullptr;
135 Crtc* ResourceManager::reserve_crtc(Crtc* crtc)
137         if (!crtc)
138                 return nullptr;
140         if (contains(m_reserved_crtcs, crtc))
141                 return nullptr;
143         m_reserved_crtcs.push_back(crtc);
145         return crtc;
148 Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format)
150         if (!crtc)
151                 return nullptr;
153         for (Plane* plane : crtc->get_possible_planes()) {
154                 if (plane->plane_type() != type)
155                         continue;
157                 if (format != PixelFormat::Undefined && !plane->supports_format(format))
158                         continue;
160                 if (contains(m_reserved_planes, plane))
161                         continue;
163                 m_reserved_planes.push_back(plane);
164                 return plane;
165         }
167         return nullptr;
170 Plane* ResourceManager::reserve_plane(Plane* plane)
172         if (!plane)
173                 return nullptr;
175         if (contains(m_reserved_planes, plane))
176                 return nullptr;
178         m_reserved_planes.push_back(plane);
180         return plane;
183 Plane* ResourceManager::reserve_generic_plane(Crtc* crtc, PixelFormat format)
185         if (!crtc)
186                 return nullptr;
188         for (Plane* plane : crtc->get_possible_planes()) {
189                 if (plane->plane_type() == PlaneType::Cursor)
190                         continue;
192                 if (format != PixelFormat::Undefined && !plane->supports_format(format))
193                         continue;
195                 if (contains(m_reserved_planes, plane))
196                         continue;
198                 m_reserved_planes.push_back(plane);
199                 return plane;
200         }
202         return nullptr;
205 Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format)
207         return reserve_plane(crtc, PlaneType::Primary, format);
210 Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format)
212         return reserve_plane(crtc, PlaneType::Overlay, format);