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
qeglimagefunctions.cpp
Go to the documentation of this file.
1
// Copyright (C) 2026 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qeglimagefunctions_p.h"
5
6
#
include
<
QtMultimedia
/
private
/
qmultimedia_ranges_p
.
h
>
7
8
#
include
<
QtCore
/
qloggingcategory
.
h
>
9
10
#
include
<
optional
>
11
#
include
<
vector
>
12
13
#
if
defined
(
EGL_KHR_image
)
14
#
include
<
limits
>
15
#
include
<
mutex
>
16
#
endif
17
18
QT_BEGIN_NAMESPACE
19
20
namespace
QtMultimediaPrivate
{
21
22
namespace
{
23
24
#
if
defined
(
EGL_KHR_image
)
25
Q_STATIC_LOGGING_CATEGORY(qLcEglImage,
"qt.multimedia.egl"
);
26
27
// eglCreateImageKHR takes an EGLint attribute list, while our callers build an EGLAttrib
28
// (intptr_t) list, as required by core eglCreateImage. On 64-bit platforms we need to perform
29
// narrowing conversion; all of our current attribute values (dimensions, fds, offsets/strides,
30
// and the already 32-bit-split dma-buf modifier) fit into EGLint, but we still validate this
31
// rather than silently truncate.
32
[[maybe_unused]] std::optional<std::vector<EGLint>> narrowToEGLint(QSpan<
const
EGLAttrib> attribs)
33
{
34
std::vector<EGLint> narrowed(size_t(attribs.size()));
35
36
Q_ASSERT(
sizeof
(EGLAttrib) >
sizeof
(EGLint));
37
static
std
::once_flag warnOnce;
38
std
::call_once(warnOnce, [] {
39
qCDebug(qLcEglImage) <<
"EGL_KHR_image_base fallback: narrowing 64-bit EGLAttrib "
40
"attribute values to 32-bit EGLint"
;
41
});
42
43
for
(qsizetype i = 0; i < attribs.size(); ++i) {
44
const
EGLAttrib value = attribs[i];
45
if
(value <
std
::numeric_limits<EGLint>::min()
46
|| value >
std
::numeric_limits<EGLint>::max()) {
47
qCWarning(qLcEglImage)
48
<<
"EGL attribute value"
<< value
49
<<
"does not fit into EGLint; cannot use the EGL_KHR_image_base fallback"
;
50
return
std
::nullopt;
51
}
52
narrowed[size_t(i)] = EGLint(value);
53
}
54
55
return
narrowed;
56
}
57
#
endif
58
59
template
<
typename
Fn>
60
Fn getEglFunction(
const
char
*name)
61
{
62
return
reinterpret_cast
<Fn>(eglGetProcAddress(name));
63
}
64
65
}
// namespace
66
67
QEglImageFunctions
::
QEglImageFunctions
()
68
:
69
#
ifdef
GL_OES_EGL_image
70
m_glEGLImageTargetTexture2DOES
{
71
getEglFunction
<
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC
>(
"glEGLImageTargetTexture2DOES"
),
72
}
73
#
endif
74
#
ifdef
EGL_VERSION_1_5
75
,
76
m_eglCreateImage
{
77
getEglFunction
<
PFNEGLCREATEIMAGEPROC
>(
"eglCreateImage"
),
78
},
79
m_eglDestroyImage
{
80
getEglFunction
<
PFNEGLDESTROYIMAGEPROC
>(
"eglDestroyImage"
),
81
}
82
#
endif
83
#
if
defined
(
EGL_KHR_image
)
84
,
85
m_eglCreateImageKHR
{
86
getEglFunction
<
PFNEGLCREATEIMAGEKHRPROC
>(
"eglCreateImageKHR"
),
87
},
88
m_eglDestroyImageKHR
{
89
getEglFunction
<
PFNEGLDESTROYIMAGEKHRPROC
>(
"eglDestroyImageKHR"
),
90
}
91
#
endif
92
#
if
defined
(
EGL_EXT_image_dma_buf_import_modifiers
)
93
,
94
m_eglQueryDmaBufModifiersEXT
{
95
getEglFunction
<
PFNEGLQUERYDMABUFMODIFIERSEXTPROC
>(
"eglQueryDmaBufModifiersEXT"
),
96
}
97
#
endif
98
{
99
}
100
101
const
QEglImageFunctions
&
QEglImageFunctions
::
instance
()
102
{
103
static
const
QEglImageFunctions
singleton
;
104
return
singleton
;
105
}
106
107
bool
QEglImageFunctions
::
isValid
()
const
108
{
109
#
ifdef
GL_OES_EGL_image
110
if
(!
m_glEGLImageTargetTexture2DOES
)
111
return
false
;
112
#
else
113
return
false
;
114
#
endif
115
116
#
ifdef
EGL_VERSION_1_5
117
if
(
m_eglCreateImage
&&
m_eglDestroyImage
)
118
return
true
;
119
#
endif
120
#
if
defined
(
EGL_KHR_image
)
121
if
(
m_eglCreateImageKHR
&&
m_eglDestroyImageKHR
)
122
return
true
;
123
#
endif
124
return
false
;
125
}
126
127
void
QEglImageFunctions
::
glEGLImageTargetTexture2DOES
(
GLenum
target
,
GLeglImageOES
image
)
const
128
{
129
#
ifdef
GL_OES_EGL_image
130
m_glEGLImageTargetTexture2DOES
(
target
,
image
);
131
#
endif
132
}
133
134
EGLImageHandle
QEglImageFunctions
::
eglCreateImage
(
EGLDisplay
dpy
,
EGLContext
ctx
,
EGLenum
target
,
135
EGLClientBuffer
buffer
,
136
QSpan
<
const
EGLAttrib
>
attribs
)
const
137
{
138
EglImageDeleter
deleter
(
dpy
);
139
#
ifdef
EGL_VERSION_1_5
140
if
(
m_eglCreateImage
) {
141
return
EGLImageHandle
(
142
m_eglCreateImage
(
dpy
,
ctx
,
target
,
buffer
,
143
attribs
.
empty
() ?
nullptr
:
attribs
.
data
()),
144
deleter
);
145
}
146
#
endif
147
#
if
defined
(
EGL_KHR_image
)
148
if
(
m_eglCreateImageKHR
) {
149
if
constexpr
(
sizeof
(
EGLAttrib
) ==
sizeof
(
EGLint
)) {
150
return
EGLImageHandle
(
151
m_eglCreateImageKHR
(
152
dpy
,
ctx
,
target
,
buffer
,
153
attribs
.
empty
() ?
nullptr
154
:
reinterpret_cast
<
const
EGLint
*>(
attribs
.
data
())),
155
deleter
);
156
}
else
{
157
const
auto
narrowed
=
narrowToEGLint
(
attribs
);
158
if
(!
narrowed
)
159
return
EGLImageHandle
(EGL_NO_IMAGE,
deleter
);
160
return
EGLImageHandle
(
161
m_eglCreateImageKHR
(
dpy
,
ctx
,
target
,
buffer
,
162
narrowed
->
empty
() ?
nullptr
:
narrowed
->
data
()),
163
deleter
);
164
}
165
}
166
#
endif
167
return
EGLImageHandle
(EGL_NO_IMAGE,
deleter
);
168
}
169
170
EGLBoolean
QEglImageFunctions
::
eglDestroyImage
(
EGLDisplay
dpy
,
EGLImage
image
)
const
171
{
172
#
ifdef
EGL_VERSION_1_5
173
if
(
m_eglDestroyImage
)
174
return
m_eglDestroyImage
(
dpy
,
image
);
175
#
endif
176
#
if
defined
(
EGL_KHR_image
)
177
if
(
m_eglDestroyImageKHR
)
178
return
m_eglDestroyImageKHR
(
dpy
,
image
);
179
#
endif
180
return
EGL_FALSE;
181
}
182
183
std
::
optional
<
bool
>
QEglImageFunctions
::
isDmaBufModifierSupported
(
EGLDisplay
display
,
184
DRMFormat
drmFormat
,
185
DRMModifier
modifier
)
const
186
{
187
#
if
defined
(
EGL_EXT_image_dma_buf_import_modifiers
)
188
if
(!
m_eglQueryDmaBufModifiersEXT
)
189
return
std
::
nullopt
;
// can't introspect
190
191
const
EGLint
format
=
EGLint
(
qToUnderlying
(
drmFormat
));
192
EGLint
numModifiers
= 0;
193
if
(!
m_eglQueryDmaBufModifiersEXT
(
display
,
format
, 0,
nullptr
,
nullptr
, &
numModifiers
)
194
||
numModifiers
<= 0)
195
return
std
::
nullopt
;
// query unsupported
196
197
std
::
vector
<
EGLuint64KHR
>
modifiers
(
numModifiers
);
198
if
(!
m_eglQueryDmaBufModifiersEXT
(
display
,
format
,
numModifiers
,
modifiers
.
data
(),
nullptr
,
199
&
numModifiers
))
200
return
std
::
nullopt
;
201
202
return
ranges
::
find
(
modifiers
,
EGLuint64KHR
(
qToUnderlying
(
modifier
))) !=
modifiers
.
end
();
203
#
else
204
Q_UNUSED
(
display
);
205
Q_UNUSED
(
drmFormat
);
206
Q_UNUSED
(
modifier
);
207
return
std
::
nullopt
;
208
#
endif
209
}
210
211
std
::
optional
<
bool
>
212
QEglImageFunctions
::
isDmaBufModifierExternalOesOnly
([[
maybe_unused
]]
EGLDisplay
display
,
213
[[
maybe_unused
]]
DRMFormat
drmFormat
,
214
[[
maybe_unused
]]
DRMModifier
modifier
)
const
215
{
216
#
if
defined
(
EGL_EXT_image_dma_buf_import_modifiers
)
217
if
(!
m_eglQueryDmaBufModifiersEXT
)
218
return
std
::
nullopt
;
219
220
const
EGLint
format
=
EGLint
(
qToUnderlying
(
drmFormat
));
221
EGLint
numModifiers
= 0;
222
if
(!
m_eglQueryDmaBufModifiersEXT
(
display
,
format
, 0,
nullptr
,
nullptr
, &
numModifiers
)
223
||
numModifiers
<= 0)
224
return
std
::
nullopt
;
225
226
std
::
vector
<
EGLuint64KHR
>
modifiers
(
numModifiers
);
227
std
::
vector
<
EGLBoolean
>
externalOnly
(
numModifiers
);
228
if
(!
m_eglQueryDmaBufModifiersEXT
(
display
,
format
,
numModifiers
,
modifiers
.
data
(),
229
externalOnly
.
data
(), &
numModifiers
))
230
return
std
::
nullopt
;
231
232
const
auto
it
=
ranges
::
find
(
modifiers
,
qToUnderlying
(
modifier
));
233
if
(
it
==
modifiers
.
end
())
234
return
std
::
nullopt
;
235
return
externalOnly
[
it
-
modifiers
.
begin
()] == EGL_TRUE;
236
#
else
237
return
std
::
nullopt
;
238
#
endif
239
}
240
241
}
// namespace QtMultimediaPrivate
242
243
QT_END_NAMESPACE
QtMultimediaPrivate::impl
Definition
qaudiosystem_p.h:257
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtmultimedia
src
multimedia
video
qeglimagefunctions.cpp
Generated on
for Qt by
1.18.0