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