Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
vulkanserverbufferintegration.cpp
Go to the documentation of this file.
1
// Copyright (C) 2019 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
// Qt-Security score:critical reason:network-protocol
4
5
#
include
"vulkanserverbufferintegration.h"
6
7
#
include
"vulkanwrapper.h"
8
9
#
include
<
QtOpenGL
/
QOpenGLTexture
>
10
#
include
<
QtGui
/
QOpenGLContext
>
11
#
include
<
QtGui
/
QOffscreenSurface
>
12
#
include
<
QtGui
/
qopengl
.
h
>
13
14
#
include
<
unistd
.
h
>
15
#
include
<
fcntl
.
h
>
16
17
#
include
<
QtCore
/
QDebug
>
18
19
QT_BEGIN_NAMESPACE
20
static
constexpr
bool
vsbiExtraDebug
=
false
;
21
22
#
define
DECL_GL_FUNCTION
(
name
,
type
)
23
type
name
24
25
#
define
FIND_GL_FUNCTION
(
name
,
type
)
26
do
{
27
name
=
reinterpret_cast
<
type
>
(
glContext
->
getProcAddress
(
#
name
)
)
;
28
if
(
!
name
)
{
29
qWarning
(
)
<<
"ERROR in GL proc lookup. Could not find "
#
name
;
30
return
false
;
31
}
32
}
while
(
0
)
33
34
struct
VulkanServerBufferGlFunctions
35
{
36
DECL_GL_FUNCTION
(glCreateMemoryObjectsEXT, PFNGLCREATEMEMORYOBJECTSEXTPROC);
37
DECL_GL_FUNCTION
(glImportMemoryFdEXT, PFNGLIMPORTMEMORYFDEXTPROC);
38
//DECL_GL_FUNCTION(glTextureStorageMem2DEXT, PFNGLTEXTURESTORAGEMEM2DEXTPROC);
39
DECL_GL_FUNCTION
(glTexStorageMem2DEXT, PFNGLTEXSTORAGEMEM2DEXTPROC);
40
DECL_GL_FUNCTION
(glDeleteMemoryObjectsEXT, PFNGLDELETEMEMORYOBJECTSEXTPROC);
41
42
bool
init
(QOpenGLContext *glContext)
43
{
44
FIND_GL_FUNCTION
(glCreateMemoryObjectsEXT, PFNGLCREATEMEMORYOBJECTSEXTPROC);
45
FIND_GL_FUNCTION
(glImportMemoryFdEXT, PFNGLIMPORTMEMORYFDEXTPROC);
46
//FIND_GL_FUNCTION(glTextureStorageMem2DEXT, PFNGLTEXTURESTORAGEMEM2DEXTPROC);
47
FIND_GL_FUNCTION
(glTexStorageMem2DEXT, PFNGLTEXSTORAGEMEM2DEXTPROC);
48
FIND_GL_FUNCTION
(glDeleteMemoryObjectsEXT, PFNGLDELETEMEMORYOBJECTSEXTPROC);
49
50
return
true
;
51
}
52
static
bool
create
(QOpenGLContext *glContext);
53
};
54
55
static
VulkanServerBufferGlFunctions
*
funcs
=
nullptr
;
56
57
//RAII
58
class
CurrentContext
59
{
60
public
:
61
CurrentContext
()
62
{
63
if
(!QOpenGLContext::currentContext()) {
64
if
(QOpenGLContext::globalShareContext()) {
65
if
(!localContext) {
66
localContext =
new
QOpenGLContext;
67
localContext->setShareContext(QOpenGLContext::globalShareContext());
68
localContext->create();
69
}
70
if
(!offscreenSurface) {
71
offscreenSurface =
new
QOffscreenSurface;
72
offscreenSurface->setFormat(localContext->format());
73
offscreenSurface->create();
74
}
75
localContext->makeCurrent(offscreenSurface);
76
localContextInUse =
true
;
77
}
else
{
78
qCritical(
"VulkanServerBufferIntegration: no globalShareContext"
);
79
}
80
}
81
}
82
~
CurrentContext
()
83
{
84
if
(localContextInUse)
85
localContext->doneCurrent();
86
}
87
QOpenGLContext *
context
() {
return
localContextInUse ? localContext : QOpenGLContext::currentContext(); }
88
private
:
89
static
QOpenGLContext *localContext;
90
static
QOffscreenSurface *offscreenSurface;
91
bool
localContextInUse =
false
;
92
};
93
94
QOpenGLContext *
CurrentContext
::localContext =
nullptr
;
95
QOffscreenSurface *
CurrentContext
::offscreenSurface =
nullptr
;
96
97
bool
VulkanServerBufferGlFunctions
::
create
(QOpenGLContext *glContext)
98
{
99
if
(
funcs
)
100
return
true
;
101
funcs
=
new
VulkanServerBufferGlFunctions
;
102
if
(!
funcs
->
init
(
glContext
)
) {
103
delete
funcs
;
104
funcs
=
nullptr
;
105
return
false
;
106
}
107
return
true
;
108
}
109
110
VulkanServerBuffer
::VulkanServerBuffer(
VulkanServerBufferIntegration
*integration,
const
QImage &qimage, QtWayland::ServerBuffer::Format format)
111
: QtWayland::ServerBuffer(qimage.size(),format)
112
, m_integration(integration)
113
, m_width(qimage.width())
114
, m_height(qimage.height())
115
{
116
m_format = format;
117
switch
(m_format) {
118
case
RGBA32:
119
m_glInternalFormat = GL_RGBA8;
120
break
;
121
// case A8:
122
// m_glInternalFormat = GL_R8;
123
// break;
124
default
:
125
qWarning(
"VulkanServerBuffer: unsupported format"
);
126
m_glInternalFormat = GL_RGBA8;
127
break
;
128
}
129
130
auto
vulkanWrapper = m_integration
->
vulkanWrapper
(
)
;
131
m_vImage = vulkanWrapper
->
createTextureImage
(
qimage
)
;
132
if
(m_vImage)
133
m_fd = vulkanWrapper
->
getImageInfo
(
m_vImage
,
&m_memorySize
)
;
134
}
135
136
VulkanServerBuffer
::
VulkanServerBuffer
(
VulkanServerBufferIntegration
*integration,
VulkanImageWrapper
*vImage, uint glInternalFormat,
const
QSize &size)
137
:
QtWayland
::
ServerBuffer
(
size
,
QtWayland
::
ServerBuffer
::
Custom
)
138
, m_integration(integration)
139
, m_width(size.width())
140
, m_height(size.height())
141
, m_vImage(vImage)
142
,
m_glInternalFormat
(
glInternalFormat
)
143
{
144
auto
vulkanWrapper = m_integration
->
vulkanWrapper
(
)
;
145
m_fd = vulkanWrapper
->
getImageInfo
(
m_vImage
,
&m_memorySize
)
;
146
}
147
148
VulkanServerBuffer
::~
VulkanServerBuffer
()
149
{
150
delete
m_texture;
//this is always nullptr for now
151
auto
vulkanWrapper = m_integration
->
vulkanWrapper
(
)
;
152
vulkanWrapper
->
freeTextureImage
(
m_vImage
)
;
153
}
154
155
struct
::wl_resource *
VulkanServerBuffer
::resourceForClient(
struct
::wl_client *client)
156
{
157
auto
*bufferResource = resourceMap().value(client);
158
if
(!bufferResource) {
159
auto
integrationResource = m_integration->resourceMap().value(client);
160
if
(!integrationResource) {
161
qWarning(
"VulkanServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the vulkan interface"
);
162
return
nullptr
;
163
}
164
struct
::wl_resource *shm_integration_resource = integrationResource->handle;
165
Resource *resource = add(client, 1);
166
m_integration->send_server_buffer_created(shm_integration_resource, resource->handle, m_fd, m_width, m_height, m_memorySize, m_glInternalFormat);
167
return
resource->handle;
168
}
169
return
bufferResource->handle;
170
}
171
172
QOpenGLTexture
*
VulkanServerBuffer
::
toOpenGlTexture
()
173
{
174
if
(m_texture && m_texture->isCreated())
175
return
m_texture;
176
177
CurrentContext
current;
178
179
if
(!
funcs
&& !
VulkanServerBufferGlFunctions
::
create
(
current
.
context
(
)
)
)
180
return
nullptr
;
181
182
funcs
->glCreateMemoryObjectsEXT(1, &m_memoryObject);
183
if
(vsbiExtraDebug) qDebug() <<
"glCreateMemoryObjectsEXT"
<< Qt::hex << glGetError();
184
185
186
int
dupfd = fcntl(m_fd, F_DUPFD_CLOEXEC, 0);
187
if
(dupfd < 0) {
188
perror(
"VulkanServerBuffer::toOpenGlTexture() Could not dup fd:"
);
189
return
nullptr
;
190
}
191
192
funcs
->glImportMemoryFdEXT(m_memoryObject, m_memorySize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, dupfd);
193
if
(vsbiExtraDebug) qDebug() <<
"glImportMemoryFdEXT"
<< Qt::hex << glGetError();
194
195
196
if
(!m_texture)
197
m_texture =
new
QOpenGLTexture(QOpenGLTexture::Target2D);
198
m_texture->create();
199
200
GLuint texId = m_texture->textureId();
201
if
(vsbiExtraDebug) qDebug() <<
"created texture"
<< texId << Qt::hex << glGetError();
202
203
m_texture->bind();
204
if
(vsbiExtraDebug) qDebug() <<
"bound texture"
<< texId << Qt::hex << glGetError();
205
funcs
->glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, m_glInternalFormat, m_size.width(), m_size.height(), m_memoryObject, 0 );
206
if
(vsbiExtraDebug) qDebug() <<
"glTexStorageMem2DEXT"
<< Qt::hex << glGetError();
207
if
(vsbiExtraDebug) qDebug() <<
"format"
<< Qt::hex << m_glInternalFormat << GL_RGBA8;
208
209
210
return
m_texture;
211
}
212
213
void
VulkanServerBuffer
::
releaseOpenGlTexture
()
214
{
215
if
(!m_texture || !m_texture->isCreated())
216
return
;
217
218
CurrentContext
current;
219
m_texture->destroy();
220
funcs
->glDeleteMemoryObjectsEXT(1, &m_memoryObject);
221
}
222
223
224
bool
VulkanServerBuffer
::
bufferInUse
()
225
{
226
return
(m_texture && m_texture->isCreated()) || resourceMap().size() > 0;
227
}
228
229
void
VulkanServerBuffer
::
server_buffer_release
(Resource *resource)
230
{
231
qCDebug(qLcWaylandCompositorHardwareIntegration) <<
"server_buffer RELEASE resource"
<< resource->handle << wl_resource_get_id(resource->handle) <<
"for client"
<< resource->client();
232
wl_resource_destroy(resource->handle);
233
}
234
235
VulkanServerBufferIntegration
::
VulkanServerBufferIntegration
()
236
{
237
}
238
239
VulkanServerBufferIntegration
::~
VulkanServerBufferIntegration
()
240
{
241
}
242
243
bool
VulkanServerBufferIntegration
::
initializeHardware
(QWaylandCompositor *compositor)
244
{
245
Q_ASSERT(QGuiApplication::platformNativeInterface());
246
247
QtWaylandServer::zqt_vulkan_server_buffer_v1::init(compositor->display(), 1);
248
return
true
;
249
}
250
251
bool
VulkanServerBufferIntegration
::
supportsFormat
(QtWayland::ServerBuffer::Format format)
const
252
{
253
switch
(format) {
254
case
QtWayland::ServerBuffer::RGBA32:
255
return
true
;
256
case
QtWayland::ServerBuffer::A8:
257
return
false
;
258
default
:
259
return
false
;
260
}
261
}
262
263
QtWayland::ServerBuffer *
VulkanServerBufferIntegration
::createServerBufferFromImage(
const
QImage &qimage, QtWayland::ServerBuffer::Format format)
264
{
265
if
(!m_vulkanWrapper) {
266
CurrentContext
current;
267
m_vulkanWrapper =
new
VulkanWrapper
(
current
.
context
(
)
)
;
268
}
269
return
new
VulkanServerBuffer
(
this
, qimage, format);
270
}
271
272
QtWayland
::
ServerBuffer
*
273
VulkanServerBufferIntegration
::
createServerBufferFromData
(QByteArrayView view,
const
QSize &size,
274
uint glInternalFormat)
275
{
276
if
(!m_vulkanWrapper) {
277
CurrentContext
current;
278
m_vulkanWrapper =
new
VulkanWrapper
(
current
.
context
(
)
)
;
279
}
280
281
auto
*vImage = m_vulkanWrapper->createTextureImageFromData(
282
reinterpret_cast
<
const
uchar *>(view.constData()), view.size(), size, glInternalFormat);
283
284
if
(vImage)
285
return
new
VulkanServerBuffer
(
this
, vImage, glInternalFormat, size);
286
287
qCWarning(qLcWaylandCompositorHardwareIntegration) <<
"could not load compressed texture"
;
288
return
nullptr
;
289
}
290
291
QT_END_NAMESPACE
CurrentContext
Definition
vulkanserverbufferintegration.cpp:59
CurrentContext::~CurrentContext
~CurrentContext()
Definition
vulkanserverbufferintegration.cpp:82
CurrentContext::CurrentContext
CurrentContext()
Definition
vulkanserverbufferintegration.cpp:61
CurrentContext::context
QOpenGLContext * context()
Definition
vulkanserverbufferintegration.cpp:87
VulkanServerBufferIntegration
Definition
vulkanserverbufferintegration.h:57
VulkanServerBufferIntegration::supportsFormat
bool supportsFormat(QtWayland::ServerBuffer::Format format) const override
Definition
vulkanserverbufferintegration.cpp:251
VulkanServerBufferIntegration::initializeHardware
bool initializeHardware(QWaylandCompositor *) override
Definition
vulkanserverbufferintegration.cpp:243
VulkanServerBufferIntegration::~VulkanServerBufferIntegration
~VulkanServerBufferIntegration() override
Definition
vulkanserverbufferintegration.cpp:239
VulkanServerBufferIntegration::VulkanServerBufferIntegration
VulkanServerBufferIntegration()
Definition
vulkanserverbufferintegration.cpp:235
VulkanServerBufferIntegration::createServerBufferFromData
QtWayland::ServerBuffer * createServerBufferFromData(QByteArrayView view, const QSize &size, uint glInternalFormat) override
Definition
vulkanserverbufferintegration.cpp:273
VulkanServerBufferIntegration::vulkanWrapper
VulkanWrapper * vulkanWrapper() const
Definition
vulkanserverbufferintegration.h:62
VulkanServerBuffer
Definition
vulkanserverbufferintegration.h:27
VulkanServerBuffer::server_buffer_release
void server_buffer_release(Resource *resource) override
Definition
vulkanserverbufferintegration.cpp:229
VulkanServerBuffer::releaseOpenGlTexture
void releaseOpenGlTexture() override
Definition
vulkanserverbufferintegration.cpp:213
VulkanServerBuffer::toOpenGlTexture
QOpenGLTexture * toOpenGlTexture() override
Definition
vulkanserverbufferintegration.cpp:172
VulkanServerBuffer::bufferInUse
bool bufferInUse() override
Definition
vulkanserverbufferintegration.cpp:224
VulkanServerBuffer::VulkanServerBuffer
VulkanServerBuffer(VulkanServerBufferIntegration *integration, VulkanImageWrapper *vImage, uint glInternalFormat, const QSize &size)
Definition
vulkanserverbufferintegration.cpp:136
VulkanServerBuffer::~VulkanServerBuffer
~VulkanServerBuffer() override
Definition
vulkanserverbufferintegration.cpp:148
VulkanWrapper
Definition
vulkanwrapper.h:20
VulkanWrapper::getImageInfo
int getImageInfo(const VulkanImageWrapper *imgWrapper, int *memSize, int *w=nullptr, int *h=nullptr)
Definition
vulkanwrapper.cpp:681
VulkanWrapper::VulkanWrapper
VulkanWrapper(QOpenGLContext *glContext)
Definition
vulkanwrapper.cpp:662
VulkanWrapper::freeTextureImage
void freeTextureImage(VulkanImageWrapper *imageWrapper)
Definition
vulkanwrapper.cpp:692
VulkanWrapper::createTextureImage
VulkanImageWrapper * createTextureImage(const QImage &img)
Definition
vulkanwrapper.cpp:667
DECL_GL_FUNCTION
#define DECL_GL_FUNCTION(name, type)
Definition
vulkanserverbufferintegration.cpp:25
FIND_GL_FUNCTION
#define FIND_GL_FUNCTION(name, type)
Definition
vulkanserverbufferintegration.cpp:28
vsbiExtraDebug
static QT_BEGIN_NAMESPACE constexpr bool vsbiExtraDebug
Definition
vulkanserverbufferintegration.cpp:20
funcs
static VulkanServerBufferGlFunctions * funcs
Definition
vulkanserverbufferintegration.cpp:55
VulkanImageWrapper
Definition
vulkanwrapper.cpp:156
VulkanServerBufferGlFunctions
Definition
vulkanserverbufferintegration.cpp:35
VulkanServerBufferGlFunctions::init
bool init(QOpenGLContext *glContext)
Definition
vulkanserverbufferintegration.cpp:42
VulkanServerBufferGlFunctions::create
static bool create(QOpenGLContext *glContext)
Definition
vulkanserverbufferintegration.cpp:97
qtwayland
src
hardwareintegration
compositor
vulkan-server
vulkanserverbufferintegration.cpp
Generated on
for Qt by
1.18.0