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