summaryrefslogtreecommitdiff
path: root/kms++/inc
diff options
context:
space:
mode:
Diffstat (limited to 'kms++/inc')
-rw-r--r--kms++/inc/kms++/atomicreq.h36
-rw-r--r--kms++/inc/kms++/blob.h22
-rw-r--r--kms++/inc/kms++/card.h71
-rw-r--r--kms++/inc/kms++/connector.h51
-rw-r--r--kms++/inc/kms++/crtc.h50
-rw-r--r--kms++/inc/kms++/decls.h19
-rw-r--r--kms++/inc/kms++/drmobject.h40
-rw-r--r--kms++/inc/kms++/drmpropobject.h35
-rw-r--r--kms++/inc/kms++/dumbframebuffer.h46
-rw-r--r--kms++/inc/kms++/encoder.h25
-rw-r--r--kms++/inc/kms++/extframebuffer.h21
-rw-r--r--kms++/inc/kms++/framebuffer.h40
-rw-r--r--kms++/inc/kms++/kms++.h15
-rw-r--r--kms++/inc/kms++/modedb.h16
-rw-r--r--kms++/inc/kms++/pagefliphandler.h11
-rw-r--r--kms++/inc/kms++/pipeline.h11
-rw-r--r--kms++/inc/kms++/pixelformats.h63
-rw-r--r--kms++/inc/kms++/plane.h41
-rw-r--r--kms++/inc/kms++/property.h44
-rw-r--r--kms++/inc/kms++/videomode.h36
20 files changed, 693 insertions, 0 deletions
diff --git a/kms++/inc/kms++/atomicreq.h b/kms++/inc/kms++/atomicreq.h
new file mode 100644
index 0000000..6ebdbf8
--- /dev/null
+++ b/kms++/inc/kms++/atomicreq.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include <map>
+
+struct _drmModeAtomicReq;
+
+#include "decls.h"
+
+namespace kms
+{
+class AtomicReq
+{
+public:
+ AtomicReq(Card& card);
+ ~AtomicReq();
+
+ AtomicReq(const AtomicReq& other) = delete;
+ AtomicReq& operator=(const AtomicReq& other) = delete;
+
+ void add(uint32_t ob_id, uint32_t prop_id, uint64_t value);
+ void add(DrmObject *ob, Property *prop, uint64_t value);
+ void add(DrmObject *ob, const std::string& prop, uint64_t value);
+ void add(DrmObject *ob, const std::map<std::string, uint64_t>& values);
+
+ int test(bool allow_modeset = false);
+ int commit(void* data, bool allow_modeset = false);
+ int commit_sync(bool allow_modeset = false);
+
+private:
+ Card& m_card;
+ _drmModeAtomicReq* m_req;
+};
+
+}
diff --git a/kms++/inc/kms++/blob.h b/kms++/inc/kms++/blob.h
new file mode 100644
index 0000000..fd872f1
--- /dev/null
+++ b/kms++/inc/kms++/blob.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "drmobject.h"
+#include <vector>
+
+namespace kms
+{
+
+class Blob : public DrmObject
+{
+public:
+ Blob(Card& card, uint32_t blob_id);
+ Blob(Card& card, void* data, size_t len);
+ virtual ~Blob();
+
+ std::vector<uint8_t> data();
+
+private:
+ bool m_created;
+};
+
+}
diff --git a/kms++/inc/kms++/card.h b/kms++/inc/kms++/card.h
new file mode 100644
index 0000000..5ecaecf
--- /dev/null
+++ b/kms++/inc/kms++/card.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include <cstdint>
+#include <vector>
+#include <map>
+
+#include "decls.h"
+#include "pipeline.h"
+
+namespace kms
+{
+class Card
+{
+ friend class Framebuffer;
+public:
+ Card();
+ Card(const std::string& device);
+ ~Card();
+
+ Card(const Card& other) = delete;
+ Card& operator=(const Card& other) = delete;
+
+ int fd() const { return m_fd; }
+
+ void drop_master();
+
+ Connector* get_first_connected_connector() const;
+
+ DrmObject* get_object(uint32_t id) const;
+ Connector* get_connector(uint32_t id) const;
+ Crtc* get_crtc(uint32_t id) const;
+ Encoder* get_encoder(uint32_t id) const;
+ Plane* get_plane(uint32_t id) const;
+ Property* get_prop(uint32_t id) const;
+ Property* get_prop(const std::string& name) const;
+
+ bool master() const { return m_master; }
+ bool has_atomic() const { return m_has_atomic; }
+ bool has_has_universal_planes() const { return m_has_universal_planes; }
+
+ const std::vector<Connector*> get_connectors() const { return m_connectors; }
+ const std::vector<Encoder*> get_encoders() const { return m_encoders; }
+ const std::vector<Crtc*> get_crtcs() const { return m_crtcs; }
+ const std::vector<Plane*> get_planes() const { return m_planes; }
+ const std::vector<Property*> get_properties() const { return m_properties; }
+
+ const std::vector<DrmObject*> get_objects() const;
+
+ std::vector<Pipeline> get_connected_pipelines();
+
+ void call_page_flip_handlers();
+
+private:
+ void restore_modes();
+
+ std::map<uint32_t, DrmObject*> m_obmap;
+
+ std::vector<Connector*> m_connectors;
+ std::vector<Encoder*> m_encoders;
+ std::vector<Crtc*> m_crtcs;
+ std::vector<Plane*> m_planes;
+ std::vector<Property*> m_properties;
+ std::vector<Framebuffer*> m_framebuffers;
+
+ int m_fd;
+ bool m_master;
+
+ bool m_has_atomic;
+ bool m_has_universal_planes;
+};
+}
diff --git a/kms++/inc/kms++/connector.h b/kms++/inc/kms++/connector.h
new file mode 100644
index 0000000..6ccc959
--- /dev/null
+++ b/kms++/inc/kms++/connector.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <vector>
+
+#include "drmpropobject.h"
+#include "videomode.h"
+
+namespace kms
+{
+
+struct ConnectorPriv;
+
+class Connector : public DrmPropObject
+{
+ friend class Card;
+public:
+ Videomode get_default_mode() const;
+
+ Videomode get_mode(const std::string& mode) const;
+ Videomode get_mode(unsigned xres, unsigned yres, unsigned refresh, bool ilace) const;
+
+ Crtc* get_current_crtc() const;
+ std::vector<Crtc*> get_possible_crtcs() const;
+
+ bool connected() const;
+
+ const std::string& fullname() const { return m_fullname; }
+ uint32_t connector_type() const;
+ uint32_t connector_type_id() const;
+ uint32_t mmWidth() const;
+ uint32_t mmHeight() const;
+ uint32_t subpixel() const;
+ const std::string& subpixel_str() const;
+ std::vector<Videomode> get_modes() const;
+ std::vector<Encoder*> get_encoders() const;
+private:
+ Connector(Card& card, uint32_t id, uint32_t idx);
+ ~Connector();
+
+ void setup();
+ void restore_mode();
+
+ ConnectorPriv* m_priv;
+
+ std::string m_fullname;
+
+ Encoder* m_current_encoder;
+
+ Crtc* m_saved_crtc;
+};
+}
diff --git a/kms++/inc/kms++/crtc.h b/kms++/inc/kms++/crtc.h
new file mode 100644
index 0000000..f3b525a
--- /dev/null
+++ b/kms++/inc/kms++/crtc.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <vector>
+
+#include "drmpropobject.h"
+
+namespace kms
+{
+
+struct CrtcPriv;
+
+class Crtc : public DrmPropObject
+{
+ friend class Card;
+ friend class Connector;
+public:
+ const std::vector<Plane*>& get_possible_planes() const { return m_possible_planes; }
+
+ int set_mode(Connector* conn, Framebuffer& fb, const Videomode& mode);
+
+ int set_plane(Plane *plane, Framebuffer &fb,
+ int32_t dst_x, int32_t dst_y, uint32_t dst_w, uint32_t dst_h,
+ float src_x, float src_y, float src_w, float src_h);
+
+ int disable_plane(Plane* plane);
+
+ Plane* get_primary_plane();
+
+ int page_flip(Framebuffer& fb, void *data);
+
+ uint32_t buffer_id() const;
+ uint32_t x() const;
+ uint32_t y() const;
+ uint32_t width() const;
+ uint32_t height() const;
+ int mode_valid() const;
+ Videomode mode() const;
+ int gamma_size() const;
+private:
+ Crtc(Card& card, uint32_t id, uint32_t idx);
+ ~Crtc();
+
+ void setup();
+ void restore_mode(Connector *conn);
+
+ CrtcPriv* m_priv;
+
+ std::vector<Plane*> m_possible_planes;
+};
+}
diff --git a/kms++/inc/kms++/decls.h b/kms++/inc/kms++/decls.h
new file mode 100644
index 0000000..e84b29a
--- /dev/null
+++ b/kms++/inc/kms++/decls.h
@@ -0,0 +1,19 @@
+#pragma once
+
+namespace kms
+{
+class AtomicReq;
+class Card;
+class Connector;
+class Crtc;
+class Encoder;
+class Framebuffer;
+class DumbFramebuffer;
+class ExtFramebuffer;
+class DrmObject;
+class PageFlipHandlerBase;
+class Plane;
+class Property;
+class Blob;
+struct Videomode;
+}
diff --git a/kms++/inc/kms++/drmobject.h b/kms++/inc/kms++/drmobject.h
new file mode 100644
index 0000000..a939aa7
--- /dev/null
+++ b/kms++/inc/kms++/drmobject.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <map>
+
+#include "decls.h"
+
+namespace kms
+{
+
+class DrmObject
+{
+ friend class Card;
+public:
+ DrmObject(const DrmObject& other) = delete;
+ DrmObject& operator=(const DrmObject& other) = delete;
+
+ uint32_t id() const { return m_id; }
+ Card& card() const { return m_card; }
+
+ uint32_t object_type() const { return m_object_type; }
+ uint32_t idx() const { return m_idx; }
+
+protected:
+ DrmObject(Card& card, uint32_t object_type);
+ DrmObject(Card& card, uint32_t id, uint32_t object_type, uint32_t idx = 0);
+
+ virtual ~DrmObject();
+
+ virtual void setup() { }
+
+ virtual void set_id(uint32_t id);
+
+private:
+ Card& m_card;
+
+ uint32_t m_id;
+ uint32_t m_object_type;
+ uint32_t m_idx;
+};
+}
diff --git a/kms++/inc/kms++/drmpropobject.h b/kms++/inc/kms++/drmpropobject.h
new file mode 100644
index 0000000..ec28d45
--- /dev/null
+++ b/kms++/inc/kms++/drmpropobject.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <map>
+#include <memory>
+
+#include "drmobject.h"
+#include "decls.h"
+
+namespace kms
+{
+
+class DrmPropObject : public DrmObject
+{
+ friend class Card;
+public:
+ void refresh_props();
+ uint64_t get_prop_value(uint32_t id) const;
+ uint64_t get_prop_value(const std::string& name) const;
+ std::unique_ptr<Blob> get_prop_value_as_blob(const std::string& name) const;
+
+ const std::map<uint32_t, uint64_t>& get_prop_map() const { return m_prop_values; }
+
+ int set_prop_value(uint32_t id, uint64_t value);
+ int set_prop_value(const std::string& name, uint64_t value);
+
+protected:
+ DrmPropObject(Card& card, uint32_t object_type);
+ DrmPropObject(Card& card, uint32_t id, uint32_t object_type, uint32_t idx = 0);
+
+ virtual ~DrmPropObject();
+
+private:
+ std::map<uint32_t, uint64_t> m_prop_values;
+};
+}
diff --git a/kms++/inc/kms++/dumbframebuffer.h b/kms++/inc/kms++/dumbframebuffer.h
new file mode 100644
index 0000000..6b3ee64
--- /dev/null
+++ b/kms++/inc/kms++/dumbframebuffer.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "framebuffer.h"
+#include "pixelformats.h"
+
+namespace kms
+{
+class DumbFramebuffer : public Framebuffer, public IMappedFramebuffer
+{
+public:
+ DumbFramebuffer(Card& card, uint32_t width, uint32_t height, const std::string& fourcc);
+ DumbFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format);
+ virtual ~DumbFramebuffer();
+
+ uint32_t width() const { return Framebuffer::width(); }
+ uint32_t height() const { return Framebuffer::height(); }
+
+ PixelFormat format() const { return m_format; }
+ unsigned num_planes() const { return m_num_planes; }
+
+ uint32_t handle(unsigned plane) const { return m_planes[plane].handle; }
+ uint32_t stride(unsigned plane) const { return m_planes[plane].stride; }
+ uint32_t size(unsigned plane) const { return m_planes[plane].size; }
+ uint32_t offset(unsigned plane) const { return m_planes[plane].offset; }
+ uint8_t* map(unsigned plane);
+ int prime_fd(unsigned plane);
+
+private:
+ struct FramebufferPlane {
+ uint32_t handle;
+ int prime_fd;
+ uint32_t size;
+ uint32_t stride;
+ uint32_t offset;
+ uint8_t *map;
+ };
+
+ void Create();
+ void Destroy();
+
+ unsigned m_num_planes;
+ struct FramebufferPlane m_planes[4];
+
+ PixelFormat m_format;
+};
+}
diff --git a/kms++/inc/kms++/encoder.h b/kms++/inc/kms++/encoder.h
new file mode 100644
index 0000000..b5aac70
--- /dev/null
+++ b/kms++/inc/kms++/encoder.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <vector>
+#include "drmpropobject.h"
+
+namespace kms
+{
+
+struct EncoderPriv;
+
+class Encoder : public DrmPropObject
+{
+ friend class Card;
+public:
+ Crtc* get_crtc() const;
+ std::vector<Crtc*> get_possible_crtcs() const;
+
+ const std::string& get_encoder_type() const;
+private:
+ Encoder(Card& card, uint32_t id, uint32_t idx);
+ ~Encoder();
+
+ EncoderPriv* m_priv;
+};
+}
diff --git a/kms++/inc/kms++/extframebuffer.h b/kms++/inc/kms++/extframebuffer.h
new file mode 100644
index 0000000..eab7e3c
--- /dev/null
+++ b/kms++/inc/kms++/extframebuffer.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "framebuffer.h"
+#include "pixelformats.h"
+
+namespace kms
+{
+
+class ExtFramebuffer : public Framebuffer
+{
+public:
+ ExtFramebuffer(Card& card, uint32_t width, uint32_t height, uint8_t depth, uint8_t bpp, uint32_t stride, uint32_t handle);
+ ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t handles[4], uint32_t pitches[4], uint32_t offsets[4]);
+ ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
+ int fds[4], uint32_t pitches[4], uint32_t offsets[4]);
+ virtual ~ExtFramebuffer();
+
+private:
+};
+}
diff --git a/kms++/inc/kms++/framebuffer.h b/kms++/inc/kms++/framebuffer.h
new file mode 100644
index 0000000..cbf705d
--- /dev/null
+++ b/kms++/inc/kms++/framebuffer.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "drmobject.h"
+#include "pixelformats.h"
+
+namespace kms
+{
+class Framebuffer : public DrmObject
+{
+public:
+ Framebuffer(Card& card, uint32_t id);
+ virtual ~Framebuffer();
+
+ uint32_t width() const { return m_width; }
+ uint32_t height() const { return m_height; }
+protected:
+ Framebuffer(Card& card, uint32_t width, uint32_t height);
+
+private:
+ uint32_t m_width;
+ uint32_t m_height;
+};
+
+class IMappedFramebuffer {
+public:
+ virtual ~IMappedFramebuffer() { }
+
+ virtual uint32_t width() const = 0;
+ virtual uint32_t height() const = 0;
+
+ virtual PixelFormat format() const = 0;
+ virtual unsigned num_planes() const = 0;
+
+ virtual uint32_t stride(unsigned plane) const = 0;
+ virtual uint32_t size(unsigned plane) const = 0;
+ virtual uint32_t offset(unsigned plane) const = 0;
+ virtual uint8_t* map(unsigned plane) = 0;
+};
+
+}
diff --git a/kms++/inc/kms++/kms++.h b/kms++/inc/kms++/kms++.h
new file mode 100644
index 0000000..3365ef7
--- /dev/null
+++ b/kms++/inc/kms++/kms++.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "atomicreq.h"
+#include "card.h"
+#include "connector.h"
+#include "crtc.h"
+#include "encoder.h"
+#include "framebuffer.h"
+#include "dumbframebuffer.h"
+#include "extframebuffer.h"
+#include "plane.h"
+#include "property.h"
+#include "blob.h"
+#include "pipeline.h"
+#include "pagefliphandler.h"
diff --git a/kms++/inc/kms++/modedb.h b/kms++/inc/kms++/modedb.h
new file mode 100644
index 0000000..43c7afc
--- /dev/null
+++ b/kms++/inc/kms++/modedb.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <cstdint>
+#include "videomode.h"
+
+namespace kms
+{
+struct Videomode;
+
+extern const Videomode dmt_modes[];
+extern const Videomode cea_modes[];
+
+const Videomode& find_dmt(uint32_t width, uint32_t height, uint32_t vrefresh, bool ilace);
+const Videomode& find_cea(uint32_t width, uint32_t height, uint32_t refresh, bool ilace);
+
+}
diff --git a/kms++/inc/kms++/pagefliphandler.h b/kms++/inc/kms++/pagefliphandler.h
new file mode 100644
index 0000000..79cda0d
--- /dev/null
+++ b/kms++/inc/kms++/pagefliphandler.h
@@ -0,0 +1,11 @@
+#pragma once
+
+namespace kms {
+class PageFlipHandlerBase
+{
+public:
+ PageFlipHandlerBase() { }
+ virtual ~PageFlipHandlerBase() { }
+ virtual void handle_page_flip(uint32_t frame, double time) = 0;
+};
+}
diff --git a/kms++/inc/kms++/pipeline.h b/kms++/inc/kms++/pipeline.h
new file mode 100644
index 0000000..ef04ec1
--- /dev/null
+++ b/kms++/inc/kms++/pipeline.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "decls.h"
+
+namespace kms
+{
+struct Pipeline {
+ Crtc* crtc;
+ Connector* connector;
+};
+}
diff --git a/kms++/inc/kms++/pixelformats.h b/kms++/inc/kms++/pixelformats.h
new file mode 100644
index 0000000..813eaef
--- /dev/null
+++ b/kms++/inc/kms++/pixelformats.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <cstdint>
+#include <string>
+
+namespace kms
+{
+constexpr uint32_t MakeFourCC(const char *fourcc)
+{
+ return fourcc[0] | (fourcc[1] << 8) | (fourcc[2] << 16) | (fourcc[3] << 24);
+}
+
+enum class PixelFormat : uint32_t
+{
+ Undefined = 0,
+
+ NV12 = MakeFourCC("NV12"),
+ NV21 = MakeFourCC("NV21"),
+
+ UYVY = MakeFourCC("UYVY"),
+ YUYV = MakeFourCC("YUYV"),
+ YVYU = MakeFourCC("YVYU"),
+ VYUY = MakeFourCC("VYUY"),
+
+ XRGB8888 = MakeFourCC("XR24"),
+ XBGR8888 = MakeFourCC("XB24"),
+ ARGB8888 = MakeFourCC("AR24"),
+ ABGR8888 = MakeFourCC("AB24"),
+
+ RGB565 = MakeFourCC("RG16"),
+};
+
+static inline PixelFormat FourCCToPixelFormat(const std::string& fourcc)
+{
+ return (PixelFormat)MakeFourCC(fourcc.c_str());
+}
+
+static inline std::string PixelFormatToFourCC(PixelFormat f)
+{
+ char buf[5] = { (char)(((int)f >> 0) & 0xff),
+ (char)(((int)f >> 8) & 0xff),
+ (char)(((int)f >> 16) & 0xff),
+ (char)(((int)f >> 24) & 0xff),
+ 0 };
+ return std::string(buf);
+}
+
+struct PixelFormatPlaneInfo
+{
+ uint8_t bitspp;
+ uint8_t xsub;
+ uint8_t ysub;
+};
+
+struct PixelFormatInfo
+{
+ uint8_t num_planes;
+ struct PixelFormatPlaneInfo planes[4];
+};
+
+const struct PixelFormatInfo& get_pixel_format_info(PixelFormat format);
+
+}
diff --git a/kms++/inc/kms++/plane.h b/kms++/inc/kms++/plane.h
new file mode 100644
index 0000000..d50e539
--- /dev/null
+++ b/kms++/inc/kms++/plane.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "drmpropobject.h"
+
+namespace kms
+{
+
+enum class PlaneType
+{
+ Overlay = 0,
+ Primary = 1,
+ Cursor = 2,
+};
+
+struct PlanePriv;
+
+class Plane : public DrmPropObject
+{
+ friend class Card;
+public:
+ bool supports_crtc(Crtc* crtc) const;
+ bool supports_format(PixelFormat fmt) const;
+
+ PlaneType plane_type() const;
+
+ std::vector<PixelFormat> get_formats() const;
+ uint32_t crtc_id() const;
+ uint32_t fb_id() const;
+
+ uint32_t crtc_x() const;
+ uint32_t crtc_y() const;
+ uint32_t x() const;
+ uint32_t y() const;
+ uint32_t gamma_size() const;
+private:
+ Plane(Card& card, uint32_t id, uint32_t idx);
+ ~Plane();
+
+ PlanePriv* m_priv;
+};
+}
diff --git a/kms++/inc/kms++/property.h b/kms++/inc/kms++/property.h
new file mode 100644
index 0000000..b9097ff
--- /dev/null
+++ b/kms++/inc/kms++/property.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "drmobject.h"
+#include <map>
+#include <vector>
+
+namespace kms
+{
+
+struct PropertyPriv;
+
+enum class PropertyType
+{
+ Range,
+ Enum,
+ Blob,
+ Bitmask,
+ Object,
+ SignedRange,
+};
+
+class Property : public DrmObject
+{
+ friend class Card;
+public:
+ const std::string& name() const;
+
+ bool is_immutable() const;
+ bool is_pending() const;
+
+ PropertyType type() const { return m_type; }
+ std::map<uint64_t, std::string> get_enums() const;
+ std::vector<uint64_t> get_values() const;
+ std::vector<uint32_t> get_blob_ids() const;
+private:
+ Property(Card& card, uint32_t id);
+ ~Property();
+
+ PropertyType m_type;
+
+ PropertyPriv* m_priv;
+ std::string m_name;
+};
+}
diff --git a/kms++/inc/kms++/videomode.h b/kms++/inc/kms++/videomode.h
new file mode 100644
index 0000000..f9abaf9
--- /dev/null
+++ b/kms++/inc/kms++/videomode.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <string>
+#include <cstdint>
+#include <memory>
+
+#include "blob.h"
+
+namespace kms
+{
+
+struct Videomode
+{
+ std::string name;
+
+ uint32_t clock;
+ uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew;
+ uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan;
+
+ uint32_t vrefresh;
+
+ uint32_t flags; // DRM_MODE_FLAG_*
+ uint32_t type; // DRM_MODE_TYPE_*
+
+ std::unique_ptr<Blob> to_blob(Card& card) const;
+
+ uint16_t hfp() const { return hsync_start - hdisplay; }
+ uint16_t hsw() const { return hsync_end - hsync_start; }
+ uint16_t hbp() const { return htotal - hsync_end; }
+
+ uint16_t vfp() const { return vsync_start - vdisplay; }
+ uint16_t vsw() const { return vsync_end - vsync_start; }
+ uint16_t vbp() const { return vtotal - vsync_end; }
+};
+
+}