From 8e9eecb32f0812b58670ebb8c135a0914c170569 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 1 Sep 2016 15:24:26 +0300 Subject: Improve struct Videomode Enable set/get for sync polarities and interlace. Add videomode_from_timings() helper to construct Videomode from non-X timings. Signed-off-by: Tomi Valkeinen --- kms++/inc/kms++/videomode.h | 19 ++++++++++- kms++/src/videomode.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 3 deletions(-) (limited to 'kms++') diff --git a/kms++/inc/kms++/videomode.h b/kms++/inc/kms++/videomode.h index ec16969..39e5639 100644 --- a/kms++/inc/kms++/videomode.h +++ b/kms++/inc/kms++/videomode.h @@ -9,6 +9,13 @@ namespace kms { +enum class SyncPolarity +{ + Undefined, + Positive, + Negative, +}; + struct Videomode { std::string name; @@ -32,8 +39,18 @@ struct Videomode uint16_t vsw() const { return vsync_end - vsync_start; } uint16_t vbp() const { return vtotal - vsync_end; } - bool interlace() const; float calculated_vrefresh() const; + + bool interlace() const; + SyncPolarity hsync() const; + SyncPolarity vsync() const; + + void set_interlace(bool ilace); + void set_hsync(SyncPolarity pol); + void set_vsync(SyncPolarity pol); }; +struct Videomode videomode_from_timings(uint32_t clock_khz, + uint16_t hact, uint16_t hfp, uint16_t hsw, uint16_t hbp, + uint16_t vact, uint16_t vfp, uint16_t vsw, uint16_t vbp); } diff --git a/kms++/src/videomode.cpp b/kms++/src/videomode.cpp index 16330bb..107ee3b 100644 --- a/kms++/src/videomode.cpp +++ b/kms++/src/videomode.cpp @@ -16,14 +16,92 @@ unique_ptr Videomode::to_blob(Card& card) const return unique_ptr(new Blob(card, &drm_mode, sizeof(drm_mode))); } +float Videomode::calculated_vrefresh() const +{ + return (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1); +} + bool Videomode::interlace() const { return flags & DRM_MODE_FLAG_INTERLACE; } -float Videomode::calculated_vrefresh() const +SyncPolarity Videomode::hsync() const { - return (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1); + if (flags & DRM_MODE_FLAG_PHSYNC) + return SyncPolarity::Positive; + if (flags & DRM_MODE_FLAG_NHSYNC) + return SyncPolarity::Negative; + return SyncPolarity::Undefined; +} + +SyncPolarity Videomode::vsync() const +{ + if (flags & DRM_MODE_FLAG_PVSYNC) + return SyncPolarity::Positive; + if (flags & DRM_MODE_FLAG_NVSYNC) + return SyncPolarity::Negative; + return SyncPolarity::Undefined; +} + +void Videomode::set_interlace(bool ilace) +{ + if (ilace) + flags |= DRM_MODE_FLAG_INTERLACE; + else + flags &= ~DRM_MODE_FLAG_INTERLACE; +} + +void Videomode::set_hsync(SyncPolarity pol) +{ + flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC); + + switch (pol) { + case SyncPolarity::Positive: + flags |= DRM_MODE_FLAG_PHSYNC; + break; + case SyncPolarity::Negative: + flags |= DRM_MODE_FLAG_NHSYNC; + break; + default: + break; + } +} + +void Videomode::set_vsync(SyncPolarity pol) +{ + flags &= ~(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC); + + switch (pol) { + case SyncPolarity::Positive: + flags |= DRM_MODE_FLAG_PVSYNC; + break; + case SyncPolarity::Negative: + flags |= DRM_MODE_FLAG_NVSYNC; + break; + default: + break; + } +} + +Videomode videomode_from_timings(uint32_t clock_khz, + uint16_t hact, uint16_t hfp, uint16_t hsw, uint16_t hbp, + uint16_t vact, uint16_t vfp, uint16_t vsw, uint16_t vbp) +{ + Videomode m { }; + m.clock = clock_khz; + + m.hdisplay = hact; + m.hsync_start = hact + hfp; + m.hsync_end = hact + hfp + hsw; + m.htotal = hact + hfp + hsw + hbp; + + m.vdisplay = vact; + m.vsync_start = vact + vfp; + m.vsync_end = vact + vfp + vsw; + m.vtotal = vact + vfp + vsw + vbp; + + return m; } } -- cgit v1.2.3