backends/drm: Reopen the drm node

GEM handles are not reference counted and are unique per drm file
descriptor.

With the upcoming changes, dmabuf and dumb buffers will be abstraced
using DmaBufAttributes.

The issue with it is that we need GEM handles to get a drm framebuffer.
drmPrimeFDToHandle() can be used to get the GEM handle for a drm file
descriptor, but we would hit the reference counting issues then and
potentially double close GEM handles.

In order to resolve that, this change makes the drm backend reopen the
drm node to get a new GEM handle namespace for rendering.
This commit is contained in:
Vlad Zahorodnii 2023-06-03 12:16:33 +03:00
parent 0a7bfcf1a3
commit 8fa6c5307b
2 changed files with 11 additions and 1 deletions

View file

@ -78,7 +78,15 @@ DrmGpu::DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t device
m_isNVidia = strstr(version->name, "nvidia-drm");
m_isVirtualMachine = strstr(version->name, "virtio") || strstr(version->name, "qxl")
|| strstr(version->name, "vmwgfx") || strstr(version->name, "vboxvideo");
m_gbmDevice = gbm_create_device(m_fd);
// Reopen the drm node to create a new GEM handle namespace.
m_gbmFd = FileDescriptor{open(devNode.toLocal8Bit(), O_RDWR | O_CLOEXEC)};
if (m_gbmFd.isValid()) {
drm_magic_t magic;
drmGetMagic(m_gbmFd.get(), &magic);
drmAuthMagic(m_fd, magic);
m_gbmDevice = gbm_create_device(m_gbmFd.get());
}
m_socketNotifier = std::make_unique<QSocketNotifier>(fd, QSocketNotifier::Read);
connect(m_socketNotifier.get(), &QSocketNotifier::activated, this, &DrmGpu::dispatchEvents);
@ -102,6 +110,7 @@ DrmGpu::~DrmGpu()
if (m_gbmDevice) {
gbm_device_destroy(m_gbmDevice);
}
m_gbmFd = FileDescriptor{};
m_platform->session()->closeRestricted(m_fd);
}

View file

@ -139,6 +139,7 @@ private:
bool m_isActive = true;
clockid_t m_presentationClock;
gbm_device *m_gbmDevice;
FileDescriptor m_gbmFd;
std::unique_ptr<EglDisplay> m_eglDisplay;
DrmBackend *const m_platform;