1 #include <kms++util/resourcemanager.h>
2 #include <algorithm>
3 #include <kms++util/strhelpers.h>
4
5 using namespace kms;
6 using namespace std;
7
ResourceManager(Card & card)8 ResourceManager::ResourceManager(Card& card)
9 : m_card(card)
10 {
11 }
12
reset()13 void ResourceManager::reset()
14 {
15 m_reserved_connectors.clear();
16 m_reserved_crtcs.clear();
17 m_reserved_planes.clear();
18 }
19
find_connector(Card & card,const set<Connector * > reserved)20 static Connector* find_connector(Card& card, const set<Connector*> reserved)
21 {
22 for (Connector* conn : card.get_connectors()) {
23 if (!conn->connected())
24 continue;
25
26 if (reserved.count(conn))
27 continue;
28
29 return conn;
30 }
31
32 return nullptr;
33 }
34
resolve_connector(Card & card,const string & name,const set<Connector * > reserved)35 static Connector* resolve_connector(Card& card, const string& name, const set<Connector*> reserved)
36 {
37 auto connectors = card.get_connectors();
38
39 if (name[0] == '@') {
40 char* endptr;
41 unsigned id = strtoul(name.c_str() + 1, &endptr, 10);
42 if (*endptr == 0) {
43 Connector* c = card.get_connector(id);
44
45 if (!c || reserved.count(c))
46 return nullptr;
47
48 return c;
49 }
50 } else {
51 char* endptr;
52 unsigned idx = strtoul(name.c_str(), &endptr, 10);
53 if (*endptr == 0) {
54 if (idx >= connectors.size())
55 return nullptr;
56
57 Connector* c = connectors[idx];
58
59 if (reserved.count(c))
60 return nullptr;
61
62 return c;
63 }
64 }
65
66 for (Connector* conn : connectors) {
67 if (to_lower(conn->fullname()).find(to_lower(name)) == string::npos)
68 continue;
69
70 if (reserved.count(conn))
71 continue;
72
73 return conn;
74 }
75
76 return nullptr;
77 }
78
reserve_connector(const string & name)79 Connector* ResourceManager::reserve_connector(const string& name)
80 {
81 Connector* conn;
82
83 if (name.empty())
84 conn = find_connector(m_card, m_reserved_connectors);
85 else
86 conn = resolve_connector(m_card, name, m_reserved_connectors);
87
88 if (!conn)
89 return nullptr;
90
91 m_reserved_connectors.insert(conn);
92 return conn;
93 }
94
reserve_connector(Connector * conn)95 Connector* ResourceManager::reserve_connector(Connector* conn)
96 {
97 if (!conn)
98 return nullptr;
99
100 if (m_reserved_connectors.count(conn))
101 return nullptr;
102
103 m_reserved_connectors.insert(conn);
104 return conn;
105 }
106
reserve_crtc(Connector * conn)107 Crtc* ResourceManager::reserve_crtc(Connector* conn)
108 {
109 if (!conn)
110 return nullptr;
111
112 if (Crtc* crtc = conn->get_current_crtc()) {
113 m_reserved_crtcs.insert(crtc);
114 return crtc;
115 }
116
117 for (Crtc* crtc : conn->get_possible_crtcs()) {
118 if (m_reserved_crtcs.count(crtc))
119 continue;
120
121 m_reserved_crtcs.insert(crtc);
122 return crtc;
123 }
124
125 return nullptr;
126 }
127
reserve_crtc(Crtc * crtc)128 Crtc* ResourceManager::reserve_crtc(Crtc* crtc)
129 {
130 if (!crtc)
131 return nullptr;
132
133 if (m_reserved_crtcs.count(crtc))
134 return nullptr;
135
136 m_reserved_crtcs.insert(crtc);
137
138 return crtc;
139 }
140
reserve_plane(Crtc * crtc,PlaneType type,PixelFormat format)141 Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format)
142 {
143 if (!crtc)
144 return nullptr;
145
146 for (Plane* plane : crtc->get_possible_planes()) {
147 if (plane->plane_type() != type)
148 continue;
149
150 if (format != PixelFormat::Undefined && !plane->supports_format(format))
151 continue;
152
153 if (m_reserved_planes.count(plane))
154 continue;
155
156 m_reserved_planes.insert(plane);
157 return plane;
158 }
159
160 return nullptr;
161 }
162
reserve_plane(Plane * plane)163 Plane* ResourceManager::reserve_plane(Plane* plane)
164 {
165 if (!plane)
166 return nullptr;
167
168 if (m_reserved_planes.count(plane))
169 return nullptr;
170
171 m_reserved_planes.insert(plane);
172
173 return plane;
174 }
175
reserve_generic_plane(Crtc * crtc,PixelFormat format)176 Plane* ResourceManager::reserve_generic_plane(Crtc* crtc, PixelFormat format)
177 {
178 if (!crtc)
179 return nullptr;
180
181 for (Plane* plane : crtc->get_possible_planes()) {
182 if (plane->plane_type() == PlaneType::Cursor)
183 continue;
184
185 if (format != PixelFormat::Undefined && !plane->supports_format(format))
186 continue;
187
188 if (m_reserved_planes.count(plane))
189 continue;
190
191 m_reserved_planes.insert(plane);
192 return plane;
193 }
194
195 return nullptr;
196 }
197
reserve_primary_plane(Crtc * crtc,PixelFormat format)198 Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format)
199 {
200 return reserve_plane(crtc, PlaneType::Primary, format);
201 }
202
reserve_overlay_plane(Crtc * crtc,PixelFormat format)203 Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format)
204 {
205 return reserve_plane(crtc, PlaneType::Overlay, format);
206 }
207