summaryrefslogtreecommitdiff
path: root/kms++/src/atomicreq.cpp
blob: 1ef4f7d2fac47ea877785838812df2061ad9a1b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <cassert>
#include <stdexcept>

#include <xf86drm.h>
#include <xf86drmMode.h>

#include <kms++/kms++.h>

#ifndef DRM_CLIENT_CAP_ATOMIC

#define DRM_MODE_ATOMIC_TEST_ONLY 0
#define DRM_MODE_ATOMIC_NONBLOCK 0

struct _drmModeAtomicReq;
typedef struct _drmModeAtomicReq* drmModeAtomicReqPtr;

static inline drmModeAtomicReqPtr drmModeAtomicAlloc()
{
	return 0;
}
static inline void drmModeAtomicFree(drmModeAtomicReqPtr)
{
}
static inline int drmModeAtomicAddProperty(drmModeAtomicReqPtr, uint32_t, uint32_t, uint64_t)
{
	return 0;
}
static inline int drmModeAtomicCommit(int, drmModeAtomicReqPtr, int, void*)
{
	return 0;
}

#endif // DRM_CLIENT_CAP_ATOMIC

using namespace std;

namespace kms
{
AtomicReq::AtomicReq(Card& card)
	: m_card(card)
{
	assert(card.has_atomic());
	m_req = drmModeAtomicAlloc();
}

AtomicReq::~AtomicReq()
{
	drmModeAtomicFree(m_req);
}

void AtomicReq::add(uint32_t ob_id, uint32_t prop_id, uint64_t value)
{
	int r = drmModeAtomicAddProperty(m_req, ob_id, prop_id, value);
	if (r <= 0)
		throw std::invalid_argument("foo");
}

void AtomicReq::add(DrmPropObject* ob, Property* prop, uint64_t value)
{
	add(ob->id(), prop->id(), value);
}

void AtomicReq::add(kms::DrmPropObject* ob, const string& prop, uint64_t value)
{
	Property* p = ob->get_prop(prop);

	if (!p)
		throw runtime_error("Property not found");

	add(ob, p, value);
}

void AtomicReq::add(kms::DrmPropObject* ob, const map<string, uint64_t>& values)
{
	for (const auto& kvp : values)
		add(ob, kvp.first, kvp.second);
}

void AtomicReq::add_display(Connector* conn, Crtc* crtc, Blob* videomode, Plane* primary, Framebuffer* fb)
{
	add(conn, {
			  { "CRTC_ID", crtc->id() },
		  });

	add(crtc, {
			  { "ACTIVE", 1 },
			  { "MODE_ID", videomode->id() },
		  });

	add(primary, {
			     { "FB_ID", fb->id() },
			     { "CRTC_ID", crtc->id() },
			     { "SRC_X", 0 << 16 },
			     { "SRC_Y", 0 << 16 },
			     { "SRC_W", fb->width() << 16 },
			     { "SRC_H", fb->height() << 16 },
			     { "CRTC_X", 0 },
			     { "CRTC_Y", 0 },
			     { "CRTC_W", fb->width() },
			     { "CRTC_H", fb->height() },
		     });
}

int AtomicReq::test(bool allow_modeset)
{
	uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY;

	if (allow_modeset)
		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;

	return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0);
}

int AtomicReq::commit(void* data, bool allow_modeset)
{
	uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;

	if (allow_modeset)
		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;

	return drmModeAtomicCommit(m_card.fd(), m_req, flags, data);
}

int AtomicReq::commit_sync(bool allow_modeset)
{
	uint32_t flags = 0;

	if (allow_modeset)
		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;

	return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0);
}
} // namespace kms