2c72ca70e2
Remove the verbose #ifndef/#define/#endif pattern for maintaining header idempotency, and replace it with a simple #pragma once. This simplifies the headers, and prevents redundant changes when header files get moved. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
333 lines
6.8 KiB
C++
333 lines
6.8 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2021, Ideas on Board Oy
|
|
*
|
|
* drm.h - DRM/KMS Helpers
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <list>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <stdint.h>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <libcamera/base/signal.h>
|
|
#include <libcamera/base/span.h>
|
|
|
|
#include <libdrm/drm.h>
|
|
#include <xf86drm.h>
|
|
#include <xf86drmMode.h>
|
|
|
|
namespace libcamera {
|
|
class FrameBuffer;
|
|
class PixelFormat;
|
|
class Size;
|
|
} /* namespace libcamera */
|
|
|
|
namespace DRM {
|
|
|
|
class Device;
|
|
class Plane;
|
|
class Property;
|
|
class PropertyValue;
|
|
|
|
class Object
|
|
{
|
|
public:
|
|
enum Type {
|
|
TypeCrtc = DRM_MODE_OBJECT_CRTC,
|
|
TypeConnector = DRM_MODE_OBJECT_CONNECTOR,
|
|
TypeEncoder = DRM_MODE_OBJECT_ENCODER,
|
|
TypeMode = DRM_MODE_OBJECT_MODE,
|
|
TypeProperty = DRM_MODE_OBJECT_PROPERTY,
|
|
TypeFb = DRM_MODE_OBJECT_FB,
|
|
TypeBlob = DRM_MODE_OBJECT_BLOB,
|
|
TypePlane = DRM_MODE_OBJECT_PLANE,
|
|
TypeAny = DRM_MODE_OBJECT_ANY,
|
|
};
|
|
|
|
Object(Device *dev, uint32_t id, Type type);
|
|
virtual ~Object();
|
|
|
|
Device *device() const { return dev_; }
|
|
uint32_t id() const { return id_; }
|
|
Type type() const { return type_; }
|
|
|
|
const Property *property(const std::string &name) const;
|
|
const PropertyValue *propertyValue(const std::string &name) const;
|
|
const std::vector<PropertyValue> &properties() const { return properties_; }
|
|
|
|
protected:
|
|
virtual int setup()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
uint32_t id_;
|
|
|
|
private:
|
|
friend Device;
|
|
|
|
Device *dev_;
|
|
Type type_;
|
|
std::vector<PropertyValue> properties_;
|
|
};
|
|
|
|
class Property : public Object
|
|
{
|
|
public:
|
|
enum Type {
|
|
TypeUnknown = 0,
|
|
TypeRange,
|
|
TypeEnum,
|
|
TypeBlob,
|
|
TypeBitmask,
|
|
TypeObject,
|
|
TypeSignedRange,
|
|
};
|
|
|
|
Property(Device *dev, drmModePropertyRes *property);
|
|
|
|
Type type() const { return type_; }
|
|
const std::string &name() const { return name_; }
|
|
|
|
bool isImmutable() const { return flags_ & DRM_MODE_PROP_IMMUTABLE; }
|
|
|
|
const std::vector<uint64_t> values() const { return values_; }
|
|
const std::map<uint32_t, std::string> &enums() const { return enums_; }
|
|
const std::vector<uint32_t> blobs() const { return blobs_; }
|
|
|
|
private:
|
|
Type type_;
|
|
std::string name_;
|
|
uint32_t flags_;
|
|
std::vector<uint64_t> values_;
|
|
std::map<uint32_t, std::string> enums_;
|
|
std::vector<uint32_t> blobs_;
|
|
};
|
|
|
|
class PropertyValue
|
|
{
|
|
public:
|
|
PropertyValue(uint32_t id, uint64_t value)
|
|
: id_(id), value_(value)
|
|
{
|
|
}
|
|
|
|
uint32_t id() const { return id_; }
|
|
uint32_t value() const { return value_; }
|
|
|
|
private:
|
|
uint32_t id_;
|
|
uint64_t value_;
|
|
};
|
|
|
|
class Blob : public Object
|
|
{
|
|
public:
|
|
Blob(Device *dev, const libcamera::Span<const uint8_t> &data);
|
|
~Blob();
|
|
|
|
bool isValid() const { return id() != 0; }
|
|
};
|
|
|
|
class Mode : public drmModeModeInfo
|
|
{
|
|
public:
|
|
Mode(const drmModeModeInfo &mode);
|
|
|
|
std::unique_ptr<Blob> toBlob(Device *dev) const;
|
|
};
|
|
|
|
class Crtc : public Object
|
|
{
|
|
public:
|
|
Crtc(Device *dev, const drmModeCrtc *crtc, unsigned int index);
|
|
|
|
unsigned int index() const { return index_; }
|
|
const std::vector<const Plane *> &planes() const { return planes_; }
|
|
|
|
private:
|
|
friend Device;
|
|
|
|
unsigned int index_;
|
|
std::vector<const Plane *> planes_;
|
|
};
|
|
|
|
class Encoder : public Object
|
|
{
|
|
public:
|
|
Encoder(Device *dev, const drmModeEncoder *encoder);
|
|
|
|
uint32_t type() const { return type_; }
|
|
|
|
const std::vector<const Crtc *> &possibleCrtcs() const { return possibleCrtcs_; }
|
|
|
|
private:
|
|
uint32_t type_;
|
|
std::vector<const Crtc *> possibleCrtcs_;
|
|
};
|
|
|
|
class Connector : public Object
|
|
{
|
|
public:
|
|
enum Status {
|
|
Connected,
|
|
Disconnected,
|
|
Unknown,
|
|
};
|
|
|
|
Connector(Device *dev, const drmModeConnector *connector);
|
|
|
|
uint32_t type() const { return type_; }
|
|
const std::string &name() const { return name_; }
|
|
|
|
Status status() const { return status_; }
|
|
|
|
const std::vector<const Encoder *> &encoders() const { return encoders_; }
|
|
const std::vector<Mode> &modes() const { return modes_; }
|
|
|
|
private:
|
|
uint32_t type_;
|
|
std::string name_;
|
|
Status status_;
|
|
std::vector<const Encoder *> encoders_;
|
|
std::vector<Mode> modes_;
|
|
};
|
|
|
|
class Plane : public Object
|
|
{
|
|
public:
|
|
enum Type {
|
|
TypeOverlay,
|
|
TypePrimary,
|
|
TypeCursor,
|
|
};
|
|
|
|
Plane(Device *dev, const drmModePlane *plane);
|
|
|
|
Type type() const { return type_; }
|
|
const std::vector<uint32_t> &formats() const { return formats_; }
|
|
const std::vector<const Crtc *> &possibleCrtcs() const { return possibleCrtcs_; }
|
|
|
|
bool supportsFormat(const libcamera::PixelFormat &format) const;
|
|
|
|
protected:
|
|
int setup() override;
|
|
|
|
private:
|
|
friend class Device;
|
|
|
|
Type type_;
|
|
std::vector<uint32_t> formats_;
|
|
std::vector<const Crtc *> possibleCrtcs_;
|
|
uint32_t possibleCrtcsMask_;
|
|
};
|
|
|
|
class FrameBuffer : public Object
|
|
{
|
|
public:
|
|
struct Plane {
|
|
uint32_t handle;
|
|
};
|
|
|
|
~FrameBuffer();
|
|
|
|
private:
|
|
friend class Device;
|
|
|
|
FrameBuffer(Device *dev);
|
|
|
|
std::map<int, Plane> planes_;
|
|
};
|
|
|
|
class AtomicRequest
|
|
{
|
|
public:
|
|
enum Flags {
|
|
FlagAllowModeset = (1 << 0),
|
|
FlagAsync = (1 << 1),
|
|
};
|
|
|
|
AtomicRequest(Device *dev);
|
|
~AtomicRequest();
|
|
|
|
Device *device() const { return dev_; }
|
|
bool isValid() const { return valid_; }
|
|
|
|
int addProperty(const Object *object, const std::string &property,
|
|
uint64_t value);
|
|
int addProperty(const Object *object, const std::string &property,
|
|
std::unique_ptr<Blob> blob);
|
|
int commit(unsigned int flags = 0);
|
|
|
|
private:
|
|
AtomicRequest(const AtomicRequest &) = delete;
|
|
AtomicRequest(const AtomicRequest &&) = delete;
|
|
AtomicRequest &operator=(const AtomicRequest &) = delete;
|
|
AtomicRequest &operator=(const AtomicRequest &&) = delete;
|
|
|
|
int addProperty(uint32_t object, uint32_t property, uint64_t value);
|
|
|
|
Device *dev_;
|
|
bool valid_;
|
|
drmModeAtomicReq *request_;
|
|
std::list<std::unique_ptr<Blob>> blobs_;
|
|
};
|
|
|
|
class Device
|
|
{
|
|
public:
|
|
Device();
|
|
~Device();
|
|
|
|
int init();
|
|
|
|
int fd() const { return fd_; }
|
|
|
|
const std::list<Crtc> &crtcs() const { return crtcs_; }
|
|
const std::list<Encoder> &encoders() const { return encoders_; }
|
|
const std::list<Connector> &connectors() const { return connectors_; }
|
|
const std::list<Plane> &planes() const { return planes_; }
|
|
const std::list<Property> &properties() const { return properties_; }
|
|
|
|
const Object *object(uint32_t id);
|
|
|
|
std::unique_ptr<FrameBuffer> createFrameBuffer(
|
|
const libcamera::FrameBuffer &buffer,
|
|
const libcamera::PixelFormat &format,
|
|
const libcamera::Size &size,
|
|
const std::array<uint32_t, 4> &strides);
|
|
|
|
libcamera::Signal<AtomicRequest *> requestComplete;
|
|
|
|
private:
|
|
Device(const Device &) = delete;
|
|
Device(const Device &&) = delete;
|
|
Device &operator=(const Device &) = delete;
|
|
Device &operator=(const Device &&) = delete;
|
|
|
|
int getResources();
|
|
|
|
void drmEvent();
|
|
static void pageFlipComplete(int fd, unsigned int sequence,
|
|
unsigned int tv_sec, unsigned int tv_usec,
|
|
void *user_data);
|
|
|
|
int fd_;
|
|
|
|
std::list<Crtc> crtcs_;
|
|
std::list<Encoder> encoders_;
|
|
std::list<Connector> connectors_;
|
|
std::list<Plane> planes_;
|
|
std::list<Property> properties_;
|
|
|
|
std::map<uint32_t, Object *> objects_;
|
|
};
|
|
|
|
} /* namespace DRM */
|