KWin
Loading...
Searching...
No Matches
drm_buffer.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
6 SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10#include "drm_buffer.h"
11
12#include "core/graphicsbuffer.h"
13#include "drm_gpu.h"
14
15// system
16#include <sys/mman.h>
17#if defined(Q_OS_LINUX)
18#include <linux/dma-buf.h>
19#include <linux/sync_file.h>
20#endif
21// drm
22#include <drm_fourcc.h>
23#include <sys/ioctl.h>
24#include <unistd.h>
25#include <xf86drm.h>
26#include <xf86drmMode.h>
27#ifdef Q_OS_LINUX
28#include <linux/dma-buf.h>
29#endif
30
31#ifndef DRM_IOCTL_MODE_CLOSEFB
32#define DRM_IOCTL_MODE_CLOSEFB 0xD0
33#endif
34
35namespace KWin
36{
37
38static bool s_envIsSet = false;
39static bool s_disableBufferWait = qEnvironmentVariableIntValue("KWIN_DRM_DISABLE_BUFFER_READABILITY_CHECKS", &s_envIsSet) && s_envIsSet;
40
41DrmFramebuffer::DrmFramebuffer(DrmGpu *gpu, uint32_t fbId, GraphicsBuffer *buffer, FileDescriptor &&readFence)
42 : m_framebufferId(fbId)
43 , m_gpu(gpu)
44 , m_bufferRef(buffer)
45{
46 if (s_disableBufferWait || (m_gpu->isI915() && !s_envIsSet)) {
47 // buffer readability checks cause frames to be wrongly delayed on some Intel laptops
48 // See https://gitlab.freedesktop.org/drm/intel/-/issues/9415
49 m_readable = true;
50 }
51 m_syncFd = std::move(readFence);
52#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
53 if (!m_syncFd.isValid()) {
54 dma_buf_export_sync_file req{
55 .flags = DMA_BUF_SYNC_READ,
56 .fd = -1,
57 };
58 if (drmIoctl(buffer->dmabufAttributes()->fd[0].get(), DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &req) == 0) {
59 m_syncFd = FileDescriptor{req.fd};
60 }
61 }
62#endif
63}
64
66{
67 uint32_t nonConstFb = m_framebufferId;
68 if (drmIoctl(m_gpu->fd(), DRM_IOCTL_MODE_CLOSEFB, &nonConstFb) != 0) {
69 drmIoctl(m_gpu->fd(), DRM_IOCTL_MODE_RMFB, &nonConstFb);
70 }
71}
72
74{
75 return m_framebufferId;
76}
77
82
84{
85 m_bufferRef = nullptr;
86}
87
89{
90 return m_syncFd;
91}
92
94{
95 if (m_readable) {
96 return true;
97 } else if (m_syncFd.isValid()) {
99 } else {
100 const auto &fds = m_bufferRef->dmabufAttributes()->fd;
101 return m_readable = std::all_of(fds.begin(), fds.end(), [](const auto &fd) {
102 return !fd.isValid() || fd.isReadable();
103 });
104 }
105}
106
107void DrmFramebuffer::setDeadline(std::chrono::steady_clock::time_point deadline)
108{
109#ifdef SYNC_IOC_SET_DEADLINE
110 if (!m_syncFd.isValid()) {
111 return;
112 }
113 sync_set_deadline args{
114 .deadline_ns = uint64_t(deadline.time_since_epoch().count()),
115 .pad = 0,
116 };
117 drmIoctl(m_syncFd.get(), SYNC_IOC_SET_DEADLINE, &args);
118#endif
119}
120}
DrmFramebuffer(DrmGpu *gpu, uint32_t fbId, GraphicsBuffer *buffer, FileDescriptor &&readFence)
uint32_t framebufferId() const
const FileDescriptor & syncFd() const
void setDeadline(std::chrono::steady_clock::time_point deadline)
DrmGpu *const m_gpu
Definition drm_buffer.h:43
GraphicsBuffer * buffer() const
GraphicsBufferRef m_bufferRef
Definition drm_buffer.h:44
FileDescriptor m_syncFd
Definition drm_buffer.h:46
const uint32_t m_framebufferId
Definition drm_buffer.h:42
int fd() const
Definition drm_gpu.cpp:648
bool isI915() const
Definition drm_gpu.cpp:693
virtual const DmaBufAttributes * dmabufAttributes() const
#define DRM_IOCTL_MODE_CLOSEFB
int drmIoctl(int fd, unsigned long request, void *arg)
Definition mock_drm.cpp:333
std::array< FileDescriptor, 4 > fd