• 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 
release_connector(Connector * conn)107 void ResourceManager::release_connector(Connector* conn)
108 {
109 	m_reserved_connectors.erase(conn);
110 }
111 
reserve_crtc(Connector * conn)112 Crtc* ResourceManager::reserve_crtc(Connector* conn)
113 {
114 	if (!conn)
115 		return nullptr;
116 
117 	if (Crtc* crtc = conn->get_current_crtc()) {
118 		m_reserved_crtcs.insert(crtc);
119 		return crtc;
120 	}
121 
122 	for (Crtc* crtc : conn->get_possible_crtcs()) {
123 		if (m_reserved_crtcs.count(crtc))
124 			continue;
125 
126 		m_reserved_crtcs.insert(crtc);
127 		return crtc;
128 	}
129 
130 	return nullptr;
131 }
132 
reserve_crtc(Crtc * crtc)133 Crtc* ResourceManager::reserve_crtc(Crtc* crtc)
134 {
135 	if (!crtc)
136 		return nullptr;
137 
138 	if (m_reserved_crtcs.count(crtc))
139 		return nullptr;
140 
141 	m_reserved_crtcs.insert(crtc);
142 
143 	return crtc;
144 }
145 
release_crtc(Crtc * crtc)146 void ResourceManager::release_crtc(Crtc* crtc)
147 {
148 	m_reserved_crtcs.erase(crtc);
149 }
150 
reserve_plane(Crtc * crtc,PlaneType type,PixelFormat format)151 Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format)
152 {
153 	if (!crtc)
154 		return nullptr;
155 
156 	for (Plane* plane : crtc->get_possible_planes()) {
157 		if (plane->plane_type() != type)
158 			continue;
159 
160 		if (format != PixelFormat::Undefined && !plane->supports_format(format))
161 			continue;
162 
163 		if (m_reserved_planes.count(plane))
164 			continue;
165 
166 		m_reserved_planes.insert(plane);
167 		return plane;
168 	}
169 
170 	return nullptr;
171 }
172 
reserve_plane(Plane * plane)173 Plane* ResourceManager::reserve_plane(Plane* plane)
174 {
175 	if (!plane)
176 		return nullptr;
177 
178 	if (m_reserved_planes.count(plane))
179 		return nullptr;
180 
181 	m_reserved_planes.insert(plane);
182 
183 	return plane;
184 }
185 
reserve_generic_plane(Crtc * crtc,PixelFormat format)186 Plane* ResourceManager::reserve_generic_plane(Crtc* crtc, PixelFormat format)
187 {
188 	if (!crtc)
189 		return nullptr;
190 
191 	for (Plane* plane : crtc->get_possible_planes()) {
192 		if (plane->plane_type() == PlaneType::Cursor)
193 			continue;
194 
195 		if (format != PixelFormat::Undefined && !plane->supports_format(format))
196 			continue;
197 
198 		if (m_reserved_planes.count(plane))
199 			continue;
200 
201 		m_reserved_planes.insert(plane);
202 		return plane;
203 	}
204 
205 	return nullptr;
206 }
207 
reserve_primary_plane(Crtc * crtc,PixelFormat format)208 Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format)
209 {
210 	return reserve_plane(crtc, PlaneType::Primary, format);
211 }
212 
reserve_overlay_plane(Crtc * crtc,PixelFormat format)213 Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format)
214 {
215 	return reserve_plane(crtc, PlaneType::Overlay, format);
216 }
217 
release_plane(Plane * plane)218 void ResourceManager::release_plane(Plane* plane)
219 {
220 	m_reserved_planes.erase(plane);
221 }
222