465d817c6e1c6ca3155cce0fead5e2694ebd1ebb
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;
100 }
102 Connector* ResourceManager::reserve_connector(Connector* conn)
103 {
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;
112 }
114 Crtc* ResourceManager::reserve_crtc(Connector* conn)
115 {
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;
133 }
135 Crtc* ResourceManager::reserve_crtc(Crtc* crtc)
136 {
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;
146 }
148 Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format)
149 {
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;
168 }
170 Plane* ResourceManager::reserve_plane(Plane* plane)
171 {
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;
181 }
183 Plane* ResourceManager::reserve_generic_plane(Crtc* crtc, PixelFormat format)
184 {
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;
203 }
205 Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format)
206 {
207 return reserve_plane(crtc, PlaneType::Primary, format);
208 }
210 Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format)
211 {
212 return reserve_plane(crtc, PlaneType::Overlay, format);
213 }