KWayland

shm_pool.h
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #ifndef WAYLAND_SHM_POOL_H
7 #define WAYLAND_SHM_POOL_H
8 
9 #include <QObject>
10 
11 #include "KWayland/Client/kwaylandclient_export.h"
12 #include "buffer.h"
13 
14 class QImage;
15 class QSize;
16 
17 struct wl_shm;
18 
19 namespace KWayland
20 {
21 namespace Client
22 {
23 class EventQueue;
24 
25 /**
26  * @short Wrapper class for wl_shm interface.
27  *
28  * This class holds a shared memory pool together with the Wayland server.
29  *
30  * To use this class one needs to interact with the Registry. There are two
31  * possible ways to create a ShmPool instance:
32  * @code
33  * ShmPool *s = registry->createShmPool(name, version);
34  * @endcode
35  *
36  * This creates the ShmPool and sets it up directly. As an alternative this
37  * can also be done in a more low level way:
38  * @code
39  * ShmPool *s = new ShmPool;
40  * s->setup(registry->bindShm(name, version));
41  * @endcode
42  *
43  * The ShmPool holds a memory-mapped file from which it provides Buffers.
44  * All Buffers are held by the ShmPool and can be reused. Whenever a Buffer
45  * is requested the ShmPool tries to reuse an existing Buffer. A Buffer can
46  * be reused if the following conditions hold
47  * @li it's no longer marked as used
48  * @li the server released the buffer
49  * @li the size matches
50  * @li the stride matches
51  * @li the format matches
52  *
53  * The ownership of a Buffer stays with ShmPool. The ShmPool might destroy the
54  * Buffer at any given time. Because of that ShmPool only provides QWeakPointer
55  * for Buffers. Users should always check whether the pointer is still valid and
56  * only promote to a QSharedPointer for a short time, e.g. to set new data.
57  *
58  * The ShmPool can provide Buffers for different purposes. One can create a Buffer
59  * from an existing QImage. This will use a Buffer with same size, stride and image
60  * format as the QImage and <b>copy</b> the content of the QImage into the Buffer.
61  * The memory is <b>not</b> shared:
62  * @code
63  * QImage image(24, 24, QImage::Format_ARG32);
64  * image.fill(Qt::transparent);
65  * Buffer::Ptr buffer = s->createBuffer(image);
66  * @endcode
67  *
68  * It is also possible to create a Buffer and copy the content from a generic location.
69  * Like above this doesn't share the content but copies it:
70  * @code
71  * QImage image(24, 24, QImage::Format_ARG32);
72  * image.fill(Qt::transparent);
73  * Buffer::Ptr buffer = s->createBuffer(image.size(), image.bytesPerLine(), image.constBits());
74  * @endcode
75  *
76  * Last but not least it is possible to get a Buffer without copying content directly to it.
77  * This means an empty area is just reserved and can be used to e.g. share the memory with a
78  * QImage:
79  * @code
80  * const QSize size = QSize(24, 24);
81  * const int stride = size.width() * 4;
82  * Buffer::Ptr buffer = s->getBuffer(size, stride, Buffer::Format::RGB32);
83  * if (!buffer) {
84  * qDebug() << "Didn't get a valid Buffer";
85  * return;
86  * }
87  * QImage image(buffer.toStrongRef()->address(), size.width(), size.height(), stride, QImage::Format_RGB32);
88  * image.fill(Qt::black);
89  * @endcode
90  *
91  * A Buffer can be attached to a Surface:
92  * @code
93  * Compositor *c = registry.createCompositor(name, version);
94  * Surface *s = c->createSurface();
95  * s->attachBuffer(buffer);
96  * s->damage(QRect(QPoint(0, 0), size));
97  * @endcode
98  *
99  * Once a Buffer is attached to a Surface and the Surface is committed, it might be released
100  * by the Wayland server and thus is free to be reused again. If the client code wants to
101  * continue using the Buffer it must call Buffer::setUsed on it. This is important if the memory
102  * is shared for example with a QImage as the memory buffer for a QImage must remain valid
103  * throughout the life time of the QImage:
104  * @code
105  * buffer.toStrongRef()->setUsed(true);
106  * @endcode
107  *
108  * This is also important for the case that the shared memory pool needs to be resized.
109  * The ShmPool will automatically resize if it cannot provide a new Buffer. During the resize
110  * all existing Buffers are unmapped and any shared objects must be recreated. The ShmPool emits
111  * the signal poolResized() after the pool got resized.
112  *
113  * @see Buffer
114  **/
115 class KWAYLANDCLIENT_EXPORT ShmPool : public QObject
116 {
117  Q_OBJECT
118 public:
119  explicit ShmPool(QObject *parent = nullptr);
120  ~ShmPool() override;
121  /**
122  * @returns @c true if the ShmPool references a wl_shm interface and the shared memory pool
123  * is setup.
124  **/
125  bool isValid() const;
126  /**
127  * Setup this ShmPool to manage the @p shm.
128  * This also creates the shared memory pool.
129  * When using Registry::createShmPool there is no need to call this
130  * method.
131  **/
132  void setup(wl_shm *shm);
133  /**
134  * Releases the wl_shm interface.
135  * After the interface has been released the ShmPool instance is no
136  * longer valid and can be setup with another wl_shm interface.
137  *
138  * This also destroys the shared memory pool and all Buffers are destroyed.
139  **/
140  void release();
141  /**
142  * Destroys the data held by this ShmPool.
143  * This method is supposed to be used when the connection to the Wayland
144  * server goes away. If the connection is not valid anymore, it's not
145  * possible to call release anymore as that calls into the Wayland
146  * connection and the call would fail. This method cleans up the data, so
147  * that the instance can be deleted or set up to a new wl_shm interface
148  * once there is a new connection available.
149  *
150  * All Buffers are destroyed!
151  *
152  * This method is automatically invoked when the Registry which created this
153  * ShmPool gets destroyed.
154  *
155  * @see release
156  **/
157  void destroy();
158 
159  /**
160  * Sets the @p queue to use for creating a Buffer.
161  **/
162  void setEventQueue(EventQueue *queue);
163  /**
164  * @returns The event queue to use for creating a Buffer.
165  **/
166  EventQueue *eventQueue();
167 
168  /**
169  * Provides a Buffer with:
170  * @li same size as @p image
171  * @li same stride as @p image
172  * @li same format as @p image
173  *
174  * If the ShmPool fails to provide such a Buffer a @c null Buffer::Ptr is returned.
175  * The content of the @p image is <b>copied</b> into the buffer. The @p image and
176  * returned Buffer do <b>not</b> share memory.
177  *
178  * @param image The image which should be copied into the Buffer
179  * @return Buffer with copied content of @p image in success case, a @c null Buffer::Ptr otherwise
180  * @see getBuffer
181  **/
182  Buffer::Ptr createBuffer(const QImage &image);
183  /**
184  * Provides a Buffer with @p size, @p stride and @p format.
185  *
186  * If the ShmPool fails to provide such a Buffer a @c null Buffer::Ptr is returned.
187  * A memory copy is performed from @p src into the Buffer. The Buffer does <b>not</b> share
188  * memory with @p src.
189  *
190  * @param size The requested size for the Buffer
191  * @param stride The requested stride for the Buffer
192  * @param src The source memory location to copy from
193  * @param format The requested format for the Buffer
194  * @return Buffer with copied content of @p src in success case, a @c null Buffer::Ptr otherwise
195  * @see getBuffer
196  **/
197  Buffer::Ptr createBuffer(const QSize &size, int32_t stride, const void *src, Buffer::Format format = Buffer::Format::ARGB32);
198  void *poolAddress() const;
199  /**
200  * Provides a Buffer with @p size, @p stride and @p format.
201  *
202  * If the ShmPool fails to provide such a Buffer a @c null Buffer::Ptr is returned.
203  * Unlike with createBuffer there is no memory copy performed. This provides a bare Buffer
204  * to be used by the user.
205  *
206  * @param size The requested size for the Buffer
207  * @param stride The requested stride for the Buffer
208  * @param format The requested format for the Buffer
209  * @return Buffer as requested in success case, a @c null Buffer::Ptr otherwise.
210  * @see createBuffer
211  **/
212  Buffer::Ptr getBuffer(const QSize &size, int32_t stride, Buffer::Format format = Buffer::Format::ARGB32);
213  wl_shm *shm();
214 Q_SIGNALS:
215  /**
216  * This signal is emitted whenever the shared memory pool gets resized.
217  * Any used Buffer must be remapped.
218  **/
219  void poolResized();
220 
221  /**
222  * The corresponding global for this interface on the Registry got removed.
223  *
224  * This signal gets only emitted if the Compositor got created by
225  * Registry::createShmPool
226  *
227  * @since 5.5
228  **/
229  void removed();
230 
231 private:
232  class Private;
234 };
235 
236 }
237 }
238 
239 #endif
virtual void release(quint64 objid)
Wrapper class for wl_event_queue interface.
Definition: event_queue.h:54
Wrapper class for wl_shm interface.
Definition: shm_pool.h:115
Format
All image formats supported by the implementation.
Definition: buffer.h:36
@ ARGB32
32-bit ARGB format, can be used for QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Sep 26 2023 03:48:29 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.