backends/drm: replace drmModeAtomicCommit with a custom implementation
drmModeAtomicCommit does additional allocations and sorting that KWin doesn't use or need
This commit is contained in:
parent
dee8a3b3a7
commit
1c18d11206
3 changed files with 61 additions and 12 deletions
|
@ -330,15 +330,35 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
|
|||
|
||||
int drmIoctl(int fd, unsigned long request, void *arg)
|
||||
{
|
||||
GPU(fd, -EINVAL);
|
||||
if (request == DRM_IOCTL_PRIME_FD_TO_HANDLE) {
|
||||
GPU(fd, -EINVAL);
|
||||
auto args = static_cast<drm_prime_handle *>(arg);
|
||||
args->handle = 42; // just pass a dummy value so the request doesn't fail
|
||||
return 0;
|
||||
} else if (request == DRM_IOCTL_PRIME_HANDLE_TO_FD) {
|
||||
return -(errno = ENOTSUP);
|
||||
} else if (request == DRM_IOCTL_GEM_CLOSE) {
|
||||
GPU(fd, -EINVAL);
|
||||
return 0;
|
||||
} else if (request == DRM_IOCTL_MODE_ATOMIC) {
|
||||
const auto args = static_cast<drm_mode_atomic *>(arg);
|
||||
auto req = drmModeAtomicAlloc();
|
||||
const uint32_t *const objects = reinterpret_cast<const uint32_t *>(args->objs_ptr);
|
||||
const uint32_t *const propsCounts = reinterpret_cast<const uint32_t *>(args->count_props_ptr);
|
||||
const uint32_t *const props = reinterpret_cast<const uint32_t *>(args->props_ptr);
|
||||
const uint64_t *const values = reinterpret_cast<const uint64_t *>(args->prop_values_ptr);
|
||||
uint32_t propIndex = 0;
|
||||
for (uint32_t objIndex = 0; objIndex < args->count_objs; objIndex++) {
|
||||
const uint32_t objectId = objects[objIndex];
|
||||
const uint32_t count = propsCounts[objIndex];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
drmModeAtomicAddProperty(req, objectId, props[propIndex + i], values[propIndex + i]);
|
||||
}
|
||||
propIndex += count;
|
||||
}
|
||||
int ret = drmModeAtomicCommit(fd, req, args->flags, reinterpret_cast<void *>(args->user_data));
|
||||
drmModeAtomicFree(req);
|
||||
return ret;
|
||||
}
|
||||
return -(errno = ENOTSUP);
|
||||
}
|
||||
|
|
|
@ -39,13 +39,12 @@ DrmGpu *DrmCommit::gpu() const
|
|||
DrmAtomicCommit::DrmAtomicCommit(const QVector<DrmPipeline *> &pipelines)
|
||||
: DrmCommit(pipelines.front()->gpu())
|
||||
, m_pipelines(pipelines)
|
||||
, m_req(drmModeAtomicAlloc())
|
||||
{
|
||||
}
|
||||
|
||||
void DrmAtomicCommit::addProperty(const DrmProperty &prop, uint64_t value)
|
||||
{
|
||||
drmModeAtomicAddProperty(m_req.get(), prop.drmObject()->id(), prop.propId(), value);
|
||||
m_properties[prop.drmObject()->id()][prop.propId()] = value;
|
||||
}
|
||||
|
||||
void DrmAtomicCommit::addBlob(const DrmProperty &prop, const std::shared_ptr<DrmBlob> &blob)
|
||||
|
@ -68,27 +67,57 @@ void DrmAtomicCommit::setVrr(DrmCrtc *crtc, bool vrr)
|
|||
|
||||
bool DrmAtomicCommit::test()
|
||||
{
|
||||
return drmModeAtomicCommit(gpu()->fd(), m_req.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK, this) == 0;
|
||||
return doCommit(DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK);
|
||||
}
|
||||
|
||||
bool DrmAtomicCommit::testAllowModeset()
|
||||
{
|
||||
return drmModeAtomicCommit(gpu()->fd(), m_req.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, this) == 0;
|
||||
return doCommit(DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET);
|
||||
}
|
||||
|
||||
bool DrmAtomicCommit::commit()
|
||||
{
|
||||
return drmModeAtomicCommit(gpu()->fd(), m_req.get(), DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, this) == 0;
|
||||
return doCommit(DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT);
|
||||
}
|
||||
|
||||
bool DrmAtomicCommit::commitModeset()
|
||||
{
|
||||
return drmModeAtomicCommit(gpu()->fd(), m_req.get(), DRM_MODE_ATOMIC_ALLOW_MODESET, this) == 0;
|
||||
return doCommit(DRM_MODE_ATOMIC_ALLOW_MODESET);
|
||||
}
|
||||
|
||||
drmModeAtomicReq *DrmAtomicCommit::req() const
|
||||
bool DrmAtomicCommit::doCommit(uint32_t flags)
|
||||
{
|
||||
return m_req.get();
|
||||
std::vector<uint32_t> objects;
|
||||
std::vector<uint32_t> propertyCounts;
|
||||
std::vector<uint32_t> propertyIds;
|
||||
std::vector<uint64_t> values;
|
||||
objects.reserve(m_properties.size());
|
||||
propertyCounts.reserve(m_properties.size());
|
||||
uint64_t totalPropertiesCount = 0;
|
||||
for (const auto &[object, properties] : m_properties) {
|
||||
objects.push_back(object);
|
||||
propertyCounts.push_back(properties.size());
|
||||
totalPropertiesCount += properties.size();
|
||||
}
|
||||
propertyIds.reserve(totalPropertiesCount);
|
||||
values.reserve(totalPropertiesCount);
|
||||
for (const auto &[object, properties] : m_properties) {
|
||||
for (const auto &[property, value] : properties) {
|
||||
propertyIds.push_back(property);
|
||||
values.push_back(value);
|
||||
}
|
||||
}
|
||||
drm_mode_atomic commitData{
|
||||
.flags = flags,
|
||||
.count_objs = uint32_t(objects.size()),
|
||||
.objs_ptr = reinterpret_cast<uint64_t>(objects.data()),
|
||||
.count_props_ptr = reinterpret_cast<uint64_t>(propertyCounts.data()),
|
||||
.props_ptr = reinterpret_cast<uint64_t>(propertyIds.data()),
|
||||
.prop_values_ptr = reinterpret_cast<uint64_t>(values.data()),
|
||||
.reserved = 0,
|
||||
.user_data = reinterpret_cast<uint64_t>(this),
|
||||
};
|
||||
return drmIoctl(m_gpu->fd(), DRM_IOCTL_MODE_ATOMIC, &commitData) == 0;
|
||||
}
|
||||
|
||||
void DrmAtomicCommit::pageFlipped(std::chrono::nanoseconds timestamp) const
|
||||
|
|
|
@ -67,17 +67,17 @@ public:
|
|||
|
||||
void pageFlipped(std::chrono::nanoseconds timestamp) const override;
|
||||
|
||||
drmModeAtomicReq *req() const;
|
||||
|
||||
bool areBuffersReadable() const;
|
||||
bool isVrr() const;
|
||||
|
||||
private:
|
||||
bool doCommit(uint32_t flags);
|
||||
|
||||
const QVector<DrmPipeline *> m_pipelines;
|
||||
DrmUniquePtr<drmModeAtomicReq> m_req;
|
||||
QHash<const DrmProperty *, std::shared_ptr<DrmBlob>> m_blobs;
|
||||
std::unordered_map<DrmPlane *, std::shared_ptr<DrmFramebuffer>> m_buffers;
|
||||
bool m_vrr = false;
|
||||
std::unordered_map<uint32_t /* object */, std::unordered_map<uint32_t /* property */, uint64_t /* value */>> m_properties;
|
||||
};
|
||||
|
||||
class DrmLegacyCommit : public DrmCommit
|
||||
|
|
Loading…
Reference in a new issue