1 | // Copyright (C) 2017 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include "shmserverbufferintegration.h" |
5 | |
6 | #include <QtOpenGL/QOpenGLTexture> |
7 | #include <QtGui/QOpenGLContext> |
8 | #include <QtCore/QSharedMemory> |
9 | |
10 | #include <QtCore/QDebug> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | ShmServerBuffer::ShmServerBuffer(ShmServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format) |
15 | : QtWayland::ServerBuffer(qimage.size(),format) |
16 | , m_integration(integration) |
17 | , m_width(qimage.width()) |
18 | , m_height(qimage.height()) |
19 | , m_bpl(qimage.bytesPerLine()) |
20 | { |
21 | m_format = format; |
22 | switch (m_format) { |
23 | case RGBA32: |
24 | m_shm_format = QtWaylandServer::qt_shm_emulation_server_buffer::format_RGBA32; |
25 | break; |
26 | case A8: |
27 | m_shm_format = QtWaylandServer::qt_shm_emulation_server_buffer::format_A8; |
28 | break; |
29 | default: |
30 | qWarning(msg: "ShmServerBuffer: unsupported format" ); |
31 | m_shm_format = QtWaylandServer::qt_shm_emulation_server_buffer::format_RGBA32; |
32 | break; |
33 | } |
34 | |
35 | QString key = "qt_shm_emulation_" + QString::number(qimage.cacheKey()); |
36 | // ### Use proper native keys the next time we can break protocol compatibility |
37 | QT_IGNORE_DEPRECATIONS(m_shm = new QSharedMemory(key);) |
38 | qsizetype shm_size = qimage.sizeInBytes(); |
39 | bool ok = m_shm->create(size: shm_size) && m_shm->lock(); |
40 | if (ok) { |
41 | memcpy(dest: m_shm->data(), src: qimage.constBits(), n: shm_size); |
42 | m_shm->unlock(); |
43 | } else { |
44 | qWarning() << "Could not create shared memory" << key << shm_size; |
45 | } |
46 | } |
47 | |
48 | ShmServerBuffer::~ShmServerBuffer() |
49 | { |
50 | delete m_shm; |
51 | } |
52 | |
53 | struct ::wl_resource *ShmServerBuffer::resourceForClient(struct ::wl_client *client) |
54 | { |
55 | auto *bufferResource = resourceMap().value(client); |
56 | if (!bufferResource) { |
57 | auto integrationResource = m_integration->resourceMap().value(client); |
58 | if (!integrationResource) { |
59 | qWarning(msg: "ShmServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the shm_emulation interface" ); |
60 | return nullptr; |
61 | } |
62 | struct ::wl_resource *shm_integration_resource = integrationResource->handle; |
63 | Resource *resource = add(client, 1); |
64 | QT_IGNORE_DEPRECATIONS(const QString shmKey = m_shm->key();) |
65 | m_integration->send_server_buffer_created(shm_integration_resource, resource->handle, shmKey, m_width, m_height, m_bpl, m_shm_format); |
66 | return resource->handle; |
67 | } |
68 | return bufferResource->handle; |
69 | } |
70 | |
71 | bool ShmServerBuffer::bufferInUse() |
72 | { |
73 | return resourceMap().size() > 0; |
74 | } |
75 | |
76 | QOpenGLTexture *ShmServerBuffer::toOpenGlTexture() |
77 | { |
78 | if (!m_texture) { |
79 | qWarning(msg: "ShmServerBuffer::toOpenGlTexture: no texture defined" ); |
80 | } |
81 | return m_texture; |
82 | } |
83 | |
84 | ShmServerBufferIntegration::ShmServerBufferIntegration() |
85 | { |
86 | } |
87 | |
88 | ShmServerBufferIntegration::~ShmServerBufferIntegration() |
89 | { |
90 | } |
91 | |
92 | bool ShmServerBufferIntegration::initializeHardware(QWaylandCompositor *compositor) |
93 | { |
94 | Q_ASSERT(QGuiApplication::platformNativeInterface()); |
95 | |
96 | QtWaylandServer::qt_shm_emulation_server_buffer::init(compositor->display(), 1); |
97 | return true; |
98 | } |
99 | |
100 | bool ShmServerBufferIntegration::supportsFormat(QtWayland::ServerBuffer::Format format) const |
101 | { |
102 | switch (format) { |
103 | case QtWayland::ServerBuffer::RGBA32: |
104 | return true; |
105 | case QtWayland::ServerBuffer::A8: |
106 | return true; |
107 | default: |
108 | return false; |
109 | } |
110 | } |
111 | |
112 | QtWayland::ServerBuffer *ShmServerBufferIntegration::createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) |
113 | { |
114 | return new ShmServerBuffer(this, qimage, format); |
115 | } |
116 | |
117 | QT_END_NAMESPACE |
118 | |