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 // stable_sort preserves QML declaration order for passes with
74 // equal dependency indices.
75 std::stable_sort(m_scheduledUserPasses.begin(), m_scheduledUserPasses.end(), [](const QSSGRenderUserPass *a, const QSSGRenderUserPass *b) {
76 return a->m_dependencyIndex > b->m_dependencyIndex;
77 });
78 }
79
80 m_passlistDirty = false;
81}
82
83bool QSSGUserRenderPassManager::derefTexture(QRhiTexture *texture)
84{
85 auto foundIt = m_trackedTextures.find(texture);
86 const bool wasFound = foundIt != m_trackedTextures.end();
87
88 if (wasFound) {
89 if (!(foundIt.value() > 1)) {
90 m_trackedTextures.erase(foundIt);
91 m_deferredReleaseTextures.insert(texture);
92 } else {
93 foundIt.value() -= 1;
94 }
95 } else {
96 qWarning() << "QSSGUserRenderPassManager::derefTexture: Trying to deref a texture that is not tracked.";
97 }
98
99 return wasFound;
100}
101
102void QSSGUserRenderPassManager::refTexture(QRhiTexture *texture)
103{
104 auto it = m_trackedTextures.find(texture);
105 if (it != m_trackedTextures.end())
106 it.value() += 1;
107 else
108 m_trackedTextures.insert(texture, 1);
109}
110
111bool QSSGUserRenderPassManager::derefTexture(const std::unique_ptr<QRhiTexture> &texture)
112{
113 return derefTexture(texture.get());
114}
115
116void QSSGUserRenderPassManager::refTexture(const std::unique_ptr<QRhiTexture> &texture)
117{
118 refTexture(texture.get());
119}
120
121void QSSGUserRenderPassManager::unregisterManagedTexture(QSSGManagedRhiTexture *textureWrapper)
122{
123 QSSG_ASSERT(textureWrapper != nullptr, return);
124
125 const auto foundIt = std::find(m_trackedTextureWrappers.cbegin(), m_trackedTextureWrappers.cend(), textureWrapper);
126 if (foundIt != m_trackedTextureWrappers.cend()) {
127 auto &texture = textureWrapper->texture();
128 if (!derefTexture(texture))
129 qWarning("QSSGSharedRhiTextureWrapper: Texture was not tracked by the manager, possible resource leak.");
130 m_trackedTextureWrappers.erase(foundIt);
131 }
132}
133
134void QSSGUserRenderPassManager::registerManagedTexture(QSSGManagedRhiTexture *textureWrapper)
135{
136 QSSG_ASSERT(textureWrapper != nullptr, return);
137
138 const auto foundIt = std::find(m_trackedTextureWrappers.cbegin(), m_trackedTextureWrappers.cend(), textureWrapper);
139 if (foundIt == m_trackedTextureWrappers.cend()) {
140 refTexture(textureWrapper->texture());
141 m_trackedTextureWrappers.push_back(textureWrapper);
142 }
143}
144
145qsizetype QSSGUserRenderPassManager::acquireUserPassSlot()
146{
147 if (m_userPassSlotsUsed < maxUserPassSlots() - 1)
148 return qsizetype(m_userPassSlotsUsed++);
149
150 qWarning() << "Exceeded maximum number of user render passes(" << QSSGUserRenderPassManager::maxUserPassSlots() << ")";
151
152 return -1;
153}
154
155void QSSGUserRenderPassManager::resetForFrame()
156{
157 qDeleteAll(m_deferredReleaseTextures.cbegin(), m_deferredReleaseTextures.cend());
158 m_deferredReleaseTextures.clear();
159
160 m_userPassSlotsUsed = 0;
161}
162
163void QSSGUserRenderPassManager::releaseAll()
164{
165 m_scheduledUserPasses.clear();
166
167 // NOTE: We own these so we'll invalidate them, meaning releasing their internal resources.
168 // Any shared pointers to them held elsewhere will become invalid, as in they will
169 // get their internal QRhiTexture released and set to nullptr.
170 for (auto &rt : m_renderPassRenderTargets)
171 rt->invalidate();
172
173 m_renderPassRenderTargets.clear();
174
175 { // We make a copy since invalidate() will call back into us to unregister itself!
176 auto cpy = m_trackedTextureWrappers;
177 for (auto &tw : cpy)
178 tw->invalidate();
179
180 cpy.clear();
181 }
182
183 qDeleteAll(m_deferredReleaseTextures.cbegin(), m_deferredReleaseTextures.cend());
184 m_deferredReleaseTextures.clear();
185
186 Q_ASSERT(m_trackedTextureWrappers.size() == 0);
187
188 if (m_trackedTextures.size() > 0) {
189 qWarning() << "QSSGUserRenderPassManager::releaseAll: There are still tracked textures (" << m_trackedTextures.size() << ") when releasing all. This indicates a resource leak.";
190 for (auto it = m_trackedTextures.constBegin(); it != m_trackedTextures.constEnd(); ++it)
191 qCDebug(QSSGUserRenderPassManagerLog) << "Texture: " << it.key()->name() << ", has ref count: " << it.value();
192 }
193}
194
195QT_END_NAMESPACE
Combined button and popup list for selecting options.