blob: c1ff86977f11d0e70d7c679316a0b5c0ca321dc6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qwltextureorphanage_p.h"
#include <QOpenGLContext>
#include <QOpenGLTexture>
#include <QDebug>
#include <QtTypeTraits>
#include <QMutexLocker>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcWTO, "qt.waylandcompositor.orphanage")
Q_GLOBAL_STATIC(QtWayland::QWaylandTextureOrphanage, inst)
namespace QtWayland {
QWaylandTextureOrphanage::~QWaylandTextureOrphanage()
{
QMutexLocker locker(&m_containerLock);
if (!m_orphanedTextures.isEmpty()) {
qCWarning(qLcWTO) << Q_FUNC_INFO << "m_orphanedTextures container isn't empty! content:"
<< m_orphanedTextures;
}
}
QWaylandTextureOrphanage *QWaylandTextureOrphanage::instance()
{
return inst;
}
void QWaylandTextureOrphanage::admitTexture(QOpenGLTexture *tex, QOpenGLContext *ctx)
{
qCDebug(qLcWTO) << Q_FUNC_INFO << "got a texture (" << (void *)tex
<< ") ready to be deleted! It's ctx:" << ctx;
{
QMutexLocker locker(&m_containerLock);
m_orphanedTextures.insert(ctx, tex);
}
connect(ctx, &QOpenGLContext::aboutToBeDestroyed, this,
[this, ctx]() { this->onContextAboutToBeDestroyed(ctx); },
Qt::ConnectionType(Qt::DirectConnection));
}
void QWaylandTextureOrphanage::deleteTextures()
{
QOpenGLContext *cCtx = QOpenGLContext::currentContext();
if (cCtx == nullptr) {
qCWarning(qLcWTO) << Q_FUNC_INFO << "cannot delete textures without current OpenGL context";
return;
}
{
QMutexLocker locker(&m_containerLock);
for (QOpenGLContext *aCtx : m_orphanedTextures.keys()) {
if (QOpenGLContext::areSharing(cCtx, aCtx)) {
qCDebug(qLcWTO) << Q_FUNC_INFO << "currentContext (" << cCtx
<< ") and ctx of orphane(s) (" << aCtx
<< ") are shared! => deleteTexturesByContext";
deleteTexturesByContext(aCtx);
}
}
}
}
void QWaylandTextureOrphanage::onContextAboutToBeDestroyed(QOpenGLContext *ctx)
{
Q_ASSERT(ctx != nullptr);
qCDebug(qLcWTO) << Q_FUNC_INFO << " ctx (" << ctx
<< ") fired aboutToBeDestroyed => deleteTexturesByContext(ctx)";
{
QMutexLocker locker(&m_containerLock);
deleteTexturesByContext(ctx);
}
}
void QWaylandTextureOrphanage::deleteTexturesByContext(QOpenGLContext *ctx)
{
// NOTE: We are (by class-internal design) locked (m_containerLock)
// when we enter this function!
// If not (e.g.: someone changes something in/around this class),
// then in a debug-build we will fail below:
Q_ASSERT(!m_containerLock.tryLock());
QList<QOpenGLTexture *> texturesToDelete = m_orphanedTextures.values(ctx);
m_orphanedTextures.remove(ctx);
for (QOpenGLTexture *tex : texturesToDelete) {
delete tex;
qCDebug(qLcWTO) << Q_FUNC_INFO << " texture (" << (void *)tex << ") got deleted";
}
}
} // namespace QtWayland
QT_END_NAMESPACE
#include "moc_qwltextureorphanage_p.cpp"
|