Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qssguserrenderpassmanager.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7#include "graphobjects/qssgrenderuserpass_p.h"
8
9#include <QtCore/qloggingcategory.h>
10
12
13Q_STATIC_LOGGING_CATEGORY(QSSGUserRenderPassManagerLog, "qt.quick3d.runtimerender.userpassmanager")
14
15QSSGUserRenderPassManager::QSSGUserRenderPassManager(Private)
16{
17
18}
19
20QSSGUserRenderPassManager::~QSSGUserRenderPassManager()
21{
22 for (auto &rt : m_renderPassRenderTargets)
23 rt.reset();
24
25 const auto textures = m_trackedTextures.keys();
26 qDeleteAll(textures);
27}
28
29void QSSGUserRenderPassManager::scheduleUserPass(QSSGRenderUserPass *userPasses)
30{
31 if (userPasses != nullptr) {
32 auto it = std::find(m_scheduledUserPasses.begin(), m_scheduledUserPasses.end(), userPasses);
33 if (it == m_scheduledUserPasses.end()) {
34 m_scheduledUserPasses.push_back(userPasses);
35 m_passlistDirty = true;
36 }
37 }
38}
39
40void QSSGUserRenderPassManager::unscheduleUserPass(const QSSGRenderUserPass *userPasses)
41{
42 if (userPasses != nullptr) {
43 auto it = std::find(m_scheduledUserPasses.cbegin(), m_scheduledUserPasses.cend(), userPasses);
44 if (it != m_scheduledUserPasses.cend()) {
45 m_scheduledUserPasses.erase(it);
46 m_passlistDirty = true;
47 }
48 }
49}
50
51QSSGRhiRenderableTextureV2Ptr QSSGUserRenderPassManager::getOrCreateRenderableTexture(const QSSGRenderUserPass &userPass)
52{
53 auto it = m_renderPassRenderTargets.find(&userPass);
54 if (it != m_renderPassRenderTargets.end())
55 return it.value();
56
57 auto iter = m_renderPassRenderTargets.insert(&userPass, std::make_shared<QSSGRhiRenderableTextureV2>(shared_from_this(), QSSGRhiRenderableTextureV2::Private::Initialize));
58 return iter.value();
59}
60
61QSSGRhiRenderableTextureV2Ptr QSSGUserRenderPassManager::getUserPassTexureResult(const QSSGRenderUserPass &userPass) const
62{
63 const auto foundIt = m_renderPassRenderTargets.find(&userPass);
64 if (foundIt != m_renderPassRenderTargets.end())
65 return foundIt.value();
66
67 return {};
68}
69
70void QSSGUserRenderPassManager::updateUserPassOrder(bool forceUpdate)
71{
72 if (m_passlistDirty || forceUpdate) {
73 std::sort(m_scheduledUserPasses.begin(), m_scheduledUserPasses.end(), [](const QSSGRenderUserPass *a, const QSSGRenderUserPass *b) {
74 return a->m_dependencyIndex > b->m_dependencyIndex;
75 });
76 }
77
78 m_passlistDirty = false;
79}
80
81bool QSSGUserRenderPassManager::derefTexture(QRhiTexture *texture)
82{
83 auto foundIt = m_trackedTextures.find(texture);
84 const bool wasFound = foundIt != m_trackedTextures.constEnd();
85
86 if (wasFound) {
87 if (!(foundIt.value() > 1)) {
88 m_trackedTextures.erase(foundIt);
89 m_deferredReleaseTextures.insert(texture);
90 } else {
91 foundIt.value() -= 1;
92 }
93 } else {
94 qWarning() << "QSSGUserRenderPassManager::derefTexture: Trying to deref a texture that is not tracked.";
95 }
96
97 return wasFound;
98}
99
100void QSSGUserRenderPassManager::refTexture(QRhiTexture *texture)
101{
102 auto it = m_trackedTextures.find(texture);
103 if (it != m_trackedTextures.end())
104 it.value() += 1;
105 else
106 m_trackedTextures.insert(texture, 1);
107}
108
109bool QSSGUserRenderPassManager::derefTexture(const std::unique_ptr<QRhiTexture> &texture)
110{
111 return derefTexture(texture.get());
112}
113
114void QSSGUserRenderPassManager::refTexture(const std::unique_ptr<QRhiTexture> &texture)
115{
116 refTexture(texture.get());
117}
118
119void QSSGUserRenderPassManager::unregisterManagedTexture(QSSGManagedRhiTexture *textureWrapper)
120{
121 QSSG_ASSERT(textureWrapper != nullptr, return);
122
123 const auto foundIt = std::find(m_trackedTextureWrappers.cbegin(), m_trackedTextureWrappers.cend(), textureWrapper);
124 if (foundIt != m_trackedTextureWrappers.cend()) {
125 auto &texture = textureWrapper->texture();
126 if (!derefTexture(texture))
127 qWarning("QSSGSharedRhiTextureWrapper: Texture was not tracked by the manager, possible resource leak.");
128 m_trackedTextureWrappers.erase(foundIt);
129 }
130}
131
132void QSSGUserRenderPassManager::registerManagedTexture(QSSGManagedRhiTexture *textureWrapper)
133{
134 QSSG_ASSERT(textureWrapper != nullptr, return);
135
136 const auto foundIt = std::find(m_trackedTextureWrappers.cbegin(), m_trackedTextureWrappers.cend(), textureWrapper);
137 if (foundIt == m_trackedTextureWrappers.cend()) {
138 refTexture(textureWrapper->texture());
139 m_trackedTextureWrappers.push_back(textureWrapper);
140 }
141}
142
143void QSSGUserRenderPassManager::resetForFrame()
144{
145 qDeleteAll(m_deferredReleaseTextures.cbegin(), m_deferredReleaseTextures.cend());
146 m_deferredReleaseTextures.clear();
147}
148
149void QSSGUserRenderPassManager::releaseAll()
150{
151 m_scheduledUserPasses.clear();
152
153 // NOTE: We own these so we'll invalidate them, meaning releasing their internal resources.
154 // Any shared pointers to them held elsewhere will become invalid, as in they will
155 // get their internal QRhiTexture released and set to nullptr.
156 for (auto &rt : m_renderPassRenderTargets)
157 rt->invalidate();
158
159 m_renderPassRenderTargets.clear();
160
161 { // We make a copy since invalidate() will call back into us to unregister itself!
162 auto cpy = m_trackedTextureWrappers;
163 for (auto &tw : cpy)
164 tw->invalidate();
165
166 cpy.clear();
167 }
168
169 qDeleteAll(m_deferredReleaseTextures.cbegin(), m_deferredReleaseTextures.cend());
170 m_deferredReleaseTextures.clear();
171
172 Q_ASSERT(m_trackedTextureWrappers.size() == 0);
173
174 if (m_trackedTextures.size() > 0) {
175 qWarning() << "QSSGUserRenderPassManager::releaseAll: There are still tracked textures (" << m_trackedTextures.size() << ") when releasing all. This indicates a resource leak.";
176 for (auto it = m_trackedTextures.constBegin(); it != m_trackedTextures.constEnd(); ++it)
177 qCDebug(QSSGUserRenderPassManagerLog) << "Texture: " << it.key()->name() << ", has ref count: " << it.value();
178 }
179}
180
181QT_END_NAMESPACE
Combined button and popup list for selecting options.