libkmsxx: Add Android.bp file to build with AOSP
[android/external-libkmsxx.git] / kms++util / src / resourcemanager.cpp
1 #include <kms++util/resourcemanager.h>
2 #include <algorithm>
3 #include <kms++util/strhelpers.h>
5 using namespace kms;
6 using namespace std;
8 ResourceManager::ResourceManager(Card& card)
9         : m_card(card)
10 {
11 }
13 void ResourceManager::reset()
14 {
15         m_reserved_connectors.clear();
16         m_reserved_crtcs.clear();
17         m_reserved_planes.clear();
18 }
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;
26                 if (reserved.count(conn))
27                         continue;
29                 return conn;
30         }
32         return nullptr;
33 }
35 static Connector* resolve_connector(Card& card, const string& name, const set<Connector*> reserved)
36 {
37         auto connectors = card.get_connectors();
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);
45                         if (!c || reserved.count(c))
46                                 return nullptr;
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;
57                         Connector* c = connectors[idx];
59                         if (reserved.count(c))
60                                 return nullptr;
62                         return c;
63                 }
64         }
66         for (Connector* conn : connectors) {
67                 if (to_lower(conn->fullname()).find(to_lower(name)) == string::npos)
68                         continue;
70                 if (reserved.count(conn))
71                         continue;
73                 return conn;
74         }
76         return nullptr;
77 }
79 Connector* ResourceManager::reserve_connector(const string& name)
80 {
81         Connector* conn;
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);
88         if (!conn)
89                 return nullptr;
91         m_reserved_connectors.insert(conn);
92         return conn;
93 }
95 Connector* ResourceManager::reserve_connector(Connector* conn)
96 {
97         if (!conn)
98                 return nullptr;
100         if (m_reserved_connectors.count(conn))
101                 return nullptr;
103         m_reserved_connectors.insert(conn);
104         return conn;
107 Crtc* ResourceManager::reserve_crtc(Connector* conn)
109         if (!conn)
110                 return nullptr;
112         if (Crtc* crtc = conn->get_current_crtc()) {
113                 m_reserved_crtcs.insert(crtc);
114                 return crtc;
115         }
117         for (Crtc* crtc : conn->get_possible_crtcs()) {
118                 if (m_reserved_crtcs.count(crtc))
119                         continue;
121                 m_reserved_crtcs.insert(crtc);
122                 return crtc;
123         }
125         return nullptr;
128 Crtc* ResourceManager::reserve_crtc(Crtc* crtc)
130         if (!crtc)
131                 return nullptr;
133         if (m_reserved_crtcs.count(crtc))
134                 return nullptr;
136         m_reserved_crtcs.insert(crtc);
138         return crtc;
141 Plane* ResourceManager::reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format)
143         if (!crtc)
144                 return nullptr;
146         for (Plane* plane : crtc->get_possible_planes()) {
147                 if (plane->plane_type() != type)
148                         continue;
150                 if (format != PixelFormat::Undefined && !plane->supports_format(format))
151                         continue;
153                 if (m_reserved_planes.count(plane))
154                         continue;
156                 m_reserved_planes.insert(plane);
157                 return plane;
158         }
160         return nullptr;
163 Plane* ResourceManager::reserve_plane(Plane* plane)
165         if (!plane)
166                 return nullptr;
168         if (m_reserved_planes.count(plane))
169                 return nullptr;
171         m_reserved_planes.insert(plane);
173         return plane;
176 Plane* ResourceManager::reserve_generic_plane(Crtc* crtc, PixelFormat format)
178         if (!crtc)
179                 return nullptr;
181         for (Plane* plane : crtc->get_possible_planes()) {
182                 if (plane->plane_type() == PlaneType::Cursor)
183                         continue;
185                 if (format != PixelFormat::Undefined && !plane->supports_format(format))
186                         continue;
188                 if (m_reserved_planes.count(plane))
189                         continue;
191                 m_reserved_planes.insert(plane);
192                 return plane;
193         }
195         return nullptr;
198 Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format)
200         return reserve_plane(crtc, PlaneType::Primary, format);
203 Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format)
205         return reserve_plane(crtc, PlaneType::Overlay, format);