1 #include <cstdio>
2 #include <iostream>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <cassert>
6 #include <xf86drm.h>
7 #include <xf86drmMode.h>
8 #include <algorithm>
9 
10 #include <kms++/kms++.h>
11 
12 using namespace std;
13 
14 namespace kms
15 {
16 struct PlanePriv {
17 	drmModePlanePtr drm_plane;
18 };
19 
Plane(Card & card,uint32_t id,uint32_t idx)20 Plane::Plane(Card& card, uint32_t id, uint32_t idx)
21 	: DrmPropObject(card, id, DRM_MODE_OBJECT_PLANE, idx)
22 {
23 	m_priv = new PlanePriv();
24 	m_priv->drm_plane = drmModeGetPlane(this->card().fd(), this->id());
25 	assert(m_priv->drm_plane);
26 }
27 
~Plane()28 Plane::~Plane()
29 {
30 	drmModeFreePlane(m_priv->drm_plane);
31 	delete m_priv;
32 }
33 
supports_crtc(Crtc * crtc) const34 bool Plane::supports_crtc(Crtc* crtc) const
35 {
36 	return m_priv->drm_plane->possible_crtcs & (1 << crtc->idx());
37 }
38 
supports_format(PixelFormat fmt) const39 bool Plane::supports_format(PixelFormat fmt) const
40 {
41 	auto p = m_priv->drm_plane;
42 
43 	for (unsigned i = 0; i < p->count_formats; ++i)
44 		if ((uint32_t)fmt == p->formats[i])
45 			return true;
46 
47 	return false;
48 }
49 
plane_type() const50 PlaneType Plane::plane_type() const
51 {
52 	if (card().has_universal_planes()) {
53 		switch (get_prop_value("type")) {
54 		case DRM_PLANE_TYPE_OVERLAY:
55 			return PlaneType::Overlay;
56 		case DRM_PLANE_TYPE_PRIMARY:
57 			return PlaneType::Primary;
58 		case DRM_PLANE_TYPE_CURSOR:
59 			return PlaneType::Cursor;
60 		default:
61 			throw invalid_argument("Bad plane type");
62 		}
63 	} else {
64 		return PlaneType::Overlay;
65 	}
66 }
67 
get_possible_crtcs() const68 vector<Crtc*> Plane::get_possible_crtcs() const
69 {
70 	unsigned idx = 0;
71 	vector<Crtc*> v;
72 	auto crtcs = card().get_crtcs();
73 
74 	for (uint32_t crtc_mask = m_priv->drm_plane->possible_crtcs;
75 	     crtc_mask;
76 	     idx++, crtc_mask >>= 1) {
77 		if ((crtc_mask & 1) == 0)
78 			continue;
79 
80 		auto iter = find_if(crtcs.begin(), crtcs.end(), [idx](Crtc* crtc) { return crtc->idx() == idx; });
81 
82 		if (iter == crtcs.end())
83 			continue;
84 
85 		v.push_back(*iter);
86 	}
87 
88 	return v;
89 }
90 
get_formats() const91 vector<PixelFormat> Plane::get_formats() const
92 {
93 	auto p = m_priv->drm_plane;
94 	vector<PixelFormat> r;
95 
96 	for (unsigned i = 0; i < p->count_formats; ++i)
97 		r.push_back((PixelFormat)p->formats[i]);
98 
99 	return r;
100 }
101 
crtc_id() const102 uint32_t Plane::crtc_id() const
103 {
104 	return m_priv->drm_plane->crtc_id;
105 }
106 
fb_id() const107 uint32_t Plane::fb_id() const
108 {
109 	return m_priv->drm_plane->fb_id;
110 }
111 
crtc_x() const112 uint32_t Plane::crtc_x() const
113 {
114 	return m_priv->drm_plane->crtc_x;
115 }
116 
crtc_y() const117 uint32_t Plane::crtc_y() const
118 {
119 	return m_priv->drm_plane->crtc_y;
120 }
121 
x() const122 uint32_t Plane::x() const
123 {
124 	return m_priv->drm_plane->x;
125 }
126 
y() const127 uint32_t Plane::y() const
128 {
129 	return m_priv->drm_plane->y;
130 }
131 
gamma_size() const132 uint32_t Plane::gamma_size() const
133 {
134 	return m_priv->drm_plane->gamma_size;
135 }
136 
137 } // namespace kms
138