summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/drm++/ioctl.hpp16
-rw-r--r--include/drm++/syncobject.hpp220
2 files changed, 102 insertions, 134 deletions
diff --git a/include/drm++/ioctl.hpp b/include/drm++/ioctl.hpp
index 1851df6..1a68dae 100644
--- a/include/drm++/ioctl.hpp
+++ b/include/drm++/ioctl.hpp
@@ -11,28 +11,30 @@
namespace drm::ioctl {
-/// Type of ioctl() error
+/// Type of ioctl() error.
enum class Error : u8 {
BadFileDescriptor,
InvalidArgument,
NotSupported,
- Other //!< check errno field
+ Other //!< Check errno field
};
-/// Exception class wrapping around ioctl()
+/// Exception class wrapping around ioctl().
class Exception : public std::exception {
public:
- /// Construct an exception from errno
+ /// Construct an exception from errno.
explicit Exception(int fd, unsigned long op);
+ /// Convert the exception into human-readable form.
+ std::string readable();
+
+ // Private access
GETTER(fd)
GETTER(op)
GETTER(code)
GETTER(syserrno)
- /// Convert the exception into human-readable form.
- std::string readable();
-
+ // Default operators and destructor
DEFAULT_OPERATORS(Exception)
~Exception() override;
private:
diff --git a/include/drm++/syncobject.hpp b/include/drm++/syncobject.hpp
index 9751559..f530c49 100644
--- a/include/drm++/syncobject.hpp
+++ b/include/drm++/syncobject.hpp
@@ -9,70 +9,34 @@
namespace drm::syncobj {
-/// Wait modes for waiting on binary sync objects
-enum class WaitMode : u8 {
- NoWaitEmpty, //!< Return -EINVAL when waiting on an empty sync object
- WaitEmpty, //!< Wait for empty sync objects to be filled and signaled
- WaitAvailable //!< Wait for empty sync objects to be filled, but do not wait for signaling
-};
-
+class SyncObject;
class TimelineSyncObject;
-/// A (binary) synchronization object is a reference-counted container which can hold a DRM fence
-/// @throws drm::ioctl::Exception on failure
-class SyncObject {
+/// Common base class for SyncObject and TimelineSyncObject.
+class SyncObjectBase {
+ friend class SyncObject;
+ friend class TimelineSyncObject;
public:
- /// Create a new sync object
- SyncObject(int fd, bool signaled = false);
+ /// Create a new sync object.
+ SyncObjectBase(int fd, bool signaled = false);
- /// Import an existing sync object
+ /// Import an existing sync object.
/// @param close Close syncobj_fd after import (regardless of success)
- SyncObject(int fd, int syncobj_fd, bool close = true);
+ SyncObjectBase(int fd, int syncobj_fd, bool close = true);
- /// Export a new reference to sync object, increasing the reference counter
+ /// Export a new reference to sync object, incrementing the reference count.
[[nodiscard]] int exportFd() const;
- /// Import a sync file (DRM fence) into the sync object
- /// @param close Close syncfile_fd after import (regardless of success)
- void importSyncFile(int syncfile_fd, bool close = true) const;
-
- /// Export a sync file from the DRM fence within the sync object
- /// Any subsequent modifications to the sync object are not applied to the exported sync file
- [[nodiscard]] int exportSyncFile() const;
-
- /// Transfer a DRM fence into another sync object
- void transfer(const SyncObject& dest) const;
- void transfer(const TimelineSyncObject& dest, u64 destPoint) const;
-
- /// Signal the sync object by emplacing a signaled fence into it
- void signal() const;
-
- /// Reset the sync object by removing the fence from it
- void reset() const;
-
- /// Wait for the sync object to be signaled
- /// @param timeout Absolute timeout in nanoseconds, or zero for polling
- /// @param deadlineHint Set a CLOCK_MONOTONIC deadline hint in nanoseconds on the fence
- void wait(
- s64 timeout,
- WaitMode waitMode = WaitMode::NoWaitEmpty,
- std::optional<u64> deadlineHint = std::nullopt
- ) const;
-
- /// Register an eventfd to the sync object
- /// @param waitAvailable Trigger when a fence is emplaced, not when it is signaled
- void registerEventFd(int eventfd_fd, bool waitAvailable = false) const;
-
// Private access
GETTER(fd)
GETTER(handle)
// Move constructor/operator
- SyncObject(SyncObject&& other) noexcept : m_fd(other.m_fd), m_handle(other.m_handle) {
+ SyncObjectBase(SyncObjectBase&& other) noexcept : m_fd(other.m_fd), m_handle(other.m_handle) {
other.m_fd = -1; // invalidate other
}
- SyncObject& operator=(SyncObject&& other) noexcept {
+ SyncObjectBase& operator=(SyncObjectBase&& other) noexcept {
if (this != &other) {
this->destruct();
this->m_handle = other.m_handle;
@@ -84,20 +48,23 @@ public:
}
// Copy constructor/operator
- SyncObject(const SyncObject& other)
- : SyncObject(other.m_fd, other.exportFd(), true) {}
+ SyncObjectBase(const SyncObjectBase& other)
+ : SyncObjectBase(other.m_fd, other.exportFd(), true) {}
- SyncObject& operator=(const SyncObject& other) {
+ SyncObjectBase& operator=(const SyncObjectBase& other) {
if (this != &other) {
const int fd{other.exportFd()};
- *this = SyncObject(other.m_fd, fd, true);
+ *this = SyncObjectBase(other.m_fd, fd, true);
}
return *this;
}
// Destructor
- ~SyncObject();
+ ~SyncObjectBase() noexcept {
+ this->destruct();
+ }
+
private:
int m_fd; // indicates object validity (>= 0)
u32 m_handle;
@@ -105,37 +72,78 @@ private:
void destruct() noexcept;
};
-/// A timeline synchronization object can hold multiple DRM fences, identified via a
-/// monotonically increasing 64-bit unsigned integer "point"
+/// Wait modes for waiting on binary sync objects.
+enum class WaitMode : u8 {
+ NoWaitEmpty, //!< Return -EINVAL when waiting on an empty sync object
+ WaitEmpty, //!< Wait for empty sync objects to be filled and signaled
+ WaitAvailable //!< Wait for empty sync objects to be filled, but do not wait for signaling
+};
+
+/// A (binary) synchronization object is a reference-counted container which can hold a DRM fence.
+/// Requires DRM_CAP_SYNCOBJ.
/// @throws drm::ioctl::Exception on failure
-class TimelineSyncObject {
+class SyncObject : public SyncObjectBase {
public:
- /// Create a new sync object
- TimelineSyncObject(int fd);
+ using SyncObjectBase::SyncObjectBase;
+ using SyncObjectBase::operator=;
- /// Import an existing sync object
- /// @param close Close syncobj_fd after import (regardless of success)
- TimelineSyncObject(int fd, int syncobj_fd, bool close = true);
+ /// Import a sync file (DRM fence) into the sync object.
+ /// @param close Close syncfile_fd after import (regardless of success)
+ void importSyncFile(int syncfile_fd, bool close = true) const;
- /// Export a new reference to sync object, increasing the reference counter
- [[nodiscard]] int exportFd() const;
+ /// Export a sync file from the DRM fence within the sync object.
+ /// Any subsequent modifications to the sync object are not applied to the exported sync file
+ [[nodiscard]] int exportSyncFile() const;
+
+ /// Transfer a DRM fence into another binary sync object.
+ void transfer(const SyncObject& dest) const;
+ void transfer(const TimelineSyncObject& dest, u64 destPoint) const;
+
+ /// Signal the sync object by emplacing a signaled fence into it.
+ void signal() const;
+
+ /// Reset the sync object by removing the fence from it.
+ void reset() const;
+
+ /// Wait for the sync object to be signaled.
+ /// @param timeout Absolute timeout in nanoseconds, or zero for polling
+ /// @param deadlineHint Set a CLOCK_MONOTONIC deadline hint in nanoseconds on the fence
+ void wait(
+ s64 timeout,
+ WaitMode waitMode = WaitMode::NoWaitEmpty,
+ std::optional<u64> deadlineHint = std::nullopt
+ ) const;
+
+ /// Register an eventfd to the sync object.
+ /// @param waitAvailable Trigger when a fence is emplaced, not when it is signaled
+ void registerEventFd(int eventfd_fd, bool waitAvailable = false) const;
+};
- /// Import a sync file (DRM fence) into the sync object
+/// A timeline synchronization object can hold multiple DRM fences, identified via a
+/// monotonically increasing 64-bit unsigned integer "point".
+/// Requires DRM_CAP_SYNCOBJ_TIMELINE.
+/// @throws drm::ioctl::Exception on failure
+class TimelineSyncObject : public SyncObjectBase {
+public:
+ using SyncObjectBase::SyncObjectBase;
+ using SyncObjectBase::operator=;
+
+ /// Import a sync file (DRM fence) into the sync object.
/// @param close Close syncfile_fd after import (regardless of success)
void importSyncFile(int syncfile_fd, u64 point, bool close = true) const;
- /// Export a sync file from the DRM fence within the sync object
- /// Any subsequent modifications to the sync object are not applied to the exported sync file
+ /// Export a sync file from the DRM fence within the sync object.
+ /// Any subsequent modifications to the sync object are not applied to the exported sync file.
[[nodiscard]] int exportSyncFile(u64 point) const;
- /// Transfer a DRM fence into another sync object
+ /// Transfer a DRM fence into another sync object.
void transfer(const TimelineSyncObject& dest, u64 srcPoint, u64 destPoint) const;
void transfer(const SyncObject& dest, u64 srcPoint) const;
- /// Signal the sync object by emplacing a signaled fence into it
+ /// Signal the sync object by emplacing a signaled fence into it.
void signal(u64 point) const;
- /// Wait for the sync object to be signaled
+ /// Wait for the sync object to be signaled.
/// @param timeout Absolute timeout in nanoseconds, or zero for polling
/// @param waitAvailable Only wait for a fence to become available, do not wait for signaling
/// @param deadlineHint Set a CLOCK_MONOTONIC deadline hint in nanoseconds on the fence
@@ -146,91 +154,49 @@ public:
std::optional<u64> deadlineHint = std::nullopt
) const;
- /// Query the current timeline point
+ /// Query the current timeline point.
/// @param lastSubmitted If true, query the last submitted point instead
[[nodiscard]] u64 query(bool lastSubmitted = false) const;
- /// Register an eventfd to the sync object
+ /// Register an eventfd to the sync object.
/// @param waitAvailable Trigger when a fence is emplaced, not when it is signaled
void registerEventFd(int eventfd_fd, u64 point, bool waitAvailable = false) const;
-
- // Private access
- GETTER(fd)
- GETTER(handle)
-
- // Move constructor/operator
- TimelineSyncObject(TimelineSyncObject&& other) noexcept
- : m_fd(other.m_fd), m_handle(other.m_handle) {
- other.m_fd = -1; // invalidate other
- }
-
- TimelineSyncObject& operator=(TimelineSyncObject&& other) noexcept {
- if (this != &other) {
- this->destruct();
- this->m_handle = other.m_handle;
- this->m_fd = other.m_fd;
- other.m_fd = -1; // invalidate other
- }
-
- return *this;
- }
-
- // Copy constructor/operator
- TimelineSyncObject(const TimelineSyncObject& other)
- : TimelineSyncObject(other.m_fd, other.exportFd(), true) {}
-
- TimelineSyncObject& operator=(const TimelineSyncObject& other) {
- if (this != &other) {
- const int fd{other.exportFd()};
- *this = TimelineSyncObject(other.m_fd, fd, true);
- }
-
- return *this;
- }
-
- // Destructor
- ~TimelineSyncObject();
-private:
- int m_fd; // indicates object validity (>= 0)
- u32 m_handle;
-
- void destruct() noexcept;
};
-/// Signal several binary sync objects at once
-void signal(const std::vector<ref<SyncObject>>& objs);
+/// Signal several binary sync objects at once.
+void signal(const std::vector<ref<const SyncObject>>& objs);
-/// Reset several binary sync objects at once
-void reset(const std::vector<ref<SyncObject>>& objs);
+/// Reset several binary sync objects at once.
+void reset(const std::vector<ref<const SyncObject>>& objs);
-// Wait on several binary sync objects at once
+/// Wait on several binary sync objects at once.
/// @param timeout Absolute timeout in nanoseconds, or zero for polling
/// @param waitAll Wait until all sync objects are signaled
/// @param deadlineHint Set a CLOCK_MONOTONIC deadline hint in nanoseconds on the fence
/// @return The first signaled sync object when waitAll is false
/// @throws std::invalid_argument if objs is empty
-SyncObject& wait(
- const std::vector<ref<SyncObject>>& objs,
+const SyncObject& wait(
+ const std::vector<ref<const SyncObject>>& objs,
s64 timeout,
bool waitAll = false,
WaitMode waitMode = WaitMode::NoWaitEmpty,
std::optional<u64> deadlineHint = std::nullopt
);
-/// Signal several timeline sync objects at once
+/// Signal several timeline sync objects at once.
/// @throws std::invalid_argument if objs.size() != points.size()
void signal(
- const std::vector<ref<TimelineSyncObject>>& objs,
- const std::vector<u64>& points
+ const std::vector<ref<const TimelineSyncObject>>& objs,
+ std::vector<u64> points
);
-/// Wait on several timeline sync objects at once
+/// Wait on several timeline sync objects at once.
/// @param timeout Absolute timeout in nanoseconds, or zero for polling
/// @param waitAvailable Only wait for a fence to become available, do not wait for signaling
/// @param deadlineHint Set a CLOCK_MONOTONIC deadline hint in nanoseconds on the fence
/// @throws std::invalid_argument if objs.size() != points.size()
void wait(
- const std::vector<ref<TimelineSyncObject>>& objs,
+ const std::vector<ref<const TimelineSyncObject>>& objs,
const std::vector<u64>& points,
s64 timeout,
bool waitAll = false,
@@ -238,10 +204,10 @@ void wait(
std::optional<u64> deadlineHint = std::nullopt
);
-/// Query several timeline sync objects at once
+/// Query several timeline sync objects at once.
/// @param lastSubmitted If true, query the last submitted point instead
std::vector<u64> query(
- const std::vector<ref<TimelineSyncObject>>& objs,
+ const std::vector<ref<const TimelineSyncObject>>& objs,
bool lastSubmitted = false
);