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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtwayland/src/compositor/hardware_integration/qwltextureorphanage.cpp