KWin
Loading...
Searching...
No Matches
shmgraphicsbufferallocator.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
8
9#include "config-kwin.h"
10
11#include "core/graphicsbuffer.h"
12#include "utils/memorymap.h"
13
14#include <drm_fourcc.h>
15#include <fcntl.h>
16#include <sys/mman.h>
17#include <unistd.h>
18
19namespace KWin
20{
21
23{
24 Q_OBJECT
25
26public:
27 ShmGraphicsBuffer(ShmAttributes &&attributes, MemoryMap &&memoryMap);
28
29 Map map(MapFlags flags) override;
30 void unmap() override;
31
32 QSize size() const override;
33 bool hasAlphaChannel() const override;
34 const ShmAttributes *shmAttributes() const override;
35
36private:
37 ShmAttributes m_attributes;
38 MemoryMap m_memoryMap;
39 bool m_hasAlphaChannel;
40};
41
43 : m_attributes(std::move(attributes))
44 , m_memoryMap(std::move(memoryMap))
45 , m_hasAlphaChannel(alphaChannelFromDrmFormat(attributes.format))
46{
47}
48
50{
51 if (m_memoryMap.isValid()) {
52 return Map{
53 .data = m_memoryMap.data(),
54 .stride = uint32_t(m_attributes.stride),
55 };
56 } else {
57 return Map{};
58 }
59}
60
64
66{
67 return m_attributes.size;
68}
69
71{
72 return m_hasAlphaChannel;
73}
74
76{
77 return &m_attributes;
78}
79
81{
82 if (!options.software) {
83 return nullptr;
84 }
85 if (!options.modifiers.isEmpty() && !options.modifiers.contains(DRM_FORMAT_MOD_LINEAR)) {
86 return nullptr;
87 }
88
89 switch (options.format) {
90 case DRM_FORMAT_ARGB8888:
91 case DRM_FORMAT_XRGB8888:
92 break;
93 default:
94 return nullptr;
95 }
96
97 const int stride = options.size.width() * 4;
98 const int bufferSize = options.size.height() * stride;
99
100#if HAVE_MEMFD
101 FileDescriptor fd = FileDescriptor(memfd_create("shm", MFD_CLOEXEC | MFD_ALLOW_SEALING));
102 if (!fd.isValid()) {
103 return nullptr;
104 }
105
106 if (ftruncate(fd.get(), bufferSize) < 0) {
107 return nullptr;
108 }
109
110 fcntl(fd.get(), F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL);
111#else
112 char templateName[] = "/tmp/kwin-shm-XXXXXX";
113 FileDescriptor fd{mkstemp(templateName)};
114 if (!fd.isValid()) {
115 return nullptr;
116 }
117
118 unlink(templateName);
119 int flags = fcntl(fd.get(), F_GETFD);
120 if (flags == -1 || fcntl(fd.get(), F_SETFD, flags | FD_CLOEXEC) == -1) {
121 return nullptr;
122 }
123
124 if (ftruncate(fd.get(), bufferSize) < 0) {
125 return nullptr;
126 }
127#endif
128
129 ShmAttributes attributes{
130 .fd = std::move(fd),
131 .stride = stride,
132 .offset = 0,
133 .size = options.size,
134 .format = options.format,
135 };
136
137 MemoryMap memoryMap(attributes.stride * attributes.size.height(), PROT_READ | PROT_WRITE, MAP_SHARED, attributes.fd.get(), attributes.offset);
138 if (!memoryMap.isValid()) {
139 return nullptr;
140 }
141
142 return new ShmGraphicsBuffer(std::move(attributes), std::move(memoryMap));
143}
144
145} // namespace KWin
146
147#include "moc_shmgraphicsbufferallocator.cpp"
148#include "shmgraphicsbufferallocator.moc"
void * data() const
Definition memorymap.h:58
bool isValid() const
Definition memorymap.h:53
GraphicsBuffer * allocate(const GraphicsBufferOptions &options) override
ShmGraphicsBuffer(ShmAttributes &&attributes, MemoryMap &&memoryMap)
Map map(MapFlags flags) override
const ShmAttributes * shmAttributes() const override
GLenum format
Definition gltexture.cpp:49
Options * options
Definition main.cpp:73
FileDescriptor fd