xref: /aosp_15_r20/external/libkmsxx/kms++/src/atomicreq.cpp (revision f0687c8a10b3e371dbe09214db6664e37c283cca)
1*f0687c8aSRaman Tenneti #include <cassert>
2*f0687c8aSRaman Tenneti #include <stdexcept>
3*f0687c8aSRaman Tenneti 
4*f0687c8aSRaman Tenneti #include <xf86drm.h>
5*f0687c8aSRaman Tenneti #include <xf86drmMode.h>
6*f0687c8aSRaman Tenneti 
7*f0687c8aSRaman Tenneti #include <kms++/kms++.h>
8*f0687c8aSRaman Tenneti 
9*f0687c8aSRaman Tenneti #ifndef DRM_CLIENT_CAP_ATOMIC
10*f0687c8aSRaman Tenneti 
11*f0687c8aSRaman Tenneti #define DRM_MODE_ATOMIC_TEST_ONLY 0
12*f0687c8aSRaman Tenneti #define DRM_MODE_ATOMIC_NONBLOCK 0
13*f0687c8aSRaman Tenneti 
14*f0687c8aSRaman Tenneti struct _drmModeAtomicReq;
15*f0687c8aSRaman Tenneti typedef struct _drmModeAtomicReq* drmModeAtomicReqPtr;
16*f0687c8aSRaman Tenneti 
drmModeAtomicAlloc()17*f0687c8aSRaman Tenneti static inline drmModeAtomicReqPtr drmModeAtomicAlloc()
18*f0687c8aSRaman Tenneti {
19*f0687c8aSRaman Tenneti 	return 0;
20*f0687c8aSRaman Tenneti }
drmModeAtomicFree(drmModeAtomicReqPtr)21*f0687c8aSRaman Tenneti static inline void drmModeAtomicFree(drmModeAtomicReqPtr)
22*f0687c8aSRaman Tenneti {
23*f0687c8aSRaman Tenneti }
drmModeAtomicAddProperty(drmModeAtomicReqPtr,uint32_t,uint32_t,uint64_t)24*f0687c8aSRaman Tenneti static inline int drmModeAtomicAddProperty(drmModeAtomicReqPtr, uint32_t, uint32_t, uint64_t)
25*f0687c8aSRaman Tenneti {
26*f0687c8aSRaman Tenneti 	return 0;
27*f0687c8aSRaman Tenneti }
drmModeAtomicCommit(int,drmModeAtomicReqPtr,int,void *)28*f0687c8aSRaman Tenneti static inline int drmModeAtomicCommit(int, drmModeAtomicReqPtr, int, void*)
29*f0687c8aSRaman Tenneti {
30*f0687c8aSRaman Tenneti 	return 0;
31*f0687c8aSRaman Tenneti }
32*f0687c8aSRaman Tenneti 
33*f0687c8aSRaman Tenneti #endif // DRM_CLIENT_CAP_ATOMIC
34*f0687c8aSRaman Tenneti 
35*f0687c8aSRaman Tenneti using namespace std;
36*f0687c8aSRaman Tenneti 
37*f0687c8aSRaman Tenneti namespace kms
38*f0687c8aSRaman Tenneti {
AtomicReq(Card & card)39*f0687c8aSRaman Tenneti AtomicReq::AtomicReq(Card& card)
40*f0687c8aSRaman Tenneti 	: m_card(card)
41*f0687c8aSRaman Tenneti {
42*f0687c8aSRaman Tenneti 	assert(card.has_atomic());
43*f0687c8aSRaman Tenneti 	m_req = drmModeAtomicAlloc();
44*f0687c8aSRaman Tenneti }
45*f0687c8aSRaman Tenneti 
~AtomicReq()46*f0687c8aSRaman Tenneti AtomicReq::~AtomicReq()
47*f0687c8aSRaman Tenneti {
48*f0687c8aSRaman Tenneti 	drmModeAtomicFree(m_req);
49*f0687c8aSRaman Tenneti }
50*f0687c8aSRaman Tenneti 
add(uint32_t ob_id,uint32_t prop_id,uint64_t value)51*f0687c8aSRaman Tenneti void AtomicReq::add(uint32_t ob_id, uint32_t prop_id, uint64_t value)
52*f0687c8aSRaman Tenneti {
53*f0687c8aSRaman Tenneti 	int r = drmModeAtomicAddProperty(m_req, ob_id, prop_id, value);
54*f0687c8aSRaman Tenneti 	if (r <= 0)
55*f0687c8aSRaman Tenneti 		throw std::invalid_argument("foo");
56*f0687c8aSRaman Tenneti }
57*f0687c8aSRaman Tenneti 
add(DrmPropObject * ob,Property * prop,uint64_t value)58*f0687c8aSRaman Tenneti void AtomicReq::add(DrmPropObject* ob, Property* prop, uint64_t value)
59*f0687c8aSRaman Tenneti {
60*f0687c8aSRaman Tenneti 	add(ob->id(), prop->id(), value);
61*f0687c8aSRaman Tenneti }
62*f0687c8aSRaman Tenneti 
add(kms::DrmPropObject * ob,const string & prop,uint64_t value)63*f0687c8aSRaman Tenneti void AtomicReq::add(kms::DrmPropObject* ob, const string& prop, uint64_t value)
64*f0687c8aSRaman Tenneti {
65*f0687c8aSRaman Tenneti 	Property* p = ob->get_prop(prop);
66*f0687c8aSRaman Tenneti 
67*f0687c8aSRaman Tenneti 	if (!p)
68*f0687c8aSRaman Tenneti 		throw runtime_error("Property not found");
69*f0687c8aSRaman Tenneti 
70*f0687c8aSRaman Tenneti 	add(ob, p, value);
71*f0687c8aSRaman Tenneti }
72*f0687c8aSRaman Tenneti 
add(kms::DrmPropObject * ob,const map<string,uint64_t> & values)73*f0687c8aSRaman Tenneti void AtomicReq::add(kms::DrmPropObject* ob, const map<string, uint64_t>& values)
74*f0687c8aSRaman Tenneti {
75*f0687c8aSRaman Tenneti 	for (const auto& kvp : values)
76*f0687c8aSRaman Tenneti 		add(ob, kvp.first, kvp.second);
77*f0687c8aSRaman Tenneti }
78*f0687c8aSRaman Tenneti 
add_display(Connector * conn,Crtc * crtc,Blob * videomode,Plane * primary,Framebuffer * fb)79*f0687c8aSRaman Tenneti void AtomicReq::add_display(Connector* conn, Crtc* crtc, Blob* videomode, Plane* primary, Framebuffer* fb)
80*f0687c8aSRaman Tenneti {
81*f0687c8aSRaman Tenneti 	add(conn, {
82*f0687c8aSRaman Tenneti 			  { "CRTC_ID", crtc->id() },
83*f0687c8aSRaman Tenneti 		  });
84*f0687c8aSRaman Tenneti 
85*f0687c8aSRaman Tenneti 	add(crtc, {
86*f0687c8aSRaman Tenneti 			  { "ACTIVE", 1 },
87*f0687c8aSRaman Tenneti 			  { "MODE_ID", videomode->id() },
88*f0687c8aSRaman Tenneti 		  });
89*f0687c8aSRaman Tenneti 
90*f0687c8aSRaman Tenneti 	add(primary, {
91*f0687c8aSRaman Tenneti 			     { "FB_ID", fb->id() },
92*f0687c8aSRaman Tenneti 			     { "CRTC_ID", crtc->id() },
93*f0687c8aSRaman Tenneti 			     { "SRC_X", 0 << 16 },
94*f0687c8aSRaman Tenneti 			     { "SRC_Y", 0 << 16 },
95*f0687c8aSRaman Tenneti 			     { "SRC_W", fb->width() << 16 },
96*f0687c8aSRaman Tenneti 			     { "SRC_H", fb->height() << 16 },
97*f0687c8aSRaman Tenneti 			     { "CRTC_X", 0 },
98*f0687c8aSRaman Tenneti 			     { "CRTC_Y", 0 },
99*f0687c8aSRaman Tenneti 			     { "CRTC_W", fb->width() },
100*f0687c8aSRaman Tenneti 			     { "CRTC_H", fb->height() },
101*f0687c8aSRaman Tenneti 		     });
102*f0687c8aSRaman Tenneti }
103*f0687c8aSRaman Tenneti 
test(bool allow_modeset)104*f0687c8aSRaman Tenneti int AtomicReq::test(bool allow_modeset)
105*f0687c8aSRaman Tenneti {
106*f0687c8aSRaman Tenneti 	uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY;
107*f0687c8aSRaman Tenneti 
108*f0687c8aSRaman Tenneti 	if (allow_modeset)
109*f0687c8aSRaman Tenneti 		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
110*f0687c8aSRaman Tenneti 
111*f0687c8aSRaman Tenneti 	return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0);
112*f0687c8aSRaman Tenneti }
113*f0687c8aSRaman Tenneti 
commit(void * data,bool allow_modeset)114*f0687c8aSRaman Tenneti int AtomicReq::commit(void* data, bool allow_modeset)
115*f0687c8aSRaman Tenneti {
116*f0687c8aSRaman Tenneti 	uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
117*f0687c8aSRaman Tenneti 
118*f0687c8aSRaman Tenneti 	if (allow_modeset)
119*f0687c8aSRaman Tenneti 		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
120*f0687c8aSRaman Tenneti 
121*f0687c8aSRaman Tenneti 	return drmModeAtomicCommit(m_card.fd(), m_req, flags, data);
122*f0687c8aSRaman Tenneti }
123*f0687c8aSRaman Tenneti 
commit_sync(bool allow_modeset)124*f0687c8aSRaman Tenneti int AtomicReq::commit_sync(bool allow_modeset)
125*f0687c8aSRaman Tenneti {
126*f0687c8aSRaman Tenneti 	uint32_t flags = 0;
127*f0687c8aSRaman Tenneti 
128*f0687c8aSRaman Tenneti 	if (allow_modeset)
129*f0687c8aSRaman Tenneti 		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
130*f0687c8aSRaman Tenneti 
131*f0687c8aSRaman Tenneti 	return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0);
132*f0687c8aSRaman Tenneti }
133*f0687c8aSRaman Tenneti } // namespace kms
134