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 8 ResourceManager::ResourceManager(Card& card) 9 : m_card(card) 10 { 11 } 12 13 void ResourceManager::reset() 14 { 15 m_reserved_connectors.clear(); 16 m_reserved_crtcs.clear(); 17 m_reserved_planes.clear(); 18 } 19 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 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 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 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 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 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 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 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 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 198 Plane* ResourceManager::reserve_primary_plane(Crtc* crtc, PixelFormat format) 199 { 200 return reserve_plane(crtc, PlaneType::Primary, format); 201 } 202 203 Plane* ResourceManager::reserve_overlay_plane(Crtc* crtc, PixelFormat format) 204 { 205 return reserve_plane(crtc, PlaneType::Overlay, format); 206 } 207