diff options
Diffstat (limited to 'kms++/inc')
-rw-r--r-- | kms++/inc/kms++/atomicreq.h | 36 | ||||
-rw-r--r-- | kms++/inc/kms++/blob.h | 22 | ||||
-rw-r--r-- | kms++/inc/kms++/card.h | 71 | ||||
-rw-r--r-- | kms++/inc/kms++/connector.h | 51 | ||||
-rw-r--r-- | kms++/inc/kms++/crtc.h | 50 | ||||
-rw-r--r-- | kms++/inc/kms++/decls.h | 19 | ||||
-rw-r--r-- | kms++/inc/kms++/drmobject.h | 40 | ||||
-rw-r--r-- | kms++/inc/kms++/drmpropobject.h | 35 | ||||
-rw-r--r-- | kms++/inc/kms++/dumbframebuffer.h | 46 | ||||
-rw-r--r-- | kms++/inc/kms++/encoder.h | 25 | ||||
-rw-r--r-- | kms++/inc/kms++/extframebuffer.h | 21 | ||||
-rw-r--r-- | kms++/inc/kms++/framebuffer.h | 40 | ||||
-rw-r--r-- | kms++/inc/kms++/kms++.h | 15 | ||||
-rw-r--r-- | kms++/inc/kms++/modedb.h | 16 | ||||
-rw-r--r-- | kms++/inc/kms++/pagefliphandler.h | 11 | ||||
-rw-r--r-- | kms++/inc/kms++/pipeline.h | 11 | ||||
-rw-r--r-- | kms++/inc/kms++/pixelformats.h | 63 | ||||
-rw-r--r-- | kms++/inc/kms++/plane.h | 41 | ||||
-rw-r--r-- | kms++/inc/kms++/property.h | 44 | ||||
-rw-r--r-- | kms++/inc/kms++/videomode.h | 36 |
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; } +}; + +} |