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