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
sharedtextureprovider.cpp
Go to the documentation of this file.
1
// Copyright (C) 2019 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
// Qt-Security score:significant reason:default
4
5
#
include
"sharedtextureprovider_p.h"
6
7
#
include
<
QFile
>
8
#
include
<
QDebug
>
9
#
include
<
qopenglfunctions
.
h
>
10
#
include
<
QQuickWindow
>
11
12
#
include
<
QtWaylandClient
/
private
/
qwaylandintegration_p
.
h
>
13
#
include
<
QtWaylandClient
/
private
/
qwaylandserverbufferintegration_p
.
h
>
14
#
include
<
QtGui
/
QGuiApplication
>
15
#
include
<
QtGui
/
private
/
qguiapplication_p
.
h
>
16
#
include
<
QtQuick
/
private
/
qsgrhisupport_p
.
h
>
17
#
include
<
QtGui
/
qpa
/
qplatformnativeinterface
.
h
>
18
#
include
<
QtGui
/
QWindow
>
19
#
include
<
QOpenGLTexture
>
20
#
include
<
QImageReader
>
21
22
#
include
<
QtCore
/
qpointer
.
h
>
23
#
include
<
QTimer
>
24
25
#
include
"texturesharingextension_p.h"
26
27
QT_BEGIN_NAMESPACE
28
29
class
SharedTextureFactory :
public
QQuickTextureFactory
30
{
31
public
:
32
SharedTextureFactory
(
const
QtWaylandClient
::QWaylandServerBuffer *buffer,
const
QString &id,
SharedTextureRegistry
*registry)
33
: m_buffer(buffer),
m_id
(
id
),
m_registry
(
registry
)
34
{
35
}
36
37
~
SharedTextureFactory
()
override
38
{
39
//qDebug() << "====> DESTRUCTOR SharedTextureFactory" << this;
40
if
(m_registry)
41
m_registry->abandonBuffer(m_id);
42
delete
m_buffer;
// TODO: make sure we are not keeping references to this elsewhere
43
//qDebug() << "buffer deleted";
44
}
45
46
QSize
textureSize
()
const
override
47
{
48
return
m_buffer ? m_buffer->size() : QSize();
49
}
50
51
int
textureByteCount
()
const
override
52
{
53
return
m_buffer ? (m_buffer->size().width() * m_buffer->size().height() * 4) : 0;
54
}
55
56
QSGTexture
*
createTexture
(QQuickWindow *window)
const
override
57
{
58
if
(m_buffer !=
nullptr
) {
59
QOpenGLTexture *texture =
const_cast
<
QtWaylandClient
::QWaylandServerBuffer *>(m_buffer)->toOpenGlTexture();
60
return
QNativeInterface::QSGOpenGLTexture::fromNative(texture->textureId(),
61
window,
62
m_buffer->size(),
63
QQuickWindow::TextureHasAlphaChannel);
64
}
65
return
nullptr
;
66
}
67
68
private
:
69
const
QtWaylandClient
::QWaylandServerBuffer *m_buffer =
nullptr
;
70
QString m_id;
71
QPointer<SharedTextureRegistry> m_registry;
72
};
73
74
75
SharedTextureRegistry
::SharedTextureRegistry()
76
: m_extension(
new
TextureSharingExtension
)
77
{
78
connect(m_extension, &TextureSharingExtension::bufferReceived,
this
, &SharedTextureRegistry::receiveBuffer);
79
connect(m_extension, &TextureSharingExtension::activeChanged,
this
, &SharedTextureRegistry::handleExtensionActive);
80
}
81
82
SharedTextureRegistry
::~
SharedTextureRegistry
()
83
{
84
delete
m_extension;
85
}
86
87
const
QtWaylandClient
::QWaylandServerBuffer *
SharedTextureRegistry
::
bufferForId
(
const
QString &id)
const
88
{
89
return
m_buffers.value(id);
90
}
91
92
void
SharedTextureRegistry
::
requestBuffer
(
const
QString &id)
93
{
94
if
(!m_extension->isActive()) {
95
//qDebug() << "Extension not active, adding" << id << "to queue";
96
m_pendingBuffers << id;
97
return
;
98
}
99
m_extension->requestImage(id);
100
}
101
102
void
SharedTextureRegistry
::
abandonBuffer
(
const
QString &id)
103
{
104
m_buffers.remove(id);
105
m_extension->abandonImage(id);
106
}
107
108
109
void
SharedTextureRegistry
::handleExtensionActive()
110
{
111
//qDebug() << "handleExtensionActive, queue:" << m_pendingBuffers;
112
if
(m_extension->isActive())
113
while
(!m_pendingBuffers.isEmpty())
114
requestBuffer(m_pendingBuffers.takeFirst());
115
}
116
117
bool
SharedTextureRegistry
::
preinitialize
()
118
{
119
if
(QSGRhiSupport::instance()->rhiBackend() != QRhi::OpenGLES2) {
120
qWarning() <<
"The shared-texture extension is only supported on OpenGL. Use QQuickWindow::setSceneGraphBackend() to override the default."
;
121
return
false
;
122
}
123
124
auto
*serverBufferIntegration = QGuiApplicationPrivate::platformIntegration()->nativeInterface()->nativeResourceForIntegration(
"server_buffer_integration"
);
125
126
if
(!serverBufferIntegration) {
127
qWarning() <<
"Wayland Server Buffer Integration not available."
;
128
return
false
;
129
}
130
131
return
true
;
132
}
133
134
void
SharedTextureRegistry
::receiveBuffer(
QtWaylandClient
::QWaylandServerBuffer *buffer,
const
QString& id)
135
{
136
//qDebug() << "ReceiveBuffer for id" << id;
137
if
(buffer)
138
m_buffers.insert(id, buffer);
139
emit replyReceived(id);
140
}
141
142
class
SharedTextureImageResponse
:
public
QQuickImageResponse
143
{
144
Q_OBJECT
145
public
:
146
SharedTextureImageResponse
(
SharedTextureRegistry
*
registry
,
const
QString
&
id
)
147
:
m_id
(
id
),
m_registry
(
registry
)
148
{
149
if
(!
m_registry
||
m_registry
->
bufferForId
(
id
)) {
150
// Shortcut: no server roundtrip needed, just let the event loop call the slot
151
QMetaObject
::
invokeMethod
(
this
,
"doResponse"
,
Qt
::
QueuedConnection
,
Q_ARG
(
QString
,
id
));
152
153
}
else
{
154
// TBD: timeout?
155
connect
(
registry
, &
SharedTextureRegistry
::
replyReceived
,
this
, &
SharedTextureImageResponse
::
doResponse
);
156
registry
->
requestBuffer
(
id
);
157
}
158
}
159
160
QQuickTextureFactory
*
textureFactory
()
const
override
161
{
162
if
(
m_registry
) {
163
const
QtWaylandClient
::
QWaylandServerBuffer
*
buffer
=
m_registry
->
bufferForId
(
m_id
);
164
if
(
buffer
) {
165
//qDebug() << "Creating shared buffer texture for" << m_id;
166
return
new
SharedTextureFactory
(
buffer
,
m_id
,
m_registry
);
167
}
168
//qDebug() << "Shared buffer NOT found for" << m_id;
169
}
170
171
// No shared buffer, do fallback
172
QString
fbPath
=
fallbackPath
();
173
if
(
fbPath
.
isEmpty
()) {
174
m_errorString
=
QStringLiteral
(
"Shared buffer not found, and no fallback path set."
);
175
return
nullptr
;
176
}
177
178
QImageReader
reader
(
fbPath
+
m_id
);
179
QImage
img
=
reader
.
read
();
180
if
(
img
.
isNull
()) {
181
qWarning
() <<
"Could not load local image from id/path"
<<
reader
.
fileName
();
182
m_errorString
=
QStringLiteral
(
"Shared buffer not found, and fallback local file loading failed: "
) +
reader
.
errorString
();
183
return
nullptr
;
184
}
185
return
QQuickTextureFactory
::
textureFactoryForImage
(
img
);
186
}
187
188
QString
errorString
()
const
override
189
{
190
return
m_errorString
;
191
}
192
193
static
QString
fallbackPath
()
194
{
195
static
QString
fbPath
;
196
static
bool
isInit
=
false
;
197
if
(!
isInit
) {
198
isInit
=
true
;
199
QByteArray
envVal
=
qgetenv
(
"QT_SHAREDTEXTURE_FALLBACK_DIR"
);
200
if
(!
envVal
.
isEmpty
()) {
201
fbPath
=
QString
::
fromLocal8Bit
(
envVal
);
202
if
(!
fbPath
.
endsWith
(
QLatin1Char
(
'/'
)))
203
fbPath
.
append
(
QLatin1Char
(
'/'
));
204
}
205
}
206
return
fbPath
;
207
}
208
209
210
public
Q_SLOTS
:
211
void
doResponse
(
const
QString
&
key
) {
212
if
(
key
!=
m_id
)
213
return
;
// not our buffer
214
215
// No need to be called again
216
if
(
m_registry
)
217
disconnect
(
m_registry
, &
SharedTextureRegistry
::
replyReceived
,
this
, &
SharedTextureImageResponse
::
doResponse
);
218
219
emit
finished
();
220
}
221
222
private
:
223
QString
m_id
;
224
SharedTextureRegistry
*m_registry =
nullptr
;
225
mutable
QString m_errorString;
226
};
227
228
229
SharedTextureProvider
::
SharedTextureProvider
()
230
{
231
m_sharingAvailable =
SharedTextureRegistry
::
preinitialize
(
)
;
232
if
(!m_sharingAvailable) {
233
if
(SharedTextureImageResponse::fallbackPath().isEmpty())
234
qWarning() <<
"Shared buffer images not available, and no fallback directory set."
;
235
else
236
qWarning() <<
"Shared buffer images not available, will fallback to local image files from"
<< SharedTextureImageResponse::fallbackPath();
237
}
238
}
239
240
SharedTextureProvider
::~
SharedTextureProvider
()
241
{
242
delete
m_registry;
243
}
244
245
QQuickImageResponse
*
SharedTextureProvider
::
requestImageResponse
(
const
QString &id,
const
QSize &requestedSize)
246
{
247
Q_UNUSED(requestedSize);
248
249
//qDebug() << "Provider: got request for" << id;
250
251
if
(m_sharingAvailable && !m_registry)
252
m_registry =
new
SharedTextureRegistry
;
253
254
return
new
SharedTextureImageResponse
(m_registry, id);
255
}
256
257
QT_END_NAMESPACE
258
259
#
include
"moc_sharedtextureprovider_p.cpp"
260
261
#
include
"sharedtextureprovider.moc"
SharedTextureFactory::createTexture
QSGTexture * createTexture(QQuickWindow *window) const override
This function is called on the scene graph rendering thread to create a QSGTexture instance from the ...
Definition
sharedtextureprovider.cpp:56
SharedTextureFactory::SharedTextureFactory
SharedTextureFactory(const QtWaylandClient::QWaylandServerBuffer *buffer, const QString &id, SharedTextureRegistry *registry)
Definition
sharedtextureprovider.cpp:32
SharedTextureFactory::textureSize
QSize textureSize() const override
Returns the size of the texture.
Definition
sharedtextureprovider.cpp:46
SharedTextureFactory::~SharedTextureFactory
~SharedTextureFactory() override
Definition
sharedtextureprovider.cpp:37
SharedTextureFactory::textureByteCount
int textureByteCount() const override
Returns the number of bytes of memory the texture consumes.
Definition
sharedtextureprovider.cpp:51
SharedTextureImageResponse
Definition
qwltexturesharingextension.cpp:70
SharedTextureProvider
Definition
sharedtextureprovider_p.h:60
SharedTextureProvider::SharedTextureProvider
SharedTextureProvider()
Definition
sharedtextureprovider.cpp:229
SharedTextureProvider::~SharedTextureProvider
~SharedTextureProvider() override
Definition
sharedtextureprovider.cpp:240
SharedTextureProvider::requestImageResponse
QQuickImageResponse * requestImageResponse(const QString &id, const QSize &requestedSize) override
Implement this method to return the job that will provide the texture with id.
Definition
sharedtextureprovider.cpp:245
SharedTextureRegistry
Definition
sharedtextureprovider_p.h:32
SharedTextureRegistry::bufferForId
const QtWaylandClient::QWaylandServerBuffer * bufferForId(const QString &id) const
Definition
sharedtextureprovider.cpp:87
SharedTextureRegistry::preinitialize
static bool preinitialize()
Definition
sharedtextureprovider.cpp:117
SharedTextureRegistry::abandonBuffer
void abandonBuffer(const QString &id)
Definition
sharedtextureprovider.cpp:102
SharedTextureRegistry::requestBuffer
void requestBuffer(const QString &id)
Definition
sharedtextureprovider.cpp:92
SharedTextureRegistry::~SharedTextureRegistry
~SharedTextureRegistry() override
Definition
sharedtextureprovider.cpp:82
TextureSharingExtension
Definition
texturesharingextension_p.h:34
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtWaylandClient
Definition
qwaylandclientextension.h:16
qtwayland
src
imports
texture-sharing
sharedtextureprovider.cpp
Generated on
for Qt by
1.18.0