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 unsigned int size; unsigned long offset; unsigned long free; } drm_via_mm_t#include <xf86drm.h> #include <xf86drmMode.h> #include <math.h> #include <kms++/kms++.h> #include "helpers.h" using namespace std; namespace kms { unique_ptr<Blob> Videomode::to_blob(Card& card) const { drmModeModeInfo drm_mode = video_mode_to_drm_mode(*this); return unique_ptr<Blob>(new Blob(card, &drm_mode, sizeof(drm_mode))); } float Videomode::calculated_vrefresh() const { // XXX interlace should only halve visible vertical lines, not blanking float refresh = (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1); return roundf(refresh * 100.0) / 100.0; } bool Videomode::interlace() const { return flags & DRM_MODE_FLAG_INTERLACE; } SyncPolarity Videomode::hsync() const { 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; } }