7#include "graphobjects/qssgrenderuserpass_p.h"
9#include <QtCore/qloggingcategory.h>
13Q_STATIC_LOGGING_CATEGORY(QSSGUserRenderPassManagerLog,
"qt.quick3d.runtimerender.userpassmanager")
15QSSGUserRenderPassManager::QSSGUserRenderPassManager(Private)
20QSSGUserRenderPassManager::~QSSGUserRenderPassManager()
22 for (
auto &rt : m_renderPassRenderTargets)
25 const auto textures = m_trackedTextures.keys();
29void QSSGUserRenderPassManager::setScheduledPasses(
const UserPassSet &topLevelPasses)
34 m_scheduledUserPasses = topLevelPasses;
35 m_passlistDirty =
true;
38void QSSGUserRenderPassManager::scheduleUserPass(QSSGRenderUserPass *userPasses)
40 if (userPasses ==
nullptr)
49 if (userPasses->role != QSSGRenderUserPass::Role::TopLevel) {
50 if (!m_subPassScheduleWarned.contains(userPasses)) {
51 m_subPassScheduleWarned.insert(userPasses);
52 qWarning() <<
"Ignoring request to schedule sub-pass" << userPasses
53 <<
"; a sub-pass renders into its parent's render target and produces no output of its own."
54 " A RenderOutputProvider must reference a top-level RenderPass.";
59 m_subPassScheduleWarned.remove(userPasses);
61 auto it = std::find(m_scheduledUserPasses.begin(), m_scheduledUserPasses.end(), userPasses);
62 if (it == m_scheduledUserPasses.end()) {
63 m_scheduledUserPasses.push_back(userPasses);
64 m_passlistDirty =
true;
68void QSSGUserRenderPassManager::unscheduleUserPass(
const QSSGRenderUserPass *userPasses)
70 if (userPasses !=
nullptr) {
71 auto it = std::find(m_scheduledUserPasses.cbegin(), m_scheduledUserPasses.cend(), userPasses);
72 if (it != m_scheduledUserPasses.cend()) {
73 m_scheduledUserPasses.erase(it);
74 m_passlistDirty =
true;
79QSSGRhiRenderableTextureV2Ptr QSSGUserRenderPassManager::getOrCreateRenderableTexture(
const QSSGRenderUserPass &userPass)
81 auto it = m_renderPassRenderTargets.find(&userPass);
82 if (it != m_renderPassRenderTargets.end())
85 auto iter = m_renderPassRenderTargets.insert(&userPass, std::make_shared<QSSGRhiRenderableTextureV2>(shared_from_this(), QSSGRhiRenderableTextureV2::Private::Initialize));
89QSSGRhiRenderableTextureV2Ptr QSSGUserRenderPassManager::getUserPassTexureResult(
const QSSGRenderUserPass &userPass)
const
91 const auto foundIt = m_renderPassRenderTargets.find(&userPass);
92 if (foundIt != m_renderPassRenderTargets.end())
93 return foundIt.value();
98void QSSGUserRenderPassManager::updateUserPassOrder(
bool forceUpdate)
100 if (m_passlistDirty || forceUpdate) {
105 std::sort(m_scheduledUserPasses.begin(), m_scheduledUserPasses.end(), [](
const QSSGRenderUserPass *a,
const QSSGRenderUserPass *b) {
106 if (a->m_nestingDepth != b->m_nestingDepth)
107 return a->m_nestingDepth > b->m_nestingDepth;
108 return a->m_declarationOrder < b->m_declarationOrder;
112 m_passlistDirty =
false;
115bool QSSGUserRenderPassManager::derefTexture(QRhiTexture *texture)
117 auto foundIt = m_trackedTextures.find(texture);
118 const bool wasFound = foundIt != m_trackedTextures.end();
121 if (!(foundIt.value() > 1)) {
122 m_trackedTextures.erase(foundIt);
123 m_deferredReleaseTextures.insert(texture);
125 foundIt.value() -= 1;
128 qWarning() <<
"QSSGUserRenderPassManager::derefTexture: Trying to deref a texture that is not tracked.";
134void QSSGUserRenderPassManager::refTexture(QRhiTexture *texture)
136 auto it = m_trackedTextures.find(texture);
137 if (it != m_trackedTextures.end())
140 m_trackedTextures.insert(texture, 1);
143bool QSSGUserRenderPassManager::derefTexture(
const std::unique_ptr<QRhiTexture> &texture)
145 return derefTexture(texture.get());
148void QSSGUserRenderPassManager::refTexture(
const std::unique_ptr<QRhiTexture> &texture)
150 refTexture(texture.get());
153void QSSGUserRenderPassManager::unregisterManagedTexture(QSSGManagedRhiTexture *textureWrapper)
155 QSSG_ASSERT(textureWrapper !=
nullptr,
return);
157 const auto foundIt = std::find(m_trackedTextureWrappers.cbegin(), m_trackedTextureWrappers.cend(), textureWrapper);
158 if (foundIt != m_trackedTextureWrappers.cend()) {
159 auto &texture = textureWrapper->texture();
160 if (!derefTexture(texture))
161 qWarning(
"QSSGSharedRhiTextureWrapper: Texture was not tracked by the manager, possible resource leak.");
162 m_trackedTextureWrappers.erase(foundIt);
166void QSSGUserRenderPassManager::registerManagedTexture(QSSGManagedRhiTexture *textureWrapper)
168 QSSG_ASSERT(textureWrapper !=
nullptr,
return);
170 const auto foundIt = std::find(m_trackedTextureWrappers.cbegin(), m_trackedTextureWrappers.cend(), textureWrapper);
171 if (foundIt == m_trackedTextureWrappers.cend()) {
172 refTexture(textureWrapper->texture());
173 m_trackedTextureWrappers.push_back(textureWrapper);
177qsizetype QSSGUserRenderPassManager::acquireUserPassSlot()
179 if (m_userPassSlotsUsed < maxUserPassSlots() - 1)
180 return qsizetype(m_userPassSlotsUsed++);
182 qWarning() <<
"Exceeded maximum number of user render passes(" << QSSGUserRenderPassManager::maxUserPassSlots() <<
")";
187void QSSGUserRenderPassManager::resetForFrame()
189 qDeleteAll(m_deferredReleaseTextures.cbegin(), m_deferredReleaseTextures.cend());
190 m_deferredReleaseTextures.clear();
192 m_userPassSlotsUsed = 0;
195void QSSGUserRenderPassManager::releaseAll()
197 m_scheduledUserPasses.clear();
198 m_subPassScheduleWarned.clear();
203 for (
auto &rt : m_renderPassRenderTargets)
206 m_renderPassRenderTargets.clear();
209 auto cpy = m_trackedTextureWrappers;
216 qDeleteAll(m_deferredReleaseTextures.cbegin(), m_deferredReleaseTextures.cend());
217 m_deferredReleaseTextures.clear();
219 Q_ASSERT(m_trackedTextureWrappers.size() == 0);
221 if (m_trackedTextures.size() > 0) {
222 qWarning() <<
"QSSGUserRenderPassManager::releaseAll: There are still tracked textures (" << m_trackedTextures.size() <<
") when releasing all. This indicates a resource leak.";
223 for (
auto it = m_trackedTextures.constBegin(); it != m_trackedTextures.constEnd(); ++it)
224 qCDebug(QSSGUserRenderPassManagerLog) <<
"Texture: " << it.key()->name() <<
", has ref count: " << it.value();
Combined button and popup list for selecting options.