diff options
Diffstat (limited to 'kms++/src/atomicreq.cpp')
| -rw-r--r-- | kms++/src/atomicreq.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/kms++/src/atomicreq.cpp b/kms++/src/atomicreq.cpp new file mode 100644 index 0000000..1ef4f7d --- /dev/null +++ b/kms++/src/atomicreq.cpp @@ -0,0 +1,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 |
