• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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