Home | History | Annotate | Download | only in src
      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